diff --git a/assets/css/app.scss b/assets/css/app.scss
index ad386c8..e30ec01 100644
--- a/assets/css/app.scss
+++ b/assets/css/app.scss
@@ -5,7 +5,9 @@
@import "./flash.scss";
/* user */
-textarea#user_description {
+textarea#user_description,
+textarea#organisation_description,
+textarea#repository_description {
min-height: 10em;
}
textarea#user_ssh_keys {
@@ -14,9 +16,6 @@ textarea#user_ssh_keys {
overflow-x: scroll;
overflow-y: scroll;
}
-textarea#organisation_description {
- min-height: 10em;
-}
pre.ssh_keys {
max-width: 20em;
white-space: pre-wrap; /* Since CSS 2.1 */
diff --git a/lib/kmxgit/organisation_manager.ex b/lib/kmxgit/organisation_manager.ex
index 31beec7..9d320f6 100644
--- a/lib/kmxgit/organisation_manager.ex
+++ b/lib/kmxgit/organisation_manager.ex
@@ -41,8 +41,8 @@ defmodule Kmxgit.OrganisationManager do
on: s.organisation_id == o.id,
where: fragment("lower(?)", s.slug) == ^String.downcase(slug),
preload: [:slug,
- repositories: [organisation: :slug,
- user: :slug],
+ owned_repositories: [organisation: :slug,
+ user: :slug],
users: :slug],
limit: 1
end
diff --git a/lib/kmxgit/organisation_manager/organisation.ex b/lib/kmxgit/organisation_manager/organisation.ex
index 553d148..dfc0cb3 100644
--- a/lib/kmxgit/organisation_manager/organisation.ex
+++ b/lib/kmxgit/organisation_manager/organisation.ex
@@ -10,7 +10,7 @@ defmodule Kmxgit.OrganisationManager.Organisation do
schema "organisations" do
field :description, :string
field :name, :string
- has_many :repositories, Repository
+ has_many :owned_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 9bd0a8d..c1f8159 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -61,8 +61,9 @@ 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, :users]],
- preload: [user: :slug]
+ preload: [members: :slug,
+ organisation: [:slug, :users],
+ user: :slug]
end
def delete_repository(%Repository{} = repository) do
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index d9e1fff..ded6b49 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -11,6 +11,7 @@ defmodule Kmxgit.RepositoryManager.Repository do
belongs_to :organisation, Organisation
field :slug, :string, unique: true
belongs_to :user, User
+ many_to_many :members, User, join_through: "users_repositories"
timestamps()
end
@@ -41,4 +42,15 @@ defmodule Kmxgit.RepositoryManager.Repository do
def splat(repo) do
String.split(repo.slug, "/")
end
+
+ def members(repo) do
+ if repo.user do
+ Enum.concat [repo.user], repo.members
+ else
+ if repo.organisation do
+ Enum.concat repo.organisation.users, repo.members
+ end
+ end
+ |> Enum.uniq
+ end
end
diff --git a/lib/kmxgit/slug_manager.ex b/lib/kmxgit/slug_manager.ex
index f159104..982fd30 100644
--- a/lib/kmxgit/slug_manager.ex
+++ b/lib/kmxgit/slug_manager.ex
@@ -26,13 +26,13 @@ defmodule Kmxgit.SlugManager do
Repo.one from s in Slug,
where: fragment("lower(?)", s.slug) == ^String.downcase(slug),
preload: [organisation: [:slug,
- repositories: [organisation: :slug,
- user: :slug],
+ owned_repositories: [organisation: :slug,
+ user: :slug],
users: :slug],
user: [:slug,
organisations: :slug,
- repositories: [organisation: :slug,
- user: :slug]]],
+ owned_repositories: [organisation: :slug,
+ user: :slug]]],
limit: 1
end
diff --git a/lib/kmxgit/user_manager.ex b/lib/kmxgit/user_manager.ex
index f419854..fdc3228 100644
--- a/lib/kmxgit/user_manager.ex
+++ b/lib/kmxgit/user_manager.ex
@@ -19,7 +19,7 @@ defmodule Kmxgit.UserManager do
user = Repo.one(from user in User,
where: [id: ^id],
preload: [organisations: :slug],
- preload: [repositories: [organisation: :slug, user: :slug]],
+ preload: [owned_repositories: [organisation: :slug, user: :slug]],
preload: :slug
)
user || raise Ecto.NoResultsError
@@ -29,7 +29,7 @@ defmodule Kmxgit.UserManager do
Repo.one from user in User,
where: [id: ^id],
preload: [organisations: :slug],
- preload: [repositories: [organisation: :slug, user: :slug]],
+ preload: [owned_repositories: [organisation: :slug, user: :slug]],
preload: :slug
end
@@ -41,7 +41,7 @@ defmodule Kmxgit.UserManager do
limit: 1,
preload: [:slug,
organisations: :slug,
- repositories: [organisation: :slug, user: :slug]]
+ owned_repositories: [organisation: :slug, user: :slug]]
end
def create_user(attrs \\ %{}) do
diff --git a/lib/kmxgit/user_manager/user.ex b/lib/kmxgit/user_manager/user.ex
index a9e731e..7a8a725 100644
--- a/lib/kmxgit/user_manager/user.ex
+++ b/lib/kmxgit/user_manager/user.ex
@@ -13,9 +13,10 @@ defmodule Kmxgit.UserManager.User do
field :encrypted_password, :string
field :is_admin, :boolean, null: false
field :name, :string
+ has_many :owned_repositories, Repository
field :password, :string, virtual: true, redact: true
field :password_confirmation, :string, virtual: true, redact: true
- has_many :repositories, Repository
+ #many_to_many :repositories, Repository, join_through: "users_repositories"
has_one :slug, Slug, on_delete: :delete_all
field :ssh_keys, :string
many_to_many :organisations, Organisation, join_through: "users_organisations", on_delete: :delete_all
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index b56cf54..76cbb87 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -31,6 +31,7 @@ defmodule KmxgitWeb.RepositoryController do
|> assign(:action, action)
|> assign(:changeset, changeset)
|> assign(:current_organisation, org)
+ |> assign(:owner, org)
|> render("new.html")
else
not_found(conn)
@@ -95,6 +96,7 @@ defmodule KmxgitWeb.RepositoryController do
|> assign_current_organisation(org)
|> assign(:current_repository, repo)
|> assign(:repo, repo)
+ |> assign(:members, Repository.members(repo))
|> render("show.html")
else
not_found(conn)
diff --git a/lib/kmxgit_web/controllers/slug_controller.ex b/lib/kmxgit_web/controllers/slug_controller.ex
index 366a542..60428e3 100644
--- a/lib/kmxgit_web/controllers/slug_controller.ex
+++ b/lib/kmxgit_web/controllers/slug_controller.ex
@@ -1,6 +1,7 @@
defmodule KmxgitWeb.SlugController do
use KmxgitWeb, :controller
+ alias Kmxgit.OrganisationManager
alias Kmxgit.SlugManager
alias KmxgitWeb.ErrorView
alias KmxgitWeb.OrganisationView
@@ -40,4 +41,21 @@ defmodule KmxgitWeb.SlugController do
end
end
end
+
+ def delete(conn, params) do
+ current_user = conn.assigns.current_user
+ slug = SlugManager.get_slug(params["slug"])
+ if slug do
+ org = slug.organisation
+ if org && Enum.find(org.users, &(&1.id == current_user.id)) do
+ {:ok, _} = OrganisationManager.delete_organisation(org)
+ conn
+ |> redirect(to: Routes.slug_path(conn, :show, current_user.slug.slug))
+ else
+ not_found(conn)
+ end
+ else
+ not_found(conn)
+ end
+ end
end
diff --git a/lib/kmxgit_web/router.ex b/lib/kmxgit_web/router.ex
index 2702e08..e4b0b3e 100644
--- a/lib/kmxgit_web/router.ex
+++ b/lib/kmxgit_web/router.ex
@@ -83,6 +83,7 @@ defmodule KmxgitWeb.Router do
pipe_through [:browser, :auth]
get "/:slug", SlugController, :show
+ delete "/:slug", SlugController, :delete
get "/:owner/*slug", RepositoryController, :show
delete "/:owner/*slug", RepositoryController, :delete
end
diff --git a/lib/kmxgit_web/templates/organisation/form.html.heex b/lib/kmxgit_web/templates/organisation/form.html.heex
index 4f4da35..4c401c9 100644
--- a/lib/kmxgit_web/templates/organisation/form.html.heex
+++ b/lib/kmxgit_web/templates/organisation/form.html.heex
@@ -21,6 +21,17 @@
</div>
<div class="mb-3">
+ <%= if @conn.assigns[:current_organisation] do %>
+ <%= link gettext("Delete organisation"),
+ to: Routes.slug_path(@conn, :delete, @current_organisation.slug.slug),
+ method: :delete,
+ class: "btn btn-danger",
+ data: [confirm: gettext("Are you sure you want to delete the organisation %{org} ?", org: @current_organisation.name || @current_organisation.slug.slug)] %>
+ <% else %>
+ <%= link gettext("Cancel"),
+ to: Routes.slug_path(@conn, :show, @current_user.slug.slug),
+ class: "btn btn-secondary" %>
+ <% end %>
<%= submit gettext("Submit"), class: "btn btn-primary" %>
</div>
diff --git a/lib/kmxgit_web/templates/organisation/show.html.heex b/lib/kmxgit_web/templates/organisation/show.html.heex
index ddf0dc6..b9a23f0 100644
--- a/lib/kmxgit_web/templates/organisation/show.html.heex
+++ b/lib/kmxgit_web/templates/organisation/show.html.heex
@@ -18,7 +18,7 @@
<div class="col col-12 col-md-7">
<hr/>
<h2><%= gettext "Repositories" %></h2>
- <%= for repo <- @org.repositories do %>
+ <%= for repo <- @org.owned_repositories do %>
<%= link Repository.full_slug(repo), to: Routes.repository_path(@conn, :show, @org.slug.slug, Repository.splat(repo)) %>
<% end %>
</div>
diff --git a/lib/kmxgit_web/templates/repository/form.html.heex b/lib/kmxgit_web/templates/repository/form.html.heex
index 338b0c9..13717bd 100644
--- a/lib/kmxgit_web/templates/repository/form.html.heex
+++ b/lib/kmxgit_web/templates/repository/form.html.heex
@@ -19,6 +19,9 @@
<div class="mb-3">
<%= if @conn.assigns[:current_repository] do %>
+ <%= link gettext("Cancel"),
+ to: Routes.repository_path(@conn, :show, Repository.owner_slug(@current_repository), Repository.splat(@current_repository)),
+ class: "btn btn-secondary" %>
<%= link gettext("Delete repository"),
to: Routes.repository_path(@conn, :delete, Repository.owner_slug(@current_repository), Repository.splat(@current_repository)),
method: :delete,
diff --git a/lib/kmxgit_web/templates/repository/show.html.heex b/lib/kmxgit_web/templates/repository/show.html.heex
index 4046b8b..5422a28 100644
--- a/lib/kmxgit_web/templates/repository/show.html.heex
+++ b/lib/kmxgit_web/templates/repository/show.html.heex
@@ -11,4 +11,31 @@
</div>
</div>
+ <div class="row">
+ <div class="col col-12 col-md-7">
+ <hr/>
+ </div>
+ <div class="col col-12 col-md-4">
+ <hr/>
+ <h2><%= gettext "Properties" %></h2>
+ <table class="table admin-properties">
+ <tr>
+ <th><%= gettext "Description" %></th>
+ <td>
+ <%= if @repo.description do %>
+ <%= raw Earmark.as_html!(@repo.description) %>
+ <% end %>
+ </td>
+ </tr>
+ <tr>
+ <th><%= gettext "Users" %></th>
+ <td>
+ <%= for user <- @members do %>
+ <%= link user.slug.slug, to: Routes.slug_path(@conn, :show, user.slug.slug) %>
+ <% end %>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
</div>
diff --git a/lib/kmxgit_web/templates/user/show.html.heex b/lib/kmxgit_web/templates/user/show.html.heex
index 14189a0..671846a 100644
--- a/lib/kmxgit_web/templates/user/show.html.heex
+++ b/lib/kmxgit_web/templates/user/show.html.heex
@@ -17,7 +17,7 @@
<div class="col col-12 col-md-7">
<hr/>
<h2><%= gettext "Repositories" %></h2>
- <%= for repo <- @user.repositories do %>
+ <%= for repo <- @user.owned_repositories do %>
<%= link Repository.full_slug(repo), to: Routes.repository_path(@conn, :show, @user.slug.slug, Repository.splat(repo)) %>
<% end %>
</div>
diff --git a/priv/repo/migrations/20211119161041_create_users_repositories.exs b/priv/repo/migrations/20211119161041_create_users_repositories.exs
new file mode 100644
index 0000000..aff0972
--- /dev/null
+++ b/priv/repo/migrations/20211119161041_create_users_repositories.exs
@@ -0,0 +1,10 @@
+defmodule Kmxgit.Repo.Migrations.CreateUsersRepositories do
+ use Ecto.Migration
+
+ def change do
+ create table(:users_repositories, foreign_key: false) do
+ add :user_id, references(:users)
+ add :repository_id, references(:repositories)
+ end
+ end
+end