Commit 6480dce3aaf8a4deccaa38e8f64231acdf7f008f

Thomas de Grivel 2021-12-02T12:27:53

allow to change repository owner

diff --git a/lib/kmxgit/repository_manager.ex b/lib/kmxgit/repository_manager.ex
index 856d778..a3fd2ea 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -5,6 +5,7 @@ defmodule Kmxgit.RepositoryManager do
   alias Kmxgit.OrganisationManager.Organisation
   alias Kmxgit.Repo
   alias Kmxgit.RepositoryManager.Repository
+  alias Kmxgit.SlugManager
   alias Kmxgit.SlugManager.Slug
   alias Kmxgit.UserManager
   alias Kmxgit.UserManager.User
@@ -48,7 +49,27 @@ defmodule Kmxgit.RepositoryManager do
     |> Repo.insert()
   end
 
-  def update_repository(repository, attrs \\ %{}) do
+  def update_repository(repository, attrs = %{"owner_slug" => owner_slug}) do
+    if owner_slug && owner_slug != "" do
+      if slug = SlugManager.get_slug(owner_slug) do
+        owner = slug.organisation || slug.user
+        IO.inspect([owner_slug: owner_slug, slug: slug, owner: owner])
+        repository
+        |> Repository.owner_changeset(attrs, owner)
+        |> Repo.update()
+      else
+        changeset = repository
+        |> Repository.changeset(attrs)
+        |> Ecto.Changeset.add_error(:owner_slug, "not found")
+        {:error, %Ecto.Changeset{changeset | action: :update}}
+      end
+    else
+      repository
+      |> Repository.changeset(attrs)
+      |> Repo.update()
+    end
+  end
+  def update_repository(repository, attrs) do
     repository
     |> Repository.changeset(attrs)
     |> Repo.update()
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index 78399af..49644d5 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -10,9 +10,10 @@ defmodule Kmxgit.RepositoryManager.Repository do
   schema "repositories" do
     field :deploy_keys, :string
     field :description, :string
-    belongs_to :organisation, Organisation
+    belongs_to :organisation, Organisation, on_replace: :nilify
+    field :owner_slug, :string, virtual: true
     field :slug, :string
-    belongs_to :user, User
+    belongs_to :user, User, on_replace: :nilify
     many_to_many :members, User, join_through: "users_repositories", on_replace: :delete, on_delete: :delete_all
     timestamps()
   end
@@ -26,6 +27,8 @@ defmodule Kmxgit.RepositoryManager.Repository do
   def owner_changeset(repository, attrs, owner = %Organisation{}) do
     repository
     |> cast(attrs, [:deploy_keys, :description, :slug])
+    |> put_change(:organisation_id, owner.id)
+    |> put_change(:user_id, nil)
     |> put_assoc(:organisation, owner)
     |> put_assoc(:user, nil)
     |> common_changeset()
@@ -33,6 +36,8 @@ defmodule Kmxgit.RepositoryManager.Repository do
   def owner_changeset(repository, attrs, owner = %User{}) do
     repository
     |> cast(attrs, [:deploy_keys, :description, :slug])
+    |> put_change(:organisation_id, nil)
+    |> put_change(:user_id, owner.id)
     |> put_assoc(:organisation, nil)
     |> put_assoc(:user, owner)
     |> common_changeset()
diff --git a/lib/kmxgit_web/controllers/admin/repository_controller.ex b/lib/kmxgit_web/controllers/admin/repository_controller.ex
index beb4b5f..ab28010 100644
--- a/lib/kmxgit_web/controllers/admin/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/admin/repository_controller.ex
@@ -118,8 +118,9 @@ defmodule KmxgitWeb.Admin.RepositoryController do
         |> redirect(to: Routes.admin_repository_path(conn, :show, repo1))
       {:error, changeset} ->
         conn
-        |> assign(:action, Routes.admin_repository__path(conn, :update, repo))
+        |> assign(:action, Routes.admin_repository_path(conn, :update, repo))
         |> assign(:changeset, changeset)
+        |> assign(:repo, repo)
         |> render("edit.html")
     end
   end
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index cd664f0..c050690 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -278,7 +278,6 @@ defmodule KmxgitWeb.RepositoryController do
     slug = Enum.join(params["slug"], "/")
     repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
     if repo && Repository.owner?(repo, current_user) do
-      org = repo.organisation
       case Repo.transaction(fn ->
             case RepositoryManager.update_repository(repo, params["repository"]) do
               {:ok, repo1} ->
@@ -295,18 +294,18 @@ defmodule KmxgitWeb.RepositoryController do
               {:error, changeset} -> Repo.rollback(changeset)
             end
           end) do
-        {:ok, repo} ->
+        {:ok, repo1} ->
           case GitManager.update_auth() do
             :ok -> nil
             error -> IO.inspect(error)
           end
           conn
-          |> redirect(to: Routes.repository_path(conn, :show, params["owner"], Repository.splat(repo)))
+          |> redirect(to: Routes.repository_path(conn, :show, Repository.owner_slug(repo1), Repository.splat(repo1)))
         {:error, changeset} ->
           conn
           |> assign(:action, Routes.repository_path(conn, :update, params["owner"], Repository.splat(repo)))
           |> assign(:changeset, changeset)
-          |> assign_current_organisation(org)
+          |> assign_current_organisation(repo.organisation)
           |> assign(:current_repository, repo)
           |> assign(:repo, repo)
           |> render("edit.html")
diff --git a/lib/kmxgit_web/templates/admin/repository/form.html.heex b/lib/kmxgit_web/templates/admin/repository/form.html.heex
index 0c4465d..265f2ad 100644
--- a/lib/kmxgit_web/templates/admin/repository/form.html.heex
+++ b/lib/kmxgit_web/templates/admin/repository/form.html.heex
@@ -18,6 +18,12 @@
   </div>
 
   <div class="mb-3">
+    <%= label f, :owner_slug, gettext("Change owner ⚠"), class: "form-label" %>
+    <%= text_input f, :owner_slug, class: "form-control" %>
+    <%= error_tag f, :owner_slug %>
+  </div>
+
+  <div class="mb-3">
     <%= if @conn.assigns[:repo] do %>
       <%= link gettext("Cancel"),
           to: Routes.admin_repository_path(@conn, :show, @repo),
diff --git a/lib/kmxgit_web/templates/repository/form.html.heex b/lib/kmxgit_web/templates/repository/form.html.heex
index b0c014a..1b84fbe 100644
--- a/lib/kmxgit_web/templates/repository/form.html.heex
+++ b/lib/kmxgit_web/templates/repository/form.html.heex
@@ -24,6 +24,12 @@
   </div>
 
   <div class="mb-3">
+    <%= label f, :owner_slug, gettext("Change owner ⚠"), class: "form-label" %>
+    <%= text_input f, :owner_slug, class: "form-control" %>
+    <%= error_tag f, :owner_slug %>
+  </div>
+
+  <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)),