-
Notifications
You must be signed in to change notification settings - Fork 23
/
app.py
255 lines (190 loc) · 9.61 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import os
import json
import logging
import logging.config
from flask import Flask, send_from_directory, render_template
from flask import request, session, make_response, redirect
from config.app_config import default_settings
from utils.okta import OktaAuth, TokenUtil
from utils.udp import SESSION_INSTANCE_SETTINGS_KEY, get_app_vertical, apply_remote_config
from GlobalBehaviorandComponents.validation import gvalidation_bp_error, FROM_URI_KEY
##############################################
# Get default settings and generate client_secrets.json
# Also set app config
# DO NOT TOUCH
##############################################
logger = logging.getLogger(__name__)
app_config = {
'SECRET_KEY': default_settings["app_secret_key"],
}
##############################################
# Set App Config
# DO NOT TOUCH
##############################################
app = Flask(__name__)
app.config.update(app_config)
##############################################
# Custom Apps
# Include all routing files
# Add more themes and routes for themese here
##############################################
# home and login
from GlobalBehaviorandComponents.login import gbac_bp
app.register_blueprint(gbac_bp, url_prefix='/')
from GlobalBehaviorandComponents.manageusers import gbac_manageusers_bp
app.register_blueprint(gbac_manageusers_bp, url_prefix='/')
from GlobalBehaviorandComponents.stepupauth import gbac_stepupauth_bp
app.register_blueprint(gbac_stepupauth_bp, url_prefix='/')
from GlobalBehaviorandComponents.userapps import gbac_userapps_bp
app.register_blueprint(gbac_userapps_bp, url_prefix='/')
from GlobalBehaviorandComponents.profile import gbac_profile_bp
app.register_blueprint(gbac_profile_bp, url_prefix='/')
from GlobalBehaviorandComponents.registration import gbac_registration_bp
app.register_blueprint(gbac_registration_bp, url_prefix='/')
from GlobalBehaviorandComponents.findusername import gbac_findusername_bp
app.register_blueprint(gbac_findusername_bp, url_prefix='/')
from GlobalBehaviorandComponents.validation import gvalidation_bp, get_userinfo
app.register_blueprint(gvalidation_bp, url_prefix='/')
from GlobalBehaviorandComponents.mfaenrollment import gbac_mfaenrollment_bp
app.register_blueprint(gbac_mfaenrollment_bp, url_prefix='/')
from GlobalBehaviorandComponents.idpmanagement import gbac_manageidps_bp
app.register_blueprint(gbac_manageidps_bp, url_prefix='/')
from GlobalBehaviorandComponents.idverification import gbac_idverification_bp
app.register_blueprint(gbac_idverification_bp, url_prefix='/')
from GlobalBehaviorandComponents.progressiveprofile import gbac_progressiveprofile_bp
app.register_blueprint(gbac_progressiveprofile_bp, url_prefix='/')
from GlobalBehaviorandComponents.manageapps import gbac_manageapps_bp
app.register_blueprint(gbac_manageapps_bp, url_prefix='/')
from GlobalBehaviorandComponents.linkedobjects import gbac_lo_bp
app.register_blueprint(gbac_lo_bp, url_prefix='/')
from GlobalBehaviorandComponents.managetrustedorigins import gbac_managetrustedorigins_bp
app.register_blueprint(gbac_managetrustedorigins_bp, url_prefix='/')
# sample theme
from _sample.views import sample_views_bp
app.register_blueprint(sample_views_bp, url_prefix='/sample')
# travel agency theme
from _travelagency.views import travelagency_views_bp
app.register_blueprint(travelagency_views_bp, url_prefix='/travelagency')
# hospitality theme
from _hospitality.views import hospitality_views_bp
app.register_blueprint(hospitality_views_bp, url_prefix='/hospitality')
# dealer theme
from _dealer.views import dealer_views_bp
app.register_blueprint(dealer_views_bp, url_prefix='/dealer')
# streaming service theme
from _streamingservice.views import streamingservice_views_bp
app.register_blueprint(streamingservice_views_bp, url_prefix='/streamingservice')
# finance theme
from _finance.views import finance_views_bp
app.register_blueprint(finance_views_bp, url_prefix='/finance')
# admin theme
from _admin.views import admin_views_bp
app.register_blueprint(admin_views_bp, url_prefix='/admin')
# credit theme
from _credit.views import credit_views_bp
app.register_blueprint(credit_views_bp, url_prefix='/credit')
# healthcare theme
from _healthcare.views import healthcare_views_bp
app.register_blueprint(healthcare_views_bp, url_prefix='/healthcare')
from _healthcareoie.views import healthcareoie_views_bp
app.register_blueprint(healthcareoie_views_bp, url_prefix='/healthcareoie')
# ecommerce theme
from _ecommerce.views import ecommerce_views_bp
app.register_blueprint(ecommerce_views_bp, url_prefix='/ecommerce')
# b2b theme
from _b2b.views import b2b_views_bp
app.register_blueprint(b2b_views_bp, url_prefix='/b2b')
# developer theme
from _developer.views import developer_views_bp
app.register_blueprint(developer_views_bp, url_prefix='/developer')
##############################################
# Main Shared Routes
# DO NOT TOUCH
##############################################
@app.route('/<path:filename>')
def serve_static_html(filename):
# serve_static_html() generic route function to serve files in the 'static' folder
logger.debug("serve_static_html('{0}')".format(filename))
root_dir = os.path.dirname(os.path.realpath(__file__))
return send_from_directory(os.path.join(root_dir, 'static'), filename)
@app.route('/healthcheck')
def healthcheck():
return "OK", 200
"""
Set path to '/authorization-code/callback' because of backward compatibility with flask-oidc legacy config
"""
@app.route('/authorization-code/callback', methods=["POST"])
@apply_remote_config
def oidc_callback_handler():
""" handler for the oidc call back of the app """
logger.debug("oidc_callback_handler()")
response = None
logger.debug(request.form)
has_app_level_mfa_policy = False
if "code" in request.form:
oidc_code = request.form["code"]
okta_auth = OktaAuth(session[SESSION_INSTANCE_SETTINGS_KEY])
oauth_token = okta_auth.get_oauth_token(
code=oidc_code,
grant_type="authorization_code",
auth_options={
"client_id": session[SESSION_INSTANCE_SETTINGS_KEY]["client_id"],
"client_secret": session[SESSION_INSTANCE_SETTINGS_KEY]["client_secret"],
}
)
logger.debug("oauth_token: {0}".format(json.dumps(oauth_token, indent=4, sort_keys=True)))
app_landing_page_url = get_post_login_landing_page_url()
response = make_response(redirect(app_landing_page_url))
okta_token_cookie = TokenUtil.create_encoded_okta_token_cookie(
oauth_token["access_token"],
oauth_token["id_token"])
# logger.debug("okta_token_cookie: {0}".format(okta_token_cookie))
response.set_cookie(TokenUtil.OKTA_TOKEN_COOKIE_KEY, okta_token_cookie)
elif "error" in request.form:
# This is in the case there is an Okta App level MFA policy
logger.error("ERROR: {0}, MESSAGE: {1}".format(request.form["error"], request.form["error_description"]))
if ("The client specified not to prompt, but the client app requires re-authentication or MFA." == request.form["error_description"]):
has_app_level_mfa_policy = True
# Error occurred with Accessing the app instance
if has_app_level_mfa_policy:
error_message = "Failed to Authenticate. Please remove App Level MFA Policy and use a Global MFA Policy. Error: {0} - {1}".format(
request.form["error"],
request.form["error_description"]
)
response = gvalidation_bp_error(error_message)
else:
error_message = "Failed to Authenticate. Check to make sure the user has access to the application. Error: {0} - {1}".format(
request.form["error"],
request.form["error_description"]
)
response = gvalidation_bp_error(error_message)
else:
# catch all error
response = gvalidation_bp_error("Failed to Authenticate. Check to make sure the user has access to the application.")
return response
def get_post_login_landing_page_url():
logger.debug("get_post_login_landing_page_url()")
app_landing_page_url = ""
# Pull from Config
hosturl = request.host_url.replace("http://", "{0}://".format(session[SESSION_INSTANCE_SETTINGS_KEY]["app_scheme"]))
if session[SESSION_INSTANCE_SETTINGS_KEY]["settings"]["app_post_login_landing_url"]:
app_landing_page_url = hosturl + "{app_template}/{landing_page}".format(
app_template=session[SESSION_INSTANCE_SETTINGS_KEY]["settings"]["app_template"],
landing_page=session[SESSION_INSTANCE_SETTINGS_KEY]["settings"]["app_post_login_landing_url"],)
else:
app_landing_page_url = hosturl + "profile"
# Check for from_uri key, this always overrides the config
if FROM_URI_KEY in session:
if session[FROM_URI_KEY]:
app_landing_page_url = session[FROM_URI_KEY]
session[FROM_URI_KEY] = ""
logger.debug("app landing page {0}".format(app_landing_page_url))
return app_landing_page_url
def page_not_found(e):
return render_template('404.html', user_info=get_userinfo(), templatename=get_app_vertical(), config=session[SESSION_INSTANCE_SETTINGS_KEY]), 404
app.register_error_handler(404, page_not_found)
if __name__ == '__main__':
log_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config", os.getenv("LOGGER_CONFIG", "DEV_logger.config"))
logging.config.fileConfig(fname=log_file_path, disable_existing_loggers=False)
logger.debug("default_settings: {0}".format(json.dumps(default_settings, indent=4, sort_keys=True)))
app.run(host=os.getenv("IP", "0.0.0.0"), port=int(os.getenv("PORT", 8666)), debug=True)