Mercurial > kallithea
changeset 7771:3e84ac8ed579
ssh: admin management of ssh keys
Based on work by Ilya Beda <ir4y.ix@gmail.com> on
https://bitbucket.org/ir4y/rhodecode/commits/branch/ssh_server_support .
Bootstrap support, updates for POST methods, and tests by Anton Schur
<tonich.sh@gmail.com>.
Additional Bootstrap fixes by Dominik Ruf.
Also heavily modified by Mads Kiilerich.
author | Christian Oyarzun <oyarzun@gmail.com> |
---|---|
date | Mon, 17 Nov 2014 14:42:45 -0500 |
parents | 6da70f4569bf |
children | 66c208bf56fe |
files | CONTRIBUTORS kallithea/config/routing.py kallithea/controllers/admin/users.py kallithea/templates/about.html kallithea/templates/admin/users/user_edit.html kallithea/templates/admin/users/user_edit_ssh_keys.html kallithea/tests/functional/test_admin_users.py scripts/contributor_data.py |
diffstat | 8 files changed, 161 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/CONTRIBUTORS Fri Jul 19 01:12:35 2019 +0200 +++ b/CONTRIBUTORS Mon Nov 17 14:42:45 2014 -0500 @@ -97,6 +97,7 @@ Aparkar <aparkar@icloud.com> 2013 Dennis Brakhane <brakhane@googlemail.com> 2013 Grzegorz Rożniecki <xaerxess@gmail.com> 2013 + Ilya Beda <ir4y.ix@gmail.com> 2013 Jonathan Sternberg <jonathansternberg@gmail.com> 2013 Leonardo Carneiro <leonardo@unity3d.com> 2013 Magnus Ericmats <magnus.ericmats@gmail.com> 2013
--- a/kallithea/config/routing.py Fri Jul 19 01:12:35 2019 +0200 +++ b/kallithea/config/routing.py Mon Nov 17 14:42:45 2014 -0500 @@ -183,6 +183,13 @@ m.connect("edit_user_api_keys_delete", "/users/{id}/edit/api_keys/delete", action="delete_api_key", conditions=dict(method=["POST"])) + m.connect("edit_user_ssh_keys", "/users/{id}/edit/ssh_keys", + action="edit_ssh_keys", conditions=dict(method=["GET"])) + m.connect("edit_user_ssh_keys", "/users/{id}/edit/ssh_keys", + action="ssh_keys_add", conditions=dict(method=["POST"])) + m.connect("edit_user_ssh_keys_delete", "/users/{id}/edit/ssh_keys/delete", + action="ssh_keys_delete", conditions=dict(method=["POST"])) + m.connect("edit_user_perms", "/users/{id}/edit/permissions", action="edit_perms", conditions=dict(method=["GET"])) m.connect("edit_user_perms_update", "/users/{id}/edit/permissions",
--- a/kallithea/controllers/admin/users.py Fri Jul 19 01:12:35 2019 +0200 +++ b/kallithea/controllers/admin/users.py Mon Nov 17 14:42:45 2014 -0500 @@ -43,9 +43,9 @@ from kallithea.lib.auth import LoginRequired, HasPermissionAnyDecorator, \ AuthUser from kallithea.lib import auth_modules -from kallithea.lib.base import BaseController, render +from kallithea.lib.base import BaseController, render, IfSshEnabled from kallithea.model.api_key import ApiKeyModel - +from kallithea.model.ssh_key import SshKeyModel from kallithea.model.db import User, UserEmailMap, UserIpMap, UserToPerm from kallithea.model.forms import UserForm, CustomDefaultPermissionsForm from kallithea.model.user import UserModel @@ -429,3 +429,37 @@ if 'default_user' in request.POST: raise HTTPFound(location=url('admin_permissions_ips')) raise HTTPFound(location=url('edit_user_ips', id=id)) + + @IfSshEnabled + def edit_ssh_keys(self, id): + c.user = self._get_user_or_raise_if_default(id) + c.active = 'ssh_keys' + c.user_ssh_keys = SshKeyModel().get_ssh_keys(c.user.user_id) + defaults = c.user.get_dict() + return htmlfill.render( + render('admin/users/user_edit.html'), + defaults=defaults, + encoding="UTF-8", + force_defaults=False) + + @IfSshEnabled + def ssh_keys_add(self, id): + c.user = self._get_user_or_raise_if_default(id) + + description = request.POST.get('description') + public_key = request.POST.get('public_key') + new_ssh_key = SshKeyModel().create(c.user.user_id, + description, public_key) + Session().commit() + h.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success') + raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id)) + + @IfSshEnabled + def ssh_keys_delete(self, id): + c.user = self._get_user_or_raise_if_default(id) + + public_key = request.POST.get('del_public_key') + SshKeyModel().delete(public_key, c.user.user_id) + Session().commit() + h.flash(_("SSH key successfully deleted"), category='success') + raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id))
--- a/kallithea/templates/about.html Fri Jul 19 01:12:35 2019 +0200 +++ b/kallithea/templates/about.html Mon Nov 17 14:42:45 2014 -0500 @@ -121,6 +121,7 @@ <li>Copyright © 2012–2013, xpol</li> <li>Copyright © 2013, Dennis Brakhane</li> <li>Copyright © 2013, Grzegorz Rożniecki</li> + <li>Copyright © 2013, Ilya Beda</li> <li>Copyright © 2013, Jonathan Sternberg</li> <li>Copyright © 2013, Leonardo Carneiro</li> <li>Copyright © 2013, Magnus Ericmats</li>
--- a/kallithea/templates/admin/users/user_edit.html Fri Jul 19 01:12:35 2019 +0200 +++ b/kallithea/templates/admin/users/user_edit.html Mon Nov 17 14:42:45 2014 -0500 @@ -28,6 +28,9 @@ <ul class="nav nav-pills nav-stacked"> <li class="${'active' if c.active=='profile' else ''}"><a href="${h.url('edit_user', id=c.user.user_id)}">${_('Profile')}</a></li> <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('edit_user_emails', id=c.user.user_id)}">${_('Emails')}</a></li> + %if c.ssh_enabled: + <li class="${'active' if c.active=='ssh_keys' else ''}"><a href="${h.url('edit_user_ssh_keys', id=c.user.user_id)}">${_('SSH Keys')}</a></li> + %endif <li class="${'active' if c.active=='api_keys' else ''}"><a href="${h.url('edit_user_api_keys', id=c.user.user_id)}">${_('API Keys')}</a></li> <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('edit_user_ips', id=c.user.user_id)}">${_('IP Whitelist')}</a></li> <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_advanced', id=c.user.user_id)}">${_('Advanced')}</a></li>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kallithea/templates/admin/users/user_edit_ssh_keys.html Mon Nov 17 14:42:45 2014 -0500 @@ -0,0 +1,63 @@ +<table class="table"> + %if c.user_ssh_keys: + <tr> + <th>${_('Fingerprint')}</th> + <th>${_('Description')}</th> + <th>${_('Action')}</th> + </tr> + %for ssh_key in c.user_ssh_keys: + <tr> + <td> + ${ssh_key.fingerprint} + </td> + <td> + ${ssh_key.description} + </td> + <td> + ${h.form(url('edit_user_ssh_keys_delete', id=c.user.user_id))} + ${h.hidden('del_public_key', ssh_key.public_key)} + <button class="btn btn-danger btn-xs" type="submit" + onclick="return confirm('${_('Confirm to remove this SSH key: %s') % ssh_key.fingerprint}');"> + <i class="icon-trashcan"></i> + ${_('Remove')} + </button> + ${h.end_form()} + </td> + </tr> + %endfor + %else: + <tr> + <td> + <div class="ip">${_('No SSH keys have been added')}</div> + </td> + </tr> + %endif +</table> + +<div> + ${h.form(url('edit_user_ssh_keys', id=c.user.user_id))} + <div class="form"> + <div class="form-group"> + <label class="control-label">${_('New SSH key')}</label> + </div> + <div class="form-group"> + <label class="control-label" for="public_key">${_('Public key')}:</label> + <div> + ${h.textarea('public_key', '', class_='form-control', placeholder=_('Public key (contents of e.g. ~/.ssh/id_rsa.pub)'), cols=80, rows=5)} + </div> + </div> + <div class="form-group"> + <label class="control-label" for="description">${_('Description')}:</label> + <div> + ${h.text('description', class_='form-control', placeholder=_('Description'))} + </div> + </div> + <div class="form-group"> + <div class="buttons"> + ${h.submit('save', _('Add'), class_="btn btn-default")} + ${h.reset('reset', _('Reset'), class_="btn btn-default")} + </div> + </div> + </div> + ${h.end_form()} +</div>
--- a/kallithea/tests/functional/test_admin_users.py Fri Jul 19 01:12:35 2019 +0200 +++ b/kallithea/tests/functional/test_admin_users.py Mon Nov 17 14:42:45 2014 -0500 @@ -18,7 +18,7 @@ from kallithea.tests.base import * from kallithea.tests.fixture import Fixture from kallithea.controllers.admin.users import UsersController -from kallithea.model.db import User, Permission, UserIpMap, UserApiKeys, RepoGroup +from kallithea.model.db import User, Permission, UserIpMap, UserApiKeys, RepoGroup, UserSshKeys from kallithea.lib.auth import check_password from kallithea.model.user import UserModel from kallithea.model import validators @@ -514,6 +514,54 @@ response = response.follow() response.mustcontain(no=[api_key]) + def test_add_ssh_key(self): + description = u'something' + public_key = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost' + fingerprint = u'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8' + + self.log_user() + user = User.get_by_username(TEST_USER_REGULAR_LOGIN) + user_id = user.user_id + + response = self.app.post(url('edit_user_ssh_keys', id=user_id), + {'description': description, + 'public_key': public_key, + '_authentication_token': self.authentication_token()}) + self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint) + + response = response.follow() + response.mustcontain(fingerprint) + ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one() + assert ssh_key.fingerprint == fingerprint + assert ssh_key.description == description + Session().delete(ssh_key) + Session().commit() + + def test_remove_ssh_key(self): + description = u'' + public_key = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost' + fingerprint = u'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8' + + self.log_user() + user = User.get_by_username(TEST_USER_REGULAR_LOGIN) + user_id = user.user_id + + response = self.app.post(url('edit_user_ssh_keys', id=user_id), + {'description': description, + 'public_key': public_key, + '_authentication_token': self.authentication_token()}) + self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint) + response.follow() + ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one() + assert ssh_key.description == description + + response = self.app.post(url('edit_user_ssh_keys_delete', id=user_id), + {'del_public_key': ssh_key.public_key, + '_authentication_token': self.authentication_token()}) + self.checkSessionFlash(response, 'SSH key successfully deleted') + keys = UserSshKeys.query().all() + assert 0 == len(keys) + class TestAdminUsersController_unittest(TestController): """ Unit tests for the users controller """
--- a/scripts/contributor_data.py Fri Jul 19 01:12:35 2019 +0200 +++ b/scripts/contributor_data.py Mon Nov 17 14:42:45 2014 -0500 @@ -66,6 +66,7 @@ # history: other = [ # Work folded into commits attributed to others: + ('2013', 'Ilya Beda <ir4y.ix@gmail.com>'), ] # Preserve contributors listed in about.html but not appearing in repository