Skip to content

Commit 96affe2

Browse files
authored
refactor: make SECRET_SIGN_KEY auto-generated on app start up instead of environment variable | [AntonioMrtz#277]
1 parent e26de3d commit 96affe2

File tree

19 files changed

+72
-41
lines changed

19 files changed

+72
-41
lines changed

.github/disabled_workflows/backend-tests-streaming-serverless.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
python -m pytest tests/
3434
env:
3535
MONGO_URI: mongodb://root:root@localhost:27017/
36-
SECRET_KEY_SIGN: "f24e2f3ac557d487b6d879fb2d86f2b2"
3736
SERVERLESS_FUNCTION_URL: ${{ secrets.SERVERLESS_FUNCTION_URL }}
3837
ARCH: "SERVERLESS"
3938
ENV_VALUE: "PROD"

.github/disabled_workflows/generate-docs.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ jobs:
3030
python generate-docs.py
3131
env:
3232
MONGO_URI : ${{ secrets.MONGO_URI }}
33-
SECRET_KEY_SIGN : none
3433
SERVERLESS_FUNCTION_URL : none
3534
ARCH : BLOB
3635
ENV_VALUE : TEST

.github/disabled_workflows/generate-openapi-schema-client.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ jobs:
3030
python -m app.tools.generate_openapi
3131
env:
3232
MONGO_URI: ${{ secrets.MONGO_URI }}
33-
SECRET_KEY_SIGN: none
3433
ARCH: BLOB
3534
ENV_VALUE: PROD
3635

.github/workflows/backend-tests-database-blob.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,5 @@ jobs:
3333
python -m pytest tests/
3434
env:
3535
MONGO_URI: mongodb://root:root@localhost:27017/
36-
SECRET_KEY_SIGN: "f24e2f3ac557d487b6d879fb2d86f2b2"
3736
ARCH: "BLOB"
3837
ENV_VALUE: "PROD"

.github/workflows/openapi-check-updated.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ jobs:
4747
python -m app.tools.generate_openapi
4848
env:
4949
MONGO_URI: mongodb://root:root@localhost:27017/
50-
SECRET_KEY_SIGN: "f24e2f3ac557d487b6d879fb2d86f2b2"
5150
ARCH: "BLOB"
5251
ENV_VALUE: "PROD"
5352

Backend/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ EXPOSE 8000
1919
#CMD ["tail", "-f", "/dev/null"]
2020

2121
#docker build -t spotify_electron_backend_image .
22-
#docker run -d --name spotify_electron_backend -e MONGO_URI=mongo-uri SECRET_KEY_SIGN=secret-key-sign SERVERLESS_FUNCTION_URL=serverless-function-url ARCH=BLOB ENV_VALUE=PROD -p 8000:8000 spotify_electron_backend_image
22+
#docker run -d --name spotify_electron_backend -e MONGO_URI=mongo-uri SERVERLESS_FUNCTION_URL=serverless-function-url ARCH=BLOB ENV_VALUE=PROD -p 8000:8000 spotify_electron_backend_image

Backend/app/__main__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
from fastapi import FastAPI
1616
from fastapi.middleware.cors import CORSMiddleware
1717

18-
from app.common.app_schema import AppConfig, AppEnvironment, AppInfo
18+
from app.auth.auth_schema import AuthConfig
19+
from app.common.app_schema import AppAuthConfig, AppConfig, AppEnvironment, AppInfo
1920
from app.common.PropertiesManager import PropertiesManager
2021
from app.database.DatabaseConnectionManager import DatabaseConnectionManager
2122
from app.logging.logging_constants import LOGGING_MAIN
@@ -53,6 +54,12 @@ async def lifespan_handler(app: FastAPI) -> AsyncGenerator[None, Any]:
5354
environment = PropertiesManager.get_environment()
5455
connection_uri = getattr(PropertiesManager, AppEnvironment.MONGO_URI_ENV_NAME)
5556

57+
AuthConfig.init_auth_config(
58+
access_token_expire_minutes=AppAuthConfig.ACCESS_TOKEN_EXPIRE_MINUTES,
59+
verification_algorithm=AppAuthConfig.VERTIFICATION_ALGORITHM,
60+
days_to_expire_cookie=AppAuthConfig.DAYS_TO_EXPIRE_COOKIE,
61+
)
62+
5663
DatabaseConnectionManager.init_database_connection(
5764
environment=environment, connection_uri=connection_uri
5865
)

Backend/app/auth/auth_schema.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Authentication schema for domain model
33
"""
44

5+
import binascii
6+
import os
57
from dataclasses import dataclass
68

79
from app.exceptions.base_exceptions_schema import SpotifyElectronException
@@ -30,6 +32,38 @@ def __init__(self, auth_value: str) -> None:
3032
self.headers[TOKEN_HEADER_FIELD_NAME] = auth_value
3133

3234

35+
class AuthConfig:
36+
"""Stores application authentication config"""
37+
38+
VERTIFICATION_ALGORITHM: str
39+
ACCESS_TOKEN_EXPIRE_MINUTES: int
40+
DAYS_TO_EXPIRE_COOKIE: int
41+
SIGNING_SECRET_KEY: str
42+
"""Key for signing JWT, generated using `openssl rand -hex 16`"""
43+
44+
@classmethod
45+
def init_auth_config(
46+
cls,
47+
verification_algorithm: str,
48+
access_token_expire_minutes: int,
49+
days_to_expire_cookie: int,
50+
) -> None:
51+
"""Init authentication configuration, required to start the app successfully
52+
53+
Args:
54+
verification_algorithm (str): JWT verification algorithm
55+
access_token_expire_minutes (int): minutes until the JWT expires
56+
days_to_expire_cookie (int): days until cookies expire
57+
"""
58+
random_bytes = os.urandom(16)
59+
hex_string = binascii.hexlify(random_bytes).decode("utf-8")
60+
cls.SIGNING_SECRET_KEY = hex_string
61+
62+
cls.VERTIFICATION_ALGORITHM = verification_algorithm
63+
cls.ACCESS_TOKEN_EXPIRE_MINUTES = access_token_expire_minutes
64+
cls.DAYS_TO_EXPIRE_COOKIE = days_to_expire_cookie
65+
66+
3367
class BadJWTTokenProvidedException(SpotifyElectronException):
3468
"""Bad JWT Token provided"""
3569

Backend/app/auth/auth_service.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
from typing import Any
77

88
import bcrypt
9-
from fastapi.security import OAuth2PasswordBearer
109
from jose import JWTError, jwt
1110

1211
import app.spotify_electron.user.base_user_service as base_user_service
1312
import app.spotify_electron.user.validations.base_user_service_validations as base_user_service_validations # noqa: E501
1413
from app.auth.auth_schema import (
14+
AuthConfig,
1515
BadJWTTokenProvidedException,
1616
CreateJWTException,
1717
JWTExpiredException,
@@ -24,8 +24,6 @@
2424
UserUnauthorizedException,
2525
VerifyPasswordException,
2626
)
27-
from app.common.app_schema import AppEnvironment
28-
from app.common.PropertiesManager import PropertiesManager
2927
from app.exceptions.base_exceptions_schema import BadParameterException
3028
from app.logging.logging_constants import LOGGING_AUTH_SERVICE
3129
from app.logging.logging_schema import SpotifyElectronLogger
@@ -41,9 +39,6 @@
4139
ACCESS_TOKEN_EXPIRE_MINUTES = 10080 # 7 days
4240
DAYS_TO_EXPIRE_COOKIE = 7
4341

44-
45-
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="users/whoami/")
46-
4742
auth_service_logger = SpotifyElectronLogger(LOGGING_AUTH_SERVICE).getLogger()
4843

4944

@@ -73,7 +68,7 @@ def create_access_token(data: dict[str, str], expires_delta: timedelta | None =
7368
to_encode.update({"exp": expire}) # type: ignore
7469
encoded_jwt = jwt.encode(
7570
to_encode,
76-
getattr(PropertiesManager, AppEnvironment.SECRET_KEY_SIGN_ENV_NAME),
71+
AuthConfig.SIGNING_SECRET_KEY,
7772
algorithm=ALGORITHM,
7873
)
7974
except Exception as exception:
@@ -105,7 +100,7 @@ def get_jwt_token_data(
105100
try:
106101
payload = jwt.decode(
107102
token_raw_data, # type: ignore
108-
getattr(PropertiesManager, AppEnvironment.SECRET_KEY_SIGN_ENV_NAME),
103+
AuthConfig.SIGNING_SECRET_KEY,
109104
algorithms=[ALGORITHM],
110105
)
111106
username = payload.get("access_token")
@@ -323,7 +318,7 @@ def validate_jwt(token: str) -> None:
323318
try:
324319
decoded_token = jwt.decode(
325320
token,
326-
getattr(PropertiesManager, AppEnvironment.SECRET_KEY_SIGN_ENV_NAME),
321+
AuthConfig.SIGNING_SECRET_KEY,
327322
ALGORITHM,
328323
)
329324
validate_token_is_expired(decoded_token)

Backend/app/common/PropertiesManager.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ def __init__(self) -> None:
3131
self.config_sections = [AppConfig.APP_INI_SECTION]
3232
self.env_variables = [
3333
AppEnvironment.MONGO_URI_ENV_NAME,
34-
AppEnvironment.SECRET_KEY_SIGN_ENV_NAME,
3534
AppEnvironment.SERVERLESS_URL_ENV_NAME,
3635
AppEnvironment.ENV_VALUE_ENV_NAME,
3736
]

0 commit comments

Comments
 (0)