diff --git a/lib/kmxgit/organisation_manager.ex b/lib/kmxgit/organisation_manager.ex
index 7d9d06a..dca53d1 100644
--- a/lib/kmxgit/organisation_manager.ex
+++ b/lib/kmxgit/organisation_manager.ex
@@ -4,18 +4,17 @@ defmodule Kmxgit.OrganisationManager do
alias Kmxgit.OrganisationManager.Organisation
alias Kmxgit.Repo
- alias Kmxgit.UserManager.User
+ alias Kmxgit.SlugManager.Slug
def list_organisations do
- Organisation
- |> Repo.all
+ Repo.all from org in Organisation, preload: :slug
end
def change_organisation(organisation \\ %Organisation{}) do
Organisation.changeset(organisation, %{})
end
- def create_organisation(user = %User{id: _}, attrs \\ %{}) do
+ def create_organisation(user, attrs \\ %{}) do
%Organisation{}
|> Organisation.changeset(attrs)
|> Ecto.Changeset.put_assoc(:users, [user])
@@ -31,13 +30,17 @@ defmodule Kmxgit.OrganisationManager do
def get_organisation(id) do
Repo.one from organisation in Organisation,
where: [id: ^id],
+ preload: :slug,
limit: 1
end
def get_organisation_by_slug(slug) do
- Repo.one from organisation in Organisation,
- where: [slug: ^slug],
- limit: 1
+ Repo.one from o in Organisation,
+ join: s in Slug,
+ on: s.organisation_id == o.id,
+ where: s.slug == ^slug,
+ preload: :slug,
+ preload: [users: :slug]
end
def delete_organisation(%Organisation{} = organisation) do
diff --git a/lib/kmxgit/organisation_manager/organisation.ex b/lib/kmxgit/organisation_manager/organisation.ex
index b13828a..954ff23 100644
--- a/lib/kmxgit/organisation_manager/organisation.ex
+++ b/lib/kmxgit/organisation_manager/organisation.ex
@@ -3,23 +3,24 @@ defmodule Kmxgit.OrganisationManager.Organisation do
use Ecto.Schema
import Ecto.Changeset
+ alias Kmxgit.SlugManager.Slug
alias Kmxgit.UserManager.User
schema "organisations" do
field :description, :string
field :name, :string
- field :slug, :string, null: false
many_to_many :users, User, join_through: "users_organisations"
+ has_one :slug, Slug
timestamps()
end
@doc false
def changeset(organisation, attrs \\ %{}) do
organisation
- |> cast(attrs, [:slug, :description, :name])
+ |> cast(attrs, [:description, :name])
+ |> cast_assoc(:users)
+ |> cast_assoc(:slug)
|> validate_required([:slug])
- |> validate_format(:slug, ~r/^[A-Za-z][-_+.0-9A-Za-z]{1,64}$/)
- |> unique_constraint(:_lower_slug)
|> Markdown.validate_markdown(:description)
end
diff --git a/lib/kmxgit/slug_manager.ex b/lib/kmxgit/slug_manager.ex
new file mode 100644
index 0000000..3d8e83f
--- /dev/null
+++ b/lib/kmxgit/slug_manager.ex
@@ -0,0 +1,36 @@
+defmodule Kmxgit.SlugManager do
+
+ import Ecto.Query, warn: false
+
+ alias Kmxgit.Repo
+ alias Kmxgit.SlugManager.Slug
+
+ def list_slugs do
+ Slug
+ |> Repo.all
+ end
+
+ def create_slug(slug) do
+ %Slug{}
+ |> Slug.changeset(%{slug: slug})
+ |> Repo.insert()
+ end
+
+ def update_slug(slug, attrs) do
+ slug
+ |> Slug.changeset(attrs)
+ |> Repo.update()
+ end
+
+ def get_slug(slug) do
+ Repo.one from s in Slug,
+ where: [slug: ^slug],
+ preload: [organisation: [:slug, [users: :slug]]],
+ preload: [user: [:slug, [organisations: :slug]]],
+ limit: 1
+ end
+
+ def delete_slug(%Slug{} = slug) do
+ Repo.delete(slug)
+ end
+end
diff --git a/lib/kmxgit/slug_manager/slug.ex b/lib/kmxgit/slug_manager/slug.ex
new file mode 100644
index 0000000..55559cb
--- /dev/null
+++ b/lib/kmxgit/slug_manager/slug.ex
@@ -0,0 +1,54 @@
+defmodule Kmxgit.SlugManager.Slug do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ alias Kmxgit.OrganisationManager.Organisation
+ alias Kmxgit.UserManager.User
+
+ schema "slugs" do
+ field :slug, :string, unique: true
+ belongs_to :organisation, Organisation
+ belongs_to :user, User
+ timestamps()
+ end
+
+ def changeset(slug, attrs) do
+ slug
+ |> cast(attrs, [:slug])
+ |> validate_required([:slug])
+ |> validate_format(:slug, ~r/^[A-Za-z][-_+.0-9A-Za-z]{1,64}$/)
+ |> unique_constraint(:_lower_slug)
+ end
+
+ def user_changeset(slug, user, attrs \\ {}) do
+ slug
+ |> changeset(attrs)
+ |> Ecto.Changeset.put_assoc(:user, user)
+ |> validate_only_user()
+ end
+
+ defp validate_only_user(changeset) do
+ c = changeset |> validate_required(:user_id)
+ if get_field(changeset, :organisation_id) do
+ add_error(c, :organisation_id, "cannot be set")
+ else
+ c
+ end
+ end
+
+ def organisation_changeset(slug, org, attrs \\ {}) do
+ slug
+ |> changeset(attrs)
+ |> Ecto.Changeset.put_assoc(:organisation, org)
+ |> validate_only_organisation()
+ end
+
+ defp validate_only_organisation(changeset) do
+ c = changeset |> validate_required(:organisation_id)
+ if get_field(changeset, :user_id) do
+ add_error(c, :user_id, "cannot be set")
+ else
+ c
+ end
+ end
+end
diff --git a/lib/kmxgit/user_manager.ex b/lib/kmxgit/user_manager.ex
index 9880c1c..181e688 100644
--- a/lib/kmxgit/user_manager.ex
+++ b/lib/kmxgit/user_manager.ex
@@ -6,75 +6,47 @@ defmodule Kmxgit.UserManager do
import Ecto.Query, warn: false
alias Kmxgit.Repo
+ alias Kmxgit.SlugManager.Slug
alias Kmxgit.UserManager.User
alias Bcrypt
- @doc """
- Returns the list of users.
-
- ## Examples
-
- iex> list_users()
- [%User{}, ...]
-
- """
def list_users do
- Repo.all(User)
+ Repo.all from user in User, preload: :slug
end
- @doc """
- Gets a single user.
-
- Raises `Ecto.NoResultsError` if the User does not exist.
-
- ## Examples
-
- iex> get_user!(123)
- %User{}
-
- iex> get_user!(456)
- ** (Ecto.NoResultsError)
-
- """
def get_user!(id) do
- Repo.one(from user in User,
+ user = Repo.one(from user in User,
where: [id: ^id],
- preload: :organisations) || raise "user #{id} not found"
+ preload: [organisations: :slug],
+ preload: :slug
+ )
+ user || raise Ecto.NoResultsError
end
def get_user(id) do
Repo.one from user in User,
where: [id: ^id],
- preload: :organisations
+ preload: [organisations: :slug],
+ preload: :slug
end
- def get_user_by_login(login) do
- Repo.one from user in User,
- where: [login: ^login],
- preload: :organisations
+ def get_user_by_slug(slug) do
+ Repo.one from u in User,
+ join: s in Slug,
+ on: s.id == u.slug_id,
+ where: s.slug == ^slug,
+ limit: 1
end
- @doc """
- Creates a user.
-
- ## Examples
-
- iex> create_user(%{field: value})
- {:ok, %User{}}
-
- iex> create_user(%{field: bad_value})
- {:error, %Ecto.Changeset{}}
-
- """
- def create_user(attrs \\ %{}) do
- %User{}
+ def create_user(slug, attrs \\ %{}) do
+ %User{slug: slug}
|> User.changeset(attrs)
|> Repo.insert()
end
- def admin_create_user(attrs \\ %{}) do
- %User{}
+ def admin_create_user(slug, attrs \\ %{}) do
+ %User{slug: slug}
|> User.admin_changeset(attrs)
|> Repo.insert()
end
diff --git a/lib/kmxgit/user_manager/user.ex b/lib/kmxgit/user_manager/user.ex
index 75148b3..1a2a557 100644
--- a/lib/kmxgit/user_manager/user.ex
+++ b/lib/kmxgit/user_manager/user.ex
@@ -3,6 +3,7 @@ defmodule Kmxgit.UserManager.User do
import Ecto.Changeset
alias Kmxgit.OrganisationManager.Organisation
+ alias Kmxgit.SlugManager.Slug
alias KmxgitWeb.Router.Helpers, as: Routes
alias BCrypt
@@ -11,10 +12,10 @@ defmodule Kmxgit.UserManager.User do
field :email, :string, unique: true
field :encrypted_password, :string
field :is_admin, :boolean, null: false
- field :login, :string, unique: true
field :name, :string
field :password, :string, virtual: true, redact: true
field :password_confirmation, :string, virtual: true, redact: true
+ has_one :slug, Slug
field :ssh_keys, :string
many_to_many :organisations, Organisation, join_through: "users_organisations"
timestamps()
@@ -24,25 +25,24 @@ defmodule Kmxgit.UserManager.User do
user
|> check_password_confirmation()
|> put_password_hash()
- |> validate_required([:email, :login, :encrypted_password])
+ |> cast_assoc(:slug)
+ |> validate_required([:email, :slug, :encrypted_password])
|> validate_format(:email, ~r/^[-_+.0-9A-Za-z]+@([-_0-9A-Za-z]+[.])+[A-Za-z]+$/)
- |> validate_format(:login, ~r/^[A-Za-z][-_0-9A-Za-z]{1,64}$/)
|> unique_constraint(:_lower_email)
- |> unique_constraint(:_lower_login)
|> Markdown.validate_markdown(:description)
end
@doc false
def changeset(user, attrs \\ %{}) do
user
- |> cast(attrs, [:description, :email, :login, :name, :password, :password_confirmation, :ssh_keys])
+ |> cast(attrs, [:description, :email, :name, :password, :password_confirmation, :ssh_keys])
|> common_changeset()
end
@doc false
def admin_changeset(user, attrs \\ %{}) do
user
- |> cast(attrs, [:description, :email, :is_admin, :login, :name, :password, :password_confirmation, :ssh_keys])
+ |> cast(attrs, [:description, :email, :is_admin, :name, :password, :password_confirmation, :ssh_keys])
|> common_changeset()
end
@@ -95,5 +95,4 @@ defmodule Kmxgit.UserManager.User do
def display_name(user) do
user.name || user.login
end
-
end
diff --git a/lib/kmxgit_web.ex b/lib/kmxgit_web.ex
index 41a2953..d24f5cf 100644
--- a/lib/kmxgit_web.ex
+++ b/lib/kmxgit_web.ex
@@ -23,6 +23,7 @@ defmodule KmxgitWeb do
import Plug.Conn
import KmxgitWeb.Gettext
+ alias KmxgitWeb.ErrorView
alias KmxgitWeb.Router.Helpers, as: Routes
end
end
diff --git a/lib/kmxgit_web/controllers/admin/organisation_controller.ex b/lib/kmxgit_web/controllers/admin/organisation_controller.ex
index e40fd1f..3b31f38 100644
--- a/lib/kmxgit_web/controllers/admin/organisation_controller.ex
+++ b/lib/kmxgit_web/controllers/admin/organisation_controller.ex
@@ -2,6 +2,8 @@ defmodule KmxgitWeb.Admin.OrganisationController do
use KmxgitWeb, :controller
alias Kmxgit.OrganisationManager
+ alias Kmxgit.Repo
+ alias Kmxgit.SlugManager
alias KmxgitWeb.ErrorView
def index(conn, _params) do
@@ -19,16 +21,27 @@ defmodule KmxgitWeb.Admin.OrganisationController do
end
def create(conn, params) do
- case OrganisationManager.create_organisation(params["organisation"]) do
- {:ok, organisation} ->
- conn
- |> redirect(to: Routes.organisation_path(conn, :show, organisation.slug))
- {:error, changeset} ->
- IO.inspect(changeset)
- conn
- |> assign(:action, Routes.admin_organisation_path(conn, :create))
- |> assign(:changeset, changeset)
- |> render("new.html")
+ current_user = conn.assigns.current_user
+ org_params = params["organisation"]
+ Repo.transaction fn ->
+ case SlugManager.create_slug(org_params["slug"]["slug"]) do
+ {:ok, slug} ->
+ case OrganisationManager.create_organisation(Map.merge(org_params, %{slug: slug, user: current_user})) do
+ {:ok, organisation} ->
+ conn
+ |> redirect(to: Routes.organisation_path(conn, :show, organisation.slug))
+ {:error, changeset} ->
+ conn
+ |> assign(:action, Routes.admin_organisation_path(conn, :create))
+ |> assign(:changeset, changeset)
+ |> render("new.html")
+ end
+ {:error, changeset} ->
+ conn
+ |> assign(:action, Routes.admin_organisation_path(conn, :create))
+ |> assign(:changeset, changeset)
+ |> render("new.html")
+ end
end
end
diff --git a/lib/kmxgit_web/controllers/organisation_controller.ex b/lib/kmxgit_web/controllers/organisation_controller.ex
index 1dc2dea..773412b 100644
--- a/lib/kmxgit_web/controllers/organisation_controller.ex
+++ b/lib/kmxgit_web/controllers/organisation_controller.ex
@@ -17,8 +17,9 @@ defmodule KmxgitWeb.OrganisationController do
case OrganisationManager.create_organisation(current_user, params["organisation"]) do
{:ok, organisation} ->
conn
- |> redirect(to: Routes.organisation_path(conn, :show, organisation.slug))
+ |> redirect(to: Routes.organisation_path(conn, :show, organisation.slug.slug))
{:error, changeset} ->
+ IO.inspect(changeset)
conn
|> assign(:action, Routes.organisation_path(conn, :create))
|> assign(:changeset, changeset)
@@ -34,14 +35,46 @@ defmodule KmxgitWeb.OrganisationController do
end
def show(conn, params) do
- org = OrganisationManager.get_organisation_by_slug(params["slug"])
+ org = OrganisationManager.get_organisation_by_slug(params["slug"])
if org do
conn
- |> assign(:current_org, org)
+ |> assign(:current_organisation, org)
|> assign(:org, org)
|> render("show.html")
else
not_found(conn)
end
end
+
+ def edit(conn, params) do
+ org = OrganisationManager.get_organisation_by_slug(params["slug"])
+ changeset = OrganisationManager.change_organisation(org)
+ if org do
+ conn
+ |> assign(:action, Routes.organisation_path(conn, :update, org.slug.slug))
+ |> assign(:changeset, changeset)
+ |> assign(:current_organisation, org)
+ |> render("edit.html")
+ else
+ not_found(conn)
+ end
+ end
+
+ def update(conn, params) do
+ organisation = OrganisationManager.get_organisation_by_slug(params["slug"])
+ if organisation do
+ case OrganisationManager.update_organisation(organisation, params["organisation"]) do
+ {:ok, org} ->
+ conn
+ |> redirect(to: Routes.organisation_path(conn, :show, org.slug.slug))
+ {:error, changeset} ->
+ IO.inspect(changeset)
+ conn
+ |> render("edit.html", changeset: changeset,
+ action: Routes.organisation_path(conn, :update, organisation.slug.slug))
+ end
+ else
+ not_found(conn)
+ end
+ end
end
diff --git a/lib/kmxgit_web/controllers/page_controller.ex b/lib/kmxgit_web/controllers/page_controller.ex
index bdd467f..c2ddb3f 100644
--- a/lib/kmxgit_web/controllers/page_controller.ex
+++ b/lib/kmxgit_web/controllers/page_controller.ex
@@ -1,6 +1,8 @@
defmodule KmxgitWeb.PageController do
use KmxgitWeb, :controller
+ alias Kmxgit.Repo
+ alias Kmxgit.SlugManager
alias Kmxgit.UserManager
alias Kmxgit.UserManager.{Guardian, User}
@@ -28,17 +30,31 @@ defmodule KmxgitWeb.PageController do
def new_admin_post(conn, params) do
if ! UserManager.admin_user_present? do
user_params = Map.merge(params["user"], %{"is_admin" => true})
- case UserManager.admin_create_user(user_params) do
- {:ok, user} ->
- conn
- |> Guardian.Plug.sign_in(user)
- |> redirect(to: "/")
- {:error, changeset} ->
- IO.inspect(changeset)
- conn
- |> assign(:no_navbar_links, true)
- |> render("new_admin.html", changeset: changeset,
- action: Routes.page_path(conn, :new_admin))
+ login = user_params["login"]
+ Repo.transaction fn ->
+ case SlugManager.create_slug(login) do
+ {:ok, slug} ->
+ case UserManager.admin_create_user(slug, user_params) do
+ {:ok, user} ->
+ conn
+ |> Guardian.Plug.sign_in(user)
+ |> redirect(to: "/")
+ {:error, changeset} ->
+ IO.inspect(changeset)
+ conn
+ |> assign(:no_navbar_links, true)
+ |> assign(:changeset, changeset)
+ |> assign(:action, Routes.page_path(conn, :new_admin))
+ |> render("new_admin.html")
+ end
+ {:error, changeset} ->
+ IO.inspect(changeset)
+ conn
+ |> assign(:no_navbar_links, true)
+ |> assign(:changeset, changeset)
+ |> assign(:action, Routes.page_path(conn, :new_admin))
+ |> render("new_admin.html")
+ end
end
else
redirect(conn, to: "/")
diff --git a/lib/kmxgit_web/controllers/slug_controller.ex b/lib/kmxgit_web/controllers/slug_controller.ex
new file mode 100644
index 0000000..ba40c07
--- /dev/null
+++ b/lib/kmxgit_web/controllers/slug_controller.ex
@@ -0,0 +1,40 @@
+defmodule KmxgitWeb.SlugController do
+ use KmxgitWeb, :controller
+
+ alias Kmxgit.SlugManager
+ alias KmxgitWeb.ErrorView
+ alias KmxgitWeb.OrganisationView
+ alias KmxgitWeb.UserView
+
+ defp not_found(conn) do
+ conn
+ |> put_status(:not_found)
+ |> put_view(ErrorView)
+ |> render(:"404")
+ end
+
+ def show(conn, params) do
+ slug = SlugManager.get_slug(params["slug"])
+ if !slug do
+ not_found(conn)
+ else
+ user = slug.user
+ if user do
+ conn
+ |> assign(:page_title, gettext("User %{login}", login: user.slug.slug))
+ |> assign(:user, user)
+ |> render(UserView, "show.html")
+ else
+ org = slug.organisation
+ if org do
+ conn
+ |> assign(:current_organisation, org)
+ |> assign(:org, org)
+ |> render(OrganisationView, "show.html")
+ else
+ not_found(conn)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/kmxgit_web/controllers/user_controller.ex b/lib/kmxgit_web/controllers/user_controller.ex
index 1f58b6f..63a8f6d 100644
--- a/lib/kmxgit_web/controllers/user_controller.ex
+++ b/lib/kmxgit_web/controllers/user_controller.ex
@@ -7,15 +7,16 @@ defmodule KmxgitWeb.UserController do
def show(conn, params) do
current_user = conn.assigns[:current_user]
- user = if current_user && params["login"] == current_user.login do
+ user = if current_user && params["login"] == current_user.slug.slug do
current_user
else
- UserManager.get_user_by_login(params["login"])
+ UserManager.get_user_by_slug(params["login"])
end
if user do
conn
- |> assign(:page_title, gettext("User %{login}", login: user.login))
- |> render("show.html", user: user)
+ |> assign(:page_title, gettext("User %{login}", login: user.slug.slug))
+ |> assign(:user, user)
+ |> render("show.html")
else
conn
|> not_found()
@@ -31,10 +32,10 @@ defmodule KmxgitWeb.UserController do
def edit(conn, params) do
current_user = conn.assigns[:current_user]
- if params["login"] == current_user.login do
+ if params["login"] == current_user.slug.slug do
changeset = User.changeset(current_user)
conn
- |> assign(:page_title, gettext("Edit user %{login}", login: current_user.login))
+ |> assign(:page_title, gettext("Edit user %{login}", login: current_user.slug.slug))
|> render("edit.html", changeset: changeset)
else
not_found(conn)
@@ -43,15 +44,16 @@ defmodule KmxgitWeb.UserController do
def update(conn, params) do
current_user = conn.assigns[:current_user]
- if params["login"] == current_user.login do
+ if params["login"] == current_user.slug.slug do
case UserManager.update_user(current_user, params["user"]) do
{:ok, user} ->
conn
- |> redirect(to: Routes.user_path(conn, :show, user.login))
+ |> redirect(to: Routes.user_path(conn, :show, user.slug.slug))
{:error, changeset} ->
conn
- |> assign(:page_title, gettext("Edit user %{login}", login: current_user.login))
- |> render("edit.html", changeset: changeset)
+ |> assign(:page_title, gettext("Edit user %{login}", login: current_user.slug.slug))
+ |> assign(:changeset, changeset)
+ |> render("edit.html")
end
else
not_found(conn)
diff --git a/lib/kmxgit_web/router.ex b/lib/kmxgit_web/router.ex
index 32f92e9..1ca56a4 100644
--- a/lib/kmxgit_web/router.ex
+++ b/lib/kmxgit_web/router.ex
@@ -33,18 +33,18 @@ defmodule KmxgitWeb.Router do
scope "/", KmxgitWeb do
pipe_through [:browser, :auth]
- get "/", PageController, :index
- get "/new_admin", PageController, :new_admin
- post "/new_admin", PageController, :new_admin_post
+ get "/", PageController, :index
+ get "/_new_admin", PageController, :new_admin
+ post "/_new_admin", PageController, :new_admin_post
- scope "/sessions" do
+ scope "/_sessions" do
get "/new", SessionController, :new
post "/new", SessionController, :login
get "/logout", SessionController, :logout
end
- get "/register", RegistrationController, :new
- post "/register", RegistrationController, :register
+ get "/_register", RegistrationController, :new
+ post "/", RegistrationController, :register
end
# definitely logged in, will redirect to login page
@@ -76,6 +76,13 @@ defmodule KmxgitWeb.Router do
end
end
+ # maybe logged in
+ scope "/", KmxgitWeb do
+ pipe_through [:browser, :auth]
+
+ get "/:slug", SlugController, :show
+ end
+
# Other scopes may use custom stacks.
# scope "/api", KmxgitWeb do
# pipe_through :api
diff --git a/lib/kmxgit_web/templates/layout/nav_connected.html.heex b/lib/kmxgit_web/templates/layout/nav_connected.html.heex
index dd004bc..f8fb67e 100644
--- a/lib/kmxgit_web/templates/layout/nav_connected.html.heex
+++ b/lib/kmxgit_web/templates/layout/nav_connected.html.heex
@@ -5,13 +5,13 @@
</li>
<%= if @conn.assigns[:current_organisation] do %>
<li class="nav-item">
- <%= link @current_organisation.name,
+ <%= link @current_organisation.name || @current_organisation.slug.slug,
to: Routes.organisation_path(@conn, :show, @current_organisation.slug),
class: "nav-link" %>
</li>
<% end %>
<li class="nav-item">
- <%= link @current_user.login, to: Routes.user_path(@conn, :show, @current_user.login), class: "nav-link" %>
+ <%= link @current_user.slug.slug, to: Routes.user_path(@conn, :show, @current_user.slug.slug), class: "nav-link" %>
</li>
<%= if @current_user.is_admin do %>
<li class="nav-item">
diff --git a/lib/kmxgit_web/templates/organisation/edit.html.heex b/lib/kmxgit_web/templates/organisation/edit.html.heex
new file mode 100644
index 0000000..d3d369c
--- /dev/null
+++ b/lib/kmxgit_web/templates/organisation/edit.html.heex
@@ -0,0 +1,4 @@
+<div class="container-fluid">
+ <h1><%= gettext("Edit organisation %{organisation}", organisation: @current_organisation.name || @current_organisation.slug.slug) %></h1>
+ <%= render "form.html", assigns %>
+</div>
diff --git a/lib/kmxgit_web/templates/organisation/form.html.heex b/lib/kmxgit_web/templates/organisation/form.html.heex
index 958588c..4f4da35 100644
--- a/lib/kmxgit_web/templates/organisation/form.html.heex
+++ b/lib/kmxgit_web/templates/organisation/form.html.heex
@@ -1,10 +1,12 @@
<%= form_for @changeset, @action, fn f -> %>
- <div class="mb-3">
- <%= label f, :slug, class: "form-label" %>
- <%= text_input f, :slug, class: "form-control" %>
- <%= error_tag f, :slug %>
- </div>
+ <%= inputs_for f, :slug, fn ff -> %>
+ <div class="mb-3">
+ <%= label ff, :slug, class: "form-label" %>
+ <%= text_input ff, :slug, class: "form-control" %>
+ <%= error_tag ff, :slug %>
+ </div>
+ <% end %>
<div class="mb-3">
<%= label f, :name, class: "form-label" %>
diff --git a/lib/kmxgit_web/templates/organisation/show.html.heex b/lib/kmxgit_web/templates/organisation/show.html.heex
index 7c5c123..8457985 100644
--- a/lib/kmxgit_web/templates/organisation/show.html.heex
+++ b/lib/kmxgit_web/templates/organisation/show.html.heex
@@ -1,11 +1,11 @@
<div class="container-fluid">
<div class="row">
<div class="col col-12 col-sm-7">
- <h1><%= @org.name || @org.slug %></h1>
+ <h1><%= @org.name || @org.slug.slug %></h1>
</div>
<div class="col col-12 col-sm-4">
<%= link gettext("Edit"),
- to: Routes.organisation_path(@conn, :edit, @org.slug),
+ to: Routes.organisation_path(@conn, :edit, @org.slug.slug),
class: "btn btn-primary" %>
</div>
@@ -22,7 +22,7 @@
<table class="table admin-properties">
<tr>
<th><%= gettext "Slug" %></th>
- <td><%= @org.slug %></td>
+ <td><%= @org.slug.slug %></td>
</tr>
<tr>
<th><%= gettext "Name" %></th>
@@ -36,6 +36,14 @@
<% end %>
</td>
</tr>
+ <tr>
+ <th><%= gettext "Users" %></th>
+ <td>
+ <%= for user <- @org.users do %>
+ <%= link(user.slug.slug, to: Routes.user_path(@conn, :show, user.slug.slug), class: "user") %>
+ <% end %>
+ </td>
+ </tr>
</table>
</div>
</div>
diff --git a/lib/kmxgit_web/templates/page/new_admin.html.heex b/lib/kmxgit_web/templates/page/new_admin.html.heex
index 3edca09..50144ba 100644
--- a/lib/kmxgit_web/templates/page/new_admin.html.heex
+++ b/lib/kmxgit_web/templates/page/new_admin.html.heex
@@ -11,37 +11,37 @@
<%= form_for @changeset, @action, fn f -> %>
- <div class="form-group">
- <%= label f, :name, class: "control-label" %>
+ <div class="mb-3">
+ <%= label f, :name, class: "form-label" %>
<%= text_input f, :name, class: "form-control" %>
<%= error_tag f, :name %>
</div>
- <div class="form-group">
- <%= label f, :email, class: "control-label" %>
+ <div class="mb-3">
+ <%= label f, :email, class: "form-label" %>
<%= text_input f, :email, class: "form-control" %>
<%= error_tag f, :email %>
</div>
- <div class="form-group">
- <%= label f, :login, class: "control-label" %>
+ <div class="mb-3">
+ <%= label f, :login, class: "form-label" %>
<%= text_input f, :login, class: "form-control" %>
<%= error_tag f, :login %>
</div>
- <div class="form-group">
- <%= label f, :password, class: "control-label" %>
+ <div class="mb-3">
+ <%= label f, :password, class: "form-label" %>
<%= password_input f, :password, class: "form-control" %>
<%= error_tag f, :password %>
</div>
- <div class="form-group">
- <%= label f, :password_confirmation, class: "control-label" %>
+ <div class="mb-3">
+ <%= label f, :password_confirmation, class: "form-label" %>
<%= password_input f, :password_confirmation, class: "form-control" %>
<%= error_tag f, :password_confirmation %>
</div>
- <div class="form-group">
+ <div class="mb-3">
<%= submit "Submit", class: "btn btn-primary" %>
</div>
diff --git a/lib/kmxgit_web/templates/user/edit.html.heex b/lib/kmxgit_web/templates/user/edit.html.heex
index daf1403..c0e1c5d 100644
--- a/lib/kmxgit_web/templates/user/edit.html.heex
+++ b/lib/kmxgit_web/templates/user/edit.html.heex
@@ -1,6 +1,6 @@
<div class="container-fluid center">
- <h1>Edit user <%= @current_user.login %></h1>
- <%= form_for @changeset, Routes.user_path(@conn, :update, @current_user.login), fn f -> %>
+ <h1>Edit user <%= @current_user.slug.slug %></h1>
+ <%= form_for @changeset, Routes.user_path(@conn, :update, @current_user.slug.slug), fn f -> %>
<div class="mb-3">
<%= label f, :name, class: "form-label" %>
@@ -12,10 +12,12 @@
<%= text_input f, :email, class: "form-control" %>
</div>
- <div class="mb-3">
- <%= label f, :login, class: "form-label" %>
- <%= text_input f, :login, class: "form-control" %>
- </div>
+ <%= inputs_for f, :slug, fn ff -> %>
+ <div class="mb-3">
+ <%= label ff, :slug, gettext("Login"), class: "form-label" %>
+ <%= text_input ff, :slug, class: "form-control" %>
+ </div>
+ <% end %>
<div class="mb-3">
<%= label f, :description, class: "form-label" %>
@@ -39,7 +41,7 @@
<div class="mb-3">
<%= link gettext("Cancel"),
- to: Routes.user_path(@conn, :show, @current_user.login),
+ to: Routes.user_path(@conn, :show, @current_user.slug.slug),
class: "btn btn-secondary" %>
<%= submit gettext("Submit"), class: "btn btn-primary" %>
diff --git a/lib/kmxgit_web/templates/user/show.html.heex b/lib/kmxgit_web/templates/user/show.html.heex
index b46fb16..36190df 100644
--- a/lib/kmxgit_web/templates/user/show.html.heex
+++ b/lib/kmxgit_web/templates/user/show.html.heex
@@ -1,11 +1,11 @@
<div class="container-fluid">
<div class="row">
<div class="col col-12 col-sm-7">
- <h1><%= @user.login %></h1>
+ <h1><%= @user.slug.slug %></h1>
</div>
<div class="col col-12 col-sm-4">
<%= link gettext("Edit"),
- to: Routes.user_path(@conn, :edit, @user.login),
+ to: Routes.user_path(@conn, :edit, @user.slug.slug),
class: "btn btn-primary" %>
</div>
</div>
@@ -29,7 +29,7 @@
</tr>
<tr>
<th><%= gettext "Login" %></th>
- <td><%= @user.login %></td>
+ <td><%= @user.slug.slug %></td>
</tr>
<tr>
<th><%= gettext "Description" %></th>
@@ -43,7 +43,7 @@
<th><%= gettext "Organisations" %></th>
<td>
<%= for org <- @user.organisations do %>
- <%= link(org.name || org.slug, to: Routes.organisation_path(@conn, :show, org.slug), class: "org") %>
+ <%= link(org.name || org.slug.slug, to: Routes.organisation_path(@conn, :show, org.slug.slug), class: "org") %>
<% end %>
</td>
</tr>
diff --git a/priv/repo/migrations/20201103085447_create_users.exs b/priv/repo/migrations/20201103085447_create_users.exs
index 9ec43f0..84fea26 100644
--- a/priv/repo/migrations/20201103085447_create_users.exs
+++ b/priv/repo/migrations/20201103085447_create_users.exs
@@ -7,11 +7,10 @@ defmodule Kmxgit.Repo.Migrations.CreateUsers do
add :email, :string
add :encrypted_password, :string
add :is_admin, :boolean, null: false, default: false
- add :login, :string
add :name, :string
+ add :ssh_keys, :text
timestamps()
end
- create index(:users, ["(lower(login))"], unique: true)
create index(:users, ["(lower(email))"], unique: true)
end
end
diff --git a/priv/repo/migrations/20211116104115_add_ssh_keys_to_users.exs b/priv/repo/migrations/20211116104115_add_ssh_keys_to_users.exs
deleted file mode 100644
index 5ef98a6..0000000
--- a/priv/repo/migrations/20211116104115_add_ssh_keys_to_users.exs
+++ /dev/null
@@ -1,9 +0,0 @@
-defmodule Kmxgit.Repo.Migrations.AddSshKeysToUsers do
- use Ecto.Migration
-
- def change do
- alter table(:users) do
- add :ssh_keys, :text
- end
- end
-end
diff --git a/priv/repo/migrations/20211116154852_create_organisations.exs b/priv/repo/migrations/20211116154852_create_organisations.exs
index 5e3cbb2..7dce83e 100644
--- a/priv/repo/migrations/20211116154852_create_organisations.exs
+++ b/priv/repo/migrations/20211116154852_create_organisations.exs
@@ -5,9 +5,7 @@ defmodule Kmxgit.Repo.Migrations.CreateOrganisations do
create table(:organisations) do
add :description, :string
add :name, :string
- add :slug, :string, null: false
timestamps()
end
- create index(:organisations, ["(lower(slug))"], unique: true)
end
end
diff --git a/priv/repo/migrations/20211118092722_create_slugs.exs b/priv/repo/migrations/20211118092722_create_slugs.exs
new file mode 100644
index 0000000..c106c7a
--- /dev/null
+++ b/priv/repo/migrations/20211118092722_create_slugs.exs
@@ -0,0 +1,13 @@
+defmodule Kmxgit.Repo.Migrations.CreateSlugs do
+ use Ecto.Migration
+
+ def change do
+ create table(:slugs) do
+ add :slug, :string, unique: true
+ add :organisation_id, references(:organisations), null: true
+ add :user_id, references(:users), null: true
+ timestamps()
+ end
+ create index(:slugs, ["(lower(slug))"], unique: true)
+ end
+end