Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions app/one_click_unsubscribe/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ def one_click_unsubscribe(notification_id, token):
max_age_seconds = 60 * 60 * 24 * 365 # set to 1 year for now

try:
email_address = check_token(
token, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"], max_age_seconds
)
email_address = check_token(token, current_app.config["SECRET_KEY"], "one_click_unsubscribe", max_age_seconds)
except BadData as e:
errors = {"unsubscribe request": "This is not a valid unsubscribe link."}
raise InvalidRequest(errors, status_code=404) from e
Expand Down
8 changes: 2 additions & 6 deletions app/organisation/invite_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@ def update_org_invite_status(organisation_id, invited_org_user_id):


def invited_org_user_url(invited_org_user_id, invite_link_host=None):
token = generate_token(
str(invited_org_user_id), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(str(invited_org_user_id), current_app.config["SECRET_KEY"], "invite_organisation")

if invite_link_host is None:
invite_link_host = current_app.config["ADMIN_BASE_URL"]
Expand All @@ -125,9 +123,7 @@ def validate_invitation_token(token):
max_age_seconds = 60 * 60 * 24 * current_app.config["INVITATION_EXPIRATION_DAYS"]

try:
invited_user_id = check_token(
token, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"], max_age_seconds
)
invited_user_id = check_token(token, current_app.config["SECRET_KEY"], "invite_organisation", max_age_seconds)
except SignatureExpired as e:
errors = {
"invitation": "Your invitation to GOV.UK Notify has expired. "
Expand Down
6 changes: 2 additions & 4 deletions app/service_invite/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def update_invited_user(service_id, invited_user_id):


def invited_user_url(invited_user_id, invite_link_host=None):
token = generate_token(str(invited_user_id), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token(str(invited_user_id), current_app.config["SECRET_KEY"], "invite_user")

if invite_link_host is None:
invite_link_host = current_app.config["ADMIN_BASE_URL"]
Expand All @@ -104,9 +104,7 @@ def validate_service_invitation_token(token):
max_age_seconds = 60 * 60 * 24 * current_app.config["INVITATION_EXPIRATION_DAYS"]

try:
invited_user_id = check_token(
token, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"], max_age_seconds
)
invited_user_id = check_token(token, current_app.config["SECRET_KEY"], "invite_service", max_age_seconds)
except SignatureExpired as e:
errors = {
"invitation": "Your invitation to GOV.UK Notify has expired. "
Expand Down
31 changes: 10 additions & 21 deletions tests/app/one_click_unsubscribe/test_one_click_unsubscribe.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ def unsubscribe_url_post(client, notification_id, token):

def test_valid_one_click_unsubscribe_url(mocker, client, sample_email_notification):
mock_redis = mocker.patch("app.one_click_unsubscribe.rest.redis_store.delete")
token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")
response = unsubscribe_url_post(client, sample_email_notification.id, token)
response_json_data = response.get_json()
created_unsubscribe_request = get_unsubscribe_request_by_notification_id_dao(sample_email_notification.id)
Expand All @@ -46,9 +44,7 @@ def test_valid_one_click_unsubscribe_url(mocker, client, sample_email_notificati


def test_duplicate_unsubscribe_requests(mocker, client, sample_email_notification):
token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")
# first unsubscribe request
unsubscribe_url_post(client, sample_email_notification.id, token)
# duplicate unsubscribe request
Expand All @@ -67,7 +63,7 @@ def test_unsubscribe_request_object_refers_to_correct_template_version_after_tem
)
notification = create_notification(template=test_template, to_field="foo@bar.com")
initial_template_version = test_template.version
token = generate_token(notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token(notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")

# update template content to generate new template version
test_template.content = "New content"
Expand All @@ -92,7 +88,7 @@ def test_unsubscribe_request_object_refers_to_correct_template_version_after_tem
)
initial_template_version = test_template.version
notification = create_notification(template=test_template, to_field="foo@bar.com")
token = generate_token(notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token(notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")

# archive template
test_template.archived = True
Expand All @@ -111,7 +107,7 @@ def test_unsubscribe_request_object_refers_to_correct_template_version_after_tem


def test_valid_one_click_unsubscribe_url_after_data_retention_period(client, sample_notification_history):
token = generate_token("foo@bar.com", current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token("foo@bar.com", current_app.config["SECRET_KEY"], "one_click_unsubscribe")
response = unsubscribe_url_post(client, sample_notification_history.id, token)
response_json_data = response.get_json()
created_unsubscribe_request = get_unsubscribe_request_by_notification_id_dao(sample_notification_history.id)
Expand All @@ -135,9 +131,7 @@ def test_invalid_one_click_unsubscribe_url_token(client, sample_email_notificati

def test_invalid_one_click_unsubscribe_url_notification_id(client, sample_email_notification):
invalid_notification_id = uuid.uuid4()
token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")
response = unsubscribe_url_post(client, invalid_notification_id, token)
response_json_data = response.get_json()
assert response.status_code == 404
Expand Down Expand Up @@ -178,9 +172,7 @@ def test_unsubscribe_from_notify_research(mocker, client, sample_email_notificat
)
sample_email_notification.service_id = service.id

token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")
response = unsubscribe_url_post(client, sample_email_notification.id, token)
response_json_data = response.get_json()

Expand All @@ -205,9 +197,7 @@ def test_unsubscribe_from_notify_features(mocker, client, sample_email_notificat
)
sample_email_notification.service_id = service.id

token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")
response = unsubscribe_url_post(client, sample_email_notification.id, token)
response_json_data = response.get_json()

Expand Down Expand Up @@ -236,9 +226,8 @@ def test_unsubscribe_from_notify_service_for_unknown_user(client, service_id, sa
)
sample_email_notification.service_id = service.id

token = generate_token(
sample_email_notification.to, current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(sample_email_notification.to, current_app.config["SECRET_KEY"], "one_click_unsubscribe")

response = unsubscribe_url_post(client, sample_email_notification.id, token)
response_json_data = response.get_json()

Expand Down
14 changes: 4 additions & 10 deletions tests/app/organisation/test_invite_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,7 @@ def test_update_org_invited_user_for_invalid_data_returns_400(admin_request, sam
],
)
def test_validate_invitation_token_returns_200_when_token_valid(client, sample_invited_org_user, endpoint_format_str):
token = generate_token(
str(sample_invited_org_user.id), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(str(sample_invited_org_user.id), current_app.config["SECRET_KEY"], "invite_organisation")

url = endpoint_format_str.format(token)
auth_header = create_admin_authorization_header()
Expand All @@ -204,9 +202,7 @@ def test_validate_invitation_token_returns_200_when_token_valid(client, sample_i

def test_validate_invitation_token_for_expired_token_returns_400(client):
with freeze_time("2016-01-01T12:00:00"):
token = generate_token(
str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_organisation")
url = f"/invite/organisation/{token}"
auth_header = create_admin_authorization_header()
response = client.get(url, headers=[("Content-Type", "application/json"), auth_header])
Expand All @@ -221,7 +217,7 @@ def test_validate_invitation_token_for_expired_token_returns_400(client):


def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(client):
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_organisation")
url = f"/invite/organisation/{token}"
auth_header = create_admin_authorization_header()
response = client.get(url, headers=[("Content-Type", "application/json"), auth_header])
Expand All @@ -233,9 +229,7 @@ def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(


def test_validate_invitation_token_returns_400_when_token_is_malformed(client):
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])[
:-2
]
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_organisation")[:-2]

url = f"/invite/organisation/{token}"
auth_header = create_admin_authorization_header()
Expand Down
14 changes: 4 additions & 10 deletions tests/app/service_invite/test_service_invite_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,7 @@ def test_update_invited_user_for_invalid_data_returns_400(client, sample_invited
],
)
def test_validate_invitation_token_returns_200_when_token_valid(client, sample_invited_user, endpoint_format_str):
token = generate_token(
str(sample_invited_user.id), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(str(sample_invited_user.id), current_app.config["SECRET_KEY"], "invite_service")
url = endpoint_format_str.format(token)
auth_header = create_admin_authorization_header()
response = client.get(url, headers=[("Content-Type", "application/json"), auth_header])
Expand All @@ -237,9 +235,7 @@ def test_validate_invitation_token_returns_200_when_token_valid(client, sample_i

def test_validate_invitation_token_for_expired_token_returns_400(client):
with freeze_time("2016-01-01T12:00:00"):
token = generate_token(
str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"]
)
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_service")
url = f"/invite/service/{token}"
auth_header = create_admin_authorization_header()
response = client.get(url, headers=[("Content-Type", "application/json"), auth_header])
Expand All @@ -254,7 +250,7 @@ def test_validate_invitation_token_for_expired_token_returns_400(client):


def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(client):
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_service")
url = f"/invite/service/{token}"
auth_header = create_admin_authorization_header()
response = client.get(url, headers=[("Content-Type", "application/json"), auth_header])
Expand All @@ -266,9 +262,7 @@ def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(


def test_validate_invitation_token_returns_400_when_token_is_malformed(client):
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"])[
:-2
]
token = generate_token(str(uuid.uuid4()), current_app.config["SECRET_KEY"], "invite_service")[:-2]

url = f"/invite/service/{token}"
auth_header = create_admin_authorization_header()
Expand Down
2 changes: 1 addition & 1 deletion tests/app/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def test_url_with_token_unsubscribe_link(sample_email_notification, hostnames, n
notification_id = sample_email_notification.id
base_url = hostnames.api
url = f"/unsubscribe/{str(notification_id)}/"
token = generate_token(data, notify_api.config["SECRET_KEY"], notify_api.config["DANGEROUS_SALT"])
token = generate_token(data, notify_api.config["SECRET_KEY"], "one_click_unsubscribe")

expected_unsubscribe_link = f"{base_url}/unsubscribe/{notification_id}/{token}"
generated_unsubscribe_link = url_with_token(data, url=url, base_url=base_url)
Expand Down
Loading