summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2013-05-06 17:10:56 +0200
committerMartin Kosek <mkosek@redhat.com>2013-05-06 20:44:00 +0200
commit03cdc22c940e82199c2afa8b4a69708237ee0a7a (patch)
tree110721c903eb032702f9980e354eec848fcbaef1
parentaedded862dce2c8450d0eef5eca3d854166af06b (diff)
downloadfreeipa-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.txt7
-rw-r--r--freeipa.spec.in1
-rw-r--r--install/ui/src/freeipa/association.js50
-rw-r--r--install/ui/src/freeipa/entity.js2
-rw-r--r--install/ui/src/freeipa/group.js3
-rw-r--r--install/ui/src/freeipa/widget.js30
-rw-r--r--ipalib/plugins/trust.py55
7 files changed, 142 insertions, 6 deletions
diff --git a/API.txt b/API.txt
index c2400e901..e5bb7beb4 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 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)