Using Google Apps Premium infrastructure for user management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/python
# -*- coding: utf-8 -*-

from django.contrib.auth.backends import ModelBackend as DefaultModelBackend
from django.contrib.auth.models import User
from gdata.apps.service import AppsService
from gdata.service import BadAuthentication, CaptchaRequired
from django.conf import settings

"""
add to settings.py
# Google Apps specific for module auth
# The user needs Adminitrative rights to your domain to be able to do the sync
GOOGLE_APPS_ADMIN_EMAIL = 'login@yourdomain.com'
GOOGLE_APPS_DOMAIN = 'yourdomain.com'
GOOGLE_APPS_ADMIN_SECRET = 'yourpassworld'

# Replace the path to where you put the file
AUTHENTICATION_BACKENDS = ('path.to.backends.GoogleAppsModelBackend',)
"""


class GoogleAppsModelBackend(DefaultModelBackend):
  """
    Using Google Apps Provisioning API to authenticate and create users.
  """
  def authenticate(self, username=None, password=None):
    # Using correct username or password here does not matter since we're using ClientLogin further down 
    service = AppsService(email=settings.GOOGLE_APPS_ADMIN_EMAIL, domain=settings.GOOGLE_APPS_DOMAIN, password=settings.GOOGLE_APPS_ADMIN_SECRET)
    check_local_password = False
    try:
      service.ClientLogin(username, password)
    except BadAuthentication: # If username is within domain but fails because of username or password
      return None
    except CaptchaRequired:
      # Google asks for captcha if the email is outside your domain. This can be used to create 'local'
      # administrator accounts, wallmounted statistics accounts etc.
      check_local = True

    try:
      user = User.objects.get(username=username)
      if check_local and not user.check_password(password):
        # Not in google and not local. Go away!
        return None
    except User.DoesNotExist:
      if not check_local:
        user = User.objects.create_user(username=username,email=username)
        user.save()
      else:
        return None

    if not check_local:
      # Here we need to us a super user
      service = AppsService(email=settings.GOOGLE_APPS_ADMIN_EMAIL, domain=settings.GOOGLE_APPS_DOMAIN, password=settings.GOOGLE_APPS_ADMIN_SECRET)
      service.ProgrammaticLogin()
      # When a user logs in is a good idea to sync if the user is actually still allowed in the domain
      guser = service.RetrieveUser(username.replace('@%s' % settings.GOOGLE_APPS_DOMAIN,''))
      if not self.google_apps_sync(guser, user): return None
    return user

  def google_apps_sync(self, guser, user):
    # Sync with google apps
    # We assume that username and email does not change
    user.first_name = guser.name.given_name
    user.last_name = guser.name.family_name
    user.is_superuser = guser.login.admin == 'true'
    user.is_active = guser.login.suspended == 'false'

    user.save()
    return user.is_active

More like this

  1. Google Contacts API friend finder by dgouldin 5 years, 1 month ago
  2. Google Contacts import by henriklied 5 years, 2 months ago
  3. MoinMoin auth backend by yourcelf 2 years, 7 months ago
  4. Specify a manager for the Admin by kylefox 5 years, 3 months ago
  5. Facebook shell by stephenemslie 3 years, 8 months ago

Comments

tommy (on July 25, 2008):

If the user defined in settings.GOOGLE_APPS_ADMIN_EMAIL does not have admin rights you'll get an gdata.apps.service.AppsForYourDomainException

#

cu8164kp (on March 26, 2009):

Works great for authentication, it's wonderfull to have this as a option. Although it causes some problems when you want a Google Apps user to use the Django Admin.

If I try to login to Django admin as a Google App user it creates that user but of course they don't have the permissions to use the app yet. Bad thing is in the Django Admin if I now want to modify that newly added Google App user the admin form won't let me. The form has the controls in place to block anything that's not alpha-numeric characters and the Google App username is a email which Django doesn't like.

I haven't been able to find a workaround on this other than hacking the base django code http://code.djangoproject.com/attachment/ticket/9541/9541-r9368-wider-choice-of-username.diff or editing the database tables directly.

#

(Forgotten your password?)