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!<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