Skip to content

Commit

Permalink
Internal Columns
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnGrubba committed Jul 2, 2024
1 parent 80f5916 commit 0e6cb53
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 9 deletions.
8 changes: 7 additions & 1 deletion config/configtemplate.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"auto_cookie_name": "session"
},
"internal": {
"internal_api_key": "CHANGE_ME_NOW"
"internal_api_key": "CHANGE_ME_NOW",
"internal_columns": [
"_id"
]
},
"account_features": {
"enable_change_password": true
}
}
Empty file.
8 changes: 7 additions & 1 deletion docs/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,10 @@ Make sure that all parameters are set correctly before starting the service.

| Parameter | Description |
|------------|-------------|
| `internal.internal_api_key` | **Datatype:** String <br> **Default:** `CHANGE_ME_NOW` <br> This is **sensitive** information and must **never** be exposed anywhere. |
| `internal.internal_api_key` | **Datatype:** String <br> **Default:** `CHANGE_ME_NOW` <br> This is **sensitive** information and must **never** be exposed anywhere. |
| `internal.internal_columns` | **Datatype:** List <br> **Default:** `["_id"]` <br> Columns that should only be revealed via the internal API. This example will never reveal `_id` to public endpoints, but just to the `/internal` endpoints as well as E-Mails. |

### Account Features Configuration
| Parameter | Description |
|------------|-------------|
| `account_features.enable_change_password` | **Datatype:** Boolean <br> **Default:** `true` <br> Enable or disable the password reset feature. |
9 changes: 9 additions & 0 deletions docs/information.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ To guarantee the security of your user data, EZAuth uses the following security
- **2FA**: Two-factor authentication can be enabled for users.
- **OAuth2**: OAuth2 can be enabled for users.

## Documentation
You are reading the informative documentation for EZAuth.
If you need a documentation of all the endpoints, you can start the service and navigate to the `/docs` endpoint to find the API Documentation.
Because we utilize FastAPI, the documentation is done automatically and displayed via Swagger UI.
This also makes the API OpenAPI compliant.

!!! Info "API Documentation"
Navigate to [`http://localhost:3250/docs`](http://localhost:3250/docs) to see the API Documentation.

## Code Examples

!!! Info "Official Libraries"
Expand Down
23 changes: 23 additions & 0 deletions src/api/dependencies/authenticated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from fastapi import HTTPException, Cookie
from tools import SessionConfig, InternalConfig
from tools import users_collection, sessions_collection
import logging


async def get_pub_user(
session_token: str = Cookie(default=None, alias=SessionConfig.auto_cookie_name)
):
if not session_token:
logging.debug("No session token")
raise HTTPException(status_code=401)
session = sessions_collection.find_one({"session_token": session_token})
if not session:
logging.debug("No session found")
raise HTTPException(status_code=401)
user = users_collection.find_one(
{"_id": session["user_id"]}, InternalConfig.internal_columns
)
if not user:
logging.debug("No user for session found")
raise HTTPException(status_code=401)
return user
11 changes: 11 additions & 0 deletions src/api/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,14 @@ async def broadcast_email(
broadcast_request.mongodb_search_condition,
)
return {"status": "E-Mail Task Started"}


@router.get("/profile")
async def profile():
"""
# Get Profile Information
## Description
This endpoint is used to get the whole profile information of the user. (Including Internal Information)
"""
return {"status": "ok"}
2 changes: 2 additions & 0 deletions src/api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from api.signup import router as signupRouter
from api.login import router as loginRouter
from api.internal import router as internalRouter
from api.profile import router as profileRouter
import logging

logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO)
Expand Down Expand Up @@ -37,3 +38,4 @@ async def root():
app.include_router(signupRouter)
app.include_router(loginRouter)
app.include_router(internalRouter)
app.include_router(profileRouter)
20 changes: 20 additions & 0 deletions src/api/profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from fastapi import APIRouter, Depends
from api.dependencies.authenticated import get_pub_user


router = APIRouter(
prefix="/profile",
tags=["Profile"],
dependencies=[Depends(get_pub_user)],
)


@router.get("/")
async def profile(user: dict = Depends(get_pub_user)):
"""
# Get Profile Information
## Description
This endpoint is used to get the public profile information of the user.
"""
return user
10 changes: 8 additions & 2 deletions src/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
from .db import users_collection, sessions_collection, insecure_cols
from .conf import SignupConfig, EmailConfig, SessionConfig, InternalConfig
from .db import users_collection, sessions_collection
from .conf import (
SignupConfig,
EmailConfig,
SessionConfig,
InternalConfig,
AccountFeaturesConfig,
)
from .mail import send_email, broadcast_emails
13 changes: 13 additions & 0 deletions src/tools/conf.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import json
from collections import ChainMap

config = json.load(open("/src/app/config/config.json", "rb"))

# Columns that should never leave EZAuth (maybe get more in the future)
insecure_cols = {"password": 0}
# Columns that can leave EZAuth but should only be used internally can be defined in config


class SignupConfig:
enable_conf_email: bool = config["signup"]["enable_conf_email"]
Expand All @@ -27,3 +32,11 @@ class SessionConfig:

class InternalConfig:
internal_api_key: str = config["internal"]["internal_api_key"]
internal_columns: dict = dict(
ChainMap(*[{col: 0} for col in config["internal"]["internal_columns"]])
)
internal_columns.update(insecure_cols)


class AccountFeaturesConfig:
enable_change_password: bool = config["account_features"]["enable_change_password"]
5 changes: 2 additions & 3 deletions src/tools/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
users_collection = db.get_collection("users")
sessions_collection = db.get_collection("sessions")

# Find Users by email and username fast (id is already indexed)
users_collection.create_index("email", unique=True)
users_collection.create_index("username", unique=True)
# Find Sessions by session_token fast
sessions_collection.create_index("session_token", unique=True)

try:
Expand All @@ -21,6 +23,3 @@
sessions_collection.create_index(
"createdAt", expireAfterSeconds=SessionConfig.session_expiry_seconds
)

# Columns that should never leave EZAuth (maybe get more in the future)
insecure_cols = {"password": 0}
6 changes: 4 additions & 2 deletions src/tools/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from . import EmailConfig
import logging
from threading import Lock
from tools import users_collection, insecure_cols
from tools import users_collection, InternalConfig


def load_template(template_name: str, **kwargs) -> str:
Expand Down Expand Up @@ -39,7 +39,9 @@ def broadcast_emails(
):
# Iter over all users and send them an email
try:
cursor = users_collection.find(mongodb_search_condition, insecure_cols)
cursor = users_collection.find(
mongodb_search_condition, InternalConfig.internal_columns
)
for user in cursor:
try:
send_email(template_name, user["email"], **user)
Expand Down

0 comments on commit 0e6cb53

Please sign in to comment.