Implementation of a generic backend of eshop in Crystal
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 

170 lignes
5.4 KiB

require "kemal"
require "../*"
require "io"
require "file"
require "exception"
require "crypto/bcrypt/password"
require "uuid"
require "uuid/json"
require "../../config"
def authenticate(user : String, token : UUID) : (User | Nil)
user_file = User.from_json File.read(Statics.data_path+"user/"+user)
if nil == user_file.tokens.not_nil!.find{ |tok| token == tok}
nil
else
user_file.password_hash = ""
user_file
end
end
def authenticate!(user : String, token : UUID) : User
authenticate(user, token).not_nil!
end
def authenticate_admin!(user : String, token : UUID) : User
user = authenticate(user, token).not_nil!
if(user.type==UserType::Administrator)
return user
end
raise "Administrator only"
end
post "/login" do |context|
user : User
user_file : User
begin
user = User.from_json context.request.body.not_nil!
user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
rescue ex
halt context, status_code: 403, response: ex.to_s
end
if Crypto::Bcrypt::Password.new(user_file.password_hash.not_nil!) == user.password_hash.not_nil!
else
halt context, status_code: 403, response: "Invalid password"
end
token = UUID.random()
if user_file.tokens.nil?
user_file.tokens = Array(UUID).new
user_file.tokens.not_nil!<<token
else
user_file.tokens.not_nil!<<token
end
if user_file.tokens.not_nil!.size>5
user_file.tokens = user_file.tokens.not_nil!.last(5)
end
File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
context.response.content_type = "application/json"
token.to_json
end
post "/logout" do |context|
user = User.from_json context.request.body.not_nil!
user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
user_file.tokens=user_file.tokens.not_nil!-user.tokens.not_nil!
File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
context.response.content_type = "application/json"
"OK".to_json
end
post "/logout-all" do |context|
user : User
begin
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
rescue ex
halt context, status_code: 403, response: ex.to_s
end
user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
user_file.tokens=Array(UUID).new
File.write(Statics.data_path+"user/"+user_file.email,user_file.to_json)
context.response.content_type = "application/json"
"OK".to_json
end
post "/user" do |context|
user = User.from_json context.request.body.not_nil!
ph = user.password_hash
user.tokens = Array(UUID).new
user.invoices = Array(Invoice).new
if ph.nil?
raise Exception.new("No password provided")
else
user.password_hash=Crypto::Bcrypt::Password.create(ph,cost: 12).to_s
end
if Statics.email_regex.match(user.email)==nil
raise Exception.new("Bad email address")
end
File.write(Statics.data_path+"user/"+user.email,user.to_json)
context.response.content_type = "application/json"
"OK".to_json
end
get "/user/tokens" do |context|
user : User
begin
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
rescue ex
halt context, status_code: 403, response: ex.to_s
end
context.response.content_type = "application/json"
user.tokens.to_json
end
get "/user/address" do |context|
user : User
begin
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
rescue ex
halt context, status_code: 403, response: ex.to_s
end
context.response.content_type = "application/json"
user.addresses.to_json
end
post "/user/address" do |context|
user : User
begin
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
rescue ex
halt context, status_code: 403, response: ex.to_s
end
addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
old_list=user_file.addresses
if old_list.nil?
else
addresses=old_list+addresses
end
user_file.addresses=addresses
File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
context.response.content_type = "application/json"
"OK".to_json
end
delete "/user/address" do |context|
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
addresses = Array(Address).from_json(context.request.body.not_nil!).not_nil!
user_file = User.from_json File.read(Statics.data_path+"user/"+user.email)
old_list=user_file.addresses
if old_list.nil?
addresses=Array(Address).new
else
addresses=old_list-addresses
end
user_file.addresses=addresses
File.write(Statics.data_path+"user/"+user.email,user_file.to_json)
context.response.content_type = "application/json"
"OK".to_json
end
get "/user" do |context|
context.response.content_type = "application/json"
user : User | Nil
begin
user = authenticate!(context.request.headers["user"],UUID.new(context.request.headers["api_token"]))
rescue ex
halt context, status_code: 403, response: ex.to_s
end
user.not_nil!
end