David Tulloh
2016-04-20 d7df42ae13a2a9bfb73a76ed96997dad88a794a9
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