Implementation of a generic backend of eshop in Crystal
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

170 righe
5.4 KiB

  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. File.write(Statics.data_path+"user/"+user.email,user.to_json)
  91. context.response.content_type = "application/json"
  92. "OK".to_json
  93. end
  94. get "/user/tokens" do |context|
  95. user : User
  96. begin
  97. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  98. rescue ex
  99. halt context, status_code: 403, response: ex.to_s
  100. end
  101. context.response.content_type = "application/json"
  102. user.tokens.to_json
  103. end
  104. get "/user/address" do |context|
  105. user : User
  106. begin
  107. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  108. rescue ex
  109. halt context, status_code: 403, response: ex.to_s
  110. end
  111. context.response.content_type = "application/json"
  112. user.addresses.to_json
  113. end
  114. post "/user/address" do |context|
  115. user : User
  116. begin
  117. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  118. rescue ex
  119. halt context, status_code: 403, response: ex.to_s
  120. end
  121. addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
  122. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  123. old_list=user_file.addresses
  124. if old_list.nil?
  125. else
  126. addresses=old_list+addresses
  127. end
  128. user_file.addresses=addresses
  129. File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
  130. context.response.content_type = "application/json"
  131. "OK".to_json
  132. end
  133. delete "/user/address" do |context|
  134. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  135. addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
  136. user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
  137. old_list=user_file.addresses
  138. if old_list.nil?
  139. addresses=Array(Address).new
  140. else
  141. addresses=old_list-addresses
  142. end
  143. user_file.addresses=addresses
  144. File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
  145. context.response.content_type = "application/json"
  146. "OK".to_json
  147. end
  148. get "/user" do |context|
  149. context.response.content_type = "application/json"
  150. user : User | Nil
  151. begin
  152. user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
  153. rescue ex
  154. halt context, status_code: 403, response: ex.to_s
  155. end
  156. user.not_nil!
  157. end