Hi! Attached are patches to allow resolving SIDs in Web UI in external membership panel for groups. Please see more detailed description in the main patch.
I haven't rebased it yet on top of Petr's Web UI rework, hopefully it should be simple. https://fedorahosted.org/freeipa/ticket/3302 Since framework doesn't allow to hide commands from CLI, underlying command is usable from CLI too: # ipa trust-resolve --sids=S-1-5-21-3502988750-125904550-3683905862-{500,512,498} Name: enterprise read-only domain controll...@ad.lan SID: S-1-5-21-3502988750-125904550-3683905862-498 Name: administra...@ad.lan SID: S-1-5-21-3502988750-125904550-3683905862-500 Name: domain adm...@ad.lan SID: S-1-5-21-3502988750-125904550-3683905862-512 -- / Alexander Bokovoy
>From a1cffc2ecc0bba739c3b5a5130f939a90dd0b88e Mon Sep 17 00:00:00 2001 From: Petr Vobornik <pvobo...@redhat.com> Date: Wed, 24 Apr 2013 13:48:07 +0200 Subject: [PATCH 2/3] Column promise support Column setup method can handle promise. It can be supplied directly or encapsulated in a object with temporal value: { promise: promise, temp: 'temp val' } Temporal value is displayed until promise is fulfilled. --- install/ui/src/freeipa/widget.js | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js index 17d9b8b..b55900d 100644 --- a/install/ui/src/freeipa/widget.js +++ b/install/ui/src/freeipa/widget.js @@ -1388,9 +1388,6 @@ IPA.column = function (spec) { } that.setup = function(container, record, suppress_link) { - - container.empty(); - var value = record[that.name]; var type; if (that.formatter) { @@ -1398,7 +1395,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) { -- 1.8.1.4
>From 016d3c827f5f9cdecf0d731a993fe5ad92191b59 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <aboko...@redhat.com> Date: Fri, 3 May 2013 21:26:08 +0300 Subject: [PATCH 1/3] web-ui: fix typo in link highliting --- install/ui/ipa.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/ui/ipa.css b/install/ui/ipa.css index 3e443d5..8afcfb1 100644 --- a/install/ui/ipa.css +++ b/install/ui/ipa.css @@ -779,7 +779,7 @@ div[name=settings].facet-group li a { border: none; } -.search-table > a:link, a:visted { +.search-table > a:link, a:visited { color:black; } -- 1.8.1.4
>From 879d686e5cf274446cf345f24be114d23bdc4db9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <aboko...@redhat.com> Date: Tue, 30 Apr 2013 13:13:25 +0300 Subject: [PATCH 3/3] 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 --- API.txt | 7 ++++++ freeipa.spec.in | 4 +++ install/ui/src/freeipa/association.js | 45 +++++++++++++++++++++++++++++++++- install/ui/src/freeipa/entity.js | 10 +++++++- install/ui/src/freeipa/facet.js | 12 +++++++++ install/ui/src/freeipa/group.js | 6 ++--- ipalib/plugins/trust.py | 46 +++++++++++++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 5 deletions(-) diff --git a/API.txt b/API.txt index c2400e9..e5bb7be 100644 --- a/API.txt +++ b/API.txt @@ -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 36e2a61..1f97418 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 @@ -839,6 +840,9 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt %changelog +* Fri May 03 2013 Alexander Bokovoy <aboko...@redhat.com> - 3.1.99-10 +- Add libsss_nss_idmap-python dependency for SID resolution + * Tue Apr 30 2013 Rob Crittenden <rcrit...@redhat.com> - 3.1.99-9 - Add Conflicts on nss-pam-ldapd < 0.8.4. The mapping from uniqueMember to member is now done automatically and having it in the config file raises diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js index c6b9e5a..dad138f 100644 --- a/install/ui/src/freeipa/association.js +++ b/install/ui/src/freeipa/association.js @@ -22,7 +22,7 @@ /* CURRENTLY ALSO REQUIRES search.js, because it reuses it's code to create * the AssociationList elements; IT NEEDS IT'S OWN CODE! */ -define(['./ipa', './jquery', './search', './dialog'], function(IPA, $) { +define(['dojo/Deferred','./ipa', './jquery', './search', './dialog'], function(Deferred, IPA, $) { IPA.associator = function (spec) { @@ -1355,6 +1355,49 @@ 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(); + + var sids = new Array(); + for(var i=0; i< value.length; i++) { + var sid = value[i][that.attribute]; + var deferred = new Deferred(); + deferred.temp = sid; + value[i][that.attribute] = deferred; + 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 08ba7e5..60fb45e 100644 --- a/install/ui/src/freeipa/entity.js +++ b/install/ui/src/freeipa/entity.js @@ -425,6 +425,14 @@ IPA.entity_builder = function() { return that; }; + that.sid_facet = function(spec) { + + spec.type = spec.type || 'sid'; + + that.facet(spec); + + return that; + }; that.standard_association_facets = function(spec) { spec = spec || {}; @@ -727,4 +735,4 @@ IPA.details_facet_update_policy = function(spec) { }; return {}; -}); \ No newline at end of file +}); diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js index 3ad868e..8517507 100644 --- a/install/ui/src/freeipa/facet.js +++ b/install/ui/src/freeipa/facet.js @@ -1131,6 +1131,7 @@ IPA.facet_builder = function(entity) { that.prepare_methods.details = that.prepare_details_spec; that.prepare_methods.association = that.prepare_association_spec; that.prepare_methods.attribute = that.prepare_attribute_spec; + that.prepare_methods.sid = that.prepare_sid_spec; } that.build_facets = function() { @@ -1271,6 +1272,17 @@ IPA.facet_builder = function(entity) { return false; }; + that.prepare_sid_spec = function(spec) { + spec.title = spec.title || entity.metadata.label_singular; + spec.label = spec.label || entity.metadata.label_singular; + + var attr_metadata = IPA.get_entity_param(entity.name, spec.attribute); + spec.tab_label = spec.tab_label || attr_metadata.label; + spec.factory = spec.factory || IPA.sid_facet; + + return spec; + }; + init(); return that; diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js index a84f49f..dbac380 100644 --- a/install/ui/src/freeipa/group.js +++ b/install/ui/src/freeipa/group.js @@ -105,11 +105,11 @@ IPA.group.entity = function(spec) { name: 'member_external', attribute: 'ipaexternalmember', tab_label: 'External', - facet_group: 'member', + facet_group: 'sid_facet', columns: [ { name: 'ipaexternalmember', - label: IPA.get_command_option('group_add_member', 'ipaexternalmember').label + label: IPA.get_command_option('group_add_member', 'ipaexternalmember').label, } ] @@ -257,4 +257,4 @@ IPA.group.make_external_action = function(spec) { IPA.register('group', IPA.group.entity); return {}; -}); \ No newline at end of file +}); diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py index a252ad6..fa384c7 100644 --- a/ipalib/plugins/trust.py +++ b/ipalib/plugins/trust.py @@ -21,6 +21,7 @@ from ipalib.plugins.baseldap import * from ipalib.plugins.dns import dns_container_exists from ipalib import api, Str, StrEnum, Password, DefaultFrom, _, ngettext, Object +from types import NoneType from ipalib.parameters import Enum from ipalib import Command from ipalib import errors @@ -32,6 +33,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 +694,42 @@ class trustconfig_show(LDAPRetrieve): return dn api.register(trustconfig_show) + +import time +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])] + result.append(entry) + except ValueError, e: + pass + + return dict(result=result) + +api.register(trust_resolve) -- 1.8.1.4
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel