Skip to content
Merged
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
75 changes: 38 additions & 37 deletions app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from sqlalchemy.orm import Session

from app import api
from app.core.core_endpoints import coredata_core, models_core
from app.core.core_endpoints import coredata_core
from app.core.google_api.google_api import GoogleAPI
from app.core.groups import models_groups
from app.core.groups.groups_type import GroupType
Expand All @@ -41,7 +41,7 @@
get_redis_client,
init_state,
)
from app.module import all_modules, module_list
from app.module import all_modules, module_list, permissions_list
from app.types.exceptions import (
ContentHTTPException,
GoogleAPIInvalidCredentialsError,
Expand Down Expand Up @@ -299,7 +299,6 @@ def initialize_module_visibility(
coredata_core.ModuleVisibilityAwareness,
db,
)

new_modules = [
module
for module in module_list
Expand All @@ -308,41 +307,41 @@ def initialize_module_visibility(
# Is run to create default module visibilities or when the table is empty
if new_modules:
hyperion_error_logger.info(
f"Startup: Some modules visibility settings are empty, initializing them ({[module.root for module in new_modules]})",
f"Startup: Some modules visibility settings are empty, initializing them : ({[module.root for module in new_modules]})",
)
for module in new_modules:
if module.default_allowed_groups_ids is not None:
for group_id in module.default_allowed_groups_ids:
module_group_visibility = models_core.ModuleGroupVisibility(
root=module.root,
allowed_group_id=group_id,
)
try:
initialization.create_module_group_visibility_sync(
module_visibility=module_group_visibility,
db=db,
)
except ValueError as error:
hyperion_error_logger.fatal(
f"Startup: Could not add module visibility {module.root} in the database: {error}",
)
if module.default_allowed_account_types is not None:
for account_type in module.default_allowed_account_types:
module_account_type_visibility = (
models_core.ModuleAccountTypeVisibility(
root=module.root,
allowed_account_type=account_type,
)
)
try:
initialization.create_module_account_type_visibility_sync(
module_visibility=module_account_type_visibility,
db=db,
)
except ValueError as error:
hyperion_error_logger.fatal(
f"Startup: Could not add module visibility {module.root} in the database: {error}",
)
module_permissions = (
list(module.permissions) if module.permissions else []
)
access_permission = next(
(p for p in module_permissions if p.startswith("access_")),
None,
)
if access_permission:
if module.default_allowed_groups_ids is not None:
for group_id in module.default_allowed_groups_ids:
try:
initialization.create_group_permission_sync(
group_id=group_id,
permission_name=access_permission,
db=db,
)
except ValueError as error:
hyperion_error_logger.fatal(
f"Startup: Could not add module visibility {module.root} in the database: {error}",
)
if module.default_allowed_account_types is not None:
for account_type in module.default_allowed_account_types:
try:
initialization.create_account_type_permission_sync(
account_type=account_type,
permission_name=access_permission,
db=db,
)
except ValueError as error:
hyperion_error_logger.fatal(
f"Startup: Could not add module visibility {module.root} in the database: {error}",
)
initialization.set_core_data_sync(
coredata_core.ModuleVisibilityAwareness(
roots=[module.root for module in module_list],
Expand Down Expand Up @@ -438,6 +437,8 @@ def init_db(
sync_engine=sync_engine,
hyperion_error_logger=hyperion_error_logger,
)
with Session(sync_engine) as db:
initialization.clean_permissions_sync(db, permissions_list)


async def init_google_API(
Expand Down Expand Up @@ -715,7 +716,7 @@ async def validation_exception_handler(
)

return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
)

Expand Down
29 changes: 10 additions & 19 deletions app/core/auth/endpoints_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from app.types.module import CoreModule
from app.types.scopes_type import ScopeType
from app.utils.auth.providers import BaseAuthClient
from app.utils.tools import is_user_member_of_any_group
from app.utils.tools import has_user_permission

router = APIRouter(tags=["Auth"])

Expand Down Expand Up @@ -314,12 +314,14 @@ async def authorize_validation(
status_code=status.HTTP_302_FOUND,
)

# The auth_client may restrict the usage of the client to specific Hyperion groups.
# For example, only ECLAIR members may be allowed to access the wiki
if auth_client.allowed_groups is not None:
if not is_user_member_of_any_group(
user=user,
allowed_groups=auth_client.allowed_groups,
# The auth_client may restrict the usage of the client to specific Hyperion permissions
if auth_client.permission is not None:
if not (
await has_user_permission(
user=user,
permission_name=auth_client.permission,
db=db,
)
):
hyperion_access_logger.warning(
f"Authorize-validation: user is not member of an allowed group {authorizereq.email} ({request_id})",
Expand All @@ -331,18 +333,7 @@ async def authorize_validation(
),
status_code=status.HTTP_302_FOUND,
)
if auth_client.allowed_account_types is not None:
if user.account_type not in auth_client.allowed_account_types:
hyperion_access_logger.warning(
f"Authorize-validation: user account type is not allowed {authorizereq.email} ({request_id})",
)
return RedirectResponse(
settings.CLIENT_URL
+ calypsso.get_message_relative_url(
message_type=calypsso.TypeMessage.user_account_type_not_allowed,
),
status_code=status.HTTP_302_FOUND,
)

# We generate a new authorization_code
# The authorization code MUST expire
# shortly after it is issued to mitigate the risk of leaks. A
Expand Down
123 changes: 0 additions & 123 deletions app/core/core_endpoints/cruds_core.py
Original file line number Diff line number Diff line change
@@ -1,132 +1,9 @@
from collections.abc import Sequence
from datetime import datetime

from sqlalchemy import delete, func, select, text
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.core_endpoints import models_core
from app.core.groups.groups_type import AccountType
from app.core.users import models_users


async def get_modules_by_user(
user: models_users.CoreUser,
db: AsyncSession,
) -> list[str]:
"""Return the modules a user has access to"""

userGroupIds = [group.id for group in user.groups]

result_group = list(
(
await db.execute(
select(models_core.ModuleGroupVisibility.root)
.where(
models_core.ModuleGroupVisibility.allowed_group_id.in_(
userGroupIds,
),
)
.group_by(models_core.ModuleGroupVisibility.root),
)
)
.unique()
.scalars()
.all(),
)
result_account_type = list(
(
await db.execute(
select(models_core.ModuleAccountTypeVisibility.root).where(
models_core.ModuleAccountTypeVisibility.allowed_account_type
== user.account_type,
),
)
)
.unique()
.scalars()
.all(),
)

return result_group + result_account_type


async def get_allowed_groups_by_root(
root: str,
db: AsyncSession,
) -> Sequence[str]:
"""Return the groups allowed to access to a specific root"""

result = await db.execute(
select(
models_core.ModuleGroupVisibility.allowed_group_id,
).where(models_core.ModuleGroupVisibility.root == root),
)

return result.unique().scalars().all()


async def get_allowed_account_types_by_root(
root: str,
db: AsyncSession,
) -> Sequence[str]:
"""Return the groups allowed to access to a specific root"""

result = await db.execute(
select(
models_core.ModuleAccountTypeVisibility.allowed_account_type,
).where(models_core.ModuleAccountTypeVisibility.root == root),
)

return result.unique().scalars().all()


async def create_module_group_visibility(
module_visibility: models_core.ModuleGroupVisibility,
db: AsyncSession,
) -> None:
"""Create a new module visibility in database and return it"""

db.add(module_visibility)
await db.flush()


async def create_module_account_type_visibility(
module_visibility: models_core.ModuleAccountTypeVisibility,
db: AsyncSession,
) -> None:
"""Create a new module visibility in database and return it"""

db.add(module_visibility)
await db.flush()


async def delete_module_group_visibility(
root: str,
allowed_group_id: str,
db: AsyncSession,
):
await db.execute(
delete(models_core.ModuleGroupVisibility).where(
models_core.ModuleGroupVisibility.root == root,
models_core.ModuleGroupVisibility.allowed_group_id == allowed_group_id,
),
)
await db.flush()


async def delete_module_account_type_visibility(
root: str,
allowed_account_type: AccountType,
db: AsyncSession,
):
await db.execute(
delete(models_core.ModuleAccountTypeVisibility).where(
models_core.ModuleAccountTypeVisibility.root == root,
models_core.ModuleAccountTypeVisibility.allowed_account_type
== allowed_account_type,
),
)
await db.flush()


async def get_core_data_crud(
Expand Down
Loading