summaryrefslogtreecommitdiffstats
path: root/ipsilon/info
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-10-09 14:44:04 -0400
committerPatrick Uiterwijk <puiterwijk@redhat.com>2014-10-24 18:03:18 +0200
commitd274763d8dc06b42f70014b14fcb2e852c086751 (patch)
treed27d9caa5ea65440325fbb94c454f4ab1e5b0172 /ipsilon/info
parentf461a713ce28e434a34dca4e4d1abbfe255ef1ff (diff)
downloadipsilon.git-d274763d8dc06b42f70014b14fcb2e852c086751.tar.gz
ipsilon.git-d274763d8dc06b42f70014b14fcb2e852c086751.tar.xz
ipsilon.git-d274763d8dc06b42f70014b14fcb2e852c086751.zip
Add attribute mapping for user information
When user information is retrieved we map any wellknown data to a standardized set of names. A ne InfoMapping class takes cares of helping the info modules to map the data they retrieve so that providers can find it in wellknown attribute names for further use. Mapping of attribute names for diplay purposes is also provided. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
Diffstat (limited to 'ipsilon/info')
-rwxr-xr-xipsilon/info/common.py42
-rwxr-xr-xipsilon/info/infoldap.py54
-rwxr-xr-xipsilon/info/nss.py55
3 files changed, 139 insertions, 12 deletions
diff --git a/ipsilon/info/common.py b/ipsilon/info/common.py
index c4be8fe..92a3ba2 100755
--- a/ipsilon/info/common.py
+++ b/ipsilon/info/common.py
@@ -47,6 +47,48 @@ class InfoProviderBase(PluginObject, Log):
self.debug('Info plugin disabled: %s' % self.name)
+class InfoMapping(Log):
+
+ def __init__(self):
+ self.standard_attributes = {
+ 'fullname': 'Full Name',
+ 'nickname': 'Nickname',
+ 'surname': 'Last Name',
+ 'firstname': 'First Name',
+ 'title': 'Title',
+ 'dob': 'Date of Birth',
+ 'email': 'E-mail Address',
+ 'gender': 'Gender',
+ 'postcode': 'Postal Code',
+ 'street': 'Street Address',
+ 'state': 'State or Province',
+ 'country': 'Country',
+ 'phone': 'Telephone Number',
+ 'language': 'Language',
+ 'timezone': 'Time Zone',
+ }
+ self.mapping = dict()
+
+ def set_mapping(self, attrs_map):
+ self.mapping = attrs_map
+
+ def display_name(self, name):
+ if name in self.standard_attributes:
+ return self.standard_attributes[name]
+ return name
+
+ def map_attrs(self, attrs):
+ s = dict()
+ e = dict()
+ for a in attrs:
+ if a in self.mapping:
+ s[self.mapping[a]] = attrs[a]
+ else:
+ e[a] = attrs[a]
+
+ return s, e
+
+
FACILITY = 'info_config'
diff --git a/ipsilon/info/infoldap.py b/ipsilon/info/infoldap.py
index 6d710bd..fb1c121 100755
--- a/ipsilon/info/infoldap.py
+++ b/ipsilon/info/infoldap.py
@@ -6,15 +6,33 @@
from ipsilon.info.common import InfoProviderBase
from ipsilon.info.common import InfoProviderInstaller
+from ipsilon.info.common import InfoMapping
from ipsilon.util.plugin import PluginObject
from ipsilon.util.log import Log
import ldap
+# TODO: fetch mapping from configuration
+ldap_mapping = {
+ 'cn': 'fullname',
+ 'commonname': 'fullname',
+ 'sn': 'surname',
+ 'mail': 'email',
+ 'destinationindicator': 'country',
+ 'postalcode': 'postcode',
+ 'st': 'state',
+ 'statetorprovincename': 'state',
+ 'streetaddress': 'street',
+ 'telephonenumber': 'phone',
+}
+
+
class InfoProvider(InfoProviderBase, Log):
def __init__(self):
super(InfoProvider, self).__init__()
+ self.mapper = InfoMapping()
+ self.mapper.set_mapping(ldap_mapping)
self.name = 'ldap'
self.description = """
Info plugin that uses LDAP to retrieve user data. """
@@ -92,24 +110,48 @@ Info plugin that uses LDAP to retrieve user data. """
return conn
- def get_user_data_from_conn(self, conn, dn):
+ def _get_user_data(self, conn, dn):
result = conn.search_s(dn, ldap.SCOPE_BASE)
if result is None or result == []:
raise Exception('User object could not be found!')
elif len(result) > 1:
raise Exception('No unique user object could be found!')
- return result[0][1]
+ data = dict()
+ for name, value in result[0][1].iteritems():
+ if type(value) is list and len(value) == 1:
+ value = value[0]
+ data[name] = value
+ return data
+
+ def _get_user_groups(self, conn, dn, ldapattrs):
+ # TODO: fixme to support RFC2307bis schemas
+ if 'memberuid' in ldapattrs:
+ return ldapattrs['memberuid']
+ else:
+ return []
+
+ def get_user_data_from_conn(self, conn, dn):
+ reply = dict()
+ try:
+ ldapattrs = self._get_user_data(conn, dn)
+ userattrs, extras = self.mapper.map_attrs(ldapattrs)
+ groups = self._get_user_groups(conn, dn, ldapattrs)
+ reply['userdata'] = userattrs
+ reply['groups'] = groups
+ reply['extras'] = {'ldap': extras}
+ except Exception, e: # pylint: disable=broad-except
+ self.error(e)
+
+ return reply
def get_user_attrs(self, user):
- userattrs = None
try:
conn = self._ldap_bind()
dn = self.user_dn_tmpl % {'username': user}
- userattrs = self.get_user_data_from_conn(conn, dn)
+ return self.get_user_data_from_conn(conn, dn)
except Exception, e: # pylint: disable=broad-except
self.error(e)
-
- return userattrs
+ return {}
class Installer(InfoProviderInstaller):
diff --git a/ipsilon/info/nss.py b/ipsilon/info/nss.py
index e9a3a96..4208442 100755
--- a/ipsilon/info/nss.py
+++ b/ipsilon/info/nss.py
@@ -6,27 +6,70 @@
from ipsilon.info.common import InfoProviderBase
from ipsilon.info.common import InfoProviderInstaller
+from ipsilon.info.common import InfoMapping
from ipsilon.util.plugin import PluginObject
+import grp
import pwd
+import os
+
+
+posix_map = {
+ 'gecos': 'fullname'
+}
class InfoProvider(InfoProviderBase):
def __init__(self):
super(InfoProvider, self).__init__()
+ self.mapper = InfoMapping()
+ self.mapper.set_mapping(posix_map)
self.name = 'nss'
+ def _get_posix_user(self, user):
+ p = pwd.getpwnam(user)
+ return {'username': p.pw_name, 'uidNumber': p.pw_uid,
+ 'gidNumber': p.pw_gid, 'gecos': p.pw_gecos,
+ 'homeDirectory': p.pw_dir, 'loginShell': p.pw_shell}
+
+ def _get_posix_groups(self, user, group):
+ groups = set()
+ getgrouplist = getattr(os, 'getgrouplist', None)
+ if getgrouplist:
+ ids = getgrouplist(user, group)
+ for i in ids:
+ try:
+ g = grp.getgrgid(i)
+ groups.add(g.gr_name)
+ except KeyError:
+ pass
+
+ else:
+ g = grp.getgrgid(group)
+ groups.add(g.gr_name)
+
+ allg = grp.getgrall()
+ for g in allg:
+ if user in g.gr_mem:
+ groups.add(g.gr_name)
+
+ return list(groups)
+
def get_user_attrs(self, user):
- userattrs = None
+ reply = dict()
try:
- p = pwd.getpwnam(user)
- userattrs = {'uidNumber': p[2], 'gidNumber': p[3],
- 'gecos': p[4], 'homeDirectory': p[5],
- 'loginShell': p[6]}
+ posix_user = self._get_posix_user(user)
+ userattrs, extras = self.mapper.map_attrs(posix_user)
+ groups = self._get_posix_groups(posix_user['username'],
+ posix_user['gidNumber'])
+ reply['userdata'] = userattrs
+ reply['groups'] = groups
+ reply['extras'] = {'posix': extras}
+
except KeyError:
pass
- return userattrs
+ return reply
class Installer(InfoProviderInstaller):