summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-06-24 23:29:09 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-06-24 23:29:09 -0400
commit7decd70de6138822ba8a5f8772bcc8c22fe0b2c8 (patch)
treebb38a6b8cf7b2538917aa779a994b547d30f4ea2
parent60d2f11b35d8367e638f2da00f515e9992cf17df (diff)
downloadaskbot-7decd70de6138822ba8a5f8772bcc8c22fe0b2c8.tar.gz
askbot-7decd70de6138822ba8a5f8772bcc8c22fe0b2c8.tar.bz2
askbot-7decd70de6138822ba8a5f8772bcc8c22fe0b2c8.zip
updated ldap protocol
-rw-r--r--askbot/conf/ldap.py31
-rw-r--r--askbot/deps/django_authopenid/backends.py64
-rw-r--r--askbot/doc/source/changelog.rst2
-rw-r--r--askbot/doc/source/debugging.rst35
-rw-r--r--askbot/doc/source/live-settings.rst37
-rw-r--r--askbot/doc/source/optional-modules.rst54
6 files changed, 194 insertions, 29 deletions
diff --git a/askbot/conf/ldap.py b/askbot/conf/ldap.py
index 077ff792..00c8a5fc 100644
--- a/askbot/conf/ldap.py
+++ b/askbot/conf/ldap.py
@@ -19,6 +19,25 @@ settings.register(
)
)
+LDAP_PROTOCOL_VERSION_CHOICES = (
+ ('3', _('Version 3')),
+ ('2', _('Version 2 (insecure and deprecated)!!!'))
+)
+
+settings.register(
+ livesettings.StringValue(
+ LDAP_SETTINGS,
+ 'LDAP_PROTOCOL_VERSION',
+ default = '3',
+ choices = LDAP_PROTOCOL_VERSION_CHOICES,
+ description = _('LDAP protocol version'),
+ help_text = _(
+ 'Note that Version 2 protocol is not secure!!! '
+ 'Do not use it on unprotected network.'
+ )
+ )
+)
+
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
@@ -39,6 +58,18 @@ settings.register(
settings.register(
livesettings.StringValue(
LDAP_SETTINGS,
+ 'LDAP_USER_FILTER_TEMPLATE',
+ description = _('User search filter template'),
+ default = '(%s=%s)',
+ help_text = _(
+ 'Python string format template, must have two string placeholders'
+ )
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ LDAP_SETTINGS,
'LDAP_SEARCH_SCOPE',
description=_('LDAP Search Scope'),
default="subs"
diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py
index ed99e44f..515fbebe 100644
--- a/askbot/deps/django_authopenid/backends.py
+++ b/askbot/deps/django_authopenid/backends.py
@@ -6,6 +6,7 @@ import datetime
import logging
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured
+from django.conf import settings as django_settings
from django.utils.translation import ugettext as _
from askbot.deps.django_authopenid.models import UserAssociation
from askbot.deps.django_authopenid import util
@@ -26,29 +27,66 @@ def ldap_authenticate(username, password):
user_information = None
try:
ldap_session = ldap.initialize(askbot_settings.LDAP_URL)
- ldap_session.protocol_version = ldap.VERSION3
- user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD,
- username)
+
+ #set protocol version
+ if askbot_settings.LDAP_PROTOCOL_VERSION == '2':
+ ldap_session.protocol_version = ldap.VERSION2
+ elif askbot_settings.LDAP_PROTOCOL_VERSION == '3':
+ ldap_session.protocol_version = ldap.VERSION3
+ else:
+ raise NotImplementedError('unsupported version of ldap protocol')
+
+ #set extra ldap options, if given
+ if hasattr(django_settings, 'LDAP_EXTRA_OPTIONS'):
+ options = django_settings.LDAP_EXTRA_OPTIONS
+ for key, value in options:
+ if key.startswith('OPT_'):
+ ldap_key = getattr(ldap, key)
+ ldap.set_option(ldap_key, value)
+ else:
+ raise ValueError('Invalid LDAP option %s' % key)
+
+ #add optional "master" LDAP authentication, if required
+ master_username = getattr(django_settings, 'LDAP_USER', None)
+ master_password = getattr(django_settings, 'LDAP_PASSWORD', None)
+ if master_username and master_password:
+ ldap_session.simple_bind_s(master_username, master_password)
+
+ user_filter = askbot_settings.LDAP_USERNAME_FILTER_TEMPLATE % (
+ askbot_settings.LDAP_USERID_FIELD,
+ username
+ )
+
+ get_attrs = (
+ askbot_settings.LDAP_EMAIL_FIELD,
+ #askbot_settings.LDAP_SCREEN_NAME_FIELD
+ #todo: here we have a chance to get more data from LDAP
+ #maybe a point for some plugin
+ )
+
# search ldap directory for user
- res = ldap_session.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None)
- if res: # User found in LDAP Directory
- user_dn = res[0][0]
- user_information = res[0][1]
- ldap_session.simple_bind_s(user_dn, password) # <-- will throw ldap.INVALID_CREDENTIALS if fails
+ user_search_result = ldap_session.search_s(
+ askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, 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.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)
+ #last_name, first_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1)
+
email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0]
try:
user = User.objects.get(username__exact=exact_username)
# always update user profile to synchronize with ldap server
user.set_password(password)
- user.first_name = first_name
- user.last_name = last_name
+ #user.first_name = first_name
+ #user.last_name = last_name
user.email = email
user.save()
except User.DoesNotExist:
@@ -56,8 +94,8 @@ def ldap_authenticate(username, password):
user = User()
user.username = exact_username
user.set_password(password)
- user.first_name = first_name
- user.last_name = last_name
+ #user.first_name = first_name
+ #user.last_name = last_name
user.email = email
user.is_staff = False
user.is_superuser = False
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index 89290fb6..e1008390 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -3,6 +3,8 @@ Changes in Askbot
Development version
-------------------
+* Updated LDAP configuration: allow protocol change, master login and
+ adding "extra options" to the ldap session (Evgeny)
* Simple tag moderation via email (Evgeny)
* Editable optional three level category selector for the tags (Evgeny)
* Tag editor adding tags as they are typed (Evgeny)
diff --git a/askbot/doc/source/debugging.rst b/askbot/doc/source/debugging.rst
index 4b46ee58..af865b12 100644
--- a/askbot/doc/source/debugging.rst
+++ b/askbot/doc/source/debugging.rst
@@ -7,6 +7,41 @@ Debugging Askbot (and other Django applications)
This document describes techniques that can be used to debug Askbot and other Django projects
If you discover new debugging techniques, please add here.
+.. _runserver:
+Use development server for debugging
+------------------------------------
+
+Django comes with a handy development webserver that can be started with the command::
+
+ python manage.py runserver
+
+With the combination of runserver,
+the :ref:`python debugger <pdb>`,
+and even inserted "print" statements directly in the code
+it is possible to "look into" the program as it runs.
+
+Inspect the log file
+--------------------
+
+By default askbot will log errors into file `log/askbot.log` within the
+project directory. See what's inside that file.
+
+Note that in the production setups there are many log files - for the
+production webserver, database, etc.
+
+.. _pdb:
+Use Python debugger
+-------------------
+
+In the problematic portion of the code, insert lines::
+
+ import pdb
+ pdb.set_trace()
+
+Then fire up the :ref:`runserver <runserver>` and step through the program.
+When you see prompt starting with `(pdb)`
+type `help` and see what options there are.
+
Use logging in code
---------------------
diff --git a/askbot/doc/source/live-settings.rst b/askbot/doc/source/live-settings.rst
index e154a257..12546e6c 100644
--- a/askbot/doc/source/live-settings.rst
+++ b/askbot/doc/source/live-settings.rst
@@ -19,3 +19,40 @@ No-one but the site administrators can change those settings.
At the moment this command is not available from the web-interface
but this will be fixed in the future.
+.. _live-settings-options:
+Entering live settings in settings.py file
+==========================================
+
+You might want to bypass live settings and enter them directly
+in the ``settings.py`` file in the ``LIVESETTINGS_OPTIONS`` dictionary.
+
+Having live settings overridden from the ``settings.py`` file may
+somewhat speed up your site
+and
+decrease a chance that the values could be accessed
+by an unauthorized person.
+
+Please see an example below::
+
+ LIVESETTINGS_OPTIONS = {
+ 1: {
+ 'DB' : True,
+ 'SETTINGS': {
+ 'EMAIL': {
+ 'REPLY_BY_EMAIL': True
+ }
+ }
+ }
+
+Firstly, the number "1" is site id. Most
+likely the number should be the same as the value of ``SITE_ID`` setting.
+
+The value for the site id key is a nested dictionary with two keys:
+``'DB'`` (if True - then the rest of settings will be taken from the database)
+and ``'SETTINGS'`` - a dictionary with the actual settings.
+In this example ``'EMAIL'`` is the settings group
+and
+``'REPLY_BY_EMAIL'`` is the setting name, with ``True`` being the value.
+
+Setting group names and setting names can be looked up in files within
+``askbot/conf`` directory.
diff --git a/askbot/doc/source/optional-modules.rst b/askbot/doc/source/optional-modules.rst
index 25bb5cc8..54043c1e 100644
--- a/askbot/doc/source/optional-modules.rst
+++ b/askbot/doc/source/optional-modules.rst
@@ -83,24 +83,46 @@ To enable authentication via LDAP
pip install python-ldap
-After that, add configuration parameters in :ref:`live settings <live-settings>`, section
-"Keys to connect the site with external services ..."
-(url ``/settings/EXTERNAL_KEYS``, relative to the domain name)
+After that, add configuration parameters in :ref:`live settings <live-settings>`,
+section "LDAP settings"
+(url ``/settings/LDAP_SETTINGS``, relative to the forum base url)
.. note::
- Location of these parameters is likely to change in the future.
- When that happens, an update notice will appear in the documentation.
-
-The parameters are:
-
-* "Use LDAP authentication for the password login" - enable/disable the feature.
- When enabled, the user name and password will be routed to use the LDAP protocol.
- Default system password authentication will be overridden.
-* "LDAP service provider name" - any string - just come up with a name for the provider service.
-* "URL fro the LDAP service" - a correct url to access the service.
-* "Explain how to change the LDAP password"
- - askbot does not provide a method to change LDAP passwords
- , therefore - use this field to explain users how they can change their passwords.
+ While it is possible to configure LDAP via web interface,
+ it is actually more safe to add them in your ``settings.py`` file in the
+ :ref:`LIVESETTINGS_OPTIONS <live-settings-options>` dictionary.
+ Consider that a breach in security of your forum might open
+ malicious access into your LDAP directory.
+
+The parameters are (note that some have pre-set defaults that might work for you)::
+
+* enable/disable LDAP for password login
+* protocol version (``LDAP_PROTOCOL_VERSION``) (version 2 is insecure and deprecated)
+* ldap url (``LDAP_URL``)
+* base distinguished name, 'dn' in LDAP parlance (``LDAP_BASEDN``)
+* user id field name (``LDAP_USERID_FIELD``)
+* email field name (``LDAP_EMAIL_FIELD``)
+* user name filter template (``LDAP_USERNAME_FILTER_TEMPLATE``)
+* user name filter template - must have two string placeholders.
+
+There are three more optional parameters that must go to the ``settings.py`` file::
+
+* ``LDAP_USER``
+* ``LDAP_PASSWORD``
+* ``LDAP_EXTRA_OPTIONS``, a list of two-item tuples - of names and values of
+ the options. Option names must be upper case strings all starting with ``OPT_``
+ as described in the `python ldap library documentation <http://www.python-ldap.org/doc/html/ldap.html#options>`_. An often used option is (`OPT_REFERRALS`, 0).
+
+Use these when you have the "directory master passsword" -
+for a specific user who can access the rest of the directory,
+these were not added to the live settings due to security concerns.
+
+``LDAP_USER`` and ``LDAP_PASSWORD`` will be used only if both are provided!
+
+Since LDAP authentication requires so many parameters,
+you might need to :ref:`debug <debugging>` the settings.
+The function to look at is `askbot.deps.django_authopenid.backends.ldap_authenticate`.
+If you have problems with LDAP please contact us at support@askbot.com.
Uploaded avatars
================