source: remit/util/SocketAuth.py @ 39bd19e

client
Last change on this file since 39bd19e was 39bd19e, checked in by Alex Dehnert <adehnert@…>, 13 years ago

Use UNUSABLE_PASSWORD with SocketAuth?

This fixes "Unknown password hashing algorithm" errors with accounts using
SocketAuth?.

  • Property mode set to 100644
File size: 2.7 KB
RevLine 
[dbb39a2]1from django.contrib.auth.models import User
[fe43b8a]2from django.core.exceptions import ObjectDoesNotExist
3from django.contrib import auth
[dbb39a2]4import socket
5import settings
6
7class SocketAuthBackend():
[734ef4f]8    """
9    SocketAuthBackend provides a simple way to authenticate with another process.
10
11    The protocol is simple:
12    * Open a connection to a socket.
13    * On the first line, pass the name of the operation
14    * Then, on successive lines, pass additional arguments, one per line
15    * Close the write half of the socket
16    * The authentication server sends back a reply, one tuple element
17      per line
18
19    Queries include:
20    * AUTHENTICATE(username, password) => boolean
21    * FINGER(username) => (first name, last name, email, )
22    """
[dbb39a2]23    def authenticate(self, username, password, ):
[e1ae8b3]24        (result,) = query(1, "AUTHENTICATE", username, password, )
[dbb39a2]25        print result
26        if result == 'true':
27            try:
28                user = User.objects.get(username=username)
29                if len(user.groups.filter(name='local-auth-only')) > 0:
30                    if user.check_password(password):
31                        return user
32                    else:
33                        return None
34                else:
35                    return user
36            except User.DoesNotExist:
[39bd19e]37                user = User(username=username)
38                user.set_unusable_password()
[dbb39a2]39                user.is_staff = False
40                user.is_superuser = False
41                # Is there a race condition here? Yes.
42                # Should I do more error-checking? Yes.
43                # Do I care? No.
[e1ae8b3]44                (first, last, email,) = query(3, 'FINGER', username)
[dbb39a2]45                user.first_name = first
46                user.last_name = last
47                user.email = email
48                user.save()
[fe43b8a]49                try:
50                    user.groups.add(auth.models.Group.objects.get(name='autocreated'))
51                except ObjectDoesNotExist:
52                    print "Failed to retrieve autocreated group"
[dbb39a2]53                return user
54        return None
55
56    def get_user(self, user_id):
57        try:
58            return User.objects.get(pk=user_id)
59        except User.DoesNotExist:
60            return None
61
[e1ae8b3]62def query(length, *args):
[dbb39a2]63    conn = socket.socket(socket.AF_UNIX)
64    conn.connect(settings.AUTH_SOCK)
65    conn.send('\n'.join(args))
66    conn.shutdown(socket.SHUT_WR)
[e1ae8b3]67    result = conn.makefile().read().split('\n')
68    if(len(result)==length+1 and result[-1] == ''):
69        result = result[:-1]
70    if len(result) != length:
71        raise ValueError("Got return value of length %d to query '%s'; needed length %d" % (len(result), args[0], length, ))
[dbb39a2]72    conn.close()
73    return result
Note: See TracBrowser for help on using the repository browser.