Commit 60c50e63d0fd8267e5e2fc330e780c0571b07802

Thomas de Grivel 2021-11-19T17:46:49

users repositories

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