diff options
author | Alexander Bokovoy <abokovoy@redhat.com> | 2013-05-06 17:10:56 +0200 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2013-05-06 20:44:00 +0200 |
commit | 03cdc22c940e82199c2afa8b4a69708237ee0a7a (patch) | |
tree | 110721c903eb032702f9980e354eec848fcbaef1 | |
parent | aedded862dce2c8450d0eef5eca3d854166af06b (diff) | |
download | freeipa-03cdc22c940e82199c2afa8b4a69708237ee0a7a.tar.gz freeipa-03cdc22c940e82199c2afa8b4a69708237ee0a7a.tar.xz freeipa-03cdc22c940e82199c2afa8b4a69708237ee0a7a.zip |
Resolve SIDs in Web UI
Introduce new command, 'trust-resolve', to aid resolving SIDs to names
in the Web UI.
The command uses new SSSD interface, nss_idmap, to resolve actual SIDs.
SSSD caches resolved data so that future requests to resolve same SIDs
are returned from a memory cache.
Web UI code is using Dojo/Deferred to deliver result of SID resolution
out of band. Once resolved names are available, they replace SID values.
Since Web UI only shows ~20 records per page, up to 20 SIDs are resolved
at the same time. They all sent within the single request to the server.
https://fedorahosted.org/freeipa/ticket/3302
-rw-r--r-- | API.txt | 7 | ||||
-rw-r--r-- | freeipa.spec.in | 1 | ||||
-rw-r--r-- | install/ui/src/freeipa/association.js | 50 | ||||
-rw-r--r-- | install/ui/src/freeipa/entity.js | 2 | ||||
-rw-r--r-- | install/ui/src/freeipa/group.js | 3 | ||||
-rw-r--r-- | install/ui/src/freeipa/widget.js | 30 | ||||
-rw-r--r-- | ipalib/plugins/trust.py | 55 |
7 files changed, 142 insertions, 6 deletions
@@ -3398,6 +3398,13 @@ option: Str('version?', exclude='webui') output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None)) output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Output('value', <type 'unicode'>, None) +command: trust_resolve +args: 0,4,1 +option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') +option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') +option: Str('sids+', csv=True) +option: Str('version?', exclude='webui') +output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None)) command: trust_show args: 1,4,3 arg: Str('cn', attribute=True, cli_name='realm', multivalue=False, primary_key=True, query=True, required=True) diff --git a/freeipa.spec.in b/freeipa.spec.in index 5ce7f3b37..78f037ee4 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -211,6 +211,7 @@ Requires: samba4 Requires: samba4-winbind %endif Requires: libsss_idmap +Requires: libsss_nss_idmap-python # We use alternatives to divert winbind_krb5_locator.so plugin to libkrb5 # on the installes where server-trust-ad subpackage is installed because # IPA AD trusts cannot be used at the same time with the locator plugin diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js index d33ec8742..71ee71d48 100644 --- a/install/ui/src/freeipa/association.js +++ b/install/ui/src/freeipa/association.js @@ -23,6 +23,7 @@ * the AssociationList elements; IT NEEDS IT'S OWN CODE! */ define([ + 'dojo/Deferred', './ipa', './jquery', './navigation', @@ -31,7 +32,7 @@ define([ './text', './search', './dialog'], - function(IPA, $, navigation, phases, reg, text) { + function(Deferred, IPA, $, navigation, phases, reg, text) { IPA.associator = function (spec) { @@ -1364,6 +1365,53 @@ IPA.attribute_facet = function(spec, no_init) { return that; }; +IPA.sid_facet = function(spec, no_init) { + + spec.name = spec.name || 'sid_facet'; + + var that = IPA.attribute_facet(spec, no_init); + + that.load_records = function(value) { + var xlate = {}; + var sidxlate_command = IPA.command({ + entity: 'trust', + method: 'resolve', + options: { + sids: '' + } + }); + sidxlate_command.on_success = function(data, text_status, xhr) { + for (var i=0; i< data.result.result.length; i++) { + var entry = data.result.result[i]; + if (entry.sid[0] in xlate) { + xlate[entry.sid[0]].resolve(entry.name[0]); + } + } + }; + that.table.empty(); + + if (value.length === 0) return; + + var sids = []; + for (var i=0; i< value.length; i++) { + var sid = value[i][that.attribute]; + var deferred = new Deferred(); + value[i][that.attribute] = { + promise: deferred.promise, + temp: sid + }; + xlate[sid] = deferred; + sids.push(sid); + that.add_record(value[i]); + } + sidxlate_command.options.sids = sids; + sidxlate_command.execute(); + }; + + return that; +}; + + IPA.attr_read_only_evaluator = function(spec) { spec.name = spec.name || 'attr_read_only_evaluator'; diff --git a/install/ui/src/freeipa/entity.js b/install/ui/src/freeipa/entity.js index 427d300e3..0d0564d1d 100644 --- a/install/ui/src/freeipa/entity.js +++ b/install/ui/src/freeipa/entity.js @@ -662,4 +662,4 @@ registry.builder.post_ops.push( exp.entity_post_ops.deleter_dialog); return exp; -});
\ No newline at end of file +}); diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js index 0408d0bc9..5e8cdf991 100644 --- a/install/ui/src/freeipa/group.js +++ b/install/ui/src/freeipa/group.js @@ -112,6 +112,7 @@ return { }, { $type: 'attribute', + $factory: IPA.sid_facet, name: 'member_external', attribute: 'ipaexternalmember', tab_label: 'External', @@ -280,4 +281,4 @@ exp.register = function() { phases.on('registration', exp.register); return exp; -});
\ No newline at end of file +}); diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js index 0fe046e44..8f1208e0b 100644 --- a/install/ui/src/freeipa/widget.js +++ b/install/ui/src/freeipa/widget.js @@ -1404,9 +1404,6 @@ IPA.column = function (spec) { } that.setup = function(container, record, suppress_link) { - - container.empty(); - var value = record[that.name]; var type; if (that.formatter) { @@ -1414,7 +1411,34 @@ IPA.column = function (spec) { value = that.formatter.format(value); type = that.formatter.type; } + + var promise, temp = ''; + if (value && typeof value.then === 'function') promise = value; + if (value && value.promise && typeof value.promise.then === 'function') { + promise = value.promise; + temp = value.temp || ''; + } + + if (promise) { + var fulfilled = false; + promise.then(function(val) { + fulfilled = true; + that.set_value(container, val, type, suppress_link); + }); + + if (fulfilled) return; + // val obj can contain temporal value which is displayed + // until promise is fulfilled + value = temp; + } + + that.set_value(container, value, type, suppress_link); + }; + + that.set_value = function(container, value, type, suppress_link) { + value = value ? value.toString() : ''; + container.empty(); var c; if (that.link && !suppress_link) { diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py index a252ad632..9bcfb417a 100644 --- a/ipalib/plugins/trust.py +++ b/ipalib/plugins/trust.py @@ -32,6 +32,12 @@ try: except Exception, e: _murmur_installed = False +try: + import pysss_nss_idmap #pylint: disable=F0401 + _nss_idmap_installed = True +except Exception, e: + _nss_idmap_installed = False + if api.env.in_server and api.env.context in ['lite', 'server']: try: import ipaserver.dcerpc #pylint: disable=F0401 @@ -687,3 +693,52 @@ class trustconfig_show(LDAPRetrieve): return dn api.register(trustconfig_show) + +if _nss_idmap_installed: + _idmap_type_dict = { + pysss_nss_idmap.ID_USER : 'user', + pysss_nss_idmap.ID_GROUP : 'group', + pysss_nss_idmap.ID_BOTH : 'both', + } + def idmap_type_string(level): + string = _idmap_type_dict.get(int(level), 'unknown') + return unicode(string) + +class trust_resolve(Command): + __doc__ = _('Resolve security identifiers of users and groups in trusted domains') + + takes_options = ( + Str('sids+', + label = _('Security Identifiers (SIDs)'), + csv = True, + ), + ) + + has_output_params = ( + Str('name', label= _('Name')), + Str('sid', label= _('SID')), + ) + + has_output = ( + output.ListOfEntries('result'), + ) + + def execute(self, *keys, **options): + result = list() + if not _nss_idmap_installed: + return dict(result=result) + try: + sids = map(lambda x: str(x), options['sids']) + xlate = pysss_nss_idmap.getnamebysid(sids) + for sid in xlate: + entry = dict() + entry['sid'] = [unicode(sid)] + entry['name'] = [unicode(xlate[sid][pysss_nss_idmap.NAME_KEY])] + entry['type'] = [idmap_type_string(xlate[sid][pysss_nss_idmap.TYPE_KEY])] + result.append(entry) + except ValueError, e: + pass + + return dict(result=result) + +api.register(trust_resolve) |