Implementation of a generic backend of eshop in Crystal
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

179 řádky
5.7 KiB

před 5 roky
  1. require "kemal"
  2. require "../*"
  3. require "io"
  4. require "file"
  5. require "exception"
  6. require "crypto/bcrypt/password"
  7. require "uuid"
  8. require "uuid/json"
  9. require "../../config"
  10. def authenticate(user : String, token : UUID) : (User | Nil)
  11. user_file = User.from_json File.read(Statics.data_path+"user/"+user)
  12. if nil == user_file.tokens.not_nil!.find{ |tok| token == tok}
  13. nil
  14. else
  15. user_file.password_hash = ""
  16. user_file
  17. end
  18. end
  19. def authenticate!(user : String, token : UUID) : User
  20. authenticate(user, token).not_nil!
  21. end
  22. def authenticate_admin!(user : String, token : UUID) : User
  23. user = authenticate(user, token).not_nil!
  24. if(user.type==UserType::Administrator)
  25. return user
  26. end
  27. raise "Administrator only"
  28. end
  29. post "/login" do |context|
  30. user : User
  31. user_file : User
  32. begin
  33. user = User.from_json context.request.body.not_nil!
  34. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  35. rescue ex
  36. halt context, status_code: 403, response: ex.to_s
  37. end
  38. if Crypto::Bcrypt::Password.new(user_file.password_hash.not_nil!) == user.password_hash.not_nil!
  39. else
  40. halt context, status_code: 403, response: "Invalid password"
  41. end
  42. token = UUID.random()
  43. if user_file.tokens.nil?
  44. user_file.tokens = Array(UUID).new
  45. user_file.tokens.not_nil!<<token
  46. else
  47. user_file.tokens.not_nil!<<token
  48. end
  49. if user_file.tokens.not_nil!.size>5
  50. user_file.tokens = user_file.tokens.not_nil!.last(5)
  51. end
  52. File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
  53. context.response.content_type = "application/json"
  54. token.to_json
  55. end
  56. post "/logout" do |context|
  57. user = User.from_json context.request.body.not_nil!
  58. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  59. user_file.tokens=user_file.tokens.not_nil!-user.tokens.not_nil!
  60. File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
  61. context.response.content_type = "application/json"
  62. "OK".to_json
  63. end
  64. post "/logout-all" do |context|
  65. user : User
  66. begin
  67. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  68. rescue ex
  69. halt context, status_code: 403, response: ex.to_s
  70. end
  71. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  72. user_file.tokens=Array(UUID).new
  73. File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
  74. context.response.content_type = "application/json"
  75. "OK".to_json
  76. end
  77. post "/user" do |context|
  78. user = User.from_json context.request.body.not_nil!
  79. ph = user.password_hash
  80. user.tokens = Array(UUID).new
  81. user.invoices = Array(Invoice).new
  82. if ph.nil?
  83. raise Exception.new("No password provided")
  84. else
  85. user.password_hash=Crypto::Bcrypt::Password.create(ph,cost: 12).to_s
  86. end
  87. if Statics.email_regex.match(user.email)==nil
  88. raise Exception.new("Bad email address")
  89. end
  90. if File.exists?(Statics.data_path+"user/"+user.email)
  91. raise Exception.new("Email address already in use")
  92. end
  93. File.write(Statics.data_path+"user/"+user.email,user.to_json)
  94. context.response.content_type = "application/json"
  95. "OK".to_json
  96. end
  97. get "/user/tokens" do |context|
  98. user : User
  99. begin
  100. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  101. rescue ex
  102. halt context, status_code: 403, response: ex.to_s
  103. end
  104. context.response.content_type = "application/json"
  105. user.tokens.to_json
  106. end
  107. get "/user/address" do |context|
  108. user : User
  109. begin
  110. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  111. rescue ex
  112. halt context, status_code: 403, response: ex.to_s
  113. end
  114. context.response.content_type = "application/json"
  115. user.addresses.to_json
  116. end
  117. post "/user/address" do |context|
  118. user : User
  119. begin
  120. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  121. rescue ex
  122. halt context, status_code: 403, response: ex.to_s
  123. end
  124. addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
  125. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  126. old_list=user_file.addresses
  127. if old_list.nil?
  128. else
  129. addresses=old_list+addresses
  130. end
  131. user_file.addresses=addresses
  132. File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
  133. context.response.content_type = "application/json"
  134. "OK".to_json
  135. end
  136. delete "/user/address" do |context|
  137. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  138. addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
  139. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  140. old_list=user_file.addresses
  141. if old_list.nil?
  142. addresses=Array(Address).new
  143. else
  144. addresses=old_list.select do |v|
  145. isin=false
  146. addresses.each do |va|
  147. isin |= v==va
  148. end
  149. !isin
  150. end
  151. end
  152. user_file.addresses=addresses
  153. File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
  154. context.response.content_type = "application/json"
  155. "OK".to_json
  156. end
  157. get "/user" do |context|
  158. context.response.content_type = "application/json"
  159. user : User | Nil
  160. begin
  161. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  162. rescue ex
  163. halt context, status_code: 403, response: ex.to_s
  164. end
  165. user.not_nil!
  166. end