site-libsoc/Server/app/resources/authentication/AuthenticationController.jl

192 lines
5.4 KiB
Julia
Raw Normal View History

2023-07-30 17:04:15 +07:00
module AuthenticationController
using Genie, Genie.Requests, Genie.Renderer, Genie.Renderer.Json, Genie.Renderer.Html, GenieSession, SearchLight, GenieAuthentication, GenieAuthorisation
using Logging
using JSON3, Random, Base64, HTTP, Dates
using Server.Users, Server.EmailSupport, Server.TemplateEditor, Server.Cookies, Server.DatabaseSupport
import Server.TemplateEditor.generate_layout_html
import Server.DatabaseSupport.select_from_table
using JWTs
#---Helpers----------------------------------------------------------
const keyset = JWKSet("https://www.googleapis.com/oauth2/v3/certs")
refresh!(keyset)
current_user() = findone(Users.User, id = get_authentication())
function send_signup_confirmation_email(receiver,confirmation_code)
subject,message = ["Sign-up confirmation","Hello!\r\nYour confirmation code is "*confirmation_code*"\r\n"]
message = "Content-Type: text/html\r\n"*message
return send_email(receiver,subject,message)
end
function register_google()
jws = rawpayload()
jws_split = split(jws,".")
payload_encoded = jws_split[2]
rem = length(payload_encoded)%4
if rem!= 0
payload_encoded = payload_encoded* "="^(4-rem)
end
payload = String(base64decode(payload_encoded))
json = JSON3.read(payload)
sub = json[:sub]
email = json[:email]
user = findone(User, email = email)
if isnothing(user)
# ENABLE WHEN IN PRODUCTION
user = User(email = email,google_id = sub) |> save!
authenticate(user.id, GenieSession.session(params()))
assign_role(user, findone(Role, name = "free"))
save(user)
return true
return 0
else
jwt = JWT(payload="")
jwt.header = jws_split[1]
jwt.payload = jws_split[2]
jwt.signature = jws_split[3]
if validate!(jwt, keyset)
if user.google_id==""
user.google_id = sub
save(user)
authenticate(user.id, GenieSession.session(params()))
return 3
elseif user.google_id==sub
authenticate(user.id, GenieSession.session(params()))
return 3
else
return 0
end
else
return 0
end
end
end
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
const auth_info = Dict(
"en" => Dict(
:title => "LibSoc - Login/Sign Up",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Логин/Регистрация",
:description => ""
)
)
#---Routing functions---------------------------------------------------
controller = "authentication"
const dict_layouts = Dict(
:auth => generate_layout_html("main",controller,"auth",libraries=["GoogleAuth"]),
2023-08-01 19:56:41 +07:00
:profile => generate_layout_html("main",controller,"profile",libraries=["Leaflet"]),
2023-07-30 17:04:15 +07:00
:email_confirmation => generate_layout_html("main",controller,"email_confirmation"),
)
function auth()
locale = get_locale()
set_cookies(params())
html(:authentication,:auth, layout = dict_layouts[:auth], context = @__MODULE__,
title = auth_info[locale][:title],
description = auth_info[locale][:description]
)
end
function profile()
set_cookies(params())
html(:authentication,:profile, layout = dict_layouts[:profile], context = @__MODULE__,
title = "Chiron | Profile",
description = ""
)
end
function email_confirmation()
set_cookies(params())
html(:authentication,:email_confirmation, layout = dict_layouts[:email_confirmation], context = @__MODULE__,
title = "Chiron | Email Confirmation",
description = ""
)
end
function confirm_email()
code = rawpayload()
user = current_user()
if code==user.confirmation_code
GenieAuthorisation.Relationship!(user, findone(Role, name = "unconfirmed")) |> delete
assign_role(user, findone(Role, name = "free"))
return true
else
return false
end
end
function register()
data = jsonpayload()
user = findone(User, email = data["email"])
if isnothing(user)
user = User(email = data["email"],
password = data["password"] |> Users.hash_password,
) |> save!
authenticate(user.id, GenieSession.session(params()))
confirmation_code = randstring('0':'9', 5)
user.confirmation_code = confirmation_code
save(user)
#send_signup_confirmation_email(data["email"],confirmation_code)
return true
else
return false
end
end
function login()
data = jsonpayload()
user = findone(User, email = data["email"])
if isnothing(user)
return 0
else
if (user.password==Users.hash_password(data["password"]))
authenticate(user.id, GenieSession.session(params()))
return 2
else
return 1
end
end
end
function logout()
deauthenticate(GenieSession.session(params()))
return
end
function change_user()
data = jsonpayload()
user = findone(Users.User, id = get_authentication())
for (field,value) in data
setfield!(user, Symbol(field), value)
end
save(user)
return JSON3.write(true)
end
function get_user()
try
user = findone(Users.User, id = get_authentication())
return JSON3.write(user)
catch ex
return JSON3.write(false)
end
end
end