cas_callbacks.py 5.65 KB
Newer Older
1
2
# standard library imports
from __future__ import absolute_import, print_function
3
# core django imports
4
from django.contrib.auth.models import User
5
from django.core.exceptions import ObjectDoesNotExist
6
from django.conf import settings
7
from django.contrib import messages
8
# third party imports
9
import requests
10
# imports from your apps
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from .models import Student, Major


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
    new_name_list = [first_name, name_list[0]]
    return new_name_list
28

29
30

def pfinfo(uname):
31
    base_url = settings.PF_URL
32
33
34
    url = base_url + "basic/all/" + str(uname)
    try:
        metadata = requests.get(url)
35
        print("Retrieving information from the peoplefinder api.")
36
37
        metadata.raise_for_status()
    except requests.exceptions.RequestException as e:
38
        print("Cannot resolve to peoplefinder api:", e)
39
40
        print("Returning empty user info tuple.")
        return ([u'', u''], u'')
41
42
    else:
        pfjson = metadata.json()
43
        try:
44
45
46
47
48
49
50
51
52
53
54
55
56
57
            if len(pfjson['results']) == 1:
                name_str = pfjson['results'][0]['name']
                name = pfparse(name_str)
                major = pfjson['results'][0]['major']
                # could conceivably throw a key error
                final_tuple = (name, major)
                return final_tuple
            else:
                name_str = pfjson['results'][1]['name']
                name = pfparse(name_str)
                major = pfjson['results'][1]['major']
                # could conceivably throw a key error
                final_tuple = (name, major)
                return final_tuple
58
59
        # if the name is not in peoplefinder, return empty first and last name
        except IndexError:
60
            print("Name not found in peoplefinder.")
61
62
63
64
65
66
            name = [u'', u'']
            major = u''
            final_tuple = (name, major)
            return final_tuple
        # if there's no major, just return that as an empty string
        except KeyError:
67
            print("Major not found in peoplefinder.")
68
69
            final_tuple = (name, u'')
            return final_tuple
70
        except Exception as e:
71
            print("Unknown peoplefinder error:", e)
72
73
            print("Returning empty user info tuple.")
            return ([u'', u''], u'')
74

Daniel W Bond's avatar
Daniel W Bond committed
75

76
77
def create_user(tree):

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

    # error handling in pfinfo function
    info_tuple = pfinfo(username)
87

88
    try:
89
        if user_created:
90
            print("Created user object %s." % username)
91
92
93
94

            # set and save the user's email
            email_str = "%s@%s" % (username, settings.ORGANIZATION_EMAIL_DOMAIN)
            user.email = email_str
95
96
97
            # 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.password = 'cas_used_instead'
98
            user.save()
99
            print("Added user's email, %s." % email_str)
100
101
102
103
104
105
106

            info_name = info_tuple[0]
            # a list of empty strings is False
            if not info_name:
                user.first_name = info_name[0]
                user.last_name = info_name[1]
                user.save()
107
                print("Added user's name, %s %s." % (info_name[0], info_name[1]))
108
            else:
109
                print("Unable to add user's name.")
110

111
            print("User object creation process completed.")
112
113

        else:
114
            print("User object already exists.")
115
116

        try:
117
            Student.objects.get(user=user)
118
            print("Student object already exists.")
119
120
121

        except ObjectDoesNotExist:
            new_student = Student.objects.create(user=user)
122
            new_student.save()
123
            print("Created student object.")
124
125
126
127
128
129

            major_name = info_tuple[1]
            try:
                major_obj = Major.objects.get(name__contains=major_name)
                new_student.major = major_obj
                new_student.save()
130
                print("Added student's major, %s." % major_name)
131
132
133
            # ironically, 'Computer Science' returns a MultipleObjectsReturned exception
            # also Major.DoesNotExist Error, but the handling for both is the same...
            except:
134
                print("Unable to add student's major.")
135
136
137
138
139
140
            try:
                new_student.original_first_name = info_name[0]
                new_student.original_last_name = info_name[1]
                print("Added student's original name for later reference.")
            except:
                print("Unable to add student's original name for later reference.")
141
142
143
144
145
146
            try:
                new_student.original_major = major_obj
                new_student.save()
                print("Added student's original major, %s, for later reference." % major_name)
            except:
                print("Unable to add student's original major for later reference.")
147

148
            print("Student object creation process completed.")
149

150
        print("CAS callback successful.")
151
    except Exception as e:
152
153
        print("Unhandled user creation error:", e)
        # mail the administrators