mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-11 09:28:27 -04:00
Merge branch 'main' into 1928-develop-new-page-templates-in-code-to-sit-behind-the-log-in
This commit is contained in:
@@ -1,18 +1,11 @@
|
||||
import os
|
||||
import secrets
|
||||
from urllib.parse import unquote
|
||||
|
||||
from flask import (
|
||||
abort,
|
||||
current_app,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
from flask import abort, current_app, redirect, render_template, request, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
from app import status_api_client
|
||||
from app import redis_client, status_api_client
|
||||
from app.formatters import apply_html_class, convert_markdown_template
|
||||
from app.main import main
|
||||
from app.main.views.pricing import CURRENT_SMS_RATE
|
||||
@@ -40,6 +33,7 @@ def check_guidance_feature():
|
||||
def index():
|
||||
if current_user and current_user.is_authenticated:
|
||||
return redirect(url_for("main.choose_account"))
|
||||
|
||||
token = generate_token(
|
||||
str(request.remote_addr),
|
||||
current_app.config["SECRET_KEY"],
|
||||
@@ -48,8 +42,12 @@ def index():
|
||||
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
||||
# handle unit tests
|
||||
|
||||
current_app.logger.warning(f"############### {str(request.remote_addr)}")
|
||||
|
||||
nonce = secrets.token_urlsafe()
|
||||
session["nonce"] = nonce
|
||||
|
||||
redis_key = f"login-nonce-{unquote(nonce)}"
|
||||
redis_client.set(redis_key, nonce)
|
||||
|
||||
if url is not None:
|
||||
url = url.replace("NONCE", nonce)
|
||||
|
||||
@@ -77,6 +77,11 @@ def invite_user(service_id, user_id=None):
|
||||
form.login_authentication.data = "sms_auth"
|
||||
|
||||
if form.validate_on_submit():
|
||||
if not form.permissions or len(form.permissions) == 0:
|
||||
return render_template(
|
||||
"views/user-has-no-permissions.html",
|
||||
user_to_invite=user_to_invite,
|
||||
)
|
||||
email_address = form.email_address.data
|
||||
invited_user = InvitedUser.create(
|
||||
current_user.id,
|
||||
|
||||
@@ -165,6 +165,7 @@ def set_up_your_profile():
|
||||
|
||||
if redis_client.get(f"invitedata-{state}") is None:
|
||||
access_token = sign_in._get_access_token(code, state)
|
||||
|
||||
debug_msg("Got the access token for login.gov")
|
||||
user_email, user_uuid = sign_in._get_user_email_and_uuid(access_token)
|
||||
debug_msg(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from flask import redirect
|
||||
from flask import send_from_directory
|
||||
|
||||
from app.main import main
|
||||
|
||||
@@ -6,6 +6,4 @@ from app.main import main
|
||||
@main.route("/.well-known/security.txt", methods=["GET"])
|
||||
@main.route("/security.txt", methods=["GET"])
|
||||
def security_policy():
|
||||
# See GDS Way security policy which this implements
|
||||
# https://gds-way.cloudapps.digital/standards/vulnerability-disclosure.html#vulnerability-disclosure-and-security-txt
|
||||
return redirect("https://vdp.cabinetoffice.gov.uk/.well-known/security.txt")
|
||||
return send_from_directory(".well-known", "security.txt")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import json
|
||||
import os
|
||||
import secrets
|
||||
import time
|
||||
import uuid
|
||||
from urllib.parse import unquote
|
||||
|
||||
import jwt
|
||||
import requests
|
||||
@@ -14,18 +14,17 @@ from flask import (
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
from flask_login import current_user
|
||||
|
||||
from app import login_manager, user_api_client
|
||||
from app import login_manager, redis_client, user_api_client
|
||||
from app.main import main
|
||||
from app.main.views.index import error
|
||||
from app.main.views.verify import activate_user
|
||||
from app.models.user import User
|
||||
from app.utils import hide_from_search_engines
|
||||
from app.utils.login import is_safe_redirect_url
|
||||
from app.utils.login import get_id_token, is_safe_redirect_url
|
||||
from app.utils.time import is_less_than_days_ago
|
||||
from app.utils.user import is_gov_user
|
||||
from notifications_utils.url_safe_token import generate_token
|
||||
@@ -43,7 +42,6 @@ def _reformat_keystring(orig): # pragma: no cover
|
||||
def _get_access_token(code, state): # pragma: no cover
|
||||
client_id = os.getenv("LOGIN_DOT_GOV_CLIENT_ID")
|
||||
access_token_url = os.getenv("LOGIN_DOT_GOV_ACCESS_TOKEN_URL")
|
||||
certs_url = os.getenv("LOGIN_DOT_GOV_CERTS_URL")
|
||||
keystring = os.getenv("LOGIN_PEM")
|
||||
if " " in keystring:
|
||||
keystring = _reformat_keystring(keystring)
|
||||
@@ -66,32 +64,13 @@ def _get_access_token(code, state): # pragma: no cover
|
||||
response = requests.post(url, headers=headers)
|
||||
|
||||
response_json = response.json()
|
||||
try:
|
||||
encoded_id_token = response_json["id_token"]
|
||||
except KeyError as e:
|
||||
current_app.logger.exception(f"Error when getting id token {response_json}")
|
||||
raise KeyError(f"'access_token' {response.json()}") from e
|
||||
|
||||
# Getting Login.gov signing keys for unpacking the id_token correctly.
|
||||
jwks = requests.get(certs_url).json()
|
||||
public_keys = {
|
||||
jwk["kid"]: {
|
||||
"key": jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk)),
|
||||
"algo": jwk["alg"],
|
||||
}
|
||||
for jwk in jwks["keys"]
|
||||
}
|
||||
kid = jwt.get_unverified_header(encoded_id_token)["kid"]
|
||||
pub_key = public_keys[kid]["key"]
|
||||
algo = public_keys[kid]["algo"]
|
||||
id_token = jwt.decode(
|
||||
encoded_id_token, pub_key, audience=client_id, algorithms=[algo]
|
||||
)
|
||||
|
||||
id_token = get_id_token(response_json)
|
||||
nonce = id_token["nonce"]
|
||||
saved_nonce = session.pop("nonce")
|
||||
if nonce != saved_nonce:
|
||||
current_app.logger.error(f"Nonce Error: {nonce} != {saved_nonce}")
|
||||
redis_key = f"login-nonce-{unquote(nonce)}"
|
||||
stored_nonce = redis_client.get(redis_key).decode("utf8")
|
||||
|
||||
if nonce != stored_nonce:
|
||||
current_app.logger.error(f"Nonce Error: {nonce} != {stored_nonce}")
|
||||
abort(403)
|
||||
|
||||
try:
|
||||
@@ -232,7 +211,8 @@ def sign_in(): # pragma: no cover
|
||||
url = os.getenv("LOGIN_DOT_GOV_INITIAL_SIGNIN_URL")
|
||||
|
||||
nonce = secrets.token_urlsafe()
|
||||
session["nonce"] = nonce
|
||||
redis_key = f"-{unquote(nonce)}"
|
||||
redis_client.set(redis_key, nonce)
|
||||
|
||||
# handle unit tests
|
||||
if url is not None:
|
||||
|
||||
Reference in New Issue
Block a user