auth-tokens: allow specifing custom expiration date manually.

- fixes #5323
This commit is contained in:
Marcin Kuzminski 2017-09-08 18:03:35 +02:00
parent 56bbe6261a
commit 0fd76867b6
6 changed files with 127 additions and 21 deletions

View file

@ -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]

View file

@ -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]

View file

@ -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

View file

@ -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);
};

View file

@ -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 = [];

View file

@ -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 = [];