Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #385 from communitiesuk/bau/add-ruff-formatting
Browse files Browse the repository at this point in the history
Switch to ruff formatting and fix formatting errors
  • Loading branch information
MarcUsher authored Dec 11, 2024
2 parents 97acfdc + f131787 commit 3adb765
Show file tree
Hide file tree
Showing 43 changed files with 261 additions and 321 deletions.
56 changes: 26 additions & 30 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
repos:
- repo: https://github.com/ambv/black
rev: 22.3.0
hooks:
- id: black
language_version: python3
args:
- --target-version=py310
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
additional_dependencies: [Flake8-pyproject]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-ast
- id: name-tests-test
args: ["--pytest-test-first"]
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version. If bumping this, please also bump requirements-dev.in
rev: v0.8.2
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: reorder-python-imports
name: Reorder Python imports (src, tests)
args: ["--application-directories", "src"]
- repo: https://github.com/Riverside-Healthcare/djLint
- id: detect-secrets
args:
[
"--disable-plugin",
"HexHighEntropyString",
"--disable-plugin",
"Base64HighEntropyString",
]
exclude: tests/keys/rsa256
# djLint moved in from assess - to apply as a precommit hook we should make sure it works with
# apply templates
- repo: https://github.com/Riverside-Healthcare/djLint
rev: v1.24.0
hooks:
- id: djlint-jinja
types_or: ['html', 'jinja']
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--disable-plugin', 'HexHighEntropyString',
'--disable-plugin', 'Base64HighEntropyString']
exclude: tests/keys/rsa256
types_or: ["html", "jinja"]
26 changes: 13 additions & 13 deletions api/magic_links/routes.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import json
from datetime import datetime
from urllib.parse import urlencode
from urllib.parse import urljoin
from urllib.parse import urlencode, urljoin

from api.session.auth_session import AuthSessionView
from config import Config
from flask import current_app
from flask import g
from flask import redirect
from flask import request
from flask import url_for
from flask import current_app, g, redirect, request, url_for
from flask.views import MethodView
from fsd_utils.authentication.decorators import login_requested

from api.session.auth_session import AuthSessionView
from config import Config
from models.account import AccountMethods
from models.magic_link import MagicLinkMethods

Expand Down Expand Up @@ -52,7 +48,10 @@ def use(self, link_id: str):
# Check account exists
account = AccountMethods.get_account(account_id=link.get("accountId"))
if not account:
current_app.logger.error(f"Tried to use magic link for non-existent account_id {link.get('accountId')}")
current_app.logger.error(
"Tried to use magic link for non-existent account_id {account_id}",
extra=dict(account_id=link.get("accountId")),
)
redirect(
url_for(
"magic_links_bp.invalid",
Expand Down Expand Up @@ -91,10 +90,11 @@ def use(self, link_id: str):
query_string = urlencode(query_params)
frontend_account_url = urljoin(Config.APPLICANT_FRONTEND_HOST, f"account?{query_string}")
current_app.logger.warning(
f"The magic link with hash: '{link_hash}' has already been"
f" used but the user with account_id: '{g.account_id}' is"
"The magic link with hash: '{link_hash}' has already been"
" used but the user with account_id: '{account_id}' is"
" logged in, redirecting to"
f" '{frontend_account_url}'."
" '{frontend_account_url}'.",
extra=dict(link_hash=link_hash, account_id=g.account_id, frontend_account_url=frontend_account_url),
)
return redirect(frontend_account_url)
return redirect(
Expand Down
33 changes: 15 additions & 18 deletions api/session/auth_session.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
from datetime import datetime
from datetime import timedelta
from datetime import datetime, timedelta
from typing import TYPE_CHECKING

import jwt
from flask import abort, current_app, make_response, redirect, request, session, url_for
from flask.views import MethodView
from fsd_utils import clear_sentry

from api.responses import error_response
from api.session.exceptions import SessionCreateError
from config import Config
from flask import abort
from flask import current_app
from flask import make_response
from flask import redirect
from flask import request
from flask import session
from flask import url_for
from flask.views import MethodView
from fsd_utils import clear_sentry
from models.magic_link import MagicLinkMethods
from security.utils import create_token
from security.utils import decode_with_options
from security.utils import validate_token
from security.utils import create_token, decode_with_options, validate_token

if TYPE_CHECKING:
from models.account import Account as Account
Expand Down Expand Up @@ -74,7 +66,9 @@ def clear_session(return_app=None, return_path=None):
valid_token = decode_with_options(existing_auth_token, options={"verify_exp": False})
status = "expired_token"
except jwt.PyJWTError as e:
current_app.logger.warning(f"PyJWTError: {e.__class__.__name__} - {e}")
current_app.logger.warning(
"PyJWTError: {error_name} - {error}", extra=dict(error_name=e.__class__.__name__), error=e
)
status = "invalid_token"

# If validly issued token: create query params for signout url,
Expand All @@ -90,9 +84,12 @@ def clear_session(return_app=None, return_path=None):
if return_app:
if safe_app := Config.SAFE_RETURN_APPS.get(return_app):
redirect_route = safe_app.logout_endpoint
current_app.logger.info(f"Returning to {return_app} using {redirect_route}")
current_app.logger.info(
"Returning to {return_app} using {redirect_route}",
extra=dict(return_app=return_app, redirect_route=redirect_route),
)
else:
current_app.logger.warning(f"{return_app} not listed as a safe app.")
current_app.logger.warning("{return_app} not listed as a safe app.", extra=dict(return_app=return_app))
abort(400, "Unknown return app.")

# Clear the cookie and redirect to signed out page
Expand Down Expand Up @@ -184,7 +181,7 @@ def create_session_and_redirect(
samesite=Config.FSD_USER_TOKEN_COOKIE_SAMESITE,
httponly=Config.SESSION_COOKIE_HTTPONLY,
)
current_app.logger.info(f"User logged in to account : {account.id}")
current_app.logger.info("User logged in to account : {account_id}", extra=dict(account_id=account.id))
return response
except SessionCreateError as e:
error_response(404, str(e))
Expand Down
30 changes: 14 additions & 16 deletions api/sso/routes.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import warnings
from urllib.parse import urlencode
from urllib.parse import urljoin
from urllib.parse import urlparse
from urllib.parse import urlencode, urljoin, urlparse

import msal
import requests
from api.session.auth_session import AuthSessionView
from config import Config
from flask import abort
from flask import current_app
from flask import make_response
from flask import redirect
from flask import request
from flask import session
from flask import abort, current_app, make_response, redirect, request, session
from flask.views import MethodView
from fsd_utils import clear_sentry

from api.session.auth_session import AuthSessionView
from config import Config
from models.account import AccountMethods


Expand All @@ -30,7 +23,9 @@ def login(self):
if return_app := request.args.get("return_app"):
session["return_app"] = return_app
session["return_path"] = request.args.get("return_path")
current_app.logger.debug(f"Setting return app to {return_app} for this session")
current_app.logger.debug(
"Setting return app to {return_app} for this session", extra=dict(return_app=return_app)
)

return redirect(session["flow"]["auth_uri"]), 302

Expand Down Expand Up @@ -104,7 +99,7 @@ def get_token(self):
session["user"] = result.get("id_token_claims")
self._save_cache(cache)
except ValueError as e: # Usually caused by CSRF
warnings.warn(f"Value Error on get_token route: {str(e)}")
current_app.logger.warning("Value Error on get_token route: {error}", extra=dict(error=str(e)))

if "user" not in session or not session["user"].get("sub"):
return {"message": "No valid token"}, 404
Expand All @@ -126,9 +121,12 @@ def get_token(self):
else:
redirect_url = safe_app.login_url

current_app.logger.info(f"Returning to {return_app} @ {redirect_url}")
current_app.logger.info(
"Returning to {return_app} @ {redirect_url}",
extra=dict(return_app=return_app, redirect_url=redirect_url),
)
else:
current_app.logger.warning(f"{return_app} not listed as a safe app.")
current_app.logger.warning("{return_app} not listed as a safe app.", extra=dict(return_app=return_app))
abort(400, "Unknown return app.")

# Create session token, set cookie and redirect
Expand Down
29 changes: 11 additions & 18 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
from copy import deepcopy
from os import getenv
from pathlib import Path
from typing import Any
from typing import Dict
from urllib.parse import urlencode
from urllib.parse import urljoin
from typing import Any, Dict
from urllib.parse import urlencode, urljoin

import connexion
import prance
import static_assets
from config import Config
from connexion.resolver import MethodViewResolver
from flask import Flask
from flask import request
from flask import Flask, request
from flask_assets import Environment
from flask_babel import Babel
from flask_babel import gettext
from flask_babel import Babel, gettext
from flask_redis import FlaskRedis
from flask_session import Session
from flask_talisman import Talisman
from frontend.magic_links.filters import datetime_format
from fsd_utils import init_sentry
from fsd_utils import LanguageSelector
from fsd_utils.healthchecks.checkers import FlaskRunningChecker
from fsd_utils.healthchecks.checkers import RedisChecker
from fsd_utils import LanguageSelector, init_sentry
from fsd_utils.healthchecks.checkers import FlaskRunningChecker, RedisChecker
from fsd_utils.healthchecks.healthcheck import Healthcheck
from fsd_utils.locale_selector.get_lang import get_lang
from fsd_utils.logging import logging
from fsd_utils.services.aws_extended_client import SQSExtendedClient
from jinja2 import ChoiceLoader
from jinja2 import PackageLoader
from jinja2 import PrefixLoader
from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader

import static_assets
from config import Config
from frontend.magic_links.filters import datetime_format
from models.fund import FundMethods

redis_mlinks = FlaskRedis(config_prefix="REDIS_MLINKS")
Expand Down
1 change: 0 additions & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


def build_govuk_assets(static_dist_root="frontend/static/dist"):

DIST_ROOT = "./" + static_dist_root
GOVUK_URL = "https://github.com/alphagov/govuk-frontend/releases/download/v4.8.0/release-v4.8.0.zip"
ZIP_FILE = "./govuk_frontend.zip"
Expand Down
13 changes: 5 additions & 8 deletions config/envs/default.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
"""Flask configuration."""

import base64
import logging
from collections import namedtuple
from os import environ
from os import getenv
from distutils.util import strtobool
from os import environ, getenv
from pathlib import Path
from urllib.parse import urljoin

import redis
from distutils.util import strtobool
from fsd_utils import CommonConfig
from fsd_utils import configclass
from fsd_utils import CommonConfig, configclass
from fsd_utils.authentication.config import SupportedApp


SafeAppConfig = namedtuple("SafeAppConfig", ("login_url", "logout_endpoint", "service_title"))


Expand Down Expand Up @@ -57,8 +55,7 @@ class DefaultConfig(object):
AZURE_AD_TENANT_ID = environ.get("AZURE_AD_TENANT_ID", "")
AZURE_AD_AUTHORITY = (
# consumers|organizations|<tenant_id> - signifies the Azure AD tenant endpoint # noqa
"https://login.microsoftonline.com/"
+ AZURE_AD_TENANT_ID
"https://login.microsoftonline.com/" + AZURE_AD_TENANT_ID
)
# The absolute URL must match the redirect URI you set
# in the app's registration in the Azure portal.
Expand Down
4 changes: 3 additions & 1 deletion config/envs/dev.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""Flask Dev Pipeline Environment Configuration."""

import logging

from config.envs.default import DefaultConfig as Config
from fsd_utils import configclass

from config.envs.default import DefaultConfig as Config


@configclass
class DevConfig(Config):
Expand Down
4 changes: 3 additions & 1 deletion config/envs/development.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Flask Local Development Environment Configuration."""

import logging
from os import getenv

from config.envs.default import DefaultConfig as Config
from fsd_utils import configclass

from config.envs.default import DefaultConfig as Config


@configclass
class DevelopmentConfig(Config):
Expand Down
6 changes: 4 additions & 2 deletions config/envs/production.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Flask Production Environment Configuration."""
from os import getenv

from config.envs.default import DefaultConfig as Config
from distutils.util import strtobool
from os import getenv

from fsd_utils import configclass

from config.envs.default import DefaultConfig as Config


@configclass
class ProductionConfig(Config):
Expand Down
10 changes: 5 additions & 5 deletions config/envs/test.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""Flask Test Environment Configuration."""
import base64
from os import environ
from os import getenv

from config.envs.default import DefaultConfig as Config
import base64
from distutils.util import strtobool
from os import environ, getenv

from fsd_utils import configclass

from config.envs.default import DefaultConfig as Config


@configclass
class TestConfig(Config):

SECRET_KEY = environ.get("SECRET_KEY", "test")

COOKIE_DOMAIN = environ.get("COOKIE_DOMAIN", ".test.fundingservice.co.uk")
Expand Down
Loading

0 comments on commit 3adb765

Please sign in to comment.