-
Notifications
You must be signed in to change notification settings - Fork 32
✨ web-server: Add Stand-alone Auth-App Entrypoint to Web-Server #7818
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
Merged
pcrespov
merged 41 commits into
ITISFoundation:master
from
pcrespov:is7781/new-auth-app
Jun 27, 2025
Merged
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
6cd2a96
split webserver helpers
pcrespov 47eb205
✨ [Tests] Enhance test fixtures with AsyncExitStack for better resour…
pcrespov 159f697
✨ Add authentication setup to application initialization
pcrespov 3865044
🎨 Refactor application initialization functions for improved clarity …
pcrespov 41aad35
✨ Add application factory name to settings and update app factory logic
pcrespov 8f023fb
moved test
pcrespov df6a393
✨ Update authentication check endpoint and improve documentation
pcrespov 57014cc
@sanderegg review: PC this attribute does not exist and mypy does no…
pcrespov fdb2698
📝 Fix docstring formatting and ensure setup_db is called in setup_sec…
pcrespov 8ddd971
✨ Implement login authentication module with routes for checking user…
pcrespov 376697d
✨ Refactor authentication decorators: move login_required to login_au…
pcrespov 9b7fa72
✨ Integrate setup_login_auth in login plugin and remove unnecessary s…
pcrespov 12c3378
impving setup
pcrespov e295a7d
✨ Replace app_module_setup with ensure_single_setup for login_auth setup
pcrespov e751a67
integrating login_auth
pcrespov 5b26e9f
fixes
pcrespov 809c7d8
flip
pcrespov c64c8ca
services/webserver api version: 0.69.0 → 0.69.1
pcrespov ded9e5a
drafting test
pcrespov 73b2900
rm dependency from storage
pcrespov 347fb32
refactor: move logging setup to app_factory and update settings usage
pcrespov ba90727
adapting user fxitures
pcrespov 144fa28
split login from users
pcrespov 5c105d9
pylint
pcrespov 2e3ae1a
pre
pcrespov 314b9e2
fix: update login decorators to use new authentication module
pcrespov 8f2cfb0
setup_db
pcrespov 4126d43
fixes user_role enum
pcrespov 9051308
fixes tests fixtures
pcrespov 1e7eea2
fixes tests fixtures
pcrespov 39c0b4c
fixing tests
pcrespov 2a1670e
cleanup imports
pcrespov 1c9e2b8
Merge branch 'master' into is7781/new-auth-app
pcrespov 66e26d1
Merge branch 'master' into is7961/refactor-pytest-users
pcrespov 4402941
bad imports
pcrespov 3bfe084
fixes tests
pcrespov 0e742b8
Merge branch 'is7961/refactor-pytest-users' into is7781/new-auth-app
pcrespov 389cf18
OAS
pcrespov 4fe1827
Merge branch 'master' into is7781/new-auth-app
pcrespov 75c12d2
Merge branch 'master' into is7781/new-auth-app
pcrespov 62aefc3
@sanderegg review:doc
pcrespov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 0.69.0 | ||
| 0.69.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 6 additions & 72 deletions
78
services/web/server/src/simcore_service_webserver/login/decorators.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,73 +1,7 @@ | ||
| import functools | ||
| import inspect | ||
| from typing import cast | ||
| from ..login_auth.decorators import get_user_id, login_required | ||
|
|
||
| from aiohttp import web | ||
| from models_library.users import UserID | ||
| from servicelib.aiohttp.typing_extension import HandlerAnyReturn | ||
| from servicelib.request_keys import RQT_USERID_KEY | ||
|
|
||
| from ..products import products_web | ||
| from ..security import security_web | ||
|
|
||
|
|
||
| def login_required(handler: HandlerAnyReturn) -> HandlerAnyReturn: | ||
| """Decorator that restrict access only for authorized users with permissions to access a given product | ||
|
|
||
| - User is considered authorized if check_authorized(request) raises no exception | ||
| - If authorized, it injects user_id in request[RQT_USERID_KEY] | ||
| - Use this decorator instead of aiohttp_security.api.login_required! | ||
|
|
||
| WARNING: Add always @router. decorator FIRST, e.g. | ||
|
|
||
| @router.get("/foo") | ||
| @login_required | ||
| async def get_foo(request: web.Request): | ||
| ... | ||
|
|
||
| and NOT as | ||
|
|
||
| @login_required | ||
| @router.get("/foo") | ||
| async def get_foo(request: web.Request): | ||
| ... | ||
|
|
||
| since the latter will register in `router` get_foo **without** `login_required` | ||
| """ | ||
| assert set(inspect.signature(handler).parameters.values()) == { # nosec | ||
| inspect.Parameter( | ||
| name="request", | ||
| kind=inspect.Parameter.POSITIONAL_OR_KEYWORD, | ||
| annotation=web.Request, | ||
| ) | ||
| }, f"Expected {handler.__name__} with request as signature, got {handler.__annotations__}" | ||
|
|
||
| @functools.wraps(handler) | ||
| async def _wrapper(request: web.Request): | ||
| """ | ||
| Raises: | ||
| HTTPUnauthorized: if unauthorized user | ||
| HTTPForbidden: if user not allowed in product | ||
| """ | ||
| # WARNING: note that check_authorized is patched in some tests. | ||
| # Careful when changing the function signature | ||
| user_id = await security_web.check_user_authorized(request) | ||
| product_name = products_web.get_product_name(request) | ||
|
|
||
| await security_web.check_user_permission( | ||
| request, | ||
| security_web.PERMISSION_PRODUCT_LOGIN_KEY, | ||
| context=security_web.AuthContextDict( | ||
| product_name=product_name, | ||
| authorized_uid=user_id, | ||
| ), | ||
| ) | ||
|
|
||
| request[RQT_USERID_KEY] = user_id | ||
| return await handler(request) | ||
|
|
||
| return _wrapper | ||
|
|
||
|
|
||
| def get_user_id(request: web.Request) -> UserID: | ||
| return cast(UserID, request[RQT_USERID_KEY]) | ||
| __all__: tuple[str, ...] = ( | ||
| "get_user_id", | ||
| "login_required", | ||
| ) | ||
| # nopycln: file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
30 changes: 30 additions & 0 deletions
30
services/web/server/src/simcore_service_webserver/login_auth/_controller_rest.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import logging | ||
|
|
||
| from aiohttp import web | ||
| from aiohttp.web import RouteTableDef | ||
| from servicelib.aiohttp import status | ||
|
|
||
| from .._meta import API_VTAG | ||
| from .decorators import login_required | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| routes = RouteTableDef() | ||
|
|
||
|
|
||
| @routes.get(f"/{API_VTAG}/auth:check", name="check_auth") | ||
| @login_required | ||
| async def check_auth(request: web.Request) -> web.Response: | ||
| """Lightweight endpoint for checking if users are authenticated & authorized to this product | ||
|
|
||
| Used primarily by Traefik auth middleware to verify session cookies | ||
| SEE https://doc.traefik.io/traefik/middlewares/http/forwardauth | ||
| """ | ||
| # NOTE: for future development | ||
| # if database access is added here, services like jupyter-math | ||
| # which load a lot of resources will have a big performance hit | ||
| # consider caching some properties required by this endpoint or rely on Redis | ||
| assert request # nosec | ||
|
|
||
| return web.json_response(status=status.HTTP_204_NO_CONTENT) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.