almost done with auth. initialized sessions stuff

This commit is contained in:
r8zavetr8v 2024-09-18 00:13:39 +03:00
parent 2dbaf1de10
commit bd99555cd8
12 changed files with 131 additions and 32 deletions

View File

@ -1,6 +1,10 @@
defmodule DraincloudCore.Auth do
def is_logon(_token) do
# TODO here
true
false
end
def auth_cookies(conn = %Plug.Conn{}, user = %DrainCloudCore.Auth.Users{}) do
end
end

View File

@ -0,0 +1,21 @@
defmodule DrainCloudCore.Auth.SessionsRepo do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
schema "sessions" do
field :token, :string
field :user_id, :id
field :user_agent, :string
field :created_at, :utc_datetime
field :expires_at, :utc_datetime
end
def changeset(session, params \\ %{}) do
session
|> cast(params, [:id, :token, :user_id, :user_agent, :created_at, :expires_at])
|> validate_required([:id, :token, :user_id, :user_agent, :created_at, :expires_at])
end
end

View File

@ -0,0 +1,21 @@
defmodule DrainCloudCore.Auth.SessionsStore do
@behaviour Plug.Session.Store
alias DrainCloudCore.Repo, as: Repo
def init(_opts), do: :ok
def put(conn, sid, any, opts) do
end
def get(conn, cookie, opts) do
end
def delete(conn, sid, opts) do
end
end

View File

@ -1,6 +1,9 @@
defmodule DrainCloudCore.Auth.Users do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias DrainCloudCore.Repo, as: Repo
schema "users" do
field :login, :string
@ -15,4 +18,12 @@ defmodule DrainCloudCore.Auth.Users do
|> cast(params, [:id, :login, :password, :updated_at, :deleted_at])
|> validate_required([:id])
end
def add_user(user) do
Repo.insert(user)
end
def password_by_login(login) do
Repo.all(from u in "users", where: u.login == ^login, select: u.password, limit: 1)
end
end

View File

@ -1,9 +0,0 @@
defmodule DrainCloudCore.UsersRepo do
alias DrainCloudCore.Repo, as: Repo
import Ecto.Query
def password_by_login(login) do
query = from u in :users, where: u.login = login, select: u.password, limit: 1
Repo.all(query)
end
end

View File

@ -1,32 +1,36 @@
defmodule DrainCloudCoreWeb.AuthController do
use DrainCloudCoreWeb, :controller
import Plug.Conn
alias DrainCloudCoreWeb.AuthController.RegisterRequest, as: RegisterRequest
alias DrainCloudCoreWeb.AuthController.LoginRequest, as: LoginRequest
alias :logger, as: Log
alias DrainCloudCore.Repo, as: Repo
alias DrainCloudCore.Auth.Users , as: Repo
def register(conn, _params) do
req = RegisterRequest.from_request(conn)
Log.debug("new register request: #{req}")
model = RegisterRequest.to_model(req)
try do
Repo.insert(model)
RegisterRequest.from_request(conn)
|> RegisterRequest.to_model
|> Repo.add_user
# TODO send cookies and tokens
send_resp(conn, 200, Jason.encode! %{ok: true})
rescue
e in RuntimeError -> Log.error("failed to insert new user: #{e}")
e in RuntimeError ->
Log.error("failed to insert new user: #{e}")
raise e
end
json(conn, req)
end
def login(conn, _params) do
req = LoginRequest.from_request(conn)
Log.debug("new login request: #{req}")
try do
LoginRequest.from_request(conn)
# TODO send cookies and tokens
send_resp(conn, 200, Jason.encode! %{ok: true})
rescue
e in RuntimeError ->
Log.error("failed to insert new user: #{e}")
raise e
end
end
end

View File

@ -56,11 +56,11 @@ defmodule DraincloudCoreWeb.AuthController.LoginRequest do
defp build(req) do
%Request{
login: Map.get(req, "login"),
password: Map.get(req, "password")
password: Map.get(req, "password") # TODO hash password
}
end
defimpl String.Chars, for: DrainCloudCoreWeb.AuthController.LoginRequest do
defimpl String.Chars, for: __MODULE__ do
def to_string(req) do
case Jason.encode(req) do
{:ok, str} -> str

View File

@ -43,11 +43,11 @@ defmodule DrainCloudCoreWeb.AuthController.RegisterRequest do
end
defp validate_password(req) do
if String.length(Map.get(req, "password")) >= 8 do
if String.length(Map.get(req, "password")) >= 4 do
req
else
raise InvalidArgumentException, %{
message: "password must be 8 symbols at minimum",
message: "password must be 4 symbols at minimum",
args: ["password"]
}
end
@ -56,11 +56,11 @@ defmodule DrainCloudCoreWeb.AuthController.RegisterRequest do
defp build(req) do
%Request{
login: Map.get(req, "login"),
password: Map.get(req, "password")
password: Map.get(req, "password") # TODO hash password
}
end
defimpl String.Chars, for: DrainCloudCoreWeb.AuthController.RegisterRequest do
defimpl String.Chars, for: __MODULE__ do
def to_string(req) do
case Jason.encode(req) do
{:ok, str} -> str

View File

@ -1,4 +1,6 @@
defmodule DrainCloudCoreWeb.Errors.InvalidArgumentException do
@derive [Jason.Encoder]
alias __MODULE__, as: InvalidArgumentException
defexception [:message, :args]
@ -14,4 +16,13 @@ defmodule DrainCloudCoreWeb.Errors.InvalidArgumentException do
_ -> %InvalidArgumentException{message: "Error: " <> term}
end
end
defimpl String.Chars, for: __MODULE__ do
def to_string(err) do
case Jason.encode(err) do
{:ok, str} -> str
{:error, msg} -> raise "failed to encode register request to string: #{msg}"
end
end
end
end

View File

@ -0,0 +1,10 @@
defmodule DrainCloudCoreWeb.ErrorHandler do
alias DrainCloudCoreWeb.Errors.InvalidArgumentException, as: InvalidArgumentException
def handle_reason(reason = %InvalidArgumentException{}), do: Jason.encode!(reason)
def handle_reason(reason) do
:logger.error(inspect(reason))
Jason.encode!(%{error: "Oops! Something went wrong!"})
end
end

View File

@ -1,5 +1,10 @@
defmodule DrainCloudCoreWeb.Router do
use DrainCloudCoreWeb, :router
use Plug.ErrorHandler
import Plug.Conn
alias :logger, as: Log
alias DrainCloudCoreWeb.ErrorHandler, as: ErrorHandler
pipeline :browser do
plug :accepts, ["html"]
@ -20,6 +25,12 @@ defmodule DrainCloudCoreWeb.Router do
post "/register", AuthController, :register
end
@impl Plug.ErrorHandler
def handle_errors(conn, %{kind: _kind, reason: reason, stack: _stack}) do
send_resp(conn, 500, ErrorHandler.handle_reason(reason))
end
# Enable LiveDashboard in development
if Application.compile_env(:draincloud_core, :dev_routes) do
# If you want to use the LiveDashboard in production, you should put

View File

@ -0,0 +1,15 @@
defmodule DrainCloudCore.Repo.Migrations.Sessions do
use Ecto.Migration
def change do
create table(:sessions) do
add :token, :string
add :user_id, references("users", on_delete: :nothing)
add :user_agent, :string
add :created_at, :utc_datetime
add :expires_at, :utc_datetime
end
create unique_index(:sessions, :token)
end
end