diff options
author | Endi Sukma Dewata <edewata@redhat.com> | 2011-12-19 18:31:35 -0600 |
---|---|---|
committer | Petr Vobornik <pvoborni@redhat.com> | 2012-01-10 18:42:26 +0100 |
commit | 74e31cd9853539f860f68e813191083e46a1192b (patch) | |
tree | 0e4914c06c68bd839d4b20897b5273f7c4ded06d | |
parent | 0e037f24ce59752713d8291eae30403cb864c758 (diff) | |
download | freeipa-74e31cd9853539f860f68e813191083e46a1192b.tar.gz freeipa-74e31cd9853539f860f68e813191083e46a1192b.tar.xz freeipa-74e31cd9853539f860f68e813191083e46a1192b.zip |
Added policies into user details page.
The user details page has been modified to show the password policy
and Kerberos ticket policy that apply to the user. The policies are
currently displayed as read-only.
Ticket #703
-rw-r--r-- | install/ui/details.js | 46 | ||||
-rw-r--r-- | install/ui/dns.js | 2 | ||||
-rw-r--r-- | install/ui/field.js | 9 | ||||
-rw-r--r-- | install/ui/hbac.js | 4 | ||||
-rw-r--r-- | install/ui/ipa.js | 168 | ||||
-rw-r--r-- | install/ui/sudo.js | 4 | ||||
-rw-r--r-- | install/ui/test/data/ipa_init.json | 2 | ||||
-rw-r--r-- | install/ui/test/data/user_get_policies.json | 135 | ||||
-rw-r--r-- | install/ui/test/data/user_show.json | 6 | ||||
-rw-r--r-- | install/ui/user.js | 257 | ||||
-rw-r--r-- | ipalib/plugins/internal.py | 2 |
11 files changed, 467 insertions, 168 deletions
diff --git a/install/ui/details.js b/install/ui/details.js index c201dad5d..4adc2770b 100644 --- a/install/ui/details.js +++ b/install/ui/details.js @@ -512,11 +512,11 @@ IPA.details_facet = function(spec) { }; - that.on_update_success = function(data, text_status, xhr) { + that.update_on_success = function(data, text_status, xhr) { that.load(data); }; - that.on_update_error = function(xhr, text_status, error_thrown) { + that.update_on_error = function(xhr, text_status, error_thrown) { }; that.add_fields_to_command = function(update_info, command) { @@ -559,9 +559,8 @@ IPA.details_facet = function(spec) { var new_update_info = IPA.update_info_builder.copy(update_info); if (update_info.fields.length > 0) { - new_update_info.append_command( - that.create_fields_update_command(update_info), - IPA.config.default_priority); + var command = that.create_fields_update_command(update_info); + new_update_info.append_command(command, IPA.config.default_priority); } new_update_info.commands.sort(function(a, b) { @@ -609,12 +608,12 @@ IPA.details_facet = function(spec) { var command = that.create_update_command(); command.on_success = function(data, text_status, xhr) { - that.on_update_success(data, text_status, xhr); + that.update_on_success(data, text_status, xhr); if (on_success) on_success.call(this, data, text_status, xhr); }; command.on_error = function(xhr, text_status, error_thrown) { - that.on_update_error(xhr, text_status, error_thrown); + that.update_on_error(xhr, text_status, error_thrown); if (on_error) on_error.call(this, xhr, text_status, error_thrown); }; @@ -641,7 +640,16 @@ IPA.details_facet = function(spec) { return command; }; - that.refresh = function() { + that.refresh_on_success = function(data, text_status, xhr) { + that.load(data); + }; + + that.refresh_on_error = function(xhr, text_status, error_thrown) { + that.redirect_error(error_thrown); + that.report_error(error_thrown); + }; + + that.refresh = function(on_success, on_error) { that.pkey = IPA.nav.get_state(that.entity.name+'-pkey'); @@ -653,12 +661,13 @@ IPA.details_facet = function(spec) { var command = that.create_refresh_command(); command.on_success = function(data, text_status, xhr) { - that.load(data); + that.refresh_on_success(data, text_status, xhr); + if (on_success) on_success.call(this, data, text_status, xhr); }; command.on_error = function(xhr, text_status, error_thrown) { - that.redirect_error(error_thrown); - that.report_error(error_thrown); + that.refresh_on_error(xhr, text_status, error_thrown); + if (on_error) on_error.call(this, xhr, text_status, error_thrown); }; command.execute(); @@ -677,10 +686,9 @@ IPA.details_facet = function(spec) { var fields = that.fields.get_fields(); for (var i = 0; i < fields.length; i++) { var field = fields[i]; - if(field.get_update_info) { - update_info = IPA.update_info_builder.merge( - update_info, - field.get_update_info()); + if (field.get_update_info) { + var ui = field.get_update_info(); + update_info = IPA.update_info_builder.merge(update_info, ui); } } @@ -726,6 +734,7 @@ IPA.details_facet = function(spec) { // methods that should be invoked by subclasses that.details_facet_create_update_command = that.create_update_command; that.details_facet_create_refresh_command = that.create_refresh_command; + that.details_facet_refresh_on_success = that.refresh_on_success; that.details_facet_load = that.load; return that; @@ -739,12 +748,13 @@ IPA.update_info = function(spec) { that.commands = spec.commands || []; that.append_field = function(field, value) { - that.fields.push(IPA.update_info_builder.new_field_info(field, value)); + var field_info = IPA.update_info_builder.new_field_info(field, value); + that.fields.push(field_info); }; that.append_command = function (command, priority) { - that.commands.push(IPA.update_info_builder.new_command_info(command, - priority)); + var command_info = IPA.update_info_builder.new_command_info(command, priority); + that.commands.push(command_info); }; return that; diff --git a/install/ui/dns.js b/install/ui/dns.js index f4f93389b..a5c9aec3a 100644 --- a/install/ui/dns.js +++ b/install/ui/dns.js @@ -704,7 +704,7 @@ IPA.dns.record_details_facet = function(spec) { var that = IPA.details_facet(spec); - that.on_update_success = function(data, text_status, xhr) { + that.update_on_success = function(data, text_status, xhr) { if (!data.result.result.idnsname) { that.reset(); diff --git a/install/ui/field.js b/install/ui/field.js index 8db0c87cb..09bd6c120 100644 --- a/install/ui/field.js +++ b/install/ui/field.js @@ -198,10 +198,10 @@ IPA.field = function(spec) { that.get_update_info = function() { var update_info = IPA.update_info_builder.new_update_info(); - if(that.is_dirty()) { - update_info.fields.push(IPA.update_info_builder.new_field_info( - that, - that.save())); + if (that.is_dirty()) { + var values = that.save(); + var field_info = IPA.update_info_builder.new_field_info(that, values); + update_info.fields.push(field_info); } return update_info; }; @@ -679,6 +679,7 @@ IPA.enable_field = function(spec) { return that; }; +// TODO: Add support for nested fields IPA.field_container = function(spec) { spec = spec || {}; diff --git a/install/ui/hbac.js b/install/ui/hbac.js index 3346d0b01..d26b894b4 100644 --- a/install/ui/hbac.js +++ b/install/ui/hbac.js @@ -513,11 +513,11 @@ IPA.hbacrule_details_facet = function(spec) { var that = IPA.details_facet(spec); - that.on_update_success = function(data, text_status, xhr) { + that.update_on_success = function(data, text_status, xhr) { that.refresh(); }; - that.on_update_error = function(xhr, text_status, error_thrown) { + that.update_on_error = function(xhr, text_status, error_thrown) { that.refresh(); }; diff --git a/install/ui/ipa.js b/install/ui/ipa.js index 23a5e4287..90d10291a 100644 --- a/install/ui/ipa.js +++ b/install/ui/ipa.js @@ -561,96 +561,104 @@ IPA.batch_command = function (spec) { that.execute = function() { that.errors.clear(); - IPA.command({ + var command = IPA.command({ name: that.name, entity: that.entity, method: that.method, args: that.args, options: that.options, - retry: that.retry, - on_success: function(data, text_status, xhr) { + retry: that.retry + }); - for (var i=0; i<that.commands.length; i++) { - var command = that.commands[i]; - var result = data.result.results[i]; - - var name = ''; - var message = ''; - - if (!result) { - name = IPA.get_message('errors.internal_error', 'Internal Error')+' '+xhr.status; - message = result ? xhr.statusText : IPA.get_message('errors.internal_error', 'Internal Error'); - - that.errors.add(command, name, message, text_status); - - if (command.on_error) command.on_error.call( - this, - xhr, - text_status, - { - name: name, - message: message - } - ); - - } else if (result.error) { - name = IPA.get_message('errors.ipa_error', 'IPA Error')+(result.error.code ? ' '+result.error.code : ''); - message = result.error.message || result.error; - - that.errors.add(command, name, message, text_status); - - if (command.on_error) command.on_error.call( - this, - xhr, - text_status, - { - name: name, - code: result.error.code, - message: message, - data: result - } - ); - - } else { - var failed = that.get_failed(command, result, text_status, xhr); - that.errors.add_range(failed); - - if (command.on_success) command.on_success.call(this, result, text_status, xhr); - } - } - //check for partial errors and show error dialog - if(that.show_error && that.errors.errors.length > 0) { - var ajax = this; - var dialog = IPA.error_dialog({ - xhr: xhr, - text_status: text_status, - error_thrown: { - name: IPA.get_message('dialogs.batch_error_title', 'Operations Error'), - message: that.error_message - }, - command: that, - errors: that.errors.errors, - visible_buttons: ['ok'] - }); + command.on_success = that.batch_command_on_success; + command.on_error = that.batch_command_on_error; - dialog.on_ok = function() { - dialog.close(); - if (that.on_success) that.on_success.call(ajax, data, text_status, xhr); - }; + command.execute(); + }; - dialog.open(); + that.batch_command_on_success = function(data, text_status, xhr) { - } else { - if (that.on_success) that.on_success.call(this, data, text_status, xhr); - } - }, - on_error: function(xhr, text_status, error_thrown) { - // TODO: undefined behavior - if (that.on_error) { - that.on_error.call(this, xhr, text_status, error_thrown); - } + for (var i=0; i<that.commands.length; i++) { + var command = that.commands[i]; + var result = data.result.results[i]; + + var name = ''; + var message = ''; + + if (!result) { + name = IPA.get_message('errors.internal_error', 'Internal Error')+' '+xhr.status; + message = result ? xhr.statusText : IPA.get_message('errors.internal_error', 'Internal Error'); + + that.errors.add(command, name, message, text_status); + + if (command.on_error) command.on_error.call( + this, + xhr, + text_status, + { + name: name, + message: message + } + ); + + } else if (result.error) { + name = IPA.get_message('errors.ipa_error', 'IPA Error')+(result.error.code ? ' '+result.error.code : ''); + message = result.error.message || result.error; + + that.errors.add(command, name, message, text_status); + + if (command.on_error) command.on_error.call( + this, + xhr, + text_status, + { + name: name, + code: result.error.code, + message: message, + data: result + } + ); + + } else { + var failed = that.get_failed(command, result, text_status, xhr); + that.errors.add_range(failed); + + if (command.on_success) command.on_success.call(this, result, text_status, xhr); } - }).execute(); + } + + //check for partial errors and show error dialog + if (that.show_error && that.errors.errors.length > 0) { + var ajax = this; + var dialog = IPA.error_dialog({ + xhr: xhr, + text_status: text_status, + error_thrown: { + name: IPA.get_message('dialogs.batch_error_title', 'Operations Error'), + message: that.error_message + }, + command: that, + errors: that.errors.errors, + visible_buttons: [ 'ok' ] + }); + + dialog.on_ok = function() { + dialog.close(); + if (that.on_success) that.on_success.call(ajax, data, text_status, xhr); + }; + + dialog.open(); + + } else { + if (that.on_success) that.on_success.call(this, data, text_status, xhr); + } + }; + + that.batch_command_on_error = function(xhr, text_status, error_thrown) { + // TODO: undefined behavior + if (that.on_error) { + that.on_error.call(this, xhr, text_status, error_thrown); + } }; return that; diff --git a/install/ui/sudo.js b/install/ui/sudo.js index eb3569908..2266bb8c4 100644 --- a/install/ui/sudo.js +++ b/install/ui/sudo.js @@ -628,11 +628,11 @@ IPA.sudorule_details_facet = function(spec) { options.facet = that; }; - that.on_update_success = function(data, text_status, xhr) { + that.update_on_success = function(data, text_status, xhr) { that.refresh(); }; - that.on_update_error = function(xhr, text_status, error_thrown) { + that.update_on_error = function(xhr, text_status, error_thrown) { that.refresh(); }; diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index 77af2f8f2..5e9d2eb0f 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -260,7 +260,7 @@ "identity": "Host Group Settings" }, "krbtpolicy": { - "identity": "Kerberos ticket policy" + "identity": "Kerberos Ticket Policy" }, "netgroup": { "identity": "Netgroup Settings" diff --git a/install/ui/test/data/user_get_policies.json b/install/ui/test/data/user_get_policies.json new file mode 100644 index 000000000..68e9084f7 --- /dev/null +++ b/install/ui/test/data/user_get_policies.json @@ -0,0 +1,135 @@ +{ + "error": null, + "id": null, + "result": { + "count": 2, + "results": [ + { + "error": null, + "result": { + "attributelevelrights": { + "aci": "rscwo", + "cn": "rscwo", + "krbmaxpwdlife": "rscwo", + "krbminpwdlife": "rscwo", + "krbpwdfailurecountinterval": "rscwo", + "krbpwdhistorylength": "rscwo", + "krbpwdlockoutduration": "rscwo", + "krbpwdmaxfailure": "rscwo", + "krbpwdmindiffchars": "rscwo", + "krbpwdminlength": "rscwo", + "nsaccountlock": "rscwo", + "objectclass": "rscwo" + }, + "cn": [ + "global_policy" + ], + "dn": "cn=global_policy,cn=dev.example.com,cn=kerberos,dc=dev,dc=example,dc=com", + "krbmaxpwdlife": [ + "90" + ], + "krbminpwdlife": [ + "1" + ], + "krbpwdfailurecountinterval": [ + "60" + ], + "krbpwdhistorylength": [ + "0" + ], + "krbpwdlockoutduration": [ + "10" + ], + "krbpwdmaxfailure": [ + "3" + ], + "krbpwdmindiffchars": [ + "0" + ], + "krbpwdminlength": [ + "8" + ], + "objectclass": [ + "top", + "nsContainer", + "krbPwdPolicy" + ] + }, + "summary": null, + "value": "global_policy" + }, + { + "error": null, + "result": { + "attributelevelrights": { + "aci": "rscwo", + "cn": "rscwo", + "krbadmservers": "rscwo", + "krbdefaultencsalttypes": "rscwo", + "krbkdcservers": "rscwo", + "krbldapservers": "rscwo", + "krbmaxrenewableage": "rscwo", + "krbmaxticketlife": "rscwo", + "krbmkey": "none", + "krbprinccontainerref": "rscwo", + "krbprincnamingattr": "rscwo", + "krbpwdpolicyreference": "rsc", + "krbpwdservers": "rscwo", + "krbsearchscope": "rscwo", + "krbsubtrees": "rscwo", + "krbsupportedencsalttypes": "rscwo", + "krbticketflags": "rsc", + "krbticketpolicyreference": "rsc", + "krbupenabled": "rsc", + "nsaccountlock": "rscwo", + "objectclass": "rscwo" + }, + "cn": [ + "DEV.EXAMPLE.COM" + ], + "dn": "cn=dev.example.com,cn=kerberos,dc=dev,dc=example,dc=com", + "krbdefaultencsalttypes": [ + "aes256-cts:special", + "aes128-cts:special", + "des3-hmac-sha1:special", + "arcfour-hmac:special" + ], + "krbmaxrenewableage": [ + "604800" + ], + "krbmaxticketlife": [ + "86400" + ], + "krbsearchscope": [ + "2" + ], + "krbsubtrees": [ + "dc=dev,dc=example,dc=com" + ], + "krbsupportedencsalttypes": [ + "aes256-cts:normal", + "aes256-cts:special", + "aes128-cts:normal", + "aes128-cts:special", + "des3-hmac-sha1:normal", + "des3-hmac-sha1:special", + "arcfour-hmac:normal", + "arcfour-hmac:special", + "des-hmac-sha1:normal", + "des-cbc-md5:normal", + "des-cbc-crc:normal", + "des-cbc-crc:v4", + "des-cbc-crc:afs3" + ], + "objectclass": [ + "top", + "krbrealmcontainer", + "krbticketpolicyaux" + ] + }, + "summary": null, + "value": "" + } + ] + } +} diff --git a/install/ui/test/data/user_show.json b/install/ui/test/data/user_show.json index 25a505a7b..703c793bf 100644 --- a/install/ui/test/data/user_show.json +++ b/install/ui/test/data/user_show.json @@ -110,6 +110,12 @@ "krblastpwdchange": [ "20101105172205Z" ], + "krbmaxrenewableage": [ + "604800" + ], + "krbmaxticketlife": [ + "86400" + ], "krbpasswordexpiration": [ "20101105172205Z" ], diff --git a/install/ui/user.js b/install/ui/user.js index 01d196cec..c50261a36 100644 --- a/install/ui/user.js +++ b/install/ui/user.js @@ -55,65 +55,133 @@ IPA.user.entity = function(spec) { 'title' ] }). - details_facet({ sections: [ - { - name: 'identity', - label: IPA.messages.details.identity, - fields: [ - 'title', - 'givenname', - 'sn', - 'cn', - 'displayname', - 'initials' - ] - }, - { - name: 'account', - fields: [ - { - factory: IPA.user_status_widget, - name: 'nsaccountlock', - label: IPA.messages.objects.user.account_status - }, - 'uid', - { factory: IPA.user_password_widget, name: 'userpassword' }, - 'uidnumber', - 'gidnumber', - 'loginshell', - 'homedirectory' - ] - }, - { - name: 'contact', - fields: [ - { type: 'multivalued', name: 'mail' }, - { type: 'multivalued', name: 'telephonenumber' }, - { type: 'multivalued', name: 'pager' }, - { type: 'multivalued', name: 'mobile' }, - { type: 'multivalued', name: 'facsimiletelephonenumber' } - ] - }, - { - name: 'mailing', - fields: ['street', 'l', 'st', 'postalcode'] - }, - { - name: 'employee', - fields: [ - 'ou', - { - type: 'entity_select', - name: 'manager', - other_entity: 'user', - other_field: 'uid' - } - ] - }, - { - name: 'misc', - fields: ['carlicense'] - }] + details_facet({ + factory: IPA.user.details_facet, + sections: [ + { + name: 'identity', + label: IPA.messages.details.identity, + fields: [ + 'title', + 'givenname', + 'sn', + 'cn', + 'displayname', + 'initials' + ] + }, + { + name: 'account', + fields: [ + { + factory: IPA.user_status_widget, + name: 'nsaccountlock', + label: IPA.messages.objects.user.account_status + }, + 'uid', + { + factory: IPA.user_password_widget, + name: 'userpassword' + }, + 'uidnumber', + 'gidnumber', + 'loginshell', + 'homedirectory' + ] + }, + { + name: 'pwpolicy', + label: IPA.messages.objects.pwpolicy.identity, + fields: [ + { + name: 'krbmaxpwdlife', + label: IPA.get_entity_param('pwpolicy', 'krbmaxpwdlife').label, + read_only: true + }, + { + name: 'krbminpwdlife', + label: IPA.get_entity_param('pwpolicy', 'krbminpwdlife').label, + read_only: true + }, + { + name: 'krbpwdhistorylength', + label: IPA.get_entity_param('pwpolicy', 'krbpwdhistorylength').label, + read_only: true + }, + { + name: 'krbpwdmindiffchars', + label: IPA.get_entity_param('pwpolicy', 'krbpwdmindiffchars').label, + read_only: true + }, + { + name: 'krbpwdminlength', + label: IPA.get_entity_param('pwpolicy', 'krbpwdminlength').label, + read_only: true + }, + { + name: 'krbpwdmaxfailure', + label: IPA.get_entity_param('pwpolicy', 'krbpwdmaxfailure').label, + read_only: true + }, + { + name: 'krbpwdfailurecountinterval', + label: IPA.get_entity_param('pwpolicy', 'krbpwdfailurecountinterval').label, + read_only: true + }, + { + name: 'krbpwdlockoutduration', + label: IPA.get_entity_param('pwpolicy', 'krbpwdlockoutduration').label, + read_only: true + } + ] + }, + { + name: 'krbtpolicy', + label: IPA.messages.objects.krbtpolicy.identity, + fields: [ + { + name: 'krbmaxrenewableage', + label: IPA.get_entity_param('krbtpolicy', 'krbmaxrenewableage').label, + read_only: true + }, + { + name: 'krbmaxticketlife', + label: IPA.get_entity_param('krbtpolicy', 'krbmaxticketlife').label, + read_only: true + } + ] + }, + { + name: 'contact', + fields: [ + { type: 'multivalued', name: 'mail' }, + { type: 'multivalued', name: 'telephonenumber' }, + { type: 'multivalued', name: 'pager' }, + { type: 'multivalued', name: 'mobile' }, + { type: 'multivalued', name: 'facsimiletelephonenumber' } + ] + }, + { + name: 'mailing', + fields: ['street', 'l', 'st', 'postalcode'] + }, + { + name: 'employee', + fields: [ + 'ou', + { + type: 'entity_select', + name: 'manager', + other_entity: 'user', + other_field: 'uid' + } + ] + }, + { + name: 'misc', + fields: [ 'carlicense' ] + } + ] }). association_facet({ name: 'memberof_group', @@ -186,6 +254,77 @@ IPA.user.entity = function(spec) { return that; }; +IPA.user.details_facet = function(spec) { + + spec = spec || {}; + + var that = IPA.details_facet(spec); + + that.refresh_on_success = function(data, text_status, xhr) { + that.details_facet_refresh_on_success(data, text_status, xhr); + + var batch = IPA.batch_command({ + name: 'user_get_policies' + }); + + var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + + var pwpolicy_command = IPA.command({ + entity: 'pwpolicy', + method: 'show', + options: { + user: pkey, + all: true, + rights: true + } + }); + + pwpolicy_command.on_success = function(data, text_status, xhr) { + // TODO: Use nested fields: that.fields.get_field('pwpolicy').get_fields(); + var fields = that.fields.get_fields(); + for (var i=0; i<fields.length; i++) { + var field = fields[i]; + + // load result into pwpolicy fields + if (field.widget_name.match(/^pwpolicy\./)) { + field.load(data.result); + } + } + }; + + batch.add_command(pwpolicy_command); + + var krbtpolicy_command = IPA.command({ + entity: 'krbtpolicy', + method: 'show', + args: [ pkey ], + options: { + all: true, + rights: true + } + }); + + krbtpolicy_command.on_success = function(data, text_status, xhr) { + // TODO: Use nested fields: that.fields.get_field('krbtpolicy').get_fields(); + var fields = that.fields.get_fields(); + for (var i=0; i<fields.length; i++) { + var field = fields[i]; + + // load result into krbtpolicy fields + if (field.widget_name.match(/^krbtpolicy\./)) { + field.load(data.result); + } + } + }; + + batch.add_command(krbtpolicy_command); + + batch.execute(); + }; + + return that; +}; + IPA.user_adder_dialog = function(spec) { var that = IPA.entity_adder_dialog(spec); diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py index 3eed9ec56..31a4f9c6a 100644 --- a/ipalib/plugins/internal.py +++ b/ipalib/plugins/internal.py @@ -398,7 +398,7 @@ class i18n_messages(Command): "identity": _("Host Group Settings"), }, "krbtpolicy": { - "identity": _("Kerberos ticket policy"), + "identity": _("Kerberos Ticket Policy"), }, "netgroup": { "identity": _("Netgroup Settings"), |