auth: refactor code and simplified instructions.
- added new rfc selector - cleanup imports
This commit is contained in:
parent
8c73a665d3
commit
8ceda76718
12 changed files with 81 additions and 51 deletions
|
|
@ -627,3 +627,21 @@ def authenticate(username, password, environ=None, auth_type=None,
|
|||
log.debug("User `%s` failed to authenticate against %s",
|
||||
display_user, plugin.get_id())
|
||||
return None
|
||||
|
||||
|
||||
def chop_at(s, sub, inclusive=False):
|
||||
"""Truncate string ``s`` at the first occurrence of ``sub``.
|
||||
|
||||
If ``inclusive`` is true, truncate just after ``sub`` rather than at it.
|
||||
|
||||
>>> chop_at("plutocratic brats", "rat")
|
||||
'plutoc'
|
||||
>>> chop_at("plutocratic brats", "rat", True)
|
||||
'plutocrat'
|
||||
"""
|
||||
pos = s.find(sub)
|
||||
if pos == -1:
|
||||
return s
|
||||
if inclusive:
|
||||
return s[:pos+len(sub)]
|
||||
return s[:pos]
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@ import base64
|
|||
import logging
|
||||
import urllib2
|
||||
|
||||
from pylons.i18n.translation import lazy_ugettext as _
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeExternalAuthPlugin, hybrid_property)
|
||||
from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.colander_utils import strip_whitespace
|
||||
|
|
|
|||
|
|
@ -21,15 +21,14 @@
|
|||
import colander
|
||||
import logging
|
||||
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeExternalAuthPlugin, hybrid_property)
|
||||
from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.colander_utils import strip_whitespace
|
||||
from rhodecode.lib.utils2 import str2bool, safe_unicode
|
||||
from rhodecode.model.db import User
|
||||
from rhodecode.translation import _
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@ import rhodecode
|
|||
import urllib
|
||||
import urllib2
|
||||
|
||||
from pylons.i18n.translation import lazy_ugettext as _
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeExternalAuthPlugin, hybrid_property)
|
||||
from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.colander_utils import strip_whitespace
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@ import colander
|
|||
import logging
|
||||
import traceback
|
||||
|
||||
from pylons.i18n.translation import lazy_ugettext as _
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeExternalAuthPlugin, chop_at, hybrid_property)
|
||||
from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.colander_utils import strip_whitespace
|
||||
|
|
@ -72,14 +71,15 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
host = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('Host of the LDAP Server'),
|
||||
description=_('Host of the LDAP Server \n'
|
||||
'(e.g., 192.168.2.154, or ldap-server.domain.com'),
|
||||
preparer=strip_whitespace,
|
||||
title=_('LDAP Host'),
|
||||
widget='string')
|
||||
port = colander.SchemaNode(
|
||||
colander.Int(),
|
||||
default=389,
|
||||
description=_('Port that the LDAP server is listening on'),
|
||||
description=_('Custom port that the LDAP server is listening on. Default: 389'),
|
||||
preparer=strip_whitespace,
|
||||
title=_('Port'),
|
||||
validator=colander.Range(min=0, max=65536),
|
||||
|
|
@ -87,7 +87,9 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
dn_user = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('User to connect to LDAP'),
|
||||
description=_('Optional user DN/account to connect to LDAP if authentication is required. \n'
|
||||
'e.g., cn=admin,dc=mydomain,dc=com, or '
|
||||
'uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('Account'),
|
||||
|
|
@ -95,7 +97,7 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
dn_pass = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('Password to connect to LDAP'),
|
||||
description=_('Password to authenticate for given user DN.'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('Password'),
|
||||
|
|
@ -117,7 +119,9 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
base_dn = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('Base DN to search (e.g., dc=mydomain,dc=com)'),
|
||||
description=_('Base DN to search. Dynamic bind is supported. Add `$login` marker '
|
||||
'in it to be replaced with current user credentials \n'
|
||||
'(e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com)'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('Base DN'),
|
||||
|
|
@ -125,22 +129,25 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
filter = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('Filter to narrow results (e.g., ou=Users, etc)'),
|
||||
description=_('Filter to narrow results \n'
|
||||
'(e.g., (&(objectCategory=Person)(objectClass=user)), or \n'
|
||||
'(memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com)))'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('LDAP Search Filter'),
|
||||
widget='string')
|
||||
|
||||
search_scope = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default=search_scope_choices[0],
|
||||
description=_('How deep to search LDAP'),
|
||||
default=search_scope_choices[2],
|
||||
description=_('How deep to search LDAP. If unsure set to SUBTREE'),
|
||||
title=_('LDAP Search Scope'),
|
||||
validator=colander.OneOf(search_scope_choices),
|
||||
widget='select')
|
||||
attr_login = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('LDAP Attribute to map to user name'),
|
||||
default='uid',
|
||||
description=_('LDAP Attribute to map to user name (e.g., uid, or sAMAccountName)'),
|
||||
preparer=strip_whitespace,
|
||||
title=_('Login Attribute'),
|
||||
missing_msg=_('The LDAP Login attribute of the CN must be specified'),
|
||||
|
|
@ -148,7 +155,7 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
attr_firstname = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('LDAP Attribute to map to first name'),
|
||||
description=_('LDAP Attribute to map to first name (e.g., givenName)'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('First Name Attribute'),
|
||||
|
|
@ -156,7 +163,7 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
attr_lastname = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('LDAP Attribute to map to last name'),
|
||||
description=_('LDAP Attribute to map to last name (e.g., sn)'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('Last Name Attribute'),
|
||||
|
|
@ -164,7 +171,9 @@ class LdapSettingsSchema(AuthnPluginSettingsSchemaBase):
|
|||
attr_email = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default='',
|
||||
description=_('LDAP Attribute to map to email address'),
|
||||
description=_('LDAP Attribute to map to email address (e.g., mail).\n'
|
||||
'Emails are a crucial part of RhodeCode. \n'
|
||||
'If possible add a valid email attribute to ldap users.'),
|
||||
missing='',
|
||||
preparer=strip_whitespace,
|
||||
title=_('Email Attribute'),
|
||||
|
|
@ -182,7 +191,7 @@ class AuthLdap(object):
|
|||
def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='',
|
||||
tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3,
|
||||
search_scope='SUBTREE', attr_login='uid',
|
||||
ldap_filter='(&(objectClass=user)(!(objectClass=computer)))'):
|
||||
ldap_filter=None):
|
||||
if ldap == Missing:
|
||||
raise LdapImportError("Missing or incompatible ldap library")
|
||||
|
||||
|
|
@ -236,14 +245,13 @@ class AuthLdap(object):
|
|||
server.start_tls_s()
|
||||
|
||||
if self.LDAP_BIND_DN and self.LDAP_BIND_PASS:
|
||||
log.debug('Trying simple_bind with password and given DN: %s',
|
||||
log.debug('Trying simple_bind with password and given login DN: %s',
|
||||
self.LDAP_BIND_DN)
|
||||
server.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS)
|
||||
|
||||
return server
|
||||
|
||||
def get_uid(self, username):
|
||||
from rhodecode.lib.helpers import chop_at
|
||||
uid = username
|
||||
for server_addr in self.SERVER_ADDRESSES:
|
||||
uid = chop_at(username, "@%s" % server_addr)
|
||||
|
|
@ -292,8 +300,11 @@ class AuthLdap(object):
|
|||
self.BASE_DN, self.SEARCH_SCOPE, filter_)
|
||||
|
||||
if not lobjects:
|
||||
log.debug("No matching LDAP objects for authentication "
|
||||
"of UID:'%s' username:(%s)", uid, username)
|
||||
raise ldap.NO_SUCH_OBJECT()
|
||||
|
||||
log.debug('Found matching ldap object, trying to authenticate')
|
||||
for (dn, _attrs) in lobjects:
|
||||
if dn is None:
|
||||
continue
|
||||
|
|
@ -304,15 +315,13 @@ class AuthLdap(object):
|
|||
break
|
||||
|
||||
else:
|
||||
log.debug("No matching LDAP objects for authentication "
|
||||
"of '%s' (%s)", uid, username)
|
||||
raise LdapPasswordError('Failed to authenticate user '
|
||||
'with given password')
|
||||
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
log.debug("LDAP says no such user '%s' (%s), org_exc:",
|
||||
uid, username, exc_info=True)
|
||||
raise LdapUsernameError()
|
||||
raise LdapUsernameError('Unable to find user')
|
||||
except ldap.SERVER_DOWN:
|
||||
org_exc = traceback.format_exc()
|
||||
raise LdapConnectionError(
|
||||
|
|
@ -447,7 +456,7 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin):
|
|||
'email': get_ldap_attr('attr_email') or email,
|
||||
'admin': admin,
|
||||
'active': active,
|
||||
"active_from_extern": None,
|
||||
'active_from_extern': None,
|
||||
'extern_name': user_dn,
|
||||
'extern_type': extern_type,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
"""
|
||||
RhodeCode authentication library for PAM
|
||||
"""
|
||||
|
|
@ -29,10 +30,9 @@ import pwd
|
|||
import re
|
||||
import socket
|
||||
|
||||
from pylons.i18n.translation import lazy_ugettext as _
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeExternalAuthPlugin, hybrid_property)
|
||||
from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.colander_utils import strip_whitespace
|
||||
|
|
|
|||
|
|
@ -25,9 +25,8 @@ RhodeCode authentication plugin for built in internal auth
|
|||
import logging
|
||||
|
||||
from pylons.i18n.translation import lazy_ugettext as _
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.authentication.base import RhodeCodeAuthPluginBase
|
||||
from rhodecode.authentication.base import RhodeCodeAuthPluginBase, hybrid_property
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.lib.utils2 import safe_str
|
||||
from rhodecode.model.db import User
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@ RhodeCode authentication token plugin for built in internal auth
|
|||
|
||||
import logging
|
||||
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.authentication.base import RhodeCodeAuthPluginBase, VCS_TYPE
|
||||
from rhodecode.authentication.base import (
|
||||
RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property)
|
||||
from rhodecode.authentication.routes import AuthnPluginResourceBase
|
||||
from rhodecode.model.db import User, UserApiKeys
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,11 @@ class AuthnPluginSettingsSchemaBase(colander.MappingSchema):
|
|||
cache_ttl = colander.SchemaNode(
|
||||
colander.Int(),
|
||||
default=0,
|
||||
description=_('Amount of seconds to cache the authentication '
|
||||
'call for this plugin. Useful for long calls like '
|
||||
'LDAP to improve the responsiveness of the '
|
||||
'authentication system (0 means disabled).'),
|
||||
description=_('Amount of seconds to cache the authentication response'
|
||||
'call for this plugin. \n'
|
||||
'Useful for long calls like LDAP to improve the '
|
||||
'performance of the authentication system '
|
||||
'(0 means disabled).'),
|
||||
missing=0,
|
||||
title=_('Auth Cache TTL'),
|
||||
validator=colander.Range(min=0, max=None),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,12 @@ class RhodecodeEvent(object):
|
|||
def actor(self):
|
||||
auth_user = self.auth_user
|
||||
if auth_user:
|
||||
return auth_user.get_instance()
|
||||
instance = auth_user.get_instance()
|
||||
if not instance:
|
||||
return AttributeDict(dict(
|
||||
username=auth_user.username
|
||||
))
|
||||
|
||||
return SYSTEM_USER
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
.help-block {
|
||||
display: block;
|
||||
margin-left: @label-width;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.action_button {
|
||||
|
|
@ -116,7 +117,7 @@
|
|||
float: none;
|
||||
margin-left: @label-width;
|
||||
|
||||
.help-block{
|
||||
.help-block {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ $(document).ready(function() {
|
|||
$("#tls_kind").select2(select2Options);
|
||||
$("#tls_reqcert").select2(select2Options);
|
||||
$("#search_scope").select2(select2Options);
|
||||
$("#group_extraction_type").select2(select2Options);
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue