Skip to content

refactor/jinja-global-variable #302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ cp app/config.py.example app/config.py
# Edit the variables' values.
# Rendering JWT_KEY:
python -c "import secrets; from pathlib import Path; f = Path('app/config.py'); f.write_text(f.read_text().replace('JWT_KEY_PLACEHOLDER', secrets.token_hex(32), 1));"
```

### Running tox
```shell
Expand Down
18 changes: 18 additions & 0 deletions app/internal/global_variable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from fastapi import Request

from app.dependencies import templates
from app.internal.security.ouath2 import (
Session, get_jwt_token, get_authorization_cookie
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use git precommit hooks to order that right and add a trailing comma

)


async def get_user_for_global_var(db: Session, jwt: str) -> str:
jwt_payload = await get_jwt_token(db, jwt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make the site query the database with every request to the site.
It's nullify the advantages of JWT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So maybe I could pull the token out of the cookie, and if the token is in the right length (and maybe more tests), I wiil set a global var: 'is_token'.
To verify that there is a logged in user.
Tell me what you think

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! You can also take the user details from the JWT, not from the database.

username = jwt_payload.get("sub")
return username


async def set_global_user_var(request: Request, db: Session, temp: templates):
jwt = await get_authorization_cookie(request)
user = await get_user_for_global_var(db, jwt)
temp.env.globals['user'] = user
52 changes: 52 additions & 0 deletions app/templates/global_var_test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn't be a file used just for testing in the templates directory.
Check the documentation for functions that allow you to load templates from strings instead.

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>PyLendar global var test</title>

</head>

<body>

<div>
<ul>
{% if user %}
<li>
<a href="#"> Profile </a>
</li>
<li>
<a href="#"> Sign Out </a>
</li>
<li>
<a href="#"> Agenda </a>
</li>
<li>
<a href="#"> Invitations </a>
</li>
{% endif %}

{% if not user %}
<li>
<a href="#"> Sign In </a>
</li>
<li>
<a href="#"> Sign Up </a>
</li>
{% endif %}

<li>
<a href="#">Search</a>
</li>

</ul>
</div>

{% if user %}
<h2>username: {{ user }}</h2>
{% endif %}

</body>
</html>
8 changes: 7 additions & 1 deletion tests/client_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
invitation, profile, weight,
)
from app.routers.salary import routes as salary
from tests import security_testing_routes
from tests import security_testing_routes, global_var_testing_routes
from tests.conftest import get_test_db, test_engine

main.app.include_router(global_var_testing_routes.router)
main.app.include_router(security_testing_routes.router)


Expand Down Expand Up @@ -44,6 +45,11 @@ def create_test_client(get_db_function) -> Generator[Session, None, None]:
Base.metadata.drop_all(bind=test_engine)


@pytest.fixture(scope="session")
def global_var_test_client() -> Iterator[TestClient]:
yield from create_test_client(global_var_testing_routes.get_db)


@pytest.fixture(scope="session")
def agenda_test_client() -> Generator[TestClient, None, None]:
yield from create_test_client(agenda.get_db)
Expand Down
21 changes: 21 additions & 0 deletions tests/global_var_testing_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from sqlalchemy.orm import Session
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this file can also be deleted


from app.dependencies import get_db, templates
from app.internal.global_variable import set_global_user_var
from fastapi import APIRouter, Depends, Request


router = APIRouter(
prefix="/global-variable",
tags=["global-variable"],
responses={404: {"description": "Not found"}},
)


@router.get("/")
async def global_var(request: Request, db: Session = Depends(get_db)):
await set_global_user_var(request, db, templates)

return templates.TemplateResponse("global_var_test.html", {
"request": request
})
28 changes: 28 additions & 0 deletions tests/test_global_variable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
REGISTER_DETAIL = {
'username': 'correct_user', 'full_name': 'full_name',
'password': 'correct_password', 'confirm_password': 'correct_password',
'email': '[email protected]', 'description': ""}

LOGIN_DATA = {'username': 'correct_user', 'password': 'correct_password'}


def test_global_var(global_var_test_client):
response = global_var_test_client.get("/global-variable")

assert response.ok
assert b'correct_user' not in response.content
assert b'Sign In' in response.content
assert b'Sign Up' in response.content

global_var_test_client.post(
global_var_test_client.app.url_path_for('register'),
data=REGISTER_DETAIL)
global_var_test_client.post(
global_var_test_client.app.url_path_for('login'),
data=LOGIN_DATA)

response = global_var_test_client.get("/global-variable")
assert response.ok
assert b'correct_user' in response.content
assert b'Sign In' not in response.content
assert b'Profile' in response.content