diff --git a/bin/save_all_bpmn.py b/bin/save_all_bpmn.py index b7b61628..fd44bb54 100644 --- a/bin/save_all_bpmn.py +++ b/bin/save_all_bpmn.py @@ -9,7 +9,6 @@ def main() -> None: """Main.""" app = create_app() with app.app_context(): - print("HEY") failing_process_models = DataSetupService.save_all_process_models() for bpmn_errors in failing_process_models: print(bpmn_errors) diff --git a/src/spiffworkflow_backend/routes/process_groups_controller.py b/src/spiffworkflow_backend/routes/process_groups_controller.py index a548099f..2a516f9d 100644 --- a/src/spiffworkflow_backend/routes/process_groups_controller.py +++ b/src/spiffworkflow_backend/routes/process_groups_controller.py @@ -4,7 +4,6 @@ from typing import Any from typing import Optional import flask.wrappers -from flask import current_app from flask import g from flask import jsonify from flask import make_response @@ -89,13 +88,7 @@ def process_group_list( "pages": pages, }, } - # response = make_response(jsonify(response_json), 200) - response = Response( - json.dumps(response_json), status=200, mimetype="application/json" - ) - current_app.logger.info("SETTING COOKIE") - response.set_cookie("TEST_COOKIE", "HEY1") - return response + return make_response(jsonify(response_json), 200) def process_group_show( diff --git a/src/spiffworkflow_backend/routes/user.py b/src/spiffworkflow_backend/routes/user.py index 499a0eda..4b2c696f 100644 --- a/src/spiffworkflow_backend/routes/user.py +++ b/src/spiffworkflow_backend/routes/user.py @@ -62,9 +62,7 @@ def verify_token( token = request.headers["Authorization"].removeprefix("Bearer ") # This should never be set here but just in case - tld = current_app.config["THREAD_LOCAL_DATA"] - if hasattr(tld, "new_access_token"): - tld.new_access_token = None + _clear_auth_tokens_from_thread_local_data() if token: user_model = None @@ -100,9 +98,9 @@ def verify_token( ) ) if auth_token and "error" not in auth_token: - print("SETTING NEW TOKEN") - print(f"auth_token: {auth_token}") + tld = current_app.config["THREAD_LOCAL_DATA"] tld.new_access_token = auth_token["access_token"] + tld.new_id_token = auth_token["id_token"] # We have the user, but this code is a bit convoluted, and will later demand # a user_info object so it can look up the user. Sorry to leave this crap here. user_info = { @@ -178,11 +176,24 @@ def verify_token( def set_new_access_token_in_cookie( response: flask.wrappers.Response, ) -> flask.wrappers.Response: - """Set_new_access_token_in_cookie.""" + """Checks if a new token has been set in THREAD_LOCAL_DATA and sets cookies if appropriate. + + It will also delete the cookies if the user has logged out. + """ tld = current_app.config["THREAD_LOCAL_DATA"] if hasattr(tld, "new_access_token") and tld.new_access_token: response.set_cookie("access_token", tld.new_access_token) - tld.new_access_token = None + + # id_token is required for logging out since this gets passed back to the openid server + if hasattr(tld, "new_id_token") and tld.new_id_token: + response.set_cookie("id_token", tld.new_id_token) + + if hasattr(tld, 'user_has_logged_out') and tld.user_has_logged_out: + response.set_cookie("id_token", '', max_age=0) + response.set_cookie("access_token", '', max_age=0) + + _clear_auth_tokens_from_thread_local_data() + return response @@ -249,12 +260,12 @@ def login_return(code: str, state: str, session_state: str) -> Optional[Response user_model.id, auth_token_object["refresh_token"] ) redirect_url = ( - f"{state_redirect_url}?" - + f"access_token={auth_token_object['access_token']}&" - + f"id_token={id_token}" + f"{state_redirect_url}" ) tld = current_app.config["THREAD_LOCAL_DATA"] tld.new_access_token = auth_token_object["access_token"] + tld.new_id_token = auth_token_object["id_token"] + print(f"REDIRECT_URL: {redirect_url}") return redirect(redirect_url) raise ApiError( @@ -300,6 +311,8 @@ def logout(id_token: str, redirect_url: Optional[str]) -> Response: """Logout.""" if redirect_url is None: redirect_url = "" + tld = current_app.config["THREAD_LOCAL_DATA"] + tld.user_has_logged_out = True return AuthenticationService().logout(redirect_url=redirect_url, id_token=id_token) @@ -328,15 +341,6 @@ def get_decoded_token(token: str) -> Optional[Dict]: error_code="unknown_token", message="Unknown token type in get_decoded_token", ) - # try: - # # see if we have an open_id token - # decoded_token = AuthorizationService.decode_auth_token(token) - # else: - # if 'sub' in decoded_token and 'iss' in decoded_token and 'aud' in decoded_token: - # token_type = 'id_token' - - # if 'token_type' in decoded_token and 'sub' in decoded_token: - # return True def get_scope(token: str) -> str: @@ -363,3 +367,14 @@ def get_user_from_decoded_internal_token(decoded_token: dict) -> Optional[UserMo return user user = UserService.create_user(service_id, service, service_id) return user + + +def _clear_auth_tokens_from_thread_local_data() -> None: + """_clear_auth_tokens_from_thread_local_data.""" + tld = current_app.config["THREAD_LOCAL_DATA"] + if hasattr(tld, "new_access_token"): + delattr(tld, "new_access_token") + if hasattr(tld, "new_id_token"): + delattr(tld, "new_id_token") + if hasattr(tld, "user_has_logged_out"): + delattr(tld, "user_has_logged_out") diff --git a/src/spiffworkflow_backend/services/authentication_service.py b/src/spiffworkflow_backend/services/authentication_service.py index 92480f7b..275be19d 100644 --- a/src/spiffworkflow_backend/services/authentication_service.py +++ b/src/spiffworkflow_backend/services/authentication_service.py @@ -64,9 +64,7 @@ class AuthenticationService: openid_config_url = f"{cls.server_url()}/.well-known/openid-configuration" print(f"openid_config_url: {openid_config_url}") if name not in AuthenticationService.ENDPOINT_CACHE: - print("BEFORE") response = requests.get(openid_config_url) - print("AFTER") AuthenticationService.ENDPOINT_CACHE = response.json() if name not in AuthenticationService.ENDPOINT_CACHE: raise Exception( @@ -95,6 +93,7 @@ class AuthenticationService: @staticmethod def generate_state(redirect_url: str) -> bytes: """Generate_state.""" + print(f"REDIRECT_URL_HEY: {redirect_url}") state = base64.b64encode(bytes(str({"redirect_url": redirect_url}), "UTF-8")) return state @@ -103,6 +102,7 @@ class AuthenticationService: ) -> str: """Get_login_redirect_url.""" return_redirect_url = f"{self.get_backend_url()}{redirect_url}" + print(f"RETURN_REDIRECT_URL_ONE: {return_redirect_url}") login_redirect_url = ( self.open_id_endpoint_for_name("authorization_endpoint") + f"?state={state}&" diff --git a/src/spiffworkflow_backend/services/authorization_service.py b/src/spiffworkflow_backend/services/authorization_service.py index 9abe2597..ba43439e 100644 --- a/src/spiffworkflow_backend/services/authorization_service.py +++ b/src/spiffworkflow_backend/services/authorization_service.py @@ -412,59 +412,6 @@ class AuthorizationService: status_code=403, ) - # def refresh_token(self, token: str) -> str: - # """Refresh_token.""" - # # if isinstance(token, str): - # # token = eval(token) - # ( - # open_id_server_url, - # open_id_client_id, - # open_id_realm_name, - # open_id_client_secret_key, - # ) = AuthorizationService.get_open_id_args() - # headers = {"Content-Type": "application/x-www-form-urlencoded"} - # request_url = f"{open_id_server_url}/realms/{open_id_realm_name}/protocol/openid-connect/token" - # data = { - # "grant_type": "refresh_token", - # "client_id": "spiffworkflow-frontend", - # "subject_token": token, - # "refresh_token": token, - # } - # refresh_response = requests.post(request_url, headers=headers, data=data) - # refresh_token = json.loads(refresh_response.text) - # return refresh_token - - # def get_bearer_token(self, basic_token: str) -> dict: - # """Get_bearer_token.""" - # ( - # open_id_server_url, - # open_id_client_id, - # open_id_realm_name, - # open_id_client_secret_key, - # ) = AuthorizationService.get_open_id_args() - # - # backend_basic_auth_string = f"{open_id_client_id}:{open_id_client_secret_key}" - # backend_basic_auth_bytes = bytes(backend_basic_auth_string, encoding="ascii") - # backend_basic_auth = base64.b64encode(backend_basic_auth_bytes) - # - # headers = { - # "Content-Type": "application/x-www-form-urlencoded", - # "Authorization": f"Basic {backend_basic_auth.decode('utf-8')}", - # } - # data = { - # "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", - # "client_id": open_id_client_id, - # "subject_token": basic_token, - # "audience": open_id_client_id, - # } - # request_url = f"{open_id_server_url}/realms/{open_id_realm_name}/protocol/openid-connect/token" - # - # backend_response = requests.post(request_url, headers=headers, data=data) - # # json_data = json.loads(backend_response.text) - # # bearer_token = json_data['access_token'] - # bearer_token: dict = json.loads(backend_response.text) - # return bearer_token - @staticmethod def decode_auth_token(auth_token: str) -> dict[str, Union[str, None]]: """Decode the auth token.