cas_callbacks.py 4.02 KB
Newer Older
1
2
# Future Imports
from __future__ import unicode_literals, absolute_import, print_function, division
David Haynes's avatar
David Haynes committed
3
4

# Django Imports
5
6
from django.contrib.auth.models import User
from django.conf import settings
David Haynes's avatar
David Haynes committed
7

David Haynes's avatar
David Haynes committed
8
# third party imports
9
import requests
10

David Haynes's avatar
David Haynes committed
11
12
13
"""
    parse what peoplefinder sends back to us and make a list out of it
"""
14
15
16
17
18
19
20
21
22
23
24
25
def pfparse(pf_name_result):
    # name comes in format of Anderson, Nicholas J
    name_list = pf_name_result.split(',')
    # there's random whitespace with the first name
    first_name_section = name_list[1].strip()
    # check if there's a middle initial
    mi_q = first_name_section.split(' ')
    # make sure that the additional elements aren't multiple names
    if len(mi_q[-1]) == 1:
        first_name = ' '.join(mi_q[:-1])
    else:
        first_name = first_name_section
David Haynes's avatar
David Haynes committed
26
    # our list containing the name of the person in a usable list
27
28
29
    new_name_list = [first_name, name_list[0]]
    return new_name_list

David Haynes's avatar
David Haynes committed
30
31
32
"""
    get information from peoplefinder
"""
33
34
35
36
37
38
39
40
41
42
def pfinfo(uname):
    base_url = settings.PF_URL
    url = base_url + "basic/all/" + str(uname)
    try:
        metadata = requests.get(url, timeout=5)
        print("Retrieving information from the peoplefinder api.")
        metadata.raise_for_status()
    except requests.exceptions.RequestException as e:
        print("Cannot resolve to peoplefinder api:", e)
        print("Returning empty user info tuple.")
43
        return ['', '']
44
45
46
47
    else:
        pfjson = metadata.json()
        try:
            if len(pfjson['results']) == 1:
Nicholas Anderson's avatar
Nicholas Anderson committed
48
49
50
51
52
53
54
                if pfjson['method'] == 'peoplefinder':
                    name_str = pfjson['results'][0]['name']
                    name = pfparse(name_str)
                elif pfjson['method'] == 'ldap':
                    name = [pfjson['results'][0]['givenname'], pfjson['results'][0]['surname']]
                else:
                    name = pfjson['results'][0]['name']
David Haynes's avatar
David Haynes committed
55
                return name
56
            else:
Nicholas Anderson's avatar
Nicholas Anderson committed
57
58
59
60
61
62
63
                if pfjson['method'] == 'peoplefinder':
                    name_str = pfjson['results'][1]['name']
                    name = pfparse(name_str)
                elif pfjson['method'] == 'ldap':
                    name = [pfjson['results'][1]['givenname'], pfjson['results'][1]['surname']]
                else:
                    name = pfjson['results'][0]['name']
David Haynes's avatar
David Haynes committed
64
                return name
65
66
67
        # if the name is not in peoplefinder, return empty first and last name
        except IndexError:
            print("Name not found in peoplefinder.")
68
            return ['','']
69
70
71
        except Exception as e:
            print("Unknown peoplefinder error:", e)
            print("Returning empty user info tuple.")
72
            return ['', '']
73

David Haynes's avatar
David Haynes committed
74
75
76
"""
    create a django user based off of the peoplefinder info we parsed earlier
"""
77
78
def create_user(tree):

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    print("Parsing CAS information.")
    try:
        username = tree[0][0].text
        user, user_created = User.objects.get_or_create(username=username)
    except Exception as e:
        print("CAS callback unsuccessful:", e)

    # error handling in pfinfo function
    info_name = pfinfo(username)

    try:
        if user_created:
            print("Created user object %s." % username)

            # set and save the user's email
David Haynes's avatar
David Haynes committed
94
            email_str = "%s%s" % (username, settings.EMAIL_DOMAIN)
95
96
97
98
99
100
101
            user.email = email_str
            # Password is a required User object field, though doesn't matter for our
            # purposes because all user auth is handled through CAS, not Django's login.
            user.set_password('cas_used_instead')
            user.save()
            print("Added user's email, %s." % email_str)

David Haynes's avatar
David Haynes committed
102
103
104
105
            user.first_name = info_name[0]
            user.last_name = info_name[1]
            user.save()
            print("Added user's name, %s %s." % (info_name[0], info_name[1]))
106
107

            print("User object creation process completed.")
108

109
110
        else:
            print("User object already exists.")
111

112
113
114
        print("CAS callback successful.")
    except Exception as e:
        print("Unhandled user creation error:", e)