3 # Copyright (C) 2014 Ipsilon Project Contributors
5 # See the file named COPYING for the project license
7 from ipsilon.info.common import InfoProviderBase
8 from ipsilon.info.common import InfoProviderInstaller
9 from ipsilon.util.plugin import PluginObject
10 from ipsilon.util.log import Log
14 class InfoProvider(InfoProviderBase, Log):
17 super(InfoProvider, self).__init__()
19 self.description = """
20 Info plugin that uses LDAP to retrieve user data. """
23 """ The LDAP server url """,
28 " What TLS level show be required " +
29 "(Demand, Allow, Try, Never, NoTLS) ",
34 """ User DN to bind as, if empty uses anonymous bind. """,
36 'uid=ipsilon,ou=People,dc=example,dc=com'
39 """ Password to use for bind operation """,
44 """ Template to turn username into DN. """,
46 'uid=%(username)s,ou=People,dc=example,dc=com'
52 return self.get_config_value('server url')
56 return self.get_config_value('tls')
60 return self.get_config_value('bind dn')
63 def bind_password(self):
64 return self.get_config_value('bind password')
67 def user_dn_tmpl(self):
68 return self.get_config_value('user dn template')
72 tls = self.tls.lower()
75 tls_req_opt = ldap.OPT_X_TLS_NEVER
77 tls_req_opt = ldap.OPT_X_TLS_DEMAND
79 tls_req_opt = ldap.OPT_X_TLS_ALLOW
81 tls_req_opt = ldap.OPT_X_TLS_TRY
82 if tls_req_opt is not None:
83 ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_opt)
85 conn = ldap.initialize(self.server_url)
88 if not self.server_url.startswith("ldaps"):
91 conn.simple_bind_s(self.bind_dn, self.bind_password)
95 def get_user_data_from_conn(self, conn, dn):
96 result = conn.search_s(dn, ldap.SCOPE_BASE)
97 if result is None or result == []:
98 raise Exception('User object could not be found!')
100 raise Exception('No unique user object could be found!')
103 def get_user_attrs(self, user):
106 conn = self._ldap_bind()
107 dn = self.user_dn_tmpl % {'username': user}
108 userattrs = self.get_user_data_from_conn(conn, dn)
109 except Exception, e: # pylint: disable=broad-except
115 class Installer(InfoProviderInstaller):
118 super(Installer, self).__init__()
121 def install_args(self, group):
122 group.add_argument('--info-ldap', choices=['yes', 'no'], default='no',
123 help='Use LDAP to populate user attrs')
124 group.add_argument('--info-ldap-server-url', action='store',
125 help='LDAP Server Url')
126 group.add_argument('--info-ldap-bind-dn', action='store',
128 group.add_argument('--info-ldap-bind-pwd', action='store',
129 help='LDAP Bind Password')
130 group.add_argument('--info-ldap-user-dn-template', action='store',
131 help='LDAP User DN Template')
133 def configure(self, opts):
134 if opts['info_ldap'] != 'yes':
137 # Add configuration data to database
141 po.wipe_config_values(self.facility)
143 if 'info_ldap_server_url' in opts:
144 config['server url'] = opts['info_ldap_server_url']
145 elif 'ldap_server_url' in opts:
146 config['server url'] = opts['ldap_server_url']
147 config = {'bind dn': opts['info_ldap_bind_dn']}
148 config = {'bind password': opts['info_ldap_bind_pwd']}
149 config = {'user dn template': opts['info_ldap_user_dn_template']}
150 if 'info_ldap_bind_dn' in opts:
151 config['bind dn'] = opts['info_ldap_bind_dn']
152 if 'info_ldap_bind_pwd' in opts:
153 config['bind password'] = opts['info_ldap_bind_pwd']
154 if 'info_ldap_user_dn_template' in opts:
155 config['user dn template'] = opts['info_ldap_user_dn_template']
156 elif 'ldap_bind_dn_template' in opts:
157 config['user dn template'] = opts['ldap_bind_dn_template']
158 config['tls'] = 'Demand'
159 po.set_config(config)
160 po.save_plugin_config(self.facility)
162 # Replace global config, only one plugin info can be used
164 globalconf = po.get_plugin_config(self.facility)
165 if 'order' in globalconf:
166 order = globalconf['order'].split(',')
170 globalconf['order'] = ','.join(order)
171 po.set_config(globalconf)
172 po.save_plugin_config(self.facility)