# Copyright (c) 2020, JINGROW # For license information, please see license.txt from contextlib import suppress import jingrow def whitelist_saas_api(func): # noqa: C901 def whitelist_wrapper(fn): return jingrow.whitelist(allow_guest=True, methods=["POST"])(fn) def auth_wrapper(*args, **kwargs): headers = jingrow.request.headers site_access_token = headers.get("x-site-access-token") site_user = headers.get("x-site-user") site = None site_token = None # check when x-site-access-token is provided if site_access_token: splitted = site_access_token.split(":") if len(splitted) != 2: jingrow.throw("Invalid x-site-access-token provided", jingrow.AuthenticationError) accessTokenDocName = splitted[0] token = splitted[1] with suppress(jingrow.DoesNotExistError): record = jingrow.get_pg("Site Access Token", accessTokenDocName) if record.token != token: jingrow.throw("Invalid x-site-access-token provided", jingrow.AuthenticationError) # set site and site token from access token record site = record.site site_token = jingrow.db.get_value("Site", site, "saas_communication_secret") # check when x-site and x-site-token are provided else: # set site and site token from headers site = headers.get("x-site") site_token = headers.get("x-site-token") # check for valid values if not site or not site_token: jingrow.throw( "(x-site and x-site-token) or x-site-access-token headers are mandatory", jingrow.AuthenticationError, ) # validate site site_record = jingrow.get_value( "Site", site, [ "name", "team", "is_standby", "standby_for_product", "saas_communication_secret", ], as_dict=True, ignore=True, ) if not site_record: jingrow.throw("Invalid x-site provided", jingrow.AuthenticationError) if site_record.saas_communication_secret != site_token: jingrow.throw("Invalid x-site-token provided", jingrow.AuthenticationError) if site_record.is_standby is None and site_record.standby_for_product is None: jingrow.throw("Sorry, this is not a SaaS site", jingrow.AuthenticationError) # set site and team name in context jingrow.local.site_name = site_record.name jingrow.local.team_name = site_record.team # set team user as current user jingrow.set_user(site_user) # set utility function to get team and site info jingrow.local.get_site = lambda: jingrow.get_pg("Site", jingrow.local.site_name) jingrow.local.get_team = lambda: jingrow.get_pg("Team", jingrow.local.team_name) # remove cmd from kwargs kwargsCopy = kwargs.copy() kwargsCopy.pop("cmd", None) return func(*args, **kwargsCopy) return whitelist_wrapper(auth_wrapper)