Browse Source

Add the possibility to add/remove ssh keys on the authorized_keys file

This is the base of the work we need to do to drop gitolite from pagure.

Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
Pierre-Yves Chibon 4 years ago
parent
commit
431630139f
4 changed files with 88 additions and 0 deletions
  1. 46 0
      pagure/lib/tasks.py
  2. 21 0
      pagure/ui/app.py
  3. 20 0
      pagure/ui/repo.py
  4. 1 0
      setup.py

+ 46 - 0
pagure/lib/tasks.py

@@ -1248,3 +1248,49 @@ def generate_archive(
         namespace=project.namespace,
         username=project.user.user if project.is_fork else None,
     )
+
+
+@conn.task(queue=pagure_config.get("AUTHORIZED_KEYS_QUEUE", None), bind=True)
+@pagure_task
+def add_key_to_authorized_keys(self, session, ssh_folder, username, sshkey):
+    """ Add the specified key to the the `authorized_keys` file of the
+    specified ssh folder.
+    """
+    if not os.path.exists(ssh_folder):
+        _log.info("No folder '%s' found", ssh_folder)
+        return
+
+    fullpath = os.path.join(ssh_folder, "authorized_keys")
+    _log.info("Add ssh key for user %s to %s", username, fullpath)
+    with open(fullpath, "a") as stream:
+        stream.write("\n")
+        stream.write(
+            "{0} {1}".format(
+                pagure_config["SSH_KEYS_OPTIONS"] % {"username": username},
+                sshkey.strip(),
+            )
+        )
+
+
+@conn.task(queue=pagure_config.get("AUTHORIZED_KEYS_QUEUE", None), bind=True)
+@pagure_task
+def remove_key_from_authorized_keys(self, session, ssh_folder, sshkey):
+    """ Remove the specified key from the the `authorized_keys` file of the
+    specified ssh folder.
+    """
+    if not os.path.exists(ssh_folder):
+        _log.info("No folder '%s' found", ssh_folder)
+        return
+
+    fullpath = os.path.join(ssh_folder, "authorized_keys")
+    _log.info("Removing ssh key in %s", fullpath)
+    output = []
+    with open(fullpath, "r") as stream:
+        for row in stream.readlines():
+            row = row.strip()
+            if sshkey in row:
+                continue
+            output.append(row)
+
+    with open(fullpath, "w") as stream:
+        stream.write("\n".join(output))

+ 21 - 0
pagure/ui/app.py

@@ -21,6 +21,7 @@ from sqlalchemy.exc import SQLAlchemyError
 import pagure.exceptions
 import pagure.lib.git
 import pagure.lib.query
+import pagure.lib.tasks
 import pagure.forms
 import pagure.ui.filters
 from pagure.config import config as pagure_config
@@ -1201,6 +1202,16 @@ def add_user_sshkey():
                 user, pagure_config.get("GITOLITE_KEYDIR", None)
             )
             pagure.lib.tasks.gitolite_post_compile_only.delay()
+            if (
+                pagure_config.get("GIT_AUTH_BACKEND")
+                == "pagure_authorized_keys"
+            ):
+                _log.info("SSH FOLDER: %s", pagure_config.get("SSH_FOLDER"))
+                pagure.lib.tasks.add_key_to_authorized_keys.delay(
+                    ssh_folder=pagure_config.get("SSH_FOLDER"),
+                    username=flask.g.fas_user.username,
+                    sshkey=form.ssh_key.data,
+                )
             flask.flash(msg)
             return flask.redirect(
                 flask.url_for("ui_ns.user_settings") + "#nav-ssh-tab"
@@ -1234,8 +1245,10 @@ def remove_user_sshkey(keyid):
     if form.validate_on_submit():
         user = _get_user(username=flask.g.fas_user.username)
         found = False
+        sshkey = None
         for key in user.sshkeys:
             if key.id == keyid:
+                sshkey = key.public_ssh_key
                 flask.g.session.delete(key)
                 found = True
                 break
@@ -1252,6 +1265,14 @@ def remove_user_sshkey(keyid):
                 user, pagure_config.get("GITOLITE_KEYDIR", None)
             )
             pagure.lib.tasks.gitolite_post_compile_only.delay()
+            if (
+                pagure_config.get("GIT_AUTH_BACKEND")
+                == "pagure_authorized_keys"
+            ):
+                _log.info("SSH FOLDER: %s", pagure_config.get("SSH_FOLDER"))
+                pagure.lib.tasks.remove_key_from_authorized_keys.delay(
+                    ssh_folder=pagure_config.get("SSH_FOLDER"), sshkey=sshkey
+                )
             flask.flash("SSH key removed")
         except SQLAlchemyError as err:  # pragma: no cover
             flask.g.session.rollback()

+ 20 - 0
pagure/ui/repo.py

@@ -1833,8 +1833,10 @@ def remove_deploykey(repo, keyid, username=None, namespace=None):
     form = pagure.forms.ConfirmationForm()
     if form.validate_on_submit():
         found = False
+        sshkey = None
         for key in repo.deploykeys:
             if key.id == keyid:
+                sshkey = key.public_ssh_key
                 flask.g.session.delete(key)
                 found = True
                 break
@@ -1857,6 +1859,14 @@ def remove_deploykey(repo, keyid, username=None, namespace=None):
                 repo, pagure_config.get("GITOLITE_KEYDIR", None)
             )
             pagure.lib.tasks.gitolite_post_compile_only.delay()
+            if (
+                pagure_config.get("GIT_AUTH_BACKEND")
+                == "pagure_authorized_keys"
+            ):
+                _log.info("SSH FOLDER: %s", pagure_config.get("SSH_FOLDER"))
+                pagure.lib.tasks.remove_key_from_authorized_keys.delay(
+                    ssh_folder=pagure_config.get("SSH_FOLDER"), sshkey=sshkey
+                )
             flask.flash("Deploy key removed")
         except SQLAlchemyError as err:  # pragma: no cover
             flask.g.session.rollback()
@@ -1981,6 +1991,16 @@ def add_deploykey(repo, username=None, namespace=None):
                 repo, pagure_config.get("GITOLITE_KEYDIR", None)
             )
             pagure.lib.tasks.gitolite_post_compile_only.delay()
+            if (
+                pagure_config.get("GIT_AUTH_BACKEND")
+                == "pagure_authorized_keys"
+            ):
+                _log.info("SSH FOLDER: %s", pagure_config.get("SSH_FOLDER"))
+                pagure.lib.tasks.add_key_to_authorized_keys.delay(
+                    ssh_folder=pagure_config.get("SSH_FOLDER"),
+                    username=flask.g.fas_user.username,
+                    sshkey=form.ssh_key.data,
+                )
             flask.flash(msg)
             return flask.redirect(
                 flask.url_for(

+ 1 - 0
setup.py

@@ -63,6 +63,7 @@ setup(
     gitolite2 = pagure.lib.git_auth:Gitolite2Auth
     gitolite3 = pagure.lib.git_auth:Gitolite3Auth
     pagure = pagure.lib.git_auth:PagureGitAuth
+    pagure_authorized_keys = pagure.lib.git_auth:PagureGitAuth
     """,
     classifiers=[
         "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",