Commit f801e018 authored by ale's avatar ale

Fix configuration of authentication modules

AuthBase.__init__ is passed the top-level Flask configuration object, so
variables should adhere to the standard naming conventions (uppercase,
etc). Use key lookups instead of attributes.
parent 35305f98
...@@ -29,7 +29,7 @@ class AuthBase(object): ...@@ -29,7 +29,7 @@ class AuthBase(object):
supports_otp = False supports_otp = False
def __init__(self, config): def __init__(self, config):
self.config = config pass
def authenticate(self, username, password, otp=None): def authenticate(self, username, password, otp=None):
"""Authenticate a user. """Authenticate a user.
......
...@@ -30,19 +30,19 @@ class Auth(AuthBase): ...@@ -30,19 +30,19 @@ class Auth(AuthBase):
This module knows about the following options: This module knows about the following options:
authclient_server_url AUTHCLIENT_SERVER_URL
The URI of the authserver. The URI of the authserver.
authclient_cert AUTHCLIENT_CERT
File with the SSL client certificate. File with the SSL client certificate.
authclient_key AUTHCLIENT_KEY
File with the SSL client private key. File with the SSL client private key.
authclient_service AUTHCLIENT_SERVICE
Service name for the authclient protocol. Service name for the authclient protocol.
authclient_shard AUTHCLIENT_SHARD
Shard for the authclient protocol (optional). Shard for the authclient protocol (optional).
""" """
...@@ -51,12 +51,12 @@ class Auth(AuthBase): ...@@ -51,12 +51,12 @@ class Auth(AuthBase):
def __init__(self, config): def __init__(self, config):
self._client = authclient.Client( self._client = authclient.Client(
url=config.authclient_server_url, url=config['AUTHCLIENT_SERVER_URL'],
client_cert=config.authclient_cert, client_cert=config['AUTHCLIENT_CERT'],
client_key=config.authclient_key, client_key=config['AUTHCLIENT_KEY'],
) )
self._service = config.authclient_service self._service = config['AUTHCLIENT_SERVICE']
self._shard = config.authclient_shard self._shard = config.get('AUTHCLIENT_SHARD')
def authenticate(self, username, password, otp=None): def authenticate(self, username, password, otp=None):
result = self._client.authenticate( result = self._client.authenticate(
......
...@@ -22,10 +22,13 @@ ...@@ -22,10 +22,13 @@
# OTHER DEALINGS IN THE SOFTWARE. # OTHER DEALINGS IN THE SOFTWARE.
import ldap import ldap
from ldap.dn import escape_dn_chars
import logging import logging
import re import re
from sso_server.auth import AuthBase from sso_server.auth import AuthBase
log = logging.getLogger(__name__)
class Auth(AuthBase): class Auth(AuthBase):
"""LDAP Authentication. """LDAP Authentication.
...@@ -33,37 +36,28 @@ class Auth(AuthBase): ...@@ -33,37 +36,28 @@ class Auth(AuthBase):
The module will attempt to bind as the user with the given credentials. The module will attempt to bind as the user with the given credentials.
It can be configured with a number of options: It can be configured with a number of options:
auth_ldap_uri AUTH_LDAP_URI
The URI of the LDAP server to connect to The URI of the LDAP server to connect to
(default: ldap://localhost:389). (default: ldap://localhost:389).
auth_ldap_base AUTH_LDAP_BASE
Base DN to build the user DN. You will need to specify this. Base DN to build the user DN. You will need to specify this.
auth_ldap_dn_format AUTH_LDAP_RDN_FORMAT
How to build the user part of the DN (default: uid=%s). How to build the RDN (default: uid=%s). The result will be
prepended to AUTH_LDAP_BASE to generate the final DN. The
"%s" token will be replaced by the username.
""" """
def __init__(self, config): def __init__(self, config):
try: self.base = config['AUTH_LDAP_BASE']
self.uri = config.auth_ldap_uri self.uri = config.get('AUTH_LDAP_URI', 'ldap://localhost:389')
except AttributeError: self.rdn_fmt = config.get('AUTH_LDAP_RDN_FORMAT', 'uid=%s')
self.uri = 'ldap://localhost:389'
try:
self.base = config.auth_ldap_base
except AttributeError:
self.base = 'o=Anarchy'
try:
self.rdn_fmt = config.auth_ldap_dn_format
except AttributeError:
self.rdn_fmt = 'uid=%s'
def authenticate(self, username, password, otp=None): def authenticate(self, username, password, otp=None):
if not re.search(r'^[-a-zA-Z0-9.]+$', username): if not username or not password:
return False
if not password:
return False return False
rdn = self.rdn_fmt % username rdn = self.rdn_fmt % escape_dn_chars(username)
dn = '%s,%s' % (rdn, self.base) dn = '%s,%s' % (rdn, self.base)
l = ldap.ldapobject.LDAPObject(self.uri) l = ldap.ldapobject.LDAPObject(self.uri)
result = False result = False
...@@ -72,10 +66,12 @@ class Auth(AuthBase): ...@@ -72,10 +66,12 @@ class Auth(AuthBase):
result = True result = True
except ldap.INVALID_CREDENTIALS: except ldap.INVALID_CREDENTIALS:
pass pass
except Exception, e: except Exception as e:
logging.error('Exception while authenticating %s: %s', username, e) log.error('LDAP error while authenticating %s: %s', username, e)
l.unbind() l.unbind()
return result return result
def match_groups(self, username, groups): def match_groups(self, username, groups):
return groups # TODO: Not implemented. There are too many ways to store
# group membership information in LDAP.
return set()
...@@ -42,16 +42,14 @@ def get_user_groups(username): ...@@ -42,16 +42,14 @@ def get_user_groups(username):
class Auth(AuthBase): class Auth(AuthBase):
"""PAM-based authentication. """PAM-based authentication.
Uses PAM to authenticate users. The default service is 'sso', but Uses PAM to authenticate users. The default service is 'sso', but you can
you can use a different one specifying the 'auth_pam_service' variable use a different one specifying the AUTH_PAM_SERVICE variable in the
in the configuration file. configuration.
""" """
def __init__(self, config): def __init__(self, config):
try: self.service = config.get('AUTH_PAM_SERVICE', 'sso')
self.service = config.auth_pam_service
except AttributeError:
self.service = "sso"
def authenticate(self, username, password, otp=None): def authenticate(self, username, password, otp=None):
pam = PAM.pam() pam = PAM.pam()
......
...@@ -31,9 +31,6 @@ class Auth(AuthBase): ...@@ -31,9 +31,6 @@ class Auth(AuthBase):
and password are equal. It is used only for testing purposes. and password are equal. It is used only for testing purposes.
The user will be granted membership to a set of sample groups. The user will be granted membership to a set of sample groups.
""" """
def __init__(self, config):
self.config = config
def authenticate(self, u, p, otp=None): def authenticate(self, u, p, otp=None):
if u == 'error': if u == 'error':
raise KeyError('blah!') raise KeyError('blah!')
......
...@@ -39,7 +39,7 @@ class LoginService(object): ...@@ -39,7 +39,7 @@ class LoginService(object):
SSO_AUTH_MODULE SSO_AUTH_MODULE
Authentication plugin. This should be the Python module path to Authentication plugin. This should be the Python module path to
something which implements the so_server.auth.AuthBase interface. something which implements the sso_server.auth.AuthBase interface.
ALLOWED_SERVICES ALLOWED_SERVICES
A list of regular expression patterns defining the services A list of regular expression patterns defining the services
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment