##// END OF EJS Templates
ssh: admin management of ssh keys...
Christian Oyarzun -
r7678:3e84ac8e default
parent child Browse files
Show More
@@ -0,0 +1,63 b''
1 <table class="table">
2 %if c.user_ssh_keys:
3 <tr>
4 <th>${_('Fingerprint')}</th>
5 <th>${_('Description')}</th>
6 <th>${_('Action')}</th>
7 </tr>
8 %for ssh_key in c.user_ssh_keys:
9 <tr>
10 <td>
11 ${ssh_key.fingerprint}
12 </td>
13 <td>
14 ${ssh_key.description}
15 </td>
16 <td>
17 ${h.form(url('edit_user_ssh_keys_delete', id=c.user.user_id))}
18 ${h.hidden('del_public_key', ssh_key.public_key)}
19 <button class="btn btn-danger btn-xs" type="submit"
20 onclick="return confirm('${_('Confirm to remove this SSH key: %s') % ssh_key.fingerprint}');">
21 <i class="icon-trashcan"></i>
22 ${_('Remove')}
23 </button>
24 ${h.end_form()}
25 </td>
26 </tr>
27 %endfor
28 %else:
29 <tr>
30 <td>
31 <div class="ip">${_('No SSH keys have been added')}</div>
32 </td>
33 </tr>
34 %endif
35 </table>
36
37 <div>
38 ${h.form(url('edit_user_ssh_keys', id=c.user.user_id))}
39 <div class="form">
40 <div class="form-group">
41 <label class="control-label">${_('New SSH key')}</label>
42 </div>
43 <div class="form-group">
44 <label class="control-label" for="public_key">${_('Public key')}:</label>
45 <div>
46 ${h.textarea('public_key', '', class_='form-control', placeholder=_('Public key (contents of e.g. ~/.ssh/id_rsa.pub)'), cols=80, rows=5)}
47 </div>
48 </div>
49 <div class="form-group">
50 <label class="control-label" for="description">${_('Description')}:</label>
51 <div>
52 ${h.text('description', class_='form-control', placeholder=_('Description'))}
53 </div>
54 </div>
55 <div class="form-group">
56 <div class="buttons">
57 ${h.submit('save', _('Add'), class_="btn btn-default")}
58 ${h.reset('reset', _('Reset'), class_="btn btn-default")}
59 </div>
60 </div>
61 </div>
62 ${h.end_form()}
63 </div>
@@ -97,6 +97,7 b' List of contributors to Kallithea projec'
97 Aparkar <aparkar@icloud.com> 2013
97 Aparkar <aparkar@icloud.com> 2013
98 Dennis Brakhane <brakhane@googlemail.com> 2013
98 Dennis Brakhane <brakhane@googlemail.com> 2013
99 Grzegorz Rożniecki <xaerxess@gmail.com> 2013
99 Grzegorz Rożniecki <xaerxess@gmail.com> 2013
100 Ilya Beda <ir4y.ix@gmail.com> 2013
100 Jonathan Sternberg <jonathansternberg@gmail.com> 2013
101 Jonathan Sternberg <jonathansternberg@gmail.com> 2013
101 Leonardo Carneiro <leonardo@unity3d.com> 2013
102 Leonardo Carneiro <leonardo@unity3d.com> 2013
102 Magnus Ericmats <magnus.ericmats@gmail.com> 2013
103 Magnus Ericmats <magnus.ericmats@gmail.com> 2013
@@ -183,6 +183,13 b' def make_map(config):'
183 m.connect("edit_user_api_keys_delete", "/users/{id}/edit/api_keys/delete",
183 m.connect("edit_user_api_keys_delete", "/users/{id}/edit/api_keys/delete",
184 action="delete_api_key", conditions=dict(method=["POST"]))
184 action="delete_api_key", conditions=dict(method=["POST"]))
185
185
186 m.connect("edit_user_ssh_keys", "/users/{id}/edit/ssh_keys",
187 action="edit_ssh_keys", conditions=dict(method=["GET"]))
188 m.connect("edit_user_ssh_keys", "/users/{id}/edit/ssh_keys",
189 action="ssh_keys_add", conditions=dict(method=["POST"]))
190 m.connect("edit_user_ssh_keys_delete", "/users/{id}/edit/ssh_keys/delete",
191 action="ssh_keys_delete", conditions=dict(method=["POST"]))
192
186 m.connect("edit_user_perms", "/users/{id}/edit/permissions",
193 m.connect("edit_user_perms", "/users/{id}/edit/permissions",
187 action="edit_perms", conditions=dict(method=["GET"]))
194 action="edit_perms", conditions=dict(method=["GET"]))
188 m.connect("edit_user_perms_update", "/users/{id}/edit/permissions",
195 m.connect("edit_user_perms_update", "/users/{id}/edit/permissions",
@@ -43,9 +43,9 b' from kallithea.lib import helpers as h'
43 from kallithea.lib.auth import LoginRequired, HasPermissionAnyDecorator, \
43 from kallithea.lib.auth import LoginRequired, HasPermissionAnyDecorator, \
44 AuthUser
44 AuthUser
45 from kallithea.lib import auth_modules
45 from kallithea.lib import auth_modules
46 from kallithea.lib.base import BaseController, render
46 from kallithea.lib.base import BaseController, render, IfSshEnabled
47 from kallithea.model.api_key import ApiKeyModel
47 from kallithea.model.api_key import ApiKeyModel
48
48 from kallithea.model.ssh_key import SshKeyModel
49 from kallithea.model.db import User, UserEmailMap, UserIpMap, UserToPerm
49 from kallithea.model.db import User, UserEmailMap, UserIpMap, UserToPerm
50 from kallithea.model.forms import UserForm, CustomDefaultPermissionsForm
50 from kallithea.model.forms import UserForm, CustomDefaultPermissionsForm
51 from kallithea.model.user import UserModel
51 from kallithea.model.user import UserModel
@@ -429,3 +429,37 b' class UsersController(BaseController):'
429 if 'default_user' in request.POST:
429 if 'default_user' in request.POST:
430 raise HTTPFound(location=url('admin_permissions_ips'))
430 raise HTTPFound(location=url('admin_permissions_ips'))
431 raise HTTPFound(location=url('edit_user_ips', id=id))
431 raise HTTPFound(location=url('edit_user_ips', id=id))
432
433 @IfSshEnabled
434 def edit_ssh_keys(self, id):
435 c.user = self._get_user_or_raise_if_default(id)
436 c.active = 'ssh_keys'
437 c.user_ssh_keys = SshKeyModel().get_ssh_keys(c.user.user_id)
438 defaults = c.user.get_dict()
439 return htmlfill.render(
440 render('admin/users/user_edit.html'),
441 defaults=defaults,
442 encoding="UTF-8",
443 force_defaults=False)
444
445 @IfSshEnabled
446 def ssh_keys_add(self, id):
447 c.user = self._get_user_or_raise_if_default(id)
448
449 description = request.POST.get('description')
450 public_key = request.POST.get('public_key')
451 new_ssh_key = SshKeyModel().create(c.user.user_id,
452 description, public_key)
453 Session().commit()
454 h.flash(_("SSH key %s successfully added") % new_ssh_key.fingerprint, category='success')
455 raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id))
456
457 @IfSshEnabled
458 def ssh_keys_delete(self, id):
459 c.user = self._get_user_or_raise_if_default(id)
460
461 public_key = request.POST.get('del_public_key')
462 SshKeyModel().delete(public_key, c.user.user_id)
463 Session().commit()
464 h.flash(_("SSH key successfully deleted"), category='success')
465 raise HTTPFound(location=url('edit_user_ssh_keys', id=c.user.user_id))
@@ -121,6 +121,7 b''
121 <li>Copyright &copy; 2012&ndash;2013, xpol</li>
121 <li>Copyright &copy; 2012&ndash;2013, xpol</li>
122 <li>Copyright &copy; 2013, Dennis Brakhane</li>
122 <li>Copyright &copy; 2013, Dennis Brakhane</li>
123 <li>Copyright &copy; 2013, Grzegorz Rożniecki</li>
123 <li>Copyright &copy; 2013, Grzegorz Rożniecki</li>
124 <li>Copyright &copy; 2013, Ilya Beda</li>
124 <li>Copyright &copy; 2013, Jonathan Sternberg</li>
125 <li>Copyright &copy; 2013, Jonathan Sternberg</li>
125 <li>Copyright &copy; 2013, Leonardo Carneiro</li>
126 <li>Copyright &copy; 2013, Leonardo Carneiro</li>
126 <li>Copyright &copy; 2013, Magnus Ericmats</li>
127 <li>Copyright &copy; 2013, Magnus Ericmats</li>
@@ -28,6 +28,9 b''
28 <ul class="nav nav-pills nav-stacked">
28 <ul class="nav nav-pills nav-stacked">
29 <li class="${'active' if c.active=='profile' else ''}"><a href="${h.url('edit_user', id=c.user.user_id)}">${_('Profile')}</a></li>
29 <li class="${'active' if c.active=='profile' else ''}"><a href="${h.url('edit_user', id=c.user.user_id)}">${_('Profile')}</a></li>
30 <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('edit_user_emails', id=c.user.user_id)}">${_('Emails')}</a></li>
30 <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('edit_user_emails', id=c.user.user_id)}">${_('Emails')}</a></li>
31 %if c.ssh_enabled:
32 <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>
33 %endif
31 <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>
34 <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>
32 <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('edit_user_ips', id=c.user.user_id)}">${_('IP Whitelist')}</a></li>
35 <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('edit_user_ips', id=c.user.user_id)}">${_('IP Whitelist')}</a></li>
33 <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_advanced', id=c.user.user_id)}">${_('Advanced')}</a></li>
36 <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_advanced', id=c.user.user_id)}">${_('Advanced')}</a></li>
@@ -18,7 +18,7 b' import pytest'
18 from kallithea.tests.base import *
18 from kallithea.tests.base import *
19 from kallithea.tests.fixture import Fixture
19 from kallithea.tests.fixture import Fixture
20 from kallithea.controllers.admin.users import UsersController
20 from kallithea.controllers.admin.users import UsersController
21 from kallithea.model.db import User, Permission, UserIpMap, UserApiKeys, RepoGroup
21 from kallithea.model.db import User, Permission, UserIpMap, UserApiKeys, RepoGroup, UserSshKeys
22 from kallithea.lib.auth import check_password
22 from kallithea.lib.auth import check_password
23 from kallithea.model.user import UserModel
23 from kallithea.model.user import UserModel
24 from kallithea.model import validators
24 from kallithea.model import validators
@@ -514,6 +514,54 b' class TestAdminUsersController(TestContr'
514 response = response.follow()
514 response = response.follow()
515 response.mustcontain(no=[api_key])
515 response.mustcontain(no=[api_key])
516
516
517 def test_add_ssh_key(self):
518 description = u'something'
519 public_key = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost'
520 fingerprint = u'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8'
521
522 self.log_user()
523 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
524 user_id = user.user_id
525
526 response = self.app.post(url('edit_user_ssh_keys', id=user_id),
527 {'description': description,
528 'public_key': public_key,
529 '_authentication_token': self.authentication_token()})
530 self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
531
532 response = response.follow()
533 response.mustcontain(fingerprint)
534 ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
535 assert ssh_key.fingerprint == fingerprint
536 assert ssh_key.description == description
537 Session().delete(ssh_key)
538 Session().commit()
539
540 def test_remove_ssh_key(self):
541 description = u''
542 public_key = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost'
543 fingerprint = u'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8'
544
545 self.log_user()
546 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
547 user_id = user.user_id
548
549 response = self.app.post(url('edit_user_ssh_keys', id=user_id),
550 {'description': description,
551 'public_key': public_key,
552 '_authentication_token': self.authentication_token()})
553 self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
554 response.follow()
555 ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
556 assert ssh_key.description == description
557
558 response = self.app.post(url('edit_user_ssh_keys_delete', id=user_id),
559 {'del_public_key': ssh_key.public_key,
560 '_authentication_token': self.authentication_token()})
561 self.checkSessionFlash(response, 'SSH key successfully deleted')
562 keys = UserSshKeys.query().all()
563 assert 0 == len(keys)
564
517
565
518 class TestAdminUsersController_unittest(TestController):
566 class TestAdminUsersController_unittest(TestController):
519 """ Unit tests for the users controller """
567 """ Unit tests for the users controller """
@@ -66,6 +66,7 b" no_about.add(('Sean Farley <sean.michael"
66 # history:
66 # history:
67 other = [
67 other = [
68 # Work folded into commits attributed to others:
68 # Work folded into commits attributed to others:
69 ('2013', 'Ilya Beda <ir4y.ix@gmail.com>'),
69 ]
70 ]
70
71
71 # Preserve contributors listed in about.html but not appearing in repository
72 # Preserve contributors listed in about.html but not appearing in repository
General Comments 0
You need to be logged in to leave comments. Login now