summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2013-09-12 15:29:01 +0200
committerAlexander Bokovoy <abokovoy@redhat.com>2014-02-11 15:02:52 +0200
commitaef15e7d5e41d7d4588f46ebf0aa1deba91b83fe (patch)
treeecc30e91d84c0f84b98d30b59acb03389c8cd235
parent1b156ff13bbab777a42c7d53991ba6a1ff8c1644 (diff)
downloadfreeipa-aef15e7d5e41d7d4588f46ebf0aa1deba91b83fe.zip
freeipa-aef15e7d5e41d7d4588f46ebf0aa1deba91b83fe.tar.gz
freeipa-aef15e7d5e41d7d4588f46ebf0aa1deba91b83fe.tar.xz
UI for OTP tokens
https://fedorahosted.org/freeipa/ticket/3369
-rw-r--r--install/ui/doc/categories.json1
-rw-r--r--install/ui/src/freeipa/app.js1
-rw-r--r--install/ui/src/freeipa/navigation/menu_spec.js10
-rw-r--r--install/ui/src/freeipa/otptoken.js306
-rw-r--r--install/ui/src/freeipa/search.js18
-rw-r--r--install/ui/test/data/ipa_init.json5
-rw-r--r--ipalib/plugins/internal.py9
7 files changed, 339 insertions, 11 deletions
diff --git a/install/ui/doc/categories.json b/install/ui/doc/categories.json
index 9f04c4b..02487e5 100644
--- a/install/ui/doc/categories.json
+++ b/install/ui/doc/categories.json
@@ -218,6 +218,7 @@
"name": "Plugins",
"classes": [
"aci",
+ "otptoken",
"user"
]
}
diff --git a/install/ui/src/freeipa/app.js b/install/ui/src/freeipa/app.js
index 2fbe077..05bef37 100644
--- a/install/ui/src/freeipa/app.js
+++ b/install/ui/src/freeipa/app.js
@@ -41,6 +41,7 @@ define([
'./host',
'./idrange',
'./netgroup',
+ './otptoken',
'./policy',
'./realmdomains',
'./rule',
diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index 9d4c5ef..e531a9f 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -56,7 +56,8 @@ var nav = {};
]
},
{ entity: 'cert', label: '@i18n:tabs.cert' },
- { entity: 'realmdomains' }
+ { entity: 'realmdomains' },
+ { entity: 'otptoken' }
]
},
{name: 'policy', label: '@i18n:tabs.policy', children: [
@@ -148,10 +149,13 @@ nav.self_service = {
{
name: 'identity',
label: '@i18n:tabs.identity',
- children: [{entity: 'user'}]
+ children: [
+ { entity: 'user' },
+ { entity: 'otptoken' }
+ ]
}
]
};
return nav;
-}); \ No newline at end of file
+});
diff --git a/install/ui/src/freeipa/otptoken.js b/install/ui/src/freeipa/otptoken.js
new file mode 100644
index 0000000..9a3ce661
--- /dev/null
+++ b/install/ui/src/freeipa/otptoken.js
@@ -0,0 +1,306 @@
+/* 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', // totp is the only option atm
+ {
+ $type: 'textarea',
+ name: 'description'
+ },
+ 'ipatokenowner',
+ 'ipatokennotbefore',
+ 'ipatokennotafter',
+ 'ipatokenvendor',
+ 'ipatokenmodel',
+ 'ipatokenserial',
+ 'ipatokenotpalgorithm',
+ 'ipatokenotpdigits',
+ 'ipatokentotpclockoffset',
+ 'ipatokentotptimestep'
+ ]
+ }
+ ]
+ }
+ ],
+
+ adder_dialog: {
+ $factory: otptoken.adder_dialog,
+ $pre_ops: [
+ otptoken.adder_dialog_preop
+ ],
+ fields: [
+ {
+ name: 'ipatokenuniqueid',
+ required: false
+ },
+ 'description',
+ {// only when not self-service
+ $type: 'entity_select',
+ name: 'ipatokenowner',
+ other_entity: 'user',
+ other_field: 'uid'
+ },
+ //'type', - only totp is supported atm
+ 'ipatokennotbefore',
+ 'ipatokennotafter',
+ 'ipatokenvendor',
+ 'ipatokenmodel',
+ 'ipatokenserial',
+ 'ipatokenotpkey',
+ {
+ $type: 'radio',
+ name: 'ipatokenotpalgorithm',
+ options: [
+ {label:'default', value: ''},
+ 'sha1', 'sha256', 'sha384', 'sha512'
+ ]
+ },
+ {
+ $type: 'radio',
+ name: 'ipatokenotpdigits',
+ options: [{label:'default', value: ''}, '6', '8']
+ },
+ 'ipatokentotptimestep'
+ ],
+ selfservice_fields: [
+ {
+ 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);
+ command.set_option('type', 'totp');
+ 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;
+});
diff --git a/install/ui/src/freeipa/search.js b/install/ui/src/freeipa/search.js
index 3c2fca7..394de3e 100644
--- a/install/ui/src/freeipa/search.js
+++ b/install/ui/src/freeipa/search.js
@@ -466,6 +466,7 @@ IPA.batch_items_action = function(spec) {
that.method = spec.method || 'disable';
that.success_msg = text.get(spec.success_msg);
+ that.options = spec.options || {};
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);
item_keys.push(selected_keys[i]);
- var command = IPA.command({
- entity: entity.name,
- method: that.method,
- args: item_keys
- });
-
+ var command = that.create_action_command(facet, item_keys);
that.batch.add_command(command);
}
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) {
facet.on_update.notify();
facet.refresh();
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index cf13591..828af9f 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -365,6 +365,11 @@
"usergroups": "User Groups",
"users": "Users"
},
+ "otptoken": {
+ "details": "OTP Token Settings",
+ "disable": "Disable token",
+ "enable": "Enable token"
+ },
"permission": {
"identity": "Identity",
"invalid_target": "Permission with invalid target specification",
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index e282dfe..1e2cec3 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -485,7 +485,7 @@ class i18n_messages(Command):
},
"krbtpolicy": {
"identity": _("Kerberos Ticket Policy"),
- },
+ },
"netgroup": {
"any_host": _("Any Host"),
"anyone": _("Anyone"),
@@ -499,7 +499,12 @@ class i18n_messages(Command):
"user": _("User"),
"usergroups": _("User Groups"),
"users": _("Users"),
- },
+ },
+ "otptoken": {
+ "details": "OTP Token Settings",
+ "disable": "Disable token",
+ "enable": "Enable token",
+ },
"permission": {
"identity": _("Identity"),
"invalid_target": _("Permission with invalid target specification"),