##// END OF EJS Templates
auth-tokens: add scope and show consitent token UI for my account and admin.
marcink -
r1480:a9c54e36 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,97 +1,98 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2013-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 authentication tokens model for RhodeCode
23 23 """
24 24
25 25 import time
26 26 import logging
27 27 import traceback
28 28 from sqlalchemy import or_
29 29
30 30 from rhodecode.model import BaseModel
31 31 from rhodecode.model.db import UserApiKeys
32 32 from rhodecode.model.meta import Session
33 33
34 34 log = logging.getLogger(__name__)
35 35
36 36
37 37 class AuthTokenModel(BaseModel):
38 38 cls = UserApiKeys
39 39
40 40 def create(self, user, description, lifetime=-1, role=UserApiKeys.ROLE_ALL):
41 41 """
42 42 :param user: user or user_id
43 43 :param description: description of ApiKey
44 44 :param lifetime: expiration time in minutes
45 45 :param role: role for the apikey
46 46 """
47 47 from rhodecode.lib.auth import generate_auth_token
48 48
49 49 user = self._get_user(user)
50 50
51 51 new_auth_token = UserApiKeys()
52 52 new_auth_token.api_key = generate_auth_token(user.username)
53 53 new_auth_token.user_id = user.user_id
54 54 new_auth_token.description = description
55 55 new_auth_token.role = role
56 new_auth_token.expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
56 new_auth_token.expires = time.time() + (lifetime * 60) \
57 if lifetime != -1 else -1
57 58 Session().add(new_auth_token)
58 59
59 60 return new_auth_token
60 61
61 62 def delete(self, api_key, user=None):
62 63 """
63 64 Deletes given api_key, if user is set it also filters the object for
64 65 deletion by given user.
65 66 """
66 67 api_key = UserApiKeys.query().filter(UserApiKeys.api_key == api_key)
67 68
68 69 if user:
69 70 user = self._get_user(user)
70 71 api_key = api_key.filter(UserApiKeys.user_id == user.user_id)
71 72
72 73 api_key = api_key.scalar()
73 74 try:
74 75 Session().delete(api_key)
75 76 except Exception:
76 77 log.error(traceback.format_exc())
77 78 raise
78 79
79 80 def get_auth_tokens(self, user, show_expired=True):
80 81 user = self._get_user(user)
81 82 user_auth_tokens = UserApiKeys.query()\
82 83 .filter(UserApiKeys.user_id == user.user_id)
83 84 if not show_expired:
84 85 user_auth_tokens = user_auth_tokens\
85 86 .filter(or_(UserApiKeys.expires == -1,
86 87 UserApiKeys.expires >= time.time()))
87 88 return user_auth_tokens
88 89
89 90 def get_auth_token(self, auth_token):
90 91 auth_token = UserApiKeys.query().filter(
91 92 UserApiKeys.api_key == auth_token)
92 93 auth_token = auth_token \
93 94 .filter(or_(UserApiKeys.expires == -1,
94 95 UserApiKeys.expires >= time.time()))\
95 96 .first()
96 97
97 98 return auth_token
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,80 +1,95 b''
1 1 <div class="panel panel-default">
2 2 <div class="panel-heading">
3 3 <h3 class="panel-title">${_('Authentication Tokens')}</h3>
4 4 </div>
5 5 <div class="panel-body">
6 6 <p>
7 ${_('Each token can have a role. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations.')}
7 ${_('Each token can have a role. Token with a role can be used only in given context, '
8 'e.g. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations only.')}
9 ${_('Additionally scope for VCS type token can narrow the use to chosen repository.')}
8 10 </p>
9 11 <table class="rctable auth_tokens">
10 12 %if c.user_auth_tokens:
13 <tr>
14 <th>${_('Token')}</th>
15 <th>${_('Scope')}</th>
16 <th>${_('Description')}</th>
17 <th>${_('Role')}</th>
18 <th>${_('Expiration')}</th>
19 <th>${_('Action')}</th>
20 </tr>
11 21 %for auth_token in c.user_auth_tokens:
12 22 <tr class="${'expired' if auth_token.expired else ''}">
13 <td class="truncate-wrap td-authtoken"><div class="user_auth_tokens truncate autoexpand"><code>${auth_token.api_key}</code></div></td>
23 <td class="truncate-wrap td-authtoken">
24 <div class="user_auth_tokens truncate autoexpand">
25 <code>${auth_token.api_key}</code>
26 </div>
27 </td>
28 <td class="td">${auth_token.scope_humanized}</td>
14 29 <td class="td-wrap">${auth_token.description}</td>
15 30 <td class="td-tags">
16 31 <span class="tag disabled">${auth_token.role_humanized}</span>
17 32 </td>
18 33 <td class="td-exp">
19 34 %if auth_token.expires == -1:
20 ${_('expires')}: ${_('never')}
35 ${_('never')}
21 36 %else:
22 37 %if auth_token.expired:
23 ${_('expired')}: ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
38 <span style="text-decoration: line-through">${h.age_component(h.time_to_utcdatetime(auth_token.expires))}</span>
24 39 %else:
25 ${_('expires')}: ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
40 ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
26 41 %endif
27 42 %endif
28 43 </td>
29 44 <td class="td-action">
30 45 ${h.secure_form(url('my_account_auth_tokens'),method='delete')}
31 46 ${h.hidden('del_auth_token',auth_token.api_key)}
32 47 <button class="btn btn-link btn-danger" type="submit"
33 48 onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token.api_key}');">
34 49 ${_('Delete')}
35 50 </button>
36 51 ${h.end_form()}
37 52 </td>
38 53 </tr>
39 54 %endfor
40 55 %else:
41 56 <tr><td><div class="ip">${_('No additional auth token specified')}</div></td></tr>
42 57 %endif
43 58 </table>
44 59
45 60 <div class="user_auth_tokens">
46 61 ${h.secure_form(url('my_account_auth_tokens'), method='post')}
47 62 <div class="form form-vertical">
48 63 <!-- fields -->
49 64 <div class="fields">
50 65 <div class="field">
51 66 <div class="label">
52 67 <label for="new_email">${_('New authentication token')}:</label>
53 68 </div>
54 69 <div class="input">
55 70 ${h.text('description', placeholder=_('Description'))}
56 71 ${h.select('lifetime', '', c.lifetime_options)}
57 72 ${h.select('role', '', c.role_options)}
58 73 </div>
59 74 </div>
60 75 <div class="buttons">
61 76 ${h.submit('save',_('Add'),class_="btn")}
62 77 ${h.reset('reset',_('Reset'),class_="btn")}
63 78 </div>
64 79 </div>
65 80 </div>
66 81 ${h.end_form()}
67 82 </div>
68 83 </div>
69 84 </div>
70 85 <script>
71 86 $(document).ready(function(){
72 87 var select2Options = {
73 88 'containerCssClass': "drop-menu",
74 89 'dropdownCssClass': "drop-menu-dropdown",
75 90 'dropdownAutoWidth': true
76 91 };
77 92 $("#lifetime").select2(select2Options);
78 93 $("#role").select2(select2Options);
79 94 });
80 95 </script>
@@ -1,83 +1,97 b''
1 1 <div class="panel panel-default">
2 2 <div class="panel-heading">
3 3 <h3 class="panel-title">${_('Authentication Access Tokens')}</h3>
4 4 </div>
5 5 <div class="panel-body">
6 6 <div class="apikeys_wrap">
7 <p>
8 ${_('Each token can have a role. Token with a role can be used only in given context, '
9 'e.g. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations only.')}
10 ${_('Additionally scope for VCS type token can narrow the use to chosen repository.')}
11 </p>
7 12 <table class="rctable auth_tokens">
13 <tr>
14 <th>${_('Token')}</th>
15 <th>${_('Scope')}</th>
16 <th>${_('Description')}</th>
17 <th>${_('Role')}</th>
18 <th>${_('Expiration')}</th>
19 <th>${_('Action')}</th>
20 </tr>
8 21 %if c.user_auth_tokens:
9 22 %for auth_token in c.user_auth_tokens:
10 23 <tr class="${'expired' if auth_token.expired else ''}">
11 24 <td class="truncate-wrap td-authtoken"><div class="user_auth_tokens truncate autoexpand"><code>${auth_token.api_key}</code></div></td>
25 <td class="td">${auth_token.scope_humanized}</td>
12 26 <td class="td-wrap">${auth_token.description}</td>
13 27 <td class="td-tags">
14 28 <span class="tag">${auth_token.role_humanized}</span>
15 29 </td>
16 30 <td class="td-exp">
17 31 %if auth_token.expires == -1:
18 ${_('expires')}: ${_('never')}
32 ${_('never')}
19 33 %else:
20 34 %if auth_token.expired:
21 ${_('expired')}: ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
35 <span style="text-decoration: line-through">${h.age_component(h.time_to_utcdatetime(auth_token.expires))}</span>
22 36 %else:
23 ${_('expires')}: ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
37 ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
24 38 %endif
25 39 %endif
26 40 </td>
27 41 <td>
28 42 ${h.secure_form(url('edit_user_auth_tokens', user_id=c.user.user_id),method='delete')}
29 43 ${h.hidden('del_auth_token',auth_token.api_key)}
30 44 <button class="btn btn-link btn-danger" type="submit"
31 45 onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token.api_key}');">
32 46 ${_('Delete')}
33 47 </button>
34 48 ${h.end_form()}
35 49 </td>
36 50 </tr>
37 51 %endfor
38 52 %else:
39 53 <tr><td><div class="ip">${_('No additional auth tokens specified')}</div></td></tr>
40 54 %endif
41 55 </table>
42 56 </div>
43 57
44 58 <div class="user_auth_tokens">
45 59 ${h.secure_form(url('edit_user_auth_tokens', user_id=c.user.user_id), method='put')}
46 60 <div class="form form-vertical">
47 61 <!-- fields -->
48 62 <div class="fields">
49 63 <div class="field">
50 64 <div class="label">
51 <label for="new_email">${_('New auth token')}:</label>
65 <label for="new_email">${_('New authentication token')}:</label>
52 66 </div>
53 67 <div class="input">
54 68 ${h.text('description', class_='medium', placeholder=_('Description'))}
55 69 ${h.select('lifetime', '', c.lifetime_options)}
56 70 ${h.select('role', '', c.role_options)}
57 71 </div>
58 72 </div>
59 73 <div class="buttons">
60 74 ${h.submit('save',_('Add'),class_="btn btn-small")}
61 75 ${h.reset('reset',_('Reset'),class_="btn btn-small")}
62 76 </div>
63 77 </div>
64 78 </div>
65 79 ${h.end_form()}
66 80 </div>
67 81 </div>
68 82 </div>
69 83
70 84 <script>
71 85 $(document).ready(function(){
72 86 $("#lifetime").select2({
73 87 'containerCssClass': "drop-menu",
74 88 'dropdownCssClass': "drop-menu-dropdown",
75 89 'dropdownAutoWidth': true
76 90 });
77 91 $("#role").select2({
78 92 'containerCssClass': "drop-menu",
79 93 'dropdownCssClass': "drop-menu-dropdown",
80 94 'dropdownAutoWidth': true
81 95 });
82 96 })
83 97 </script>
General Comments 0
You need to be logged in to leave comments. Login now