Current section

Files

Jump to
blossom lib blossom controllers users.ex
Raw

lib/blossom/controllers/users.ex

defmodule Blossom.Controllers.Users do
alias Blossom.Controllers.Users
alias Blossom.Passwords
alias KilnCore.Utils
def new_user_own_role(outcome, ctx) do
case outcome do
{:ok, user} ->
case ctx[:settings].get_value("new_users_own_role") do
nil ->
outcome
value ->
ctx[:roles_assignments].assign(user, value, nil, user.id)
outcome
end
e ->
e
end
end
def make_user(outcome, user, model) do
case outcome do
{:ok, params} ->
params
|> Map.replace("email", String.downcase(params["email"]))
|> model.new(user)
error ->
error
end
end
def autojoin_orgs(outcome, ctx) do
case outcome do
{:ok, user} -> ctx[:casks].process_autojoins(user)
_ -> nil
end
outcome
end
def queue(outcome, kind, ctx) do
case outcome do
{:ok, user} -> ctx[:worker].queue(user.id, kind)
_ -> nil
end
outcome
end
def process_password(params, realm, ctx) do
settings = ctx[:settings].password_settings(realm)
password = params["password"]
case ctx[:auth].validate_new_password(password, settings) do
{:ok, _} ->
{:ok, Map.put(params, "password", Passwords.hash(password))}
error ->
error
end
end
def handle_password(params, realm, ctx) do
case params do
%{"password" => _} -> Users.process_password(params, realm, ctx)
_ -> {:ok, params}
end
end
def handle_new_user(params, user, ctx) do
params
|> Users.handle_password(params["realm"], ctx)
|> Users.make_user(user, ctx[:model])
|> Users.new_user_own_role(ctx)
|> Users.autojoin_orgs(ctx)
|> Users.queue("email_verification", ctx)
end
def new(params, user, ctx) do
case params do
%{"email" => _, "realm" => realm} ->
if ctx[:settings].is_enabled?("allow_new_users", realm) do
Users.handle_new_user(params, user, ctx)
else
{:error, :forbidden}
end
_ ->
{:error, :unprocessable}
end
end
def edit(params, id, user, ctx) do
case Users.handle_password(params, user["iss"], ctx) do
{:ok, new_params} -> ctx[:model].edit(new_params, id, user)
error -> error
end
end
def get_login_user(email, realm, ctx) do
%{"email" => String.downcase(email), "realm" => realm}
|> ctx[:model].get(:system)
|> List.first()
end
def make_login(outcome, email, password, ctx) do
case outcome do
[client] ->
email
|> Users.get_login_user(client.casks.realm, ctx)
|> ctx[:auth].login(password, client)
_ ->
{:error, :unauthorized}
end
end
def login(params, ctx) do
case params do
%{"email" => email, "password" => password, "client_id" => client_id} ->
%{"id" => client_id, "embeds" => ["casks"]}
|> ctx[:clients].get(:system)
|> Users.make_login(email, password, ctx)
_ ->
{:error, :unprocessable}
end
end
def verify_email(code, user, ctx) do
params = %{"code" => code, "kind" => "email_verification"}
case ctx[:codes].verify(params, user) do
{:ok, code} ->
ctx[:model].edit(%{"email_verified" => true}, code.user, :system)
error ->
error
end
end
def start_reset_password(params, ctx) do
case params do
%{"email" => email, "realm" => realm} ->
case ctx[:model].get(%{"email" => email, "realm" => realm}, :system) do
[user] -> Users.queue({:ok, user}, "password_reset", ctx)
[] -> {:error, :forbidden}
end
_ ->
{:error, :unprocessable}
end
end
def make_new_password(params, ctx) do
new_params = Map.put(params, "kind", "password_reset")
case ctx[:codes].verify(new_params, :system) do
{:ok, code} ->
%{"password" => Passwords.hash(params["password"])}
|> ctx[:model].edit(code.user, :system)
_error ->
{:error, :forbidden}
end
end
def confirm_reset_password(params, ctx) do
if params["password"] != nil do
settings = ctx[:settings].password_settings(params["realm"])
case ctx[:auth].validate_new_password(params["password"], settings) do
{:ok, _} -> Users.make_new_password(params, ctx)
e -> e
end
else
{:error, :unprocessable}
end
end
defmacro __using__(opts \\ []) do
quote do
use KilnCore.Controller, unquote(opts)
@auth Utils.option_or_mod_replace(
@caller,
unquote(opts),
:auth,
Auth,
1,
0..1
)
@casks Utils.option_or_mod_replace(
@caller,
unquote(opts),
:casks,
Casks,
2
)
@clients Utils.option_or_mod_replace(
@caller,
unquote(opts),
:clients,
Clients,
2
)
@codes Utils.option_or_mod_replace(
@caller,
unquote(opts),
:otp_codes,
OtpCodes,
2
)
@roles_assignments Utils.option_or_mod_replace(
@caller,
unquote(opts),
:roles_assignments,
RolesAssignments,
2
)
@settings Utils.option_or_mod_replace(
@caller,
unquote(opts),
:settings,
Settings,
2
)
@worker Utils.option_or_mod_replace(
Utils.replace_module(@caller, Workers),
unquote(opts),
:worker,
Mailer,
2
)
@ctx [
auth: @auth,
casks: @casks,
clients: @clients,
codes: @codes,
model: @model,
settings: @settings,
worker: @worker
]
def new(params, user, _opts) do
Users.new(params, user, @ctx)
end
def edit(params, id, user, _opts) do
Users.edit(params, id, user, @ctx)
end
def login(params, _user, _opts), do: Users.login(params, @ctx)
def verify_email(code, user, _opts) do
Users.verify_email(code, user, @ctx)
end
def start_reset_password(params, _user, _opts) do
Users.start_reset_password(params, @ctx)
end
def confirm_reset_password(params, _user, _opts) do
Users.confirm_reset_password(params, @ctx)
end
defoverridable new: 3,
login: 3,
verify_email: 3,
start_reset_password: 3,
confirm_reset_password: 3
end
end
end