diff --git a/lib/kmxgit/organisation_manager.ex b/lib/kmxgit/organisation_manager.ex
index 9d7ad57..31beec7 100644
--- a/lib/kmxgit/organisation_manager.ex
+++ b/lib/kmxgit/organisation_manager.ex
@@ -39,9 +39,12 @@ defmodule Kmxgit.OrganisationManager do
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]
+ where: fragment("lower(?)", s.slug) == ^String.downcase(slug),
+ preload: [:slug,
+ repositories: [organisation: :slug,
+ user: :slug],
+ users: :slug],
+ limit: 1
end
def delete_organisation(%Organisation{} = organisation) do
diff --git a/lib/kmxgit/organisation_manager/organisation.ex b/lib/kmxgit/organisation_manager/organisation.ex
index 2e63dd9..553d148 100644
--- a/lib/kmxgit/organisation_manager/organisation.ex
+++ b/lib/kmxgit/organisation_manager/organisation.ex
@@ -3,12 +3,14 @@ defmodule Kmxgit.OrganisationManager.Organisation do
use Ecto.Schema
import Ecto.Changeset
+ alias Kmxgit.RepositoryManager.Repository
alias Kmxgit.SlugManager.Slug
alias Kmxgit.UserManager.User
schema "organisations" do
field :description, :string
field :name, :string
+ has_many :repositories, Repository
many_to_many :users, User, join_through: "users_organisations", on_delete: :delete_all
has_one :slug, Slug, on_delete: :delete_all
timestamps()
diff --git a/lib/kmxgit/repository_manager.ex b/lib/kmxgit/repository_manager.ex
index d596007..9bd0a8d 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -61,7 +61,7 @@ defmodule Kmxgit.RepositoryManager do
full_join: us in Slug,
on: us.user_id == u.id,
where: (fragment("lower(?)", os.slug) == ^downcase_owner or fragment("lower(?)", us.slug) == ^downcase_owner) and fragment("lower(?)", r.slug) == ^downcase_slug,
- preload: [organisation: :slug],
+ preload: [organisation: [:slug, :users]],
preload: [user: :slug]
end
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index ca96d00..d9e1fff 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -23,10 +23,10 @@ defmodule Kmxgit.RepositoryManager.Repository do
|> Markdown.validate_markdown(:description)
end
- def owner(repo = %__MODULE__{organisation: org = %Organisation{}}) do
+ def owner(%__MODULE__{organisation: org = %Organisation{}}) do
org
end
- def owner(repo = %__MODULE__{user: user = %User{}}) do
+ def owner(%__MODULE__{user: user = %User{}}) do
user
end
diff --git a/lib/kmxgit/slug_manager.ex b/lib/kmxgit/slug_manager.ex
index f71a06a..f159104 100644
--- a/lib/kmxgit/slug_manager.ex
+++ b/lib/kmxgit/slug_manager.ex
@@ -24,8 +24,10 @@ defmodule Kmxgit.SlugManager do
def get_slug(slug) do
Repo.one from s in Slug,
- where: fragment("lower(slug)") == ^String.downcase(slug),
+ where: fragment("lower(?)", s.slug) == ^String.downcase(slug),
preload: [organisation: [:slug,
+ repositories: [organisation: :slug,
+ user: :slug],
users: :slug],
user: [:slug,
organisations: :slug,
diff --git a/lib/kmxgit_web/controllers/page_controller.ex b/lib/kmxgit_web/controllers/page_controller.ex
index 964a934..123c3b8 100644
--- a/lib/kmxgit_web/controllers/page_controller.ex
+++ b/lib/kmxgit_web/controllers/page_controller.ex
@@ -2,7 +2,6 @@ defmodule KmxgitWeb.PageController do
use KmxgitWeb, :controller
alias Kmxgit.Repo
- alias Kmxgit.SlugManager
alias Kmxgit.UserManager
alias Kmxgit.UserManager.{Guardian, User}
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index 038c2b7..ba1880e 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -2,26 +2,72 @@ defmodule KmxgitWeb.RepositoryController do
use KmxgitWeb, :controller
alias Kmxgit.RepositoryManager
+ alias Kmxgit.RepositoryManager.Repository
+ alias Kmxgit.SlugManager
def new(conn, params) do
- current_user = conn.assigns.current_user
- # TODO: check the owner part of path
+ action = Routes.repository_path(conn, :create, params["owner"])
changeset = RepositoryManager.change_repository
- conn
- |> assign(:action, Routes.repository_path(conn, :create, params["owner"]))
- |> assign(:changeset, changeset)
- |> render("new.html")
+ current_user = conn.assigns.current_user
+ slug = SlugManager.get_slug(params["owner"])
+ if !slug do
+ not_found(conn)
+ else
+ user = slug.user
+ if user do
+ if user != current_user && !current_user.is_admin do
+ not_found(conn)
+ else
+ conn
+ |> assign(:action, action)
+ |> assign(:changeset, changeset)
+ |> render("new.html")
+ end
+ else
+ org = slug.organisation
+ if org do
+ conn
+ |> assign(:action, action)
+ |> assign(:changeset, changeset)
+ |> assign(:current_organisation, org)
+ |> render("new.html")
+ else
+ not_found(conn)
+ end
+ end
+ end
end
def create(conn, params) do
current_user = conn.assigns.current_user
- # TODO: handle organisations
- owner = current_user
+ slug = SlugManager.get_slug(params["owner"])
+ if !slug do
+ not_found(conn)
+ else
+ user = slug.user
+ if user do
+ if user != current_user && !current_user.is_admin do
+ not_found(conn)
+ else
+ create_repo(conn, user, params["repository"])
+ end
+ else
+ org = slug.organisation
+ if org do
+ create_repo(conn, org, params["repository"])
+ else
+ not_found(conn)
+ end
+ end
+ end
+ end
# TODO: check the owner part of path
- case RepositoryManager.create_repository(current_user, params["repository"]) do
- {:ok, repository} ->
+
+ defp create_repo(conn, owner, params) do
+ case RepositoryManager.create_repository(owner, params) do
+ {:ok, repo} ->
conn
- |> redirect(to: Routes.repository_path(conn, :show, owner.slug.slug, repository.slug))
+ |> redirect(to: Routes.repository_path(conn, :show, owner.slug.slug, Repository.splat(repo)))
{:error, changeset} ->
IO.inspect(changeset)
conn
@@ -40,10 +86,9 @@ defmodule KmxgitWeb.RepositoryController do
def show(conn, params) do
slug = Enum.join(params["slug"], "/")
- repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
+ repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
if repo do
org = repo.organisation
- user = repo.user
conn
|> assign_current_organisation(org)
|> assign(:current_repository, repo)
@@ -55,36 +100,49 @@ defmodule KmxgitWeb.RepositoryController do
end
def edit(conn, params) do
+ current_user = conn.assigns.current_user
slug = Enum.join(params["slug"], "/")
- repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
- changeset = RepositoryManager.change_repository(repo)
+ repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
if repo do
org = repo.organisation
- user = repo.user
- conn
- |> assign(:action, Routes.repository_path(conn, :update, org.slug.slug))
- |> assign(:changeset, changeset)
- |> assign_current_organisation(org)
- |> assign(:current_repository, repo)
- |> assign(:repo, repo)
- |> render("edit.html")
+ if org && Enum.find(org.users, &(&1.id == current_user.id)) || repo.user_id == current_user.id do
+ changeset = RepositoryManager.change_repository(repo)
+ conn
+ |> assign(:action, Routes.repository_path(conn, :update, params["owner"], Repository.splat(repo)))
+ |> assign(:changeset, changeset)
+ |> assign_current_organisation(org)
+ |> assign(:current_repository, repo)
+ |> assign(:repo, repo)
+ |> render("edit.html")
+ else
+ not_found(conn)
+ end
else
not_found(conn)
end
end
def update(conn, params) do
- repository = RepositoryManager.get_repository_by_slug(params["slug"])
- if repository do
- case RepositoryManager.update_repository(repository, params["repository"]) do
- {:ok, org} ->
- conn
- |> redirect(to: Routes.slug_path(conn, :show, org.slug.slug))
- {:error, changeset} ->
- IO.inspect(changeset)
- conn
- |> render("edit.html", changeset: changeset,
- action: Routes.repository_path(conn, :update, repository.slug.slug))
+ current_user = conn.assigns.current_user
+ slug = Enum.join(params["slug"], "/")
+ repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
+ if repo do
+ org = repo.organisation
+ if org && Enum.find(org.users, &(&1.id == current_user.id)) || repo.user_id == current_user.id do
+ case RepositoryManager.update_repository(repo, params["repository"]) do
+ {:ok, repo} ->
+ conn
+ |> redirect(to: Routes.repository_path(conn, :show, params["owner"], Repository.splat(repo)))
+ {:error, changeset} ->
+ IO.inspect(changeset)
+ conn
+ |> assign(:action, Routes.repository_path(conn, :update, params["owner"], Repository.splat(repo)))
+ |> assign(:changeset, changeset)
+ |> assign_current_organisation(org)
+ |> assign(:current_repository, repo)
+ |> assign(:repo, repo)
+ |> render("edit.html")
+ end
end
else
not_found(conn)
diff --git a/lib/kmxgit_web/controllers/slug_controller.ex b/lib/kmxgit_web/controllers/slug_controller.ex
index ba40c07..366a542 100644
--- a/lib/kmxgit_web/controllers/slug_controller.ex
+++ b/lib/kmxgit_web/controllers/slug_controller.ex
@@ -23,14 +23,17 @@ defmodule KmxgitWeb.SlugController do
conn
|> assign(:page_title, gettext("User %{login}", login: user.slug.slug))
|> assign(:user, user)
- |> render(UserView, "show.html")
+ |> put_view(UserView)
+ |> render("show.html")
else
org = slug.organisation
if org do
conn
|> assign(:current_organisation, org)
|> assign(:org, org)
- |> render(OrganisationView, "show.html")
+ |> assign(:page_title, org.name || org.slug.slug)
+ |> put_view(OrganisationView)
+ |> render("show.html")
else
not_found(conn)
end
diff --git a/lib/kmxgit_web/templates/organisation/show.html.heex b/lib/kmxgit_web/templates/organisation/show.html.heex
index 04c9cf2..ddf0dc6 100644
--- a/lib/kmxgit_web/templates/organisation/show.html.heex
+++ b/lib/kmxgit_web/templates/organisation/show.html.heex
@@ -4,6 +4,9 @@
<h1><%= @org.name || @org.slug.slug %></h1>
</div>
<div class="col col-12 col-sm-4">
+ <%= link gettext("New repository"),
+ to: Routes.repository_path(@conn, :new, @org.slug.slug),
+ class: "btn btn-primary" %>
<%= link gettext("Edit"),
to: Routes.organisation_path(@conn, :edit, @org.slug.slug),
class: "btn btn-primary" %>
@@ -15,6 +18,9 @@
<div class="col col-12 col-md-7">
<hr/>
<h2><%= gettext "Repositories" %></h2>
+ <%= for repo <- @org.repositories do %>
+ <%= link Repository.full_slug(repo), to: Routes.repository_path(@conn, :show, @org.slug.slug, Repository.splat(repo)) %>
+ <% end %>
</div>
<div class="col col-12 col-md-4">
<hr/>
diff --git a/lib/kmxgit_web/templates/repository/edit.html.heex b/lib/kmxgit_web/templates/repository/edit.html.heex
new file mode 100644
index 0000000..a8e8bf7
--- /dev/null
+++ b/lib/kmxgit_web/templates/repository/edit.html.heex
@@ -0,0 +1,7 @@
+<div class="container-fluid">
+ <h1>
+ <%= gettext "Edit repository" %>
+ <%= Repository.full_slug(@repo) %>
+ </h1>
+ <%= render "form.html", assigns %>
+</div>
diff --git a/lib/kmxgit_web/views/organisation_view.ex b/lib/kmxgit_web/views/organisation_view.ex
index 12fbdd5..1e9b731 100644
--- a/lib/kmxgit_web/views/organisation_view.ex
+++ b/lib/kmxgit_web/views/organisation_view.ex
@@ -1,3 +1,5 @@
defmodule KmxgitWeb.OrganisationView do
use KmxgitWeb, :view
+
+ alias Kmxgit.RepositoryManager.Repository
end