d080ca2cc6
further improve developer morale get initial angular loading Add remote css to config index Starts work to port endpoints into config app Add the api blueprint
151 lines
5.9 KiB
Python
151 lines
5.9 KiB
Python
import logging
|
|
import datetime
|
|
import os
|
|
|
|
from flask import make_response, render_template, request, session
|
|
from flask_login import login_user
|
|
from flask_principal import identity_changed
|
|
|
|
import endpoints.decorated # Register the various exceptions via decorators.
|
|
import features
|
|
|
|
from app import app, oauth_apps, oauth_login, LoginWrappedDBUser, user_analytics
|
|
from auth import scopes
|
|
from auth.permissions import QuayDeferredPermissionUser
|
|
from config import frontend_visible_config
|
|
from external_libraries import get_external_javascript, get_external_css
|
|
from endpoints.common_models_pre_oci import pre_oci_model as model
|
|
from util.secscan import PRIORITY_LEVELS
|
|
from util.saas.useranalytics import build_error_callback
|
|
from util.timedeltastring import convert_to_timedelta
|
|
from _init import __version__
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
JS_BUNDLE_NAME = 'bundle'
|
|
|
|
|
|
def common_login(user_uuid, permanent_session=True):
|
|
""" Performs login of the given user, with optional non-permanence on the session. """
|
|
user = model.get_user(user_uuid)
|
|
if user is None:
|
|
return False
|
|
|
|
if login_user(LoginWrappedDBUser(user_uuid)):
|
|
logger.debug('Successfully signed in as user %s with uuid %s', user.username, user_uuid)
|
|
new_identity = QuayDeferredPermissionUser.for_id(user_uuid)
|
|
identity_changed.send(app, identity=new_identity)
|
|
session['login_time'] = datetime.datetime.now()
|
|
|
|
if permanent_session and features.PERMANENT_SESSIONS:
|
|
session_timeout_str = app.config.get('SESSION_TIMEOUT', '31d')
|
|
session.permanent = True
|
|
session.permanent_session_lifetime = convert_to_timedelta(session_timeout_str)
|
|
|
|
# Inform our user analytics that we have a new "lead"
|
|
create_lead_future = user_analytics.create_lead(
|
|
user.email,
|
|
user.username,
|
|
user.given_name,
|
|
user.family_name,
|
|
user.company,
|
|
user.location,
|
|
)
|
|
create_lead_future.add_done_callback(build_error_callback('Create lead failed'))
|
|
return True
|
|
|
|
logger.debug('User could not be logged in, inactive?')
|
|
return False
|
|
|
|
|
|
def _list_files(path, extension, contains=""):
|
|
""" Returns a list of all the files with the given extension found under the given path. """
|
|
def matches(f):
|
|
return os.path.splitext(f)[1] == '.' + extension and contains in os.path.splitext(f)[0]
|
|
|
|
def join_path(dp, f):
|
|
# Remove the static/ prefix. It is added in the template.
|
|
return os.path.join(dp, f)[len('static/'):]
|
|
|
|
filepath = os.path.join('static/', path)
|
|
return [join_path(dp, f) for dp, _, files in os.walk(filepath) for f in files if matches(f)]
|
|
|
|
|
|
def render_page_template(name, route_data=None, **kwargs):
|
|
""" Renders the page template with the given name as the response and returns its contents. """
|
|
main_scripts = _list_files('build', 'js', JS_BUNDLE_NAME)
|
|
|
|
use_cdn = app.config.get('USE_CDN', True)
|
|
if request.args.get('use_cdn') is not None:
|
|
use_cdn = request.args.get('use_cdn') == 'true'
|
|
|
|
external_styles = get_external_css(local=not use_cdn)
|
|
external_scripts = get_external_javascript(local=not use_cdn)
|
|
|
|
# Add Stripe checkout if billing is enabled.
|
|
if features.BILLING:
|
|
external_scripts.append('//checkout.stripe.com/checkout.js')
|
|
|
|
def get_external_login_config():
|
|
login_config = []
|
|
for login_service in oauth_login.services:
|
|
login_config.append({
|
|
'id': login_service.service_id(),
|
|
'title': login_service.service_name(),
|
|
'config': login_service.get_public_config(),
|
|
'icon': login_service.get_icon(),
|
|
})
|
|
|
|
return login_config
|
|
|
|
def get_oauth_config():
|
|
oauth_config = {}
|
|
for oauth_app in oauth_apps:
|
|
oauth_config[oauth_app.key_name] = oauth_app.get_public_config()
|
|
|
|
return oauth_config
|
|
|
|
contact_href = None
|
|
if len(app.config.get('CONTACT_INFO', [])) == 1:
|
|
contact_href = app.config['CONTACT_INFO'][0]
|
|
|
|
version_number = ''
|
|
if not features.BILLING:
|
|
version_number = 'Quay %s' % __version__
|
|
|
|
scopes_set = {scope.scope: scope._asdict() for scope in scopes.app_scopes(app.config).values()}
|
|
|
|
contents = render_template(name,
|
|
route_data=route_data,
|
|
external_styles=external_styles,
|
|
external_scripts=external_scripts,
|
|
main_scripts=main_scripts,
|
|
feature_set=features.get_features(),
|
|
config_set=frontend_visible_config(app.config),
|
|
oauth_set=get_oauth_config(),
|
|
external_login_set=get_external_login_config(),
|
|
scope_set=scopes_set,
|
|
vuln_priority_set=PRIORITY_LEVELS,
|
|
enterprise_logo=app.config.get('ENTERPRISE_LOGO_URL', ''),
|
|
mixpanel_key=app.config.get('MIXPANEL_KEY', ''),
|
|
munchkin_key=app.config.get('MARKETO_MUNCHKIN_ID', ''),
|
|
recaptcha_key=app.config.get('RECAPTCHA_SITE_KEY', ''),
|
|
google_tagmanager_key=app.config.get('GOOGLE_TAGMANAGER_KEY', ''),
|
|
google_anaytics_key=app.config.get('GOOGLE_ANALYTICS_KEY', ''),
|
|
sentry_public_dsn=app.config.get('SENTRY_PUBLIC_DSN', ''),
|
|
is_debug=str(app.config.get('DEBUGGING', False)).lower(),
|
|
show_chat=features.SUPPORT_CHAT,
|
|
aci_conversion=features.ACI_CONVERSION,
|
|
has_billing=features.BILLING,
|
|
contact_href=contact_href,
|
|
hostname=app.config['SERVER_HOSTNAME'],
|
|
preferred_scheme=app.config['PREFERRED_URL_SCHEME'],
|
|
version_number=version_number,
|
|
current_year=datetime.datetime.now().year,
|
|
**kwargs)
|
|
|
|
resp = make_response(contents)
|
|
resp.headers['X-FRAME-OPTIONS'] = 'DENY'
|
|
return resp
|