This repository has been archived by the owner on May 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.py
117 lines (89 loc) · 3.4 KB
/
auth.py
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# -----------------------------------------------------------------------
# auth.py
# Authors: Alex Halderman, Scott Karlin, Brian Kernighan, Bob Dondero
# -----------------------------------------------------------------------
import urllib.request
import urllib.parse
import re
import flask
from database import get_user, post_user
# -----------------------------------------------------------------------
_CAS_URL = "https://fed.princeton.edu/cas/"
# -----------------------------------------------------------------------
# Return url after stripping out the "ticket" parameter that was
# added by the CAS server.
def strip_ticket(url):
if url is None:
return "something is badly wrong"
url = re.sub(r"ticket=[^&]*&?", "", url)
url = re.sub(r"\?&?$|&$", "", url)
return url
# -----------------------------------------------------------------------
# Validate a login ticket by contacting the CAS server. If
# valid, return the user's username; otherwise, return None.
def validate(ticket):
val_url = (
_CAS_URL
+ "validate"
+ "?service="
+ urllib.parse.quote(strip_ticket(flask.request.url))
+ "&ticket="
+ urllib.parse.quote(ticket)
)
lines = []
with urllib.request.urlopen(val_url) as flo:
lines = flo.readlines() # Should return 2 lines.
if len(lines) != 2:
return None
first_line = lines[0].decode("utf-8")
second_line = lines[1].decode("utf-8")
if not first_line.startswith("yes"):
return None
return second_line
# -----------------------------------------------------------------------
# Authenticate the remote user, and return the user's username.
# Do not return unless the user is successfully authenticated.
def authenticate():
# If the username is in the session, then the user was
# authenticated previously. So return the username.
if "username" in flask.session:
return flask.session.get("username")
# If the request does not contain a login ticket, then redirect
# the browser to the login page to get one.
ticket = flask.request.args.get("ticket")
if ticket is None:
login_url = _CAS_URL + "login?service=" + urllib.parse.quote(flask.request.url)
flask.abort(flask.redirect(login_url))
# If the login ticket is invalid, then redirect the browser
# to the login page to get a new one.
username = validate(ticket)
if username is None:
login_url = (
_CAS_URL
+ "login?service="
+ urllib.parse.quote(strip_ticket(flask.request.url))
)
flask.abort(flask.redirect(login_url))
# The user is authenticated, so store the username in
# the session.
username = username.strip()
flask.session["username"] = username
# make a get_user request to check if the user is in our db
# if not, add the user to the database
temp = get_user(username)
if not temp: # if no user was found with puid == username
# create the user
# TODO: error handling
post_user(username)
return username
def logout():
flask.session.clear()
# Log out of the CAS session, and then the application.
logout_url = (
_CAS_URL
+ "logout?service="
+ urllib.parse.quote(flask.request.url.replace("logout", ""))
)
print(logout_url)
flask.abort(flask.redirect(logout_url))