summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-06-29 02:52:50 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-06-29 02:52:50 -0400
commit33fb5deb70373f251788b257e9fa0cbe16849b95 (patch)
treeaa4ee325a83e02ad0c95ff31b76029bf9a13a0b3
parent5f055c4b2cae52325817ffa1153e3c97f6d62c44 (diff)
downloadaskbot-33fb5deb70373f251788b257e9fa0cbe16849b95.tar.gz
askbot-33fb5deb70373f251788b257e9fa0cbe16849b95.tar.bz2
askbot-33fb5deb70373f251788b257e9fa0cbe16849b95.zip
another change in the LDAP protocol
-rw-r--r--askbot/conf/ldap.py91
-rw-r--r--askbot/deps/django_authopenid/backends.py80
2 files changed, 139 insertions, 32 deletions
diff --git a/askbot/conf/ldap.py b/askbot/conf/ldap.py
index 00c8a5fc..ae916313 100644
--- a/askbot/conf/ldap.py
+++ b/askbot/conf/ldap.py
@@ -50,8 +50,27 @@ settings.register(
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
- 'LDAP_BASEDN',
- description=_('LDAP BASE DN')
+ 'LDAP_ENCODING',
+ description = _('LDAP encoding'),
+ default = 'utf-8',
+ help_text = _(
+ 'This value in almost all cases is "utf-8". '
+ 'Change it if yours is different. '
+ 'This field is required'
+ )
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ LDAP_SETTINGS,
+ 'LDAP_BASE_DN',
+ description=_('Base DN (distinguished name)'),
+ help_text = _(
+ 'Usually base DN mirrors domain name of your organization, '
+ 'e.g. "dn=example,dn=com" when your site url is "example.com".'
+ 'This value is the "root" address of your LDAP directory.'
+ )
)
)
@@ -62,7 +81,26 @@ settings.register(
description = _('User search filter template'),
default = '(%s=%s)',
help_text = _(
- 'Python string format template, must have two string placeholders'
+ 'Python string format template, must have two string placeholders, '
+ 'which should be left in the intact format. '
+ 'First placeholder will be used for the user id field name, '
+ 'and the second - for the user id value. '
+ 'The template can be extended to match schema of your '
+ 'LDAP directory.'
+ )
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ LDAP_SETTINGS,
+ 'LDAP_LOGIN_NAME_FIELD',
+ description = _('UserID/login field'),
+ default = 'uid',
+ help_text = _(
+ 'This field is required. '
+ 'For Microsoft Active Directory this value usually '
+ 'is "sAMAccountName".'
)
)
)
@@ -70,27 +108,51 @@ settings.register(
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
- 'LDAP_SEARCH_SCOPE',
- description=_('LDAP Search Scope'),
- default="subs"
+ 'LDAP_COMMON_NAME_FIELD',
+ description=_('"Common Name" field'),
+ help_text=_(
+ 'Common name is a formal or informal name '
+ 'of a person, can be blank. '
+ 'Use it only if surname and given names are not '
+ 'available.'
+ ),
+ default = 'cn'
+ )
+)
+
+COMMON_NAME_FIELD_FORMAT_CHOICES = (
+ ('first,last', _('First name, Last name')),
+ ('last,first', _('Last name, First name')),
+)
+
+settings.register(
+ livesettings.StringValue(
+ LDAP_SETTINGS,
+ 'LDAP_COMMON_NAME_FIELD_FORMAT',
+ description = _('"Common Name" field format'),
+ default = 'first,last',
+ choices = COMMON_NAME_FIELD_FORMAT_CHOICES,
+ help_text = _('Use this only if "Common Name" field is used.')
)
)
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
- 'LDAP_USERID_FIELD',
- description=_('LDAP Server USERID field name'),
- default="uid"
+ 'LDAP_GIVEN_NAME_FIELD',
+ description = _('Given (First) name'),
+ default = 'givenName',
+ help_text = _('This field can be blank')
)
)
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
- 'LDAP_COMMONNAME_FIELD',
- description=_('LDAP Server "Common Name" field name'),
- default="cn"
+ 'LDAP_SURNAME_FIELD',
+ description = _('Surname (last) name'),
+ default = 'sn',
+ help_text = _('This field can be blank')
)
)
@@ -98,8 +160,9 @@ settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
'LDAP_EMAIL_FIELD',
- description=_('LDAP Server EMAIL field name'),
- default="mail"
+ description = _('LDAP Server EMAIL field name'),
+ default = 'mail',
+ help_text = _('This field is required')
)
)
diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py
index 01a19e4d..5ff49c1b 100644
--- a/askbot/deps/django_authopenid/backends.py
+++ b/askbot/deps/django_authopenid/backends.py
@@ -15,6 +15,20 @@ from askbot.models.signals import user_registered
log = logging.getLogger('configuration')
+def split_name(full_name, name_format):
+ bits = full_name.strip().split()
+ if len(bits) == 1:
+ bits.push('')
+ elif len(bits) == 0:
+ bits = ['', '']
+
+ if name_format == 'first,last':
+ return bits[0], bits[1]
+ elif name_format == 'last,first':
+ return bits[1], bits[0]
+ else:
+ raise ValueError('Unexpected value of name_format')
+
def ldap_authenticate(username, password):
"""
@@ -26,8 +40,6 @@ def ldap_authenticate(username, password):
import ldap
user_information = None
try:
- import pdb
- pdb.set_trace()
ldap_session = ldap.initialize(askbot_settings.LDAP_URL)
#set protocol version
@@ -38,6 +50,8 @@ def ldap_authenticate(username, password):
else:
raise NotImplementedError('unsupported version of ldap protocol')
+ ldap.set_option(ldap.OPT_REFERRALS, 0)
+
#set extra ldap options, if given
if hasattr(django_settings, 'LDAP_EXTRA_OPTIONS'):
options = django_settings.LDAP_EXTRA_OPTIONS
@@ -51,38 +65,68 @@ def ldap_authenticate(username, password):
#add optional "master" LDAP authentication, if required
master_username = getattr(django_settings, 'LDAP_USER', None)
master_password = getattr(django_settings, 'LDAP_PASSWORD', None)
+
+ login_name_field = askbot_settings.LDAP_LOGIN_NAME_FIELD
+ base_dn = askbot_settings.LDAP_BASE_DN
+ login_template = login_name_field + '=%s,' + base_dn
+ encoding = askbot_settings.LDAP_ENCODING
+
if master_username and master_password:
- ldap_session.simple_bind_s(master_username, master_password)
+ login_dn = login_template % master_username
+ ldap_session.simple_bind_s(
+ login_dn.encode(encoding),
+ master_password.encode(encoding)
+ )
user_filter = askbot_settings.LDAP_USER_FILTER_TEMPLATE % (
- askbot_settings.LDAP_USERID_FIELD,
- username
- )
+ askbot_settings.LDAP_LOGIN_NAME_FIELD,
+ username
+ )
- get_attrs = (
- str(askbot_settings.LDAP_EMAIL_FIELD),
+ email_field = askbot_settings.LDAP_EMAIL_FIELD
+
+ get_attrs = [
+ email_field.encode(encoding),
+ login_name_field.encode(encoding)
#str(askbot_settings.LDAP_USERID_FIELD)
#todo: here we have a chance to get more data from LDAP
#maybe a point for some plugin
- )
+ ]
+
+ common_name_field = askbot_settings.LDAP_COMMON_NAME_FIELD.strip()
+ given_name_field = askbot_settings.LDAP_GIVEN_NAME_FIELD.strip()
+ surname_field = askbot_settings.LDAP_SURNAME_FIELD.strip()
+
+ if given_name_field and surname_field:
+ get_attrs.append(given_name_field.encode(encoding))
+ get_attrs.append(surname_field.encode(encoding))
+ elif common_name_field:
+ get_attrs.append(common_name_field.encode(encoding))
# search ldap directory for user
user_search_result = ldap_session.search_s(
- askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, get_attrs
+ askbot_settings.LDAP_BASE_DN.encode(encoding),
+ ldap.SCOPE_SUBTREE,
+ user_filter.encode(encoding),
+ get_attrs
)
if user_search_result: # User found in LDAP Directory
user_dn = user_search_result[0][0]
user_information = user_search_result[0][1]
- ldap_session.simple_bind_s(user_dn, password) #raises INVALID_CREDENTIALS
+ ldap_session.simple_bind_s(user_dn, password.encode(encoding)) #raises INVALID_CREDENTIALS
ldap_session.unbind_s()
- exact_username = user_information[askbot_settings.LDAP_USERID_FIELD][0]
-
- # Assuming last, first order
- # --> may be different
- #last_name, first_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1)
+ exact_username = user_information[login_name_field][0]
+ email = user_information[email_field][0]
- email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0]
+ if given_name_field and surname_field:
+ last_name = user_information[surname_field][0]
+ first_name = user_information[given_name_field][0]
+ elif surname_field:
+ common_name_format = askbot_settings.LDAP_COMMON_NAME_FIELD_FORMAT
+ common_name = user_information[common_name_field][0]
+ first_name, last_name = split_name(common_name, common_name_format)
+
try:
user = User.objects.get(username__exact=exact_username)
# always update user profile to synchronize with ldap server
@@ -95,7 +139,7 @@ def ldap_authenticate(username, password):
# create new user in local db
user = User()
user.username = exact_username
- user.set_password(password)
+ user.set_password(password)#copy password from LDAP locally
#user.first_name = first_name
#user.last_name = last_name
user.email = email