From 425bd62eb65b84d12db075f7ba455d99578de1d8 Mon Sep 17 00:00:00 2001 From: Ben Larabie Date: Tue, 12 Nov 2024 15:01:07 -0500 Subject: [PATCH 1/2] Auto vpn (#1991) --- .github/workflows/docker.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 2e75f37175..083edbba7d 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -71,9 +71,17 @@ jobs: curl -o 1pass.deb https://downloads.1password.com/linux/debian/amd64/stable/1password-cli-amd64-latest.deb sudo dpkg -i 1pass.deb - - name: One Password Fetch - run: | - op read op://4eyyuwddp6w4vxlabrr2i2duxm/"Staging Github Actions VPN"/notesPlain > /var/tmp/staging.ovpn + - name: Setup Terraform tools + uses: cds-snc/terraform-tools-setup@v1 + env: # In case you want to override default versions + CONFTEST_VERSION: 0.30.0 + TERRAFORM_VERSION: 1.9.5 + TERRAGRUNT_VERSION: 0.66.9 + TF_SUMMARIZE_VERSION: 0.2.3 + + - name: Fetch VPN + run: | + curl https://raw.githubusercontent.com/cds-snc/notification-manifests/refs/heads/main/scripts/createVPNConfig.sh | bash -s staging - name: Connect to VPN uses: "kota65535/github-openvpn-connect-action@cd2ed8a90cc7b060dc4e001143e811b5f7ea0af5" From be632866a2ff414ac6d70c4648b52f936277dc6d Mon Sep 17 00:00:00 2001 From: Philippe Caron Date: Wed, 13 Nov 2024 10:11:15 -0500 Subject: [PATCH 2/2] Fix content on the email address settings page (#1988) * fix content on the email address settings page * make tests pass * Update app/templates/views/service-settings/email_from.html Co-authored-by: Andrew --------- Co-authored-by: Andrew --- app/config.py | 60 +++++++------------ app/main/forms.py | 2 +- app/main/views/add_service.py | 1 + app/main/views/service_settings.py | 2 +- .../add-service/step-create-service.html | 4 +- .../views/service-settings/email_from.html | 17 ++++-- app/translations/csv/fr.csv | 2 +- 7 files changed, 39 insertions(+), 49 deletions(-) diff --git a/app/config.py b/app/config.py index 616fb4bd7f..920bbf13cc 100644 --- a/app/config.py +++ b/app/config.py @@ -25,8 +25,7 @@ class Config(object): ALLOW_DEBUG_ROUTE = env.bool("ALLOW_DEBUG_ROUTE", False) # List of allowed service IDs that are allowed to send HTML through their templates. - ALLOW_HTML_SERVICE_IDS: List[str] = [ - id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")] + ALLOW_HTML_SERVICE_IDS: List[str] = [id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")] ADMIN_BASE_URL = ( "https://" + os.environ.get("HEROKU_APP_NAME", "") + ".herokuapp.com" if os.environ.get("HEROKU_APP_NAME", "") != "" @@ -48,15 +47,12 @@ class Config(object): BULK_SEND_AWS_BUCKET = os.getenv("BULK_SEND_AWS_BUCKET") CHECK_PROXY_HEADER = False - CONTACT_EMAIL = os.environ.get( - "CONTACT_EMAIL", "assistance+notification@cds-snc.ca") - CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv( - "CRM_GITHUB_PERSONAL_ACCESS_TOKEN") + CONTACT_EMAIL = os.environ.get("CONTACT_EMAIL", "assistance+notification@cds-snc.ca") + CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv("CRM_GITHUB_PERSONAL_ACCESS_TOKEN") CRM_ORG_LIST_URL = os.getenv("CRM_ORG_LIST_URL") CSV_MAX_ROWS = env.int("CSV_MAX_ROWS", 50_000) CSV_MAX_ROWS_BULK_SEND = env.int("CSV_MAX_ROWS_BULK_SEND", 100_000) - CSV_UPLOAD_BUCKET_NAME = os.getenv( - "CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload") + CSV_UPLOAD_BUCKET_NAME = os.getenv("CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload") DANGEROUS_SALT = os.environ.get("DANGEROUS_SALT") DEBUG = False DEBUG_KEY = os.environ.get("DEBUG_KEY", "") @@ -71,18 +67,15 @@ class Config(object): "other": 25_000, } DEFAULT_LIVE_SERVICE_LIMIT = env.int("DEFAULT_LIVE_SERVICE_LIMIT", 10_000) - DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int( - "DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000) + DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int("DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000) DEFAULT_SERVICE_LIMIT = env.int("DEFAULT_SERVICE_LIMIT", 50) DEFAULT_SMS_DAILY_LIMIT = env.int("DEFAULT_SMS_DAILY_LIMIT", 50) - DOCUMENTATION_DOMAIN = os.getenv( - "DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca") + DOCUMENTATION_DOMAIN = os.getenv("DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca") EMAIL_2FA_EXPIRY_SECONDS = 1_800 # 30 Minutes EMAIL_EXPIRY_SECONDS = 3600 # 1 hour # for waffles: pull out the routes into a flat list of the form ['/home', '/accueil', '/why-gc-notify', ...] - EXTRA_ROUTES = [item for sublist in map( - lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist] + EXTRA_ROUTES = [item for sublist in map(lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist] # FEATURE FLAGS FF_SALESFORCE_CONTACT = env.bool("FF_SALESFORCE_CONTACT", True) @@ -91,12 +84,9 @@ class Config(object): FREE_YEARLY_EMAIL_LIMIT = env.int("FREE_YEARLY_EMAIL_LIMIT", 10_000_000) FREE_YEARLY_SMS_LIMIT = env.int("FREE_YEARLY_SMS_LIMIT", 25_000) - GC_ARTICLES_API = os.environ.get( - "GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify") - GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get( - "GC_ARTICLES_API_AUTH_PASSWORD") - GC_ARTICLES_API_AUTH_USERNAME = os.environ.get( - "GC_ARTICLES_API_AUTH_USERNAME") + GC_ARTICLES_API = os.environ.get("GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify") + GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get("GC_ARTICLES_API_AUTH_PASSWORD") + GC_ARTICLES_API_AUTH_USERNAME = os.environ.get("GC_ARTICLES_API_AUTH_USERNAME") GOOGLE_ANALYTICS_ID = os.getenv("GOOGLE_ANALYTICS_ID", "UA-102484926-14") GOOGLE_TAG_MANAGER_ID = os.getenv("GOOGLE_TAG_MANAGER_ID", "GTM-KRKRZQV") HC_EN_SERVICE_ID = os.getenv("HC_EN_SERVICE_ID") @@ -104,11 +94,9 @@ class Config(object): HIPB_ENABLED = True HTTP_PROTOCOL = "http" INVITATION_EXPIRY_SECONDS = 3_600 * 24 * 2 # 2 days - also set on api - IP_GEOLOCATE_SERVICE = os.environ.get( - "IP_GEOLOCATE_SERVICE", "").rstrip("/") + IP_GEOLOCATE_SERVICE = os.environ.get("IP_GEOLOCATE_SERVICE", "").rstrip("/") LANGUAGES = ["en", "fr"] - LOGO_UPLOAD_BUCKET_NAME = os.getenv( - "ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload") + LOGO_UPLOAD_BUCKET_NAME = os.getenv("ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload") MAX_FAILED_LOGIN_COUNT = 10 MOU_BUCKET_NAME = os.getenv("MOU_BUCKET_NAME", "") @@ -131,10 +119,8 @@ class Config(object): SCANFILES_URL = os.environ.get("SCANFILES_URL", "") SECRET_KEY = env.list("SECRET_KEY", []) - SECURITY_EMAIL = os.environ.get( - "SECURITY_EMAIL", "security+securite@cds-snc.ca") - SENDING_DOMAIN = os.environ.get( - "SENDING_DOMAIN", "notification.alpha.canada.ca") + SECURITY_EMAIL = os.environ.get("SECURITY_EMAIL", "security+securite@cds-snc.ca") + SENDING_DOMAIN = os.environ.get("SENDING_DOMAIN", "notification.alpha.canada.ca") SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_NAME = "notify_admin_session" SESSION_COOKIE_SAMESITE = "Lax" @@ -148,10 +134,8 @@ class Config(object): STATSD_PORT = 8_125 STATSD_PREFIX = os.getenv("STATSD_PREFIX") - TEMPLATE_PREVIEW_API_HOST = os.environ.get( - "TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013") - TEMPLATE_PREVIEW_API_KEY = os.environ.get( - "TEMPLATE_PREVIEW_API_KEY", "my-secret-key") + TEMPLATE_PREVIEW_API_HOST = os.environ.get("TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013") + TEMPLATE_PREVIEW_API_KEY = os.environ.get("TEMPLATE_PREVIEW_API_KEY", "my-secret-key") WAF_SECRET = os.environ.get("WAF_SECRET", "waf-secret") WTF_CSRF_ENABLED = True WTF_CSRF_TIME_LIMIT = None @@ -162,8 +146,7 @@ class Config(object): NOTIFY_USER_ID = "6af522d0-2915-4e52-83a3-3690455a5fe6" NOTIFY_SERVICE_ID = "d6aa2c68-a2d9-4437-ab19-3ae8eb202553" - NO_BRANDING_ID = os.environ.get( - "NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef") + NO_BRANDING_ID = os.environ.get("NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef") @classmethod def get_sensitive_config(cls) -> list[str]: @@ -191,8 +174,7 @@ def get_safe_config(cls) -> dict[str, Any]: class Development(Config): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "http://localhost:6016" ANTIVIRUS_API_KEY = "test-key" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") @@ -210,8 +192,7 @@ class Development(Config): class Test(Development): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "https://test-antivirus" ANTIVIRUS_API_KEY = "test-antivirus-secret" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") @@ -238,8 +219,7 @@ class Test(Development): class ProductionFF(Config): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "https://test-antivirus" ANTIVIRUS_API_KEY = "test-antivirus-secret" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") diff --git a/app/main/forms.py b/app/main/forms.py index b92c09eec8..96668819cd 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -544,7 +544,7 @@ def __init__(self, *args, **kwargs): self.service_id = service_id email_from = StringField( - _l("Sending email address name"), + _l("Enter the part before ‘@notification.canada.ca’"), validators=[ DataRequired(message=_l("This cannot be empty")), validate_email_from, diff --git a/app/main/views/add_service.py b/app/main/views/add_service.py index d43dd38f51..f5f669ba85 100644 --- a/app/main/views/add_service.py +++ b/app/main/views/add_service.py @@ -167,6 +167,7 @@ def _renderTemplateStep(form, current_step: str, government_type: Optional[str]) back_link = url_for(".add_service", current_step=STEP_ORGANISATION) return render_template( "views/add-service.html", + sending_domain=current_app.config["SENDING_DOMAIN"], form=form, heading=_(WIZARD_DICT[current_step]["header"]), # type: ignore step_num=step_num, diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 902a089f3e..677344fb94 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -174,7 +174,7 @@ def _check_password(pwd): @main.route("/services//service-settings/email_from", methods=["GET", "POST"]) @user_has_permissions("manage_service") def service_email_from_change(service_id): - form = ChangeEmailFromServiceForm(service_id=service_id) + form = ChangeEmailFromServiceForm(service_id=service_id, sending_domain=current_app.config["SENDING_DOMAIN"]) if request.method == "GET": form.email_from.data = current_service.email_from diff --git a/app/templates/partials/add-service/step-create-service.html b/app/templates/partials/add-service/step-create-service.html index 5f5698b454..8d68708a3c 100644 --- a/app/templates/partials/add-service/step-create-service.html +++ b/app/templates/partials/add-service/step-create-service.html @@ -23,7 +23,7 @@

{{ _("Service name") }}

{{ textbox(form.name, hint=hint_txt, maxlength=255) }}

{{ _("Email address") }}

-

{{ _("The email address always ends with ‘@notification.canada.ca’.") }} +

{{ _("The email address always ends with ‘@{}’.").format(sending_domain) }} {% set hint_txt = _('Maximum 64 characters with no spaces. Characters can include letters, numbers, dots, dashes, and underscores.') %} {{ textbox(form.email_from, hint=hint_txt, suffix=suffix_txt, width='1-2', maxlength=64) }} @@ -33,7 +33,7 @@

{{ _("Email address") }}

{{_("Make sure we have formatted your email address correctly.")}}

{{_("Your service’s email address will be: ")}} - @notification.canada.ca + @{{sending_domain}}

{% endcall %} diff --git a/app/templates/views/service-settings/email_from.html b/app/templates/views/service-settings/email_from.html index 7bd03e8902..321b6ee3f0 100644 --- a/app/templates/views/service-settings/email_from.html +++ b/app/templates/views/service-settings/email_from.html @@ -3,6 +3,7 @@ {% from "components/page-header.html" import page_header %} {% from "components/page-footer.html" import page_footer %} {% from "components/form.html" import form_wrapper %} +{% from "components/confirmation-preview.html" import confirmation_preview %} {% block service_page_title %} {{ _('Change your sending email address') }} @@ -18,14 +19,22 @@

{{ _('Users will see your sending email address in the \'From\' field of the emails you send.') }}

{{ _('Your sending email address helps build trust with recipients. A good email address is relevant and as concise as possible.') }}

-

{{ _('You may use letters, numbers, dots, dashes or underscores.') }}

{% call form_wrapper() %} {% set save_txt = _('Save') %} - {% set hint_txt = _('Up to 64 characters. Enter what comes before the at symbol, without spaces.') %} - {% set suffix_txt = '@' + sending_domain %} - {{ textbox(form.email_from, hint=hint_txt, suffix=suffix_txt) }} + {% set hint_txt = _('Maximum 64 characters with no spaces. Characters can include letters, numbers, dots, dashes, and + underscores.') %} + {{ textbox(form.email_from, hint=hint_txt) }} +
+ {% call confirmation_preview() %} +

{{_("Make sure we have formatted your email address correctly.")}}

+

+ {{_("Your service’s email address will be: ")}} + {{form.email_from.data}}@{{sending_domain}} +

+ {% endcall %} +
{{ page_footer(save_txt) }} {% endcall %} diff --git a/app/translations/csv/fr.csv b/app/translations/csv/fr.csv index f1f335e027..e393f1cbec 100644 --- a/app/translations/csv/fr.csv +++ b/app/translations/csv/fr.csv @@ -1678,7 +1678,7 @@ "This email address cannot receive replies. In Settings, you can enter a different email for replies. Currently your service is set to prevent replies.","Cette adresse courriel ne peut pas recevoir de réponses. Vous pouvez saisir une adresse courriel différente pour les réponses via les paramètres. Votre service est actuellement configuré pour empêcher les réponses." "Your service’s email address will be: ","L’adresse courriel de votre service sera : " "You can change the order later in Settings.","Vous pourrez changer l’ordre ultérieurement via les paramètres." -"The email address always ends with ‘@notification.canada.ca’.","L’adresse courriel se termine toujours par « @notification.canada.ca »." +"The email address always ends with ‘@{}’.","L’adresse courriel se termine toujours par «@{} »." "Enter the part before ‘@notification.canada.ca’","Saisissez la partie précédant « @notification.canada.ca »." "You can send {} text message parts per day","Vous pouvez envoyer {} bouts de messages texte" "If a text message is more than 160 characters, it’s divided into several parts. ","Si un message texte contient plus de 160 caractères, il est divisé en plusieurs bouts. "