##// END OF EJS Templates
auth: refactor code and simplified instructions....
marcink -
r1454:01fbc7af default
parent child Browse files
Show More
@@ -627,3 +627,21 b' def authenticate(username, password, env'
627 627 log.debug("User `%s` failed to authenticate against %s",
628 628 display_user, plugin.get_id())
629 629 return None
630
631
632 def chop_at(s, sub, inclusive=False):
633 """Truncate string ``s`` at the first occurrence of ``sub``.
634
635 If ``inclusive`` is true, truncate just after ``sub`` rather than at it.
636
637 >>> chop_at("plutocratic brats", "rat")
638 'plutoc'
639 >>> chop_at("plutocratic brats", "rat", True)
640 'plutocrat'
641 """
642 pos = s.find(sub)
643 if pos == -1:
644 return s
645 if inclusive:
646 return s[:pos+len(sub)]
647 return s[:pos]
@@ -28,10 +28,9 b' import base64'
28 28 import logging
29 29 import urllib2
30 30
31 from pylons.i18n.translation import lazy_ugettext as _
32 from sqlalchemy.ext.hybrid import hybrid_property
33
34 from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
31 from rhodecode.translation import _
32 from rhodecode.authentication.base import (
33 RhodeCodeExternalAuthPlugin, hybrid_property)
35 34 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
36 35 from rhodecode.authentication.routes import AuthnPluginResourceBase
37 36 from rhodecode.lib.colander_utils import strip_whitespace
@@ -21,15 +21,14 b''
21 21 import colander
22 22 import logging
23 23
24 from sqlalchemy.ext.hybrid import hybrid_property
25
26 from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
24 from rhodecode.translation import _
25 from rhodecode.authentication.base import (
26 RhodeCodeExternalAuthPlugin, hybrid_property)
27 27 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
28 28 from rhodecode.authentication.routes import AuthnPluginResourceBase
29 29 from rhodecode.lib.colander_utils import strip_whitespace
30 30 from rhodecode.lib.utils2 import str2bool, safe_unicode
31 31 from rhodecode.model.db import User
32 from rhodecode.translation import _
33 32
34 33
35 34 log = logging.getLogger(__name__)
@@ -30,10 +30,9 b' import rhodecode'
30 30 import urllib
31 31 import urllib2
32 32
33 from pylons.i18n.translation import lazy_ugettext as _
34 from sqlalchemy.ext.hybrid import hybrid_property
35
36 from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
33 from rhodecode.translation import _
34 from rhodecode.authentication.base import (
35 RhodeCodeExternalAuthPlugin, hybrid_property)
37 36 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
38 37 from rhodecode.authentication.routes import AuthnPluginResourceBase
39 38 from rhodecode.lib.colander_utils import strip_whitespace
@@ -27,10 +27,9 b' import colander'
27 27 import logging
28 28 import traceback
29 29
30 from pylons.i18n.translation import lazy_ugettext as _
31 from sqlalchemy.ext.hybrid import hybrid_property
32
33 from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
30 from rhodecode.translation import _
31 from rhodecode.authentication.base import (
32 RhodeCodeExternalAuthPlugin, chop_at, hybrid_property)
34 33 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
35 34 from rhodecode.authentication.routes import AuthnPluginResourceBase
36 35 from rhodecode.lib.colander_utils import strip_whitespace
@@ -72,14 +71,15 b' class LdapSettingsSchema(AuthnPluginSett'
72 71 host = colander.SchemaNode(
73 72 colander.String(),
74 73 default='',
75 description=_('Host of the LDAP Server'),
74 description=_('Host of the LDAP Server \n'
75 '(e.g., 192.168.2.154, or ldap-server.domain.com'),
76 76 preparer=strip_whitespace,
77 77 title=_('LDAP Host'),
78 78 widget='string')
79 79 port = colander.SchemaNode(
80 80 colander.Int(),
81 81 default=389,
82 description=_('Port that the LDAP server is listening on'),
82 description=_('Custom port that the LDAP server is listening on. Default: 389'),
83 83 preparer=strip_whitespace,
84 84 title=_('Port'),
85 85 validator=colander.Range(min=0, max=65536),
@@ -87,7 +87,9 b' class LdapSettingsSchema(AuthnPluginSett'
87 87 dn_user = colander.SchemaNode(
88 88 colander.String(),
89 89 default='',
90 description=_('User to connect to LDAP'),
90 description=_('Optional user DN/account to connect to LDAP if authentication is required. \n'
91 'e.g., cn=admin,dc=mydomain,dc=com, or '
92 'uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com'),
91 93 missing='',
92 94 preparer=strip_whitespace,
93 95 title=_('Account'),
@@ -95,7 +97,7 b' class LdapSettingsSchema(AuthnPluginSett'
95 97 dn_pass = colander.SchemaNode(
96 98 colander.String(),
97 99 default='',
98 description=_('Password to connect to LDAP'),
100 description=_('Password to authenticate for given user DN.'),
99 101 missing='',
100 102 preparer=strip_whitespace,
101 103 title=_('Password'),
@@ -117,7 +119,9 b' class LdapSettingsSchema(AuthnPluginSett'
117 119 base_dn = colander.SchemaNode(
118 120 colander.String(),
119 121 default='',
120 description=_('Base DN to search (e.g., dc=mydomain,dc=com)'),
122 description=_('Base DN to search. Dynamic bind is supported. Add `$login` marker '
123 'in it to be replaced with current user credentials \n'
124 '(e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com)'),
121 125 missing='',
122 126 preparer=strip_whitespace,
123 127 title=_('Base DN'),
@@ -125,22 +129,25 b' class LdapSettingsSchema(AuthnPluginSett'
125 129 filter = colander.SchemaNode(
126 130 colander.String(),
127 131 default='',
128 description=_('Filter to narrow results (e.g., ou=Users, etc)'),
132 description=_('Filter to narrow results \n'
133 '(e.g., (&(objectCategory=Person)(objectClass=user)), or \n'
134 '(memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com)))'),
129 135 missing='',
130 136 preparer=strip_whitespace,
131 137 title=_('LDAP Search Filter'),
132 138 widget='string')
139
133 140 search_scope = colander.SchemaNode(
134 141 colander.String(),
135 default=search_scope_choices[0],
136 description=_('How deep to search LDAP'),
142 default=search_scope_choices[2],
143 description=_('How deep to search LDAP. If unsure set to SUBTREE'),
137 144 title=_('LDAP Search Scope'),
138 145 validator=colander.OneOf(search_scope_choices),
139 146 widget='select')
140 147 attr_login = colander.SchemaNode(
141 148 colander.String(),
142 default='',
143 description=_('LDAP Attribute to map to user name'),
149 default='uid',
150 description=_('LDAP Attribute to map to user name (e.g., uid, or sAMAccountName)'),
144 151 preparer=strip_whitespace,
145 152 title=_('Login Attribute'),
146 153 missing_msg=_('The LDAP Login attribute of the CN must be specified'),
@@ -148,7 +155,7 b' class LdapSettingsSchema(AuthnPluginSett'
148 155 attr_firstname = colander.SchemaNode(
149 156 colander.String(),
150 157 default='',
151 description=_('LDAP Attribute to map to first name'),
158 description=_('LDAP Attribute to map to first name (e.g., givenName)'),
152 159 missing='',
153 160 preparer=strip_whitespace,
154 161 title=_('First Name Attribute'),
@@ -156,7 +163,7 b' class LdapSettingsSchema(AuthnPluginSett'
156 163 attr_lastname = colander.SchemaNode(
157 164 colander.String(),
158 165 default='',
159 description=_('LDAP Attribute to map to last name'),
166 description=_('LDAP Attribute to map to last name (e.g., sn)'),
160 167 missing='',
161 168 preparer=strip_whitespace,
162 169 title=_('Last Name Attribute'),
@@ -164,7 +171,9 b' class LdapSettingsSchema(AuthnPluginSett'
164 171 attr_email = colander.SchemaNode(
165 172 colander.String(),
166 173 default='',
167 description=_('LDAP Attribute to map to email address'),
174 description=_('LDAP Attribute to map to email address (e.g., mail).\n'
175 'Emails are a crucial part of RhodeCode. \n'
176 'If possible add a valid email attribute to ldap users.'),
168 177 missing='',
169 178 preparer=strip_whitespace,
170 179 title=_('Email Attribute'),
@@ -182,7 +191,7 b' class AuthLdap(object):'
182 191 def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='',
183 192 tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3,
184 193 search_scope='SUBTREE', attr_login='uid',
185 ldap_filter='(&(objectClass=user)(!(objectClass=computer)))'):
194 ldap_filter=None):
186 195 if ldap == Missing:
187 196 raise LdapImportError("Missing or incompatible ldap library")
188 197
@@ -236,14 +245,13 b' class AuthLdap(object):'
236 245 server.start_tls_s()
237 246
238 247 if self.LDAP_BIND_DN and self.LDAP_BIND_PASS:
239 log.debug('Trying simple_bind with password and given DN: %s',
248 log.debug('Trying simple_bind with password and given login DN: %s',
240 249 self.LDAP_BIND_DN)
241 250 server.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS)
242 251
243 252 return server
244 253
245 254 def get_uid(self, username):
246 from rhodecode.lib.helpers import chop_at
247 255 uid = username
248 256 for server_addr in self.SERVER_ADDRESSES:
249 257 uid = chop_at(username, "@%s" % server_addr)
@@ -292,8 +300,11 b' class AuthLdap(object):'
292 300 self.BASE_DN, self.SEARCH_SCOPE, filter_)
293 301
294 302 if not lobjects:
303 log.debug("No matching LDAP objects for authentication "
304 "of UID:'%s' username:(%s)", uid, username)
295 305 raise ldap.NO_SUCH_OBJECT()
296 306
307 log.debug('Found matching ldap object, trying to authenticate')
297 308 for (dn, _attrs) in lobjects:
298 309 if dn is None:
299 310 continue
@@ -304,15 +315,13 b' class AuthLdap(object):'
304 315 break
305 316
306 317 else:
307 log.debug("No matching LDAP objects for authentication "
308 "of '%s' (%s)", uid, username)
309 318 raise LdapPasswordError('Failed to authenticate user '
310 319 'with given password')
311 320
312 321 except ldap.NO_SUCH_OBJECT:
313 322 log.debug("LDAP says no such user '%s' (%s), org_exc:",
314 323 uid, username, exc_info=True)
315 raise LdapUsernameError()
324 raise LdapUsernameError('Unable to find user')
316 325 except ldap.SERVER_DOWN:
317 326 org_exc = traceback.format_exc()
318 327 raise LdapConnectionError(
@@ -447,7 +456,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
447 456 'email': get_ldap_attr('attr_email') or email,
448 457 'admin': admin,
449 458 'active': active,
450 "active_from_extern": None,
459 'active_from_extern': None,
451 460 'extern_name': user_dn,
452 461 'extern_type': extern_type,
453 462 }
@@ -17,6 +17,7 b''
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20 21 """
21 22 RhodeCode authentication library for PAM
22 23 """
@@ -29,10 +30,9 b' import pwd'
29 30 import re
30 31 import socket
31 32
32 from pylons.i18n.translation import lazy_ugettext as _
33 from sqlalchemy.ext.hybrid import hybrid_property
34
35 from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
33 from rhodecode.translation import _
34 from rhodecode.authentication.base import (
35 RhodeCodeExternalAuthPlugin, hybrid_property)
36 36 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
37 37 from rhodecode.authentication.routes import AuthnPluginResourceBase
38 38 from rhodecode.lib.colander_utils import strip_whitespace
@@ -25,9 +25,8 b' RhodeCode authentication plugin for buil'
25 25 import logging
26 26
27 27 from pylons.i18n.translation import lazy_ugettext as _
28 from sqlalchemy.ext.hybrid import hybrid_property
29 28
30 from rhodecode.authentication.base import RhodeCodeAuthPluginBase
29 from rhodecode.authentication.base import RhodeCodeAuthPluginBase, hybrid_property
31 30 from rhodecode.authentication.routes import AuthnPluginResourceBase
32 31 from rhodecode.lib.utils2 import safe_str
33 32 from rhodecode.model.db import User
@@ -24,10 +24,9 b' RhodeCode authentication token plugin fo'
24 24
25 25 import logging
26 26
27 from sqlalchemy.ext.hybrid import hybrid_property
28
29 27 from rhodecode.translation import _
30 from rhodecode.authentication.base import RhodeCodeAuthPluginBase, VCS_TYPE
28 from rhodecode.authentication.base import (
29 RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property)
31 30 from rhodecode.authentication.routes import AuthnPluginResourceBase
32 31 from rhodecode.model.db import User, UserApiKeys
33 32
@@ -40,10 +40,11 b' class AuthnPluginSettingsSchemaBase(cola'
40 40 cache_ttl = colander.SchemaNode(
41 41 colander.Int(),
42 42 default=0,
43 description=_('Amount of seconds to cache the authentication '
44 'call for this plugin. Useful for long calls like '
45 'LDAP to improve the responsiveness of the '
46 'authentication system (0 means disabled).'),
43 description=_('Amount of seconds to cache the authentication response'
44 'call for this plugin. \n'
45 'Useful for long calls like LDAP to improve the '
46 'performance of the authentication system '
47 '(0 means disabled).'),
47 48 missing=0,
48 49 title=_('Auth Cache TTL'),
49 50 validator=colander.Range(min=0, max=None),
@@ -57,7 +57,12 b' class RhodecodeEvent(object):'
57 57 def actor(self):
58 58 auth_user = self.auth_user
59 59 if auth_user:
60 return auth_user.get_instance()
60 instance = auth_user.get_instance()
61 if not instance:
62 return AttributeDict(dict(
63 username=auth_user.username
64 ))
65
61 66 return SYSTEM_USER
62 67
63 68 @property
@@ -61,6 +61,7 b''
61 61 .help-block {
62 62 display: block;
63 63 margin-left: @label-width;
64 white-space: pre;
64 65 }
65 66
66 67 .action_button {
@@ -116,7 +117,7 b''
116 117 float: none;
117 118 margin-left: @label-width;
118 119
119 .help-block{
120 .help-block {
120 121 margin-left: 0;
121 122 }
122 123 }
@@ -111,6 +111,7 b''
111 111 $("#tls_kind").select2(select2Options);
112 112 $("#tls_reqcert").select2(select2Options);
113 113 $("#search_scope").select2(select2Options);
114 $("#group_extraction_type").select2(select2Options);
114 115 });
115 116 </script>
116 117 </%def>
General Comments 0
You need to be logged in to leave comments. Login now