|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 |
|
13 __docformat__ = 'restructuredtext' |
|
14 |
|
15 |
|
16 # import standard library |
|
17 from ldap3 import SEARCH_SCOPE_BASE_OBJECT, SEARCH_SCOPE_SINGLE_LEVEL, SEARCH_SCOPE_WHOLE_SUBTREE |
|
18 |
|
19 # import interfaces |
|
20 from pyams_security.interfaces import IAuthenticationPlugin, IDirectorySearchPlugin |
|
21 |
|
22 # import packages |
|
23 from zope.schema import TextLine, Bool, Int, Choice |
|
24 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm |
|
25 |
|
26 from pyams_ldap import _ |
|
27 |
|
28 |
|
29 SEARCH_SCOPES = {SEARCH_SCOPE_BASE_OBJECT: _("Base object"), |
|
30 SEARCH_SCOPE_SINGLE_LEVEL: _("Single level"), |
|
31 SEARCH_SCOPE_WHOLE_SUBTREE: _("Whole subtree")} |
|
32 |
|
33 SEARCH_SCOPES_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t) for v, t in SEARCH_SCOPES.items()]) |
|
34 |
|
35 |
|
36 class ILDAPPlugin(IAuthenticationPlugin, IDirectorySearchPlugin): |
|
37 """LDAP authentication plug-in interface""" |
|
38 |
|
39 server_uri = TextLine(title=_("LDAP server URI"), |
|
40 description=_("Full URI (including protocol) of LDAP server"), |
|
41 default="ldap://localhost:389", |
|
42 required=True) |
|
43 |
|
44 bind_dn = TextLine(title=_("Bind DN"), |
|
45 description=_("DN used for LDAP bind; keep empty for anonymous"), |
|
46 required=False) |
|
47 |
|
48 bind_password = TextLine(title=_("Bind password"), |
|
49 description=_("Password used for LDAP bind"), |
|
50 required=False) |
|
51 |
|
52 use_tls = Bool(title=_("Use TLS?"), |
|
53 required=True, |
|
54 default=False) |
|
55 |
|
56 use_pool = Bool(title=_("Use connections pool?"), |
|
57 required=True, |
|
58 default=True) |
|
59 |
|
60 pool_size = Int(title=_("Pool size"), |
|
61 required=False, |
|
62 default=10) |
|
63 |
|
64 pool_lifetime = Int(title=_("Pool lifetime"), |
|
65 description=_("Duration, in seconds, of pool lifetime"), |
|
66 required=False) |
|
67 |
|
68 base_dn = TextLine(title=_("Base DN"), |
|
69 description=_("LDAP base DN"), |
|
70 required=True) |
|
71 |
|
72 search_scope = Choice(title=_("Search scope"), |
|
73 vocabulary=SEARCH_SCOPES_VOCABULARY, |
|
74 default=SEARCH_SCOPE_WHOLE_SUBTREE, |
|
75 required=True) |
|
76 |
|
77 login_attribute = TextLine(title=_("Login attribute"), |
|
78 description=_("LDAP attribute used as user login"), |
|
79 required=True, |
|
80 default='uid') |
|
81 |
|
82 login_query = TextLine(title=_("Login query"), |
|
83 description=_("Query template used to authenticate user " |
|
84 "(based on login attribute called 'login')"), |
|
85 required=True, |
|
86 default='(uid={login})') |
|
87 |
|
88 uid_attribute = TextLine(title=_("UID attribute"), |
|
89 description=_("LDAP attribute used as principal identifier"), |
|
90 required=True, |
|
91 default='dn') |
|
92 |
|
93 uid_query = TextLine(title=_("UID query"), |
|
94 description=_("Query template used to get principal information " |
|
95 "(based on UID attribute called 'login')"), |
|
96 required=True, |
|
97 default="(objectClass=*)") |
|
98 |
|
99 title_format = TextLine(title=_("Title format"), |
|
100 description=_("Principal's title format string"), |
|
101 required=True, |
|
102 default='{givenName[0]} {sn[0]}') |
|
103 |
|
104 groups_base_dn = TextLine(title=_("Groups base DN"), |
|
105 description=_("Base DN used to search LDAP groups; keep empty to " |
|
106 "disable groups usage"), |
|
107 required=False) |
|
108 |
|
109 groups_search_scope = Choice(title=_("Groups search scope"), |
|
110 vocabulary=SEARCH_SCOPES_VOCABULARY, |
|
111 default=SEARCH_SCOPE_WHOLE_SUBTREE, |
|
112 required=False) |
|
113 |
|
114 groups_query = TextLine(title=_("Groups query"), |
|
115 description=_("Query template used to get principal groups " |
|
116 "(based on DN and UID attributes called 'dn' " |
|
117 "and 'login')"), |
|
118 required=False, |
|
119 default="(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))") |
|
120 |
|
121 group_prefix = TextLine(title=_("Group prefix"), |
|
122 description=_("Prefix used to identify groups"), |
|
123 required=False, |
|
124 default='group') |
|
125 |
|
126 group_uid_attribute = TextLine(title=_("Group UID attribute"), |
|
127 description=_("LDAP attribute used as group identifier"), |
|
128 required=False, |
|
129 default='dn') |
|
130 |
|
131 group_title_format = TextLine(title=_("Group title format"), |
|
132 description=_("Principal's title format string"), |
|
133 required=True, |
|
134 default='{cn[0]}') |
|
135 |
|
136 users_select_query = TextLine(title=_("Users select query"), |
|
137 description=_("Query template used to select users"), |
|
138 required=True, |
|
139 default='(|(givenName={query}*)(sn={query}*))') |
|
140 |
|
141 users_search_query = TextLine(title=_("Users search query"), |
|
142 description=_("Query template used to search users"), |
|
143 required=True, |
|
144 default='(|(givenName={query}*)(sn={query}*))') |
|
145 |
|
146 groups_select_query = TextLine(title=_("Groups select query"), |
|
147 description=_("Query template used to select groups"), |
|
148 required=True, |
|
149 default='(cn=*{query}*)') |
|
150 |
|
151 groups_search_query = TextLine(title=_("Groups search query"), |
|
152 description=_("Query template used to search groups"), |
|
153 required=True, |
|
154 default='(cn=*{query}*)') |
|
155 |
|
156 def get_connection(self): |
|
157 """Get LDAP connection""" |