cas_callbacks.py 4.04 KB
Newer Older
1
2
"""
go/cas_callbacks.py
David Haynes's avatar
David Haynes committed
3

David Haynes's avatar
David Haynes committed
4
5
Parse the CAS/PF responses and create users in the database.
"""
David Haynes's avatar
David Haynes committed
6
7
# Other Imports
import requests
David Haynes's avatar
David Haynes committed
8
# Django Imports
9
from django.conf import settings
David Haynes's avatar
David Haynes committed
10
from django.contrib.auth.models import User
David Haynes's avatar
David Haynes committed
11

12

David Haynes's avatar
David Haynes committed
13
def pfparse(pf_name_result: str) -> list:
David Haynes's avatar
David Haynes committed
14
    """
David Haynes's avatar
David Haynes committed
15
    Parse what peoplefinder sends back to us and make a list out of it.
David Haynes's avatar
David Haynes committed
16
    """
17
18
19
20
21
22
23
24
25
26
27
    # 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
28
    # our list containing the name of the person in a usable list
29
30
31
    new_name_list = [first_name, name_list[0]]
    return new_name_list

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

David Haynes's avatar
David Haynes committed
75
def create_user(tree: list):
David Haynes's avatar
David Haynes committed
76
    """
David Haynes's avatar
David Haynes committed
77
    Create a django user based off of the peoplefinder info we parsed earlier.
David Haynes's avatar
David Haynes committed
78
    """
79
80
81
82
    print("Parsing CAS information.")
    try:
        username = tree[0][0].text
        user, user_created = User.objects.get_or_create(username=username)
83
84
    except Exception as ex:
        print("CAS callback unsuccessful:", ex)
85
86
87
88
89
90
91
92
93

    # 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
108
109
110

            print("User object creation process completed.")
        else:
            print("User object already exists.")
        print("CAS callback successful.")
111
112
    except Exception as ex:
        print("Unhandled user creation error:", ex)