-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
161 lines (114 loc) · 3.67 KB
/
app.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import os
import jwt
from flask import Flask, request, session
from flask_session import Session
from FlaskOIDC import FlaskOIDC
from config import oidc_config, session_config
DEBUG = os.environ.get('DEBUG', False)
app = Flask(__name__)
app.config.from_mapping(session_config)
Session(app)
auth = FlaskOIDC(config=oidc_config, app=app)
#
# Authentication: require_login decorator
#
@app.route('/login')
@app.route('/logon')
@auth.require_login
def login():
""" Login """
return {'username': session['username']}
#
# logout
#
@app.route('/logout')
@app.route('/logoff')
def bye():
""" Logout """
if auth.is_authenticated:
return auth.initiate_logout(next=request.url)
else:
return 'ok'
#
# Authorization: require_user decorator
#
@app.route('/bob')
@auth.require_user(['bob','rkras'])
def bob():
""" Only bob """
return 'hi bob'
#
# Authorization: require_attribute decorator
#
@app.route('/sa')
@auth.require_attribute('groups', ['netadmin', 'sysadmin'])
def sa():
return 'hi sa'
if DEBUG:
# DEBUG helpers
@app.route('/mysession')
def my_session_status():
""" Dump username/attributes from OIDC id token state """
return {
'username': auth.my_username,
'attributes': auth.my_attrs
}
@app.route('/<scpname>/expire')
@app.route('/expire')
@auth.assert_login
def expire(scpname=auth.token_name):
""" Hasten token expiration by 1 hr. - for testing auto token refresh """
session[scpname]['exp'] -= 3600
session.modified = True
return 'ok'
def decode_jwt(token):
""" decode and return token response. """
payload = jwt.decode(token, options={'verify_signature': False})
return payload
@app.route('/<scpname>/new')
@auth.assert_login
def new_scope_token(scpname='meh'):
"""
Request new tokens with new scope.
New requested scope is provided a query string "scp="
GET /dbaccess/new?scp=[db.dbread]
'dbaccess' is the name then used to access the tokens.
"""
newscp = request.args.get('scp')
tokens = auth.get_access_token(scpname, scope=newscp)
return {'tokens': tokens}
@app.route('/id') # decode id token for login scope
@app.route('/<scpname>/id') # decode id token for named scope
@auth.assert_login
def decode_id_tok(scpname=auth.token_name):
"""
decode id token
GET /id
returns id token for login (default) scope
GET /dbaccess/id
returns id token for `dbaccess` named tokens
"""
return decode_jwt(session[scpname]['id_token'])
@app.route('/id/raw')
@app.route('/<scpname>/id/raw')
@auth.assert_login
def raw_id_tok(scpname=auth.token_name):
""" Return the id token raw """
return session[scpname]['id_token']
@app.route('/access') # decode access token from login
@app.route('/<scpname>/access') # decode access token for named scope
def decode_access_tok(scpname=auth.token_name):
"""
decode access token
GET /access
return access token for login (default) scope
GET /dbaccess/access
return access token for 'dbaccess' named token
"""
return decode_jwt(session[scpname]['access_token'])
@app.route('/access/raw')
@app.route('/<scpname>/access/raw')
@auth.assert_login
def raw_access_tok(scpname=auth.token_name):
""" Return the access token raw """
return session[scpname]['access_token']