commit | author | age
|
bd39e1
|
1 |
# Standalone login application for demo SSO: |
TS |
2 |
# N.B.: this version does *not* use repoze.who at all, but should produce |
|
3 |
# a cookie which repoze.who.plugin.authtkt can use. |
|
4 |
import datetime |
|
5 |
|
|
6 |
from paste.auth import auth_tkt |
|
7 |
from webob import Request |
|
8 |
|
|
9 |
LOGIN_FORM_TEMPLATE = """\ |
|
10 |
<html> |
|
11 |
<head> |
|
12 |
<title> Demo SSO Login </title> |
|
13 |
</head> |
|
14 |
<body> |
|
15 |
<h1> Demo SSO Login </h1> |
|
16 |
<p style="color: Red">%(message)s</p> |
|
17 |
<form action="#" method="post"> |
|
18 |
<input type="hidden" name="came_from" value="%(came_from)s" /> |
|
19 |
<fieldset id="login_name_fs"> |
|
20 |
<label for="login_name">Login Name</label> |
|
21 |
<input type="text" id="login_name" name="login_name" value="%(login_name)s" /> |
|
22 |
</fieldset> |
|
23 |
<fieldset id="password_fs"> |
|
24 |
<label for="password">Login Name</label> |
|
25 |
<input type="password" id="password" name="password" /> |
|
26 |
</fieldset> |
|
27 |
<input type="submit" name="form.submitted" value="Log In" /> |
|
28 |
</form> |
|
29 |
</body> |
|
30 |
</html> |
|
31 |
""" |
|
32 |
|
4a8793
|
33 |
# oh emacs python-mode, you disappoint me """ |
CM |
34 |
|
bd39e1
|
35 |
# Clients have to know about these values out-of-band |
TS |
36 |
SECRET = 's33kr1t' |
|
37 |
COOKIE_NAME = 'auth_cookie' |
|
38 |
|
|
39 |
MAX_AGE = '3600' # seconds |
|
40 |
|
|
41 |
AUTH = { |
|
42 |
'phred': 'y4bb3d4bb4d00', |
|
43 |
'bharney': 'b3dr0ck', |
|
44 |
} |
|
45 |
|
|
46 |
def _validate(login_name, password): |
|
47 |
# Your application's logic goes here |
|
48 |
return AUTH.get(login_name) == password |
|
49 |
|
|
50 |
def _get_cookies(environ, value): |
|
51 |
|
|
52 |
later = (datetime.datetime.now() + |
|
53 |
datetime.timedelta(seconds=int(MAX_AGE))) |
|
54 |
# Wdy, DD-Mon-YY HH:MM:SS GMT |
|
55 |
expires = later.strftime('%a, %d %b %Y %H:%M:%S') |
|
56 |
# the Expires header is *required* at least for IE7 (IE7 does |
|
57 |
# not respect Max-Age) |
|
58 |
tail = "; Max-Age=%s; Expires=%s" % (MAX_AGE, expires) |
|
59 |
|
|
60 |
cur_domain = environ.get('HTTP_HOST', environ.get('SERVER_NAME')) |
|
61 |
wild_domain = '.' + cur_domain |
|
62 |
|
|
63 |
return [('Set-Cookie', '%s="%s"; Path=/; Domain=%s%s' |
|
64 |
% (COOKIE_NAME, value, wild_domain, tail)), |
|
65 |
] |
|
66 |
|
|
67 |
def login(environ, start_response): |
|
68 |
request = Request(environ) |
|
69 |
message = '' |
43e387
|
70 |
if 'form.submitted' in request.POST: |
TS |
71 |
came_from = request.POST['came_from'] |
|
72 |
login_name = request.POST['login_name'] |
|
73 |
password = request.POST['password'] |
bd39e1
|
74 |
remote_addr = environ['REMOTE_ADDR'] |
43e387
|
75 |
if _validate(login_name, password): |
bd39e1
|
76 |
headers = [('Location', came_from)] |
TS |
77 |
ticket = auth_tkt.AuthTicket(SECRET, login_name, remote_addr, |
d7df42
|
78 |
cookie_name=COOKIE_NAME, secure=True, |
DT |
79 |
digest_algo="sha512") |
43e387
|
80 |
headers = _get_cookies(environ, ticket.cookie_value()) |
TS |
81 |
headers.append(('Location', came_from)) |
|
82 |
start_response('302 Found', headers) |
|
83 |
return [] |
bd39e1
|
84 |
message = 'Authentication failed' |
TS |
85 |
else: |
43e387
|
86 |
came_from = request.GET.get('came_from', '') |
bd39e1
|
87 |
login_name = '' |
TS |
88 |
|
|
89 |
body = LOGIN_FORM_TEMPLATE % {'message': message, |
|
90 |
'came_from': came_from, |
|
91 |
'login_name': login_name, |
|
92 |
} |
43e387
|
93 |
start_response('200 OK', []) |
TS |
94 |
return [body] |
|
95 |
|
|
96 |
|
|
97 |
def main(global_config, **local_config): |
|
98 |
return login |