Commit e8a03cbe8dc2f049f3cc5bf6918f893cb52a23e3

Thomas de Grivel 2021-11-30T14:11:11

deploy keys

diff --git a/assets/css/app.scss b/assets/css/app.scss
index f12356d..3250371 100644
--- a/assets/css/app.scss
+++ b/assets/css/app.scss
@@ -10,7 +10,8 @@ textarea#organisation_description,
 textarea#repository_description {
     min-height: 10em;
 }
-textarea#user_ssh_keys {
+textarea#user_ssh_keys,
+textarea#repository_deploy_keys {
     font-family: monospace;
     min-height: 20em;
     overflow-x: scroll;
diff --git a/bin/update_etc_git_auth b/bin/update_etc_git_auth
index 8676ea4..6b97be6 100755
--- a/bin/update_etc_git_auth
+++ b/bin/update_etc_git_auth
@@ -1,4 +1,4 @@
 #!/bin/sh
 set -e
-cd /etc/git
-ftp -o auth.conf https://git.kmx.io/_etc/git/auth.conf
+cd /etc/git/
+curl > auth.conf https://git.kmx.io/_etc/git/auth.conf
diff --git a/bin/update_git_ssh_authorized_keys b/bin/update_git_ssh_authorized_keys
new file mode 100755
index 0000000..f4c76a9
--- /dev/null
+++ b/bin/update_git_ssh_authorized_keys
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -e
+cd /home/git/.ssh/
+curl > authorized_keys https://git.kmx.io/_etc/ssh/authorized_keys
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index 38f3340..1212ffa 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -10,6 +10,7 @@ defmodule Kmxgit.RepositoryManager.Repository do
   alias Kmxgit.UserManager.User
 
   schema "repositories" do
+    field :deploy_keys, :string
     field :description, :string
     belongs_to :organisation, Organisation
     field :slug, :string
@@ -20,20 +21,20 @@ defmodule Kmxgit.RepositoryManager.Repository do
 
   def changeset(repository, attrs) do
     repository
-    |> cast(attrs, [:description, :slug])
+    |> cast(attrs, [:deploy_keys, :description, :slug])
     |> common_changeset()
   end
 
   def owner_changeset(repository, attrs, owner = %Organisation{}) do
     repository
-    |> cast(attrs, [:description, :slug])
+    |> cast(attrs, [:deploy_keys, :description, :slug])
     |> put_assoc(:organisation, owner)
     |> put_assoc(:user, nil)
     |> common_changeset()
   end
   def owner_changeset(repository, attrs, owner = %User{}) do
     repository
-    |> cast(attrs, [:description, :slug])
+    |> cast(attrs, [:deploy_keys, :description, :slug])
     |> put_assoc(:organisation, nil)
     |> put_assoc(:user, owner)
     |> common_changeset()
@@ -135,7 +136,8 @@ defmodule Kmxgit.RepositoryManager.Repository do
   end
 
   def auth(repo) do
-    repo
+    full_slug = full_slug(repo)
+    auth = repo
     |> members()
     |> Enum.sort(fn a, b ->
       a.slug.slug < b.slug.slug
@@ -146,7 +148,29 @@ defmodule Kmxgit.RepositoryManager.Repository do
         else
           "rw"
         end
-      "#{user.slug.slug} #{mode} \"#{full_slug(repo)}.git\"\n"
+      auth_line(user.slug.slug, mode, full_slug)
+    end)
+    auth ++ [auth_line(deploy_user(repo), "r", full_slug)]
+  end
+
+  defp auth_line(user, mode, slug) do
+    "#{user} #{mode} '#{slug}.git'\n"
+  end
+
+  def deploy_user(repo) do
+    "_deploy_#{full_slug(repo)}"
+  end
+
+  def deploy_keys_with_env(repo) do
+    (repo.deploy_keys || "")
+    |> String.split("\n")
+    |> Enum.map(fn line ->
+      if Regex.match?(~r/^[ \t]*ssh-/, line) do
+        "environment=\"GIT_AUTH_ID=#{deploy_user(repo)}\" #{line}"
+      else
+        line
+      end
     end)
+    |> Enum.join("\n")
   end
 end
diff --git a/lib/kmxgit_web/controllers/page_controller.ex b/lib/kmxgit_web/controllers/page_controller.ex
index 8c2d3ce..966abb0 100644
--- a/lib/kmxgit_web/controllers/page_controller.ex
+++ b/lib/kmxgit_web/controllers/page_controller.ex
@@ -51,9 +51,11 @@ defmodule KmxgitWeb.PageController do
   end
 
   def keys(conn, _params) do
-    k = UserManager.list_users
-    |> Enum.map(fn user -> User.ssh_keys_with_env(user) end)
-    |> Enum.join("\n")
+    k1 = UserManager.list_users
+    |> Enum.map(&User.ssh_keys_with_env/1)
+    k2 = RepositoryManager.list_repositories
+    |> Enum.map(&Repository.deploy_keys_with_env/1)
+    k = (k1 ++ k2) |> Enum.join("\n")
     conn
     |> put_resp_content_type("text/text")
     |> resp(200, k)
diff --git a/lib/kmxgit_web/templates/repository/form.html.heex b/lib/kmxgit_web/templates/repository/form.html.heex
index 1535a36..b0c014a 100644
--- a/lib/kmxgit_web/templates/repository/form.html.heex
+++ b/lib/kmxgit_web/templates/repository/form.html.heex
@@ -18,6 +18,12 @@
   </div>
 
   <div class="mb-3">
+    <%= label f, :deploy_keys, class: "form-label" %>
+    <%= textarea f, :deploy_keys, class: "form-control" %>
+    <%= error_tag f, :deploy_keys %>
+  </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)),