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 word_from_stream(stream) do
stream
|> Enum.random()
|> String.trim()
|> String.downcase()
end
def make_username(params) do
if File.exists?("/usr/share/dict/words") do
stream = File.stream!("/usr/share/dict/words")
word_one = Users.word_from_stream(stream)
word_two = Users.word_from_stream(stream)
"#{word_one}-#{word_two}-#{Enum.random(1..100)}"
else
params["email"]
|> String.split("@")
|> List.first()
end
end
def new_user_params(params) do
params
|> Map.replace("email", String.downcase(params["email"]))
|> Map.replace("password", Passwords.hash(params["password"]))
|> Map.put_new("username", Users.make_username(params))
end
def make_user(outcome, params, model) do
case outcome do
{:ok, _} ->
params
|> Users.new_user_params()
|> model.new(:public)
error ->
error
end
end
def autojoin_orgs(outcome, ctx) do
case outcome do
{:ok, user} -> ctx[:organizations].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 new(params, ctx) do
if ctx[:settings].is_enabled?("allow_new_users") do
case params do
%{"email" => _, "password" => password} ->
password
|> ctx[:auth].validate_new_password()
|> Users.make_user(params, ctx[:model])
|> Users.autojoin_orgs(ctx)
|> Users.queue("email_verification", ctx)
_ ->
{:error, :missing_fields}
end
else
{:error, :forbidden}
end
end
def login(params, ctx) do
case params do
%{"email" => email, "password" => password, "realm" => realm} ->
%{"email" => String.downcase(email), "realm" => realm}
|> ctx[:model].get(:system)
|> List.first()
|> ctx[:auth].login(password)
_ ->
{:error, :missing_fields}
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)
[] -> []
end
_ ->
{:error, :missing_fields}
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
case ctx[:auth].validate_new_password(params["password"]) do
{:ok, _} -> Users.make_new_password(params, ctx)
e -> e
end
else
{:error, :missing_fields}
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
)
@organizations Utils.option_or_mod_replace(
@caller,
unquote(opts),
:organizations,
Organizations,
2
)
@settings Utils.option_or_mod_replace(
@caller,
unquote(opts),
:settings,
Settings,
2
)
@codes Utils.option_or_mod_replace(
@caller,
unquote(opts),
:otp_codes,
OtpCodes,
2
)
@worker Utils.option_or_mod_replace(
Utils.replace_module(@caller, Workers),
unquote(opts),
:worker,
Mailer,
2
)
@ctx [
auth: @auth,
codes: @codes,
model: @model,
organizations: @organizations,
settings: @settings,
worker: @worker
]
def new(params, _user, _opts) do
Users.new(params, @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