auth-tokens: allow specifing custom expiration date manually.
- fixes #5323
This commit is contained in:
parent
56bbe6261a
commit
0fd76867b6
6 changed files with 127 additions and 21 deletions
|
|
@ -18,6 +18,7 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import time
|
||||
import logging
|
||||
import datetime
|
||||
import formencode
|
||||
|
|
@ -177,14 +178,7 @@ class AdminUsersView(BaseAppView, DataGridAppView):
|
|||
|
||||
c.active = 'auth_tokens'
|
||||
|
||||
c.lifetime_values = [
|
||||
(str(-1), _('forever')),
|
||||
(str(5), _('5 minutes')),
|
||||
(str(60), _('1 hour')),
|
||||
(str(60 * 24), _('1 day')),
|
||||
(str(60 * 24 * 30), _('1 month')),
|
||||
]
|
||||
c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
|
||||
c.lifetime_values = AuthTokenModel.get_lifetime_values(translator=_)
|
||||
c.role_values = [
|
||||
(x, AuthTokenModel.cls._get_role_name(x))
|
||||
for x in AuthTokenModel.cls.ROLES]
|
||||
|
|
|
|||
|
|
@ -152,15 +152,7 @@ class MyAccountView(BaseAppView, DataGridAppView):
|
|||
|
||||
c = self.load_default_context()
|
||||
c.active = 'auth_tokens'
|
||||
|
||||
c.lifetime_values = [
|
||||
(str(-1), _('forever')),
|
||||
(str(5), _('5 minutes')),
|
||||
(str(60), _('1 hour')),
|
||||
(str(60 * 24), _('1 day')),
|
||||
(str(60 * 24 * 30), _('1 month')),
|
||||
]
|
||||
c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
|
||||
c.lifetime_values = AuthTokenModel.get_lifetime_values(translator=_)
|
||||
c.role_values = [
|
||||
(x, AuthTokenModel.cls._get_role_name(x))
|
||||
for x in AuthTokenModel.cls.ROLES]
|
||||
|
|
|
|||
|
|
@ -37,6 +37,28 @@ log = logging.getLogger(__name__)
|
|||
class AuthTokenModel(BaseModel):
|
||||
cls = UserApiKeys
|
||||
|
||||
@classmethod
|
||||
def get_lifetime_values(cls, translator):
|
||||
from rhodecode.lib import helpers as h
|
||||
_ = translator
|
||||
|
||||
def date_after_min(mins):
|
||||
after = time.time() + (60 * mins)
|
||||
return h.format_date(h.time_to_datetime(after))
|
||||
|
||||
return [
|
||||
(str(-1),
|
||||
_('forever')),
|
||||
(str(5),
|
||||
_('5 minutes {end_date}').format(end_date=date_after_min(5))),
|
||||
(str(60),
|
||||
_('1 hour {end_date}').format(end_date=date_after_min(60))),
|
||||
(str(60 * 24),
|
||||
_('1 day {end_date}').format(end_date=date_after_min(60 * 24))),
|
||||
(str(60 * 24 * 30),
|
||||
_('1 month {end_date}').format(end_date=date_after_min(60 * 24 * 30))),
|
||||
]
|
||||
|
||||
def create(self, user, description, lifetime=-1, role=UserApiKeys.ROLE_ALL):
|
||||
"""
|
||||
:param user: user or user_id
|
||||
|
|
|
|||
|
|
@ -499,3 +499,62 @@ $(document).ready(function() {
|
|||
}
|
||||
collapsableContent();
|
||||
});
|
||||
|
||||
var feedLifetimeOptions = function(query, initialData){
|
||||
var data = {results: []};
|
||||
var isQuery = typeof query.term !== 'undefined';
|
||||
|
||||
var section = _gettext('Lifetime');
|
||||
var children = [];
|
||||
|
||||
//filter results
|
||||
$.each(initialData.results, function(idx, value) {
|
||||
|
||||
if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
|
||||
children.push({
|
||||
'id': this.id,
|
||||
'text': this.text
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
data.results.push({
|
||||
'text': section,
|
||||
'children': children
|
||||
});
|
||||
|
||||
if (isQuery) {
|
||||
|
||||
var now = moment.utc();
|
||||
|
||||
var parseQuery = function(entry, now){
|
||||
var fmt = 'DD/MM/YYYY H:mm';
|
||||
var parsed = moment.utc(entry, fmt);
|
||||
var diffInMin = parsed.diff(now, 'minutes');
|
||||
|
||||
if (diffInMin > 0){
|
||||
return {
|
||||
id: diffInMin,
|
||||
text: parsed.format(fmt)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
id: undefined,
|
||||
text: parsed.format('DD/MM/YYYY') + ' ' + _gettext('date not in future')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
data.results.push({
|
||||
'text': _gettext('Specified expiration date'),
|
||||
'children': [{
|
||||
'id': parseQuery(query.term, now).id,
|
||||
'text': parseQuery(query.term, now).text
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
query.callback(data);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
<div class="input">
|
||||
${h.text('description', class_='medium', placeholder=_('Description'))}
|
||||
${h.select('lifetime', '', c.lifetime_options)}
|
||||
${h.hidden('lifetime')}
|
||||
${h.select('role', '', c.role_options)}
|
||||
|
||||
% if c.allow_scoped_tokens:
|
||||
|
|
@ -100,9 +100,29 @@ var select2Options = {
|
|||
'dropdownCssClass': "drop-menu-dropdown",
|
||||
'dropdownAutoWidth': true
|
||||
};
|
||||
$("#lifetime").select2(select2Options);
|
||||
$("#role").select2(select2Options);
|
||||
|
||||
|
||||
var preloadData = {
|
||||
results: [
|
||||
% for entry in c.lifetime_values:
|
||||
{id:${entry[0]}, text:"${entry[1]}"}${'' if loop.last else ','}
|
||||
% endfor
|
||||
]
|
||||
};
|
||||
|
||||
$("#lifetime").select2({
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
dropdownAutoWidth: true,
|
||||
data: preloadData,
|
||||
placeholder: ${_('Select or enter expiration date')},
|
||||
query: function(query) {
|
||||
feedLifetimeOptions(query, preloadData);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var repoFilter = function(data) {
|
||||
var results = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
</div>
|
||||
<div class="input">
|
||||
${h.text('description', class_='medium', placeholder=_('Description'))}
|
||||
${h.select('lifetime', '', c.lifetime_options)}
|
||||
${h.hidden('lifetime')}
|
||||
${h.select('role', '', c.role_options)}
|
||||
|
||||
% if c.allow_scoped_tokens:
|
||||
|
|
@ -97,9 +97,28 @@ var select2Options = {
|
|||
'dropdownCssClass': "drop-menu-dropdown",
|
||||
'dropdownAutoWidth': true
|
||||
};
|
||||
$("#lifetime").select2(select2Options);
|
||||
$("#role").select2(select2Options);
|
||||
|
||||
var preloadData = {
|
||||
results: [
|
||||
% for entry in c.lifetime_values:
|
||||
{id:${entry[0]}, text:"${entry[1]}"}${'' if loop.last else ','}
|
||||
% endfor
|
||||
]
|
||||
};
|
||||
|
||||
$("#lifetime").select2({
|
||||
containerCssClass: "drop-menu",
|
||||
dropdownCssClass: "drop-menu-dropdown",
|
||||
dropdownAutoWidth: true,
|
||||
data: preloadData,
|
||||
placeholder: ${_('Select or enter expiration date')},
|
||||
query: function(query) {
|
||||
feedLifetimeOptions(query, preloadData);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var repoFilter = function(data) {
|
||||
var results = [];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue