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()))
|
|
|
|
assign_role(user, findone(Role, name = "free"))
|
|
|
|
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
|