From a90479c84079826f307b8ab1d615476227a8c73f Mon Sep 17 00:00:00 2001 From: Shahan Neda Date: Sun, 1 Sep 2024 15:07:53 -0700 Subject: [PATCH] Add FRONTEND_URL as a dynamic var for emails and auth --- .github/actions/heroku-deploy/action.yml | 3 +++ .github/workflows/prod-heroku-deploy.yml | 1 + .github/workflows/staging-heroku-deploy.yml | 1 + backend/app/__init__.py | 9 +++++---- backend/app/graphql/onboarding_request.py | 5 ++--- backend/app/resources/validate_utils.py | 1 - backend/app/services/implementations/auth_service.py | 11 ++++------- .../app/services/implementations/mock_auth_service.py | 5 +++-- backend/app/utilities/get_fe_url.py | 9 +++++++++ backend/requirements.txt | 8 ++++---- backend/setup.cfg | 2 +- 11 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 backend/app/utilities/get_fe_url.py diff --git a/.github/actions/heroku-deploy/action.yml b/.github/actions/heroku-deploy/action.yml index d06106a6..acff1e00 100644 --- a/.github/actions/heroku-deploy/action.yml +++ b/.github/actions/heroku-deploy/action.yml @@ -45,6 +45,8 @@ inputs: required: true flaskConfig: required: true + frontendUrl: + required: true sourceBranch: required: false default: main @@ -95,6 +97,7 @@ runs: config MAILER_REFRESH_TOKEN "${{ inputs.mailerRefreshToken }}" config PREVIEW_DEPLOY true config FLASK_CONFIG "${{ inputs.flaskConfig }}" + config FRONTEND_URL "${{ inputs.frontendUrl }}" shell: bash - name: Push to Heroku run: git push heroku `git subtree split --prefix backend "${{ inputs.sourceBranch }}"`:refs/heads/main --force diff --git a/.github/workflows/prod-heroku-deploy.yml b/.github/workflows/prod-heroku-deploy.yml index ea42cf72..ea2ad4a8 100644 --- a/.github/workflows/prod-heroku-deploy.yml +++ b/.github/workflows/prod-heroku-deploy.yml @@ -47,4 +47,5 @@ jobs: googleApiKey: "${{ secrets.GOOGLE_API_KEY }}" adminCCEmail: "${{ vars.ADMIN_CC_EMAIL }}" flaskConfig: "${{ vars.FLASK_CONFIG }}" + frontendUrl: "${{ vars.FRONTEND_URL }}" sourceBranch: "main" diff --git a/.github/workflows/staging-heroku-deploy.yml b/.github/workflows/staging-heroku-deploy.yml index d4d7256c..0b2cca5b 100644 --- a/.github/workflows/staging-heroku-deploy.yml +++ b/.github/workflows/staging-heroku-deploy.yml @@ -44,4 +44,5 @@ jobs: googleApiKey: "${{ secrets.DEV_GOOGLE_API_KEY }}" adminCCEmail: "${{ secrets.DEV_ADMIN_CC_EMAIL }}" flaskConfig: "${{ secrets.DEV_FLASK_CONFIG }}" + frontendUrl: "${{ vars.FRONTEND_URL }}" sourceBranch: "main" diff --git a/backend/app/__init__.py b/backend/app/__init__.py index 94784b03..81211e38 100644 --- a/backend/app/__init__.py +++ b/backend/app/__init__.py @@ -2,6 +2,7 @@ import sentry_sdk import os import re +from app.utilities.get_fe_url import get_fe_url import firebase_admin from flask import Flask @@ -41,6 +42,7 @@ "MAILER_USER", "MG_DB_NAME", "MG_DATABASE_URL", + "FRONTEND_URL", ] @@ -97,9 +99,7 @@ def create_app(config_name): view_func=GraphQLView.as_view( "graphql", schema=graphql_schema, - # TODO: renable this - # graphiql=False if config_name == "production" else True, - graphiql=True, + graphiql=False if config_name == "production" else True, validation_rules=( # We can't turn this off since for some reason the Apollo Client needs this to make any queries # DisableIntrospection, @@ -115,7 +115,8 @@ def create_app(config_name): re.compile(r"^https:\/\/feeding-canadian-kids-staging--pr.*\.web\.app$"), "https://feeding-canadian-kids-prod.firebaseapp.com", "https://feeding-canadian-kids-prod.web.app", - "https://mealpairingplatform.feedingcanadiankids.org" + "https://mealpairingplatform.feedingcanadiankids.org", + get_fe_url(), ] app.config["CORS_SUPPORTS_CREDENTIALS"] = True app.config["SCHEDULER_API_ENABLED"] = True diff --git a/backend/app/graphql/onboarding_request.py b/backend/app/graphql/onboarding_request.py index e6db22e7..862475ee 100644 --- a/backend/app/graphql/onboarding_request.py +++ b/backend/app/graphql/onboarding_request.py @@ -114,7 +114,7 @@ class Arguments: onboarding_request = graphene.Field(OnboardingRequest) - # @requires_role("Admin") + @requires_role("Admin") def mutate(self, info, id): onboarding_request_dto = services[ "onboarding_request_service" @@ -135,8 +135,7 @@ class Arguments: onboarding_request = graphene.Field(OnboardingRequest) - # TODO: Remove this after creating the first admin account! - # @requires_role("Admin") + @requires_role("Admin") def mutate(self, info, id): onboarding_request_dto = services[ "onboarding_request_service" diff --git a/backend/app/resources/validate_utils.py b/backend/app/resources/validate_utils.py index 79a87a31..07170a20 100644 --- a/backend/app/resources/validate_utils.py +++ b/backend/app/resources/validate_utils.py @@ -50,7 +50,6 @@ def validate_role_info(role, role_info, role_info_str, error_list): ) elif field == "num_kids" and role_info["num_kids"] < 0: error_list.append("num_kids must be greater than or equal to zero.") - # TODO: Add donor info validation once meal donor schema is finalized return error_list diff --git a/backend/app/services/implementations/auth_service.py b/backend/app/services/implementations/auth_service.py index 28e21011..d0eb552b 100644 --- a/backend/app/services/implementations/auth_service.py +++ b/backend/app/services/implementations/auth_service.py @@ -1,3 +1,4 @@ +from app.utilities.get_fe_url import get_fe_url from .email_service import EmailService import firebase_admin.auth @@ -112,9 +113,7 @@ def forgot_password(self, email): try: set_password_link = firebase_admin.auth.generate_password_reset_link( email, - firebase_admin.auth.ActionCodeSettings( - "https://feeding-canadian-kids-staging.web.app" - ), + firebase_admin.auth.ActionCodeSettings(get_fe_url()), ) email_body = EmailService.read_email_template( @@ -169,9 +168,7 @@ def send_email_verification_link(self, email): try: verification_link = firebase_admin.auth.generate_email_verification_link( email, - firebase_admin.auth.ActionCodeSettings( - "https://feeding-canadian-kids-staging.web.app" - ), + firebase_admin.auth.ActionCodeSettings(get_fe_url()), ) email_body = EmailService.read_email_template( "email_templates/verification_email.html" @@ -194,7 +191,7 @@ def send_onboarding_request_approve_email(self, objectID, email): raise Exception(error_message) try: - url = "https://feeding-canadian-kids-staging.web.app" + url = get_fe_url() set_password_link = "{url}/{ObjectID}/set-password".format( url=url, ObjectID=objectID ) diff --git a/backend/app/services/implementations/mock_auth_service.py b/backend/app/services/implementations/mock_auth_service.py index b3fe848b..56274c31 100644 --- a/backend/app/services/implementations/mock_auth_service.py +++ b/backend/app/services/implementations/mock_auth_service.py @@ -1,3 +1,4 @@ +from app.utilities.get_fe_url import get_fe_url from .email_service import EmailService from ..interfaces.auth_service import IAuthService @@ -45,7 +46,7 @@ def forgot_password(self, email): try: user = self.user_service.get_user_by_email(email) - url = "https://feeding-canadian-kids-staging.web.app" + url = get_fe_url() set_password_link = "{url}/{ObjectID}/reset-password".format( url=url, ObjectID=user.id ) @@ -117,7 +118,7 @@ def send_onboarding_request_approve_email(self, objectID, email): raise Exception(error_message) try: - url = "https://feeding-canadian-kids-staging.web.app" + url = get_fe_url() set_password_link = "{url}/{ObjectID}/set-password".format( url=url, ObjectID=objectID ) diff --git a/backend/app/utilities/get_fe_url.py b/backend/app/utilities/get_fe_url.py new file mode 100644 index 00000000..3cf94e7b --- /dev/null +++ b/backend/app/utilities/get_fe_url.py @@ -0,0 +1,9 @@ +import os + + +def get_fe_url(): + url = os.getenv("FRONTEND_URL") + + if url is None: + raise Exception("Frontend URL is not set in the environment file!") + return url diff --git a/backend/requirements.txt b/backend/requirements.txt index 208bbd32..53792d97 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -49,12 +49,12 @@ msgpack==1.0.2 mypy-extensions==0.4.3 packaging==22.0 pathspec==0.9.0 -pluggy==0.13.1 +pluggy==1.5.0 promise==2.3 proto-plus==1.18.1 protobuf==3.15.8 psycopg2==2.8.6 -py==1.10.0 +py==1.11.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycodestyle==2.10.0 @@ -62,8 +62,8 @@ pycparser==2.20 pyflakes==3.0.0 pymongo==4.8.0 pyparsing==2.4.7 -pytest==6.2.4 -pytest-mock==3.6.1 +pytest==8.3.2 +pytest-mock==3.14.0 python-dateutil==2.8.1 python-dotenv==0.15.0 python-editor==1.0.4 diff --git a/backend/setup.cfg b/backend/setup.cfg index 8bbe463d..40416a95 100644 --- a/backend/setup.cfg +++ b/backend/setup.cfg @@ -1,4 +1,4 @@ [flake8] max-line-length = 88 -extend-ignore = E203,E501,W503 +extend-ignore = E203,E501,W503,E202,E231 exclude = /home/runner/work/feeding-canadian-kids/feeding-canadian-kids/backend/typings/graphene/relay/mutation.pyi