mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
UI for OTP tokens
https://fedorahosted.org/freeipa/ticket/3369 Reviewed-By: Adam Misnyovszki <amisnyov@redhat.com>
This commit is contained in:
committed by
Petr Viktorin
parent
0700b13807
commit
fef26fe3d8
@@ -218,6 +218,7 @@
|
|||||||
"name": "Plugins",
|
"name": "Plugins",
|
||||||
"classes": [
|
"classes": [
|
||||||
"aci",
|
"aci",
|
||||||
|
"otptoken",
|
||||||
"user"
|
"user"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ define([
|
|||||||
'./host',
|
'./host',
|
||||||
'./idrange',
|
'./idrange',
|
||||||
'./netgroup',
|
'./netgroup',
|
||||||
|
'./otptoken',
|
||||||
'./policy',
|
'./policy',
|
||||||
'./realmdomains',
|
'./realmdomains',
|
||||||
'./rule',
|
'./rule',
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ var nav = {};
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ entity: 'cert', label: '@i18n:tabs.cert' },
|
{ entity: 'cert', label: '@i18n:tabs.cert' },
|
||||||
{ entity: 'realmdomains' }
|
{ entity: 'realmdomains' },
|
||||||
|
{ entity: 'otptoken' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{name: 'policy', label: '@i18n:tabs.policy', children: [
|
{name: 'policy', label: '@i18n:tabs.policy', children: [
|
||||||
@@ -148,10 +149,13 @@ nav.self_service = {
|
|||||||
{
|
{
|
||||||
name: 'identity',
|
name: 'identity',
|
||||||
label: '@i18n:tabs.identity',
|
label: '@i18n:tabs.identity',
|
||||||
children: [{entity: 'user'}]
|
children: [
|
||||||
|
{ entity: 'user' },
|
||||||
|
{ entity: 'otptoken' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
return nav;
|
return nav;
|
||||||
});
|
});
|
||||||
|
|||||||
328
install/ui/src/freeipa/otptoken.js
Normal file
328
install/ui/src/freeipa/otptoken.js
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
/* Authors:
|
||||||
|
* Petr Vobornik <pvoborni@redhat.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Red Hat
|
||||||
|
* see file 'COPYING' for use and warranty information
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./ipa',
|
||||||
|
'./jquery',
|
||||||
|
'./menu',
|
||||||
|
'./phases',
|
||||||
|
'./reg',
|
||||||
|
'./details',
|
||||||
|
'./facet',
|
||||||
|
'./search',
|
||||||
|
'./entity'],
|
||||||
|
function(IPA, $, menu, phases, reg, mod_details, mod_facet) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP tokens module
|
||||||
|
* @class
|
||||||
|
* @singleton
|
||||||
|
*/
|
||||||
|
var otptoken = IPA.otptoken = {};
|
||||||
|
|
||||||
|
var make_spec = function() {
|
||||||
|
return {
|
||||||
|
name: 'otptoken',
|
||||||
|
enable_test: function() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
facets: [
|
||||||
|
{
|
||||||
|
$type: 'search',
|
||||||
|
$pre_ops: [
|
||||||
|
// redefining 'add' and 'remove' actions to be shown in
|
||||||
|
// self service
|
||||||
|
{
|
||||||
|
$replace: [ [ 'actions', [
|
||||||
|
[
|
||||||
|
'add',
|
||||||
|
{
|
||||||
|
$type:'add',
|
||||||
|
name: 'add',
|
||||||
|
hide_cond: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'batch_remove',
|
||||||
|
{
|
||||||
|
$type: 'batch_remove',
|
||||||
|
name: 'remove',
|
||||||
|
hide_cond: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
] ] ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
$type: 'batch_items',
|
||||||
|
name: 'enable',
|
||||||
|
method: 'mod',
|
||||||
|
options: { ipatokendisabled: false },
|
||||||
|
needs_confirm: true,
|
||||||
|
enable_cond: ['item-selected'],
|
||||||
|
success_msg: '@i18n:search.enabled',
|
||||||
|
confirm_msg: '@i18n:search.enable_confirm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$type: 'batch_items',
|
||||||
|
name: 'disable',
|
||||||
|
method: 'mod',
|
||||||
|
options: { ipatokendisabled: true },
|
||||||
|
needs_confirm: true,
|
||||||
|
enable_cond: ['item-selected'],
|
||||||
|
success_msg: '@i18n:search.disabled',
|
||||||
|
confirm_msg: '@i18n:search.disable_confirm'
|
||||||
|
},
|
||||||
|
'delete'
|
||||||
|
],
|
||||||
|
control_buttons: [
|
||||||
|
{
|
||||||
|
name: 'disable',
|
||||||
|
label: '@i18n:buttons.disable',
|
||||||
|
icon: 'fa-minus'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enable',
|
||||||
|
label: '@i18n:buttons.enable',
|
||||||
|
icon: 'fa-check'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
'ipatokenuniqueid',
|
||||||
|
'ipatokenowner',
|
||||||
|
{
|
||||||
|
name: 'ipatokendisabled',
|
||||||
|
label: '@i18n:status.label',
|
||||||
|
formatter: {
|
||||||
|
$type: 'boolean_status',
|
||||||
|
invert_value: true,
|
||||||
|
empty_value: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'description'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$type: 'details',
|
||||||
|
actions: [
|
||||||
|
'select',
|
||||||
|
{
|
||||||
|
$type: 'object',
|
||||||
|
name: 'otp_enable',
|
||||||
|
label: '@i18n:objects.otptoken.enable',
|
||||||
|
method: 'mod',
|
||||||
|
options: { ipatokendisabled: false },
|
||||||
|
enable_cond: ['disabled'],
|
||||||
|
hide_cond: ['self-service']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$type: 'object',
|
||||||
|
name: 'otp_disable',
|
||||||
|
label: '@i18n:objects.otptoken.disable',
|
||||||
|
method: 'mod',
|
||||||
|
options: { ipatokendisabled: true },
|
||||||
|
enable_cond: ['enabled'],
|
||||||
|
hide_cond: ['self-service']
|
||||||
|
},
|
||||||
|
'delete'
|
||||||
|
],
|
||||||
|
header_actions: ['select_action', 'otp_enable', 'otp_disable', 'delete'],
|
||||||
|
state: {
|
||||||
|
evaluators: [
|
||||||
|
{
|
||||||
|
$factory: mod_details.enable_state_evaluator,
|
||||||
|
field: 'ipatokendisabled',
|
||||||
|
parser: {
|
||||||
|
$factory: IPA.boolean_formatter,
|
||||||
|
invert_value: true,
|
||||||
|
empty_value: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mod_facet.self_service_state_evaluator
|
||||||
|
],
|
||||||
|
summary_conditions: [
|
||||||
|
mod_details.enabled_summary_cond,
|
||||||
|
mod_details.disabled_summary_cond
|
||||||
|
]
|
||||||
|
},
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
name: 'details',
|
||||||
|
label: '@i18n:objects.otptoken.details',
|
||||||
|
fields: [
|
||||||
|
'ipatokenuniqueid',
|
||||||
|
{
|
||||||
|
$type: 'textarea',
|
||||||
|
name: 'description'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$type: 'entity_select',
|
||||||
|
name: 'ipatokenowner',
|
||||||
|
other_entity: 'user',
|
||||||
|
other_field: 'uid'
|
||||||
|
},
|
||||||
|
'ipatokennotbefore',
|
||||||
|
'ipatokennotafter',
|
||||||
|
'ipatokenvendor',
|
||||||
|
'ipatokenmodel',
|
||||||
|
'ipatokenserial',
|
||||||
|
'ipatokenotpalgorithm',
|
||||||
|
'ipatokenotpdigits',
|
||||||
|
'ipatokentotpclockoffset',
|
||||||
|
'ipatokentotptimestep',
|
||||||
|
'ipatokenhotpcounter'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
adder_dialog: {
|
||||||
|
$factory: otptoken.adder_dialog,
|
||||||
|
$pre_ops: [
|
||||||
|
otptoken.adder_dialog_preop
|
||||||
|
],
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
$type: 'radio',
|
||||||
|
name: 'type',
|
||||||
|
default_value: 'totp',
|
||||||
|
options: [
|
||||||
|
{ label: 'TOTP', value: 'totp' },
|
||||||
|
{ label: 'HOTP', value: 'hotp' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipatokenuniqueid',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
'description',
|
||||||
|
{// only when not self-service
|
||||||
|
$type: 'entity_select',
|
||||||
|
name: 'ipatokenowner',
|
||||||
|
other_entity: 'user',
|
||||||
|
other_field: 'uid'
|
||||||
|
},
|
||||||
|
'ipatokennotbefore',
|
||||||
|
'ipatokennotafter',
|
||||||
|
'ipatokenvendor',
|
||||||
|
'ipatokenmodel',
|
||||||
|
'ipatokenserial',
|
||||||
|
'ipatokenotpkey',
|
||||||
|
{
|
||||||
|
$type: 'radio',
|
||||||
|
name: 'ipatokenotpalgorithm',
|
||||||
|
default_value: 'sha1',
|
||||||
|
options: [
|
||||||
|
'sha1', 'sha256', 'sha384', 'sha512'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$type: 'radio',
|
||||||
|
name: 'ipatokenotpdigits',
|
||||||
|
default_value: '6',
|
||||||
|
options: ['6', '8']
|
||||||
|
},
|
||||||
|
'ipatokentotptimestep'
|
||||||
|
],
|
||||||
|
selfservice_fields: [
|
||||||
|
{
|
||||||
|
$type: 'radio',
|
||||||
|
name: 'type',
|
||||||
|
default_value: 'totp',
|
||||||
|
options: [
|
||||||
|
{ label: 'TOTP', value: 'totp' },
|
||||||
|
{ label: 'HOTP', value: 'hotp' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipatokenuniqueid',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
'description'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP adder dialog pre-op.
|
||||||
|
*
|
||||||
|
* Switches fields to different set when in self-service.
|
||||||
|
*/
|
||||||
|
otptoken.adder_dialog_preop = function(spec) {
|
||||||
|
|
||||||
|
spec.self_service = IPA.is_selfservice;
|
||||||
|
|
||||||
|
if (IPA.is_selfservice) {
|
||||||
|
spec.fields = spec.selfservice_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP adder dialog
|
||||||
|
*
|
||||||
|
* - otp-add requires 'type' to be set. At the moment IPA supports only 'totp'
|
||||||
|
* @class
|
||||||
|
* @extends IPA.entity_adder_dialog
|
||||||
|
*/
|
||||||
|
otptoken.adder_dialog = function(spec) {
|
||||||
|
|
||||||
|
var that = IPA.entity_adder_dialog(spec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog sends different command options when in self-service mode.
|
||||||
|
*/
|
||||||
|
that.self_service = !!spec.self_service;
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
that.create_add_command = function(record) {
|
||||||
|
|
||||||
|
var command = that.entity_adder_dialog_create_add_command(record);
|
||||||
|
if (that.self_service) {
|
||||||
|
command.set_option('ipatokenowner', IPA.whoami.uid[0]);
|
||||||
|
}
|
||||||
|
return command;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity specification object
|
||||||
|
* @member otptoken
|
||||||
|
*/
|
||||||
|
otptoken.spec = make_spec();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register entity
|
||||||
|
* @member otptoken
|
||||||
|
*/
|
||||||
|
otptoken.register = function() {
|
||||||
|
var e = reg.entity;
|
||||||
|
e.register({type: 'otptoken', spec: otptoken.spec});
|
||||||
|
};
|
||||||
|
|
||||||
|
phases.on('registration', otptoken.register);
|
||||||
|
|
||||||
|
return otptoken;
|
||||||
|
});
|
||||||
@@ -466,6 +466,7 @@ IPA.batch_items_action = function(spec) {
|
|||||||
|
|
||||||
that.method = spec.method || 'disable';
|
that.method = spec.method || 'disable';
|
||||||
that.success_msg = text.get(spec.success_msg);
|
that.success_msg = text.get(spec.success_msg);
|
||||||
|
that.options = spec.options || {};
|
||||||
|
|
||||||
that.execute_action = function(facet, on_success, on_error) {
|
that.execute_action = function(facet, on_success, on_error) {
|
||||||
|
|
||||||
@@ -483,18 +484,23 @@ IPA.batch_items_action = function(spec) {
|
|||||||
var item_keys = pkeys.splice(0);
|
var item_keys = pkeys.splice(0);
|
||||||
item_keys.push(selected_keys[i]);
|
item_keys.push(selected_keys[i]);
|
||||||
|
|
||||||
var command = IPA.command({
|
var command = that.create_action_command(facet, item_keys);
|
||||||
entity: entity.name,
|
|
||||||
method: that.method,
|
|
||||||
args: item_keys
|
|
||||||
});
|
|
||||||
|
|
||||||
that.batch.add_command(command);
|
that.batch.add_command(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
that.batch.execute();
|
that.batch.execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
that.create_action_command = function(facet, keys) {
|
||||||
|
var command = IPA.command({
|
||||||
|
entity: facet.managed_entity.name,
|
||||||
|
method: that.method,
|
||||||
|
args: keys,
|
||||||
|
options: that.options
|
||||||
|
});
|
||||||
|
return command;
|
||||||
|
};
|
||||||
|
|
||||||
that.on_success = function(facet, data, text_status, xhr) {
|
that.on_success = function(facet, data, text_status, xhr) {
|
||||||
facet.on_update.notify();
|
facet.on_update.notify();
|
||||||
facet.refresh();
|
facet.refresh();
|
||||||
|
|||||||
@@ -365,6 +365,11 @@
|
|||||||
"usergroups": "User Groups",
|
"usergroups": "User Groups",
|
||||||
"users": "Users"
|
"users": "Users"
|
||||||
},
|
},
|
||||||
|
"otptoken": {
|
||||||
|
"details": "OTP Token Settings",
|
||||||
|
"disable": "Disable token",
|
||||||
|
"enable": "Enable token"
|
||||||
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"identity": "Identity",
|
"identity": "Identity",
|
||||||
"invalid_target": "Permission with invalid target specification",
|
"invalid_target": "Permission with invalid target specification",
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ class i18n_messages(Command):
|
|||||||
},
|
},
|
||||||
"krbtpolicy": {
|
"krbtpolicy": {
|
||||||
"identity": _("Kerberos Ticket Policy"),
|
"identity": _("Kerberos Ticket Policy"),
|
||||||
},
|
},
|
||||||
"netgroup": {
|
"netgroup": {
|
||||||
"any_host": _("Any Host"),
|
"any_host": _("Any Host"),
|
||||||
"anyone": _("Anyone"),
|
"anyone": _("Anyone"),
|
||||||
@@ -499,7 +499,12 @@ class i18n_messages(Command):
|
|||||||
"user": _("User"),
|
"user": _("User"),
|
||||||
"usergroups": _("User Groups"),
|
"usergroups": _("User Groups"),
|
||||||
"users": _("Users"),
|
"users": _("Users"),
|
||||||
},
|
},
|
||||||
|
"otptoken": {
|
||||||
|
"details": "OTP Token Settings",
|
||||||
|
"disable": "Disable token",
|
||||||
|
"enable": "Enable token",
|
||||||
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"identity": _("Identity"),
|
"identity": _("Identity"),
|
||||||
"invalid_target": _("Permission with invalid target specification"),
|
"invalid_target": _("Permission with invalid target specification"),
|
||||||
|
|||||||
Reference in New Issue
Block a user