Login

Using Google Apps Premium infrastructure for user management

Author:
tommy
Posted:
July 25, 2008
Language:
Python
Version:
.96
Score:
1 (after 1 ratings)

To create a lower entry barrier to logging into our intranet I created a very simple backend using Google Apps Premium provisioning API (http://code.google.com/apis/apps/gdata_provisioning_api_v2.0_reference.html).

This enables controlling access for your users based on their status in your Google Apps instance. (NOTE! Since the provisioning API is only available in the Premium version of Google Apps you first need to upgrade if you haven't done so already)

Requirements: You need Google Data libraries for python. They can be downloaded from http://code.google.com/p/gdata-python-client/downloads/list Google Apps Premium -- User used by the script must have admin rights

 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 = '[email protected]'
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. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 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

#

Please login first before commenting.