]> git.ipfire.org Git - ipfire.org.git/commitdiff
people: Show SSH keys for users
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Oct 2018 15:04:04 +0000 (16:04 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Oct 2018 15:12:45 +0000 (16:12 +0100)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/accounts.py
src/scss/style.scss
src/templates/people/ssh-keys/base.html [new file with mode: 0644]
src/templates/people/ssh-keys/index.html [new file with mode: 0644]
src/templates/people/user-base.html
src/web/__init__.py
src/web/people.py

index 178798eccf4e1e685e857f86793026bd22db9603..64283de722a490f56344e884b6e73a3c757957bd 100644 (file)
@@ -176,6 +176,12 @@ templates_people_modules_DATA = \
 
 templates_people_modulesdir = $(templates_peopledir)/modules
 
+templates_people_ssh_keys_DATA = \
+       src/templates/people/ssh-keys/base.html \
+       src/templates/people/ssh-keys/index.html
+
+templates_people_ssh_keysdir = $(templates_peopledir)/ssh-keys
+
 templates_static_DATA = \
        src/templates/static/chat.html \
        src/templates/static/features.html \
index d1bd6d144971b738857b24ef98d6278e0f8814c8..9f29da82a1ba3de4a3979f02465adb90c1076456 100644 (file)
@@ -9,6 +9,7 @@ import ldap
 import ldap.modlist
 import logging
 import phonenumbers
+import sshpubkeys
 import urllib.parse
 import urllib.request
 
@@ -570,6 +571,24 @@ class Account(Object):
        def upload_avatar(self, avatar):
                self._set("jpegPhoto", avatar)
 
+       # SSH Keys
+
+       @lazy_property
+       def ssh_keys(self):
+               ret = []
+
+               for key in self._get_strings("sshPublicKey"):
+                       s = sshpubkeys.SSHKey()
+
+                       try:
+                               s.parse(key)
+                       except (sshpubkeys.InvalidKeyError, NotImplementedError) as e:
+                               logging.warning("Could not parse SSH key %s: %s" % (key, e))
+                               continue
+
+                       ret.append(s)
+
+               return ret
 
 if __name__ == "__main__":
        a = Accounts()
index b5bc5122a5616d7cfa3e16208b07b6d3b26a2e2c..dcfa203b82929137e1faba39b545bef6207242e1 100644 (file)
@@ -73,6 +73,12 @@ body {
        }
 }
 
+.list-group {
+       .list-group-item {
+               @extend .inverse;
+       }
+}
+
 .nav {
        .nav-link {
                color: $white;
diff --git a/src/templates/people/ssh-keys/base.html b/src/templates/people/ssh-keys/base.html
new file mode 100644 (file)
index 0000000..5842b7d
--- /dev/null
@@ -0,0 +1 @@
+{% extends "../user-base.html" %}
diff --git a/src/templates/people/ssh-keys/index.html b/src/templates/people/ssh-keys/index.html
new file mode 100644 (file)
index 0000000..de86027
--- /dev/null
@@ -0,0 +1,49 @@
+{% extends "base.html" %}
+
+{% block title %}{{ account }} - {{ _("SSH Keys") }}{% end block %}
+
+{% block main %}
+       <h1>{{ _("SSH Keys") }}</h1>
+
+       <ul class="list-group mb-3">
+               {% for key in account.ssh_keys %}
+                       <li class="list-group-item">
+                               <h5 class="mb-1">
+                                       <a class="text-dark" href="/users/{{ account.uid }}/ssh-keys/{{ key.hash_md5() }}">
+                                               {{ key.comment or _("%s Key") % key.key_type.decode() }}
+                                       </a>
+                               </h5>
+
+                               <p class="text-monospace mb-0">{{ key.hash_md5() }}</p>
+
+                               {% if key.options %}
+                                       <p class="my-1">{{ _("Options") }}</p>
+
+                                       <ul class="mb-0">
+                                               {% for option, values in sorted(key.options.items()) %}
+                                                       <li class="small">
+                                                               <span class="text-monospace">{{ option }}</span>
+
+                                                               {% if not values == [True] %}
+                                                                       = <span class="text-monospace">{{ "".join(values) }}</span>
+                                                               {% end %}
+                                                       </li>
+                                               {% end %}
+                                       </ul>
+                               {% end %}
+
+                               {% if account.can_be_managed_by(current_user) %}
+                                       <a class="btn btn-outline-danger btn-sm btn-block mt-2" href="/users/{{ account.uid }}/ssh-keys/{{ key.hash_md5() }}/delete">
+                                               {{ _("Delete") }}
+                                       </a>
+                               {% end %}
+                       </li>
+               {% end %}
+       </ul>
+
+       {% if account.can_be_managed_by(current_user) %}
+               <a class="btn btn-success btn-block" href="/users/{{ account.uid }}/ssh-keys/upload">
+                       {{ _("Upload New SSH Key") }}
+               </a>
+       {% end %}
+{% end block %}
index d9f20e60530341d01c4aee3e17ef470266b7b578..c685afcde6631f1f953f7d0e5947bbf5774fce67 100644 (file)
                                        </h5>
                                {% end %}
 
-                               {% if account.can_be_managed_by(current_user) %}
-                                       <div class="btn-toolbar mb-3">
+                               <div class="btn-toolbar mb-3">
+                                       <a class="btn btn-light btn-sm btn-block" href="/users/{{ account.uid }}/ssh-keys">
+                                               <span class="fas fa-key mr-2"></span> {{ _("SSH Keys") }}
+                                       </a>
+
+                                       {% if account.can_be_managed_by(current_user) %}
                                                <a class="btn btn-warning btn-sm btn-block" href="/users/{{ account.uid }}/edit">
                                                        <span class="fas fa-edit mr-2"></span> {{ _("Edit") }}
                                                </a>
                                                <a class="btn btn-light btn-sm btn-block" href="/users/{{ account.uid }}/passwd">
                                                        {{ _("Change Password") }}
                                                </a>
-
-                                               <a class="btn btn-light btn-sm btn-block" href="/users/{{ account.uid }}/ssh-keys">
-                                                       <span class="fas fa-key mr-2"></span> {{ _("Manage SSH Keys") }}
-                                               </a>
-                                       </div>
-                               {% end %}
+                                       {% end %}
+                               </div>
                        </div>
                {% end %}
 
index 70b44985d53a9dac42f3f5a9c020f459ffd8cf40..a25a1a00760a2831495c803882b65da4733073bc 100644 (file)
@@ -260,6 +260,7 @@ class Application(tornado.web.Application):
                        (r"/users/(\w+)/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
                        (r"/users/(\w+)/edit", people.UserEditHandler),
                        (r"/users/(\w+)/passwd", people.UserPasswdHandler),
+                       (r"/users/(\w+)/ssh-keys", people.SSHKeysIndexHandler),
                        (r"/users/(\w+)/sip", people.SIPHandler),
                ]  + authentication_handlers)
 
index 4f97388415a6809401ca2c59a94b3aa1dade9c58..5cad8e2a81f575d7107712718e46692c1ea57107 100644 (file)
@@ -103,6 +103,16 @@ class SearchHandler(base.BaseHandler):
                self.render("people/search.html", q=q, accounts=accounts)
 
 
+class SSHKeysIndexHandler(base.BaseHandler):
+       @tornado.web.authenticated
+       def get(self, uid):
+               account = self.backend.accounts.get_by_uid(uid)
+               if not account:
+                       raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
+
+               self.render("people/ssh-keys/index.html", account=account)
+
+
 class SIPHandler(base.BaseHandler):
        @tornado.web.authenticated
        def get(self, uid):