Implement user links
This commit is contained in:
@@ -16,12 +16,15 @@ from app.models.event import (
|
|||||||
EventsPublic,
|
EventsPublic,
|
||||||
EventUpdate,
|
EventUpdate,
|
||||||
EventUserLink,
|
EventUserLink,
|
||||||
|
EventUserLinkCreate,
|
||||||
|
EventUserLinkUpdate,
|
||||||
|
EventUserLinkPublic,
|
||||||
|
EventUserLinksPublic,
|
||||||
)
|
)
|
||||||
from app.models.user import (
|
from app.models.user import (
|
||||||
PermissionModule,
|
PermissionModule,
|
||||||
PermissionPart,
|
PermissionPart,
|
||||||
PermissionRight,
|
PermissionRight,
|
||||||
PermissionRightObject,
|
|
||||||
User,
|
User,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,7 +90,7 @@ def read_event(session: SessionDep, current_user: CurrentUser, id: RowId) -> Any
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.READ,
|
rights=PermissionRight.READ,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.READ)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.READ)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
return event
|
return event
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@ def update_event(
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.UPDATE,
|
rights=PermissionRight.UPDATE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.UPDATE)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.UPDATE)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
return Event.update(db_obj=event, in_obj=event_in, session=session)
|
return Event.update(db_obj=event, in_obj=event_in, session=session)
|
||||||
|
|
||||||
@@ -154,7 +157,7 @@ def delete_event(
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.DELETE,
|
rights=PermissionRight.DELETE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.DELETE)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.DELETE)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
session.delete(event)
|
session.delete(event)
|
||||||
session.commit()
|
session.commit()
|
||||||
@@ -167,18 +170,56 @@ def delete_event(
|
|||||||
# region # Events / Users ######################################################
|
# region # Events / Users ######################################################
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{id}/users/{user_id}", tags=[ApiTags.USERS])
|
@router.get("/{event_id}/users/", response_model=EventUserLinksPublic)
|
||||||
def add_user_to_event(
|
def read_event_users(
|
||||||
|
session: SessionDep, current_user: CurrentUser, event_id: RowId, skip: int = 0, limit: int = 100
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
Retrieve all event users.
|
||||||
|
"""
|
||||||
|
|
||||||
|
event = session.get(Event, event_id)
|
||||||
|
if not event:
|
||||||
|
raise HTTPException(status_code=404, detail="Event not found")
|
||||||
|
|
||||||
|
if not current_user.has_permissions(
|
||||||
|
module=PermissionModule.EVENT,
|
||||||
|
part=PermissionPart.ADMIN,
|
||||||
|
rights=PermissionRight.MANAGE_USERS,
|
||||||
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_USERS)):
|
||||||
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
|
count_statement = (select(func.count())
|
||||||
|
.select_from(EventUserLink)
|
||||||
|
.where(EventUserLink.event_id == event.id)
|
||||||
|
)
|
||||||
|
count = session.exec(count_statement).one()
|
||||||
|
statement = (select(EventUserLink)
|
||||||
|
.where(EventUserLink.event_id == event.id)
|
||||||
|
.offset(skip)
|
||||||
|
.limit(limit)
|
||||||
|
)
|
||||||
|
event_user_links = session.exec(statement).all()
|
||||||
|
|
||||||
|
return EventUserLinksPublic(data=event_user_links, count=count)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{event_id}/users/", tags=[ApiTags.USERS], response_model=EventUserLinkPublic)
|
||||||
|
def create_event_user(
|
||||||
session: SessionDep,
|
session: SessionDep,
|
||||||
current_user: CurrentUser,
|
current_user: CurrentUser,
|
||||||
id: RowId,
|
event_id: RowId,
|
||||||
user_id: RowId,
|
user_in: EventUserLinkCreate,
|
||||||
rights_in: PermissionRightObject,
|
) -> Any:
|
||||||
) -> Message:
|
|
||||||
"""
|
"""
|
||||||
Add or update a user to an event.
|
Create a new link between a user and an event.
|
||||||
"""
|
"""
|
||||||
event = session.get(Event, id)
|
|
||||||
|
if user_in.rights & ~PermissionRight.ADMIN:
|
||||||
|
# FIXME: find a proper richts checker
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid permission rights")
|
||||||
|
|
||||||
|
event = session.get(Event, event_id)
|
||||||
if not event:
|
if not event:
|
||||||
raise HTTPException(status_code=404, detail="Event not found")
|
raise HTTPException(status_code=404, detail="Event not found")
|
||||||
|
|
||||||
@@ -186,45 +227,89 @@ def add_user_to_event(
|
|||||||
module=PermissionModule.EVENT,
|
module=PermissionModule.EVENT,
|
||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.MANAGE_USERS,
|
rights=PermissionRight.MANAGE_USERS,
|
||||||
) and not (
|
) and not (event.user_has_rights(user=current_user, rights=(PermissionRight.MANAGE_USERS | user_in.rights))):
|
||||||
event.user_has_rights(
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
user=current_user, rights=(PermissionRight.MANAGE_USERS | rights_in.rights)
|
|
||||||
)
|
|
||||||
):
|
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
|
||||||
|
|
||||||
user = session.get(User, user_id)
|
user = session.get(User, user_in.user_id)
|
||||||
if not event:
|
if not user:
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
event.add_user(user=user, rights=rights_in.rights, session=session)
|
user_link = event.get_user_link(user)
|
||||||
return Message(
|
if user_link:
|
||||||
message="User added successfully"
|
raise HTTPException(status_code=400, detail="User already part of this event")
|
||||||
)
|
|
||||||
|
return event.add_user(user=user, rights=user_in.rights, session=session)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{id}/users/{user_id}", tags=[ApiTags.USERS])
|
@router.put("/{event_id}/users/{user_id}", tags=[ApiTags.USERS], response_model=EventUserLinkPublic)
|
||||||
def remove_user_from_event(
|
def update_user_in_event(
|
||||||
session: SessionDep, current_user: CurrentUser, id: RowId, user_id: RowId
|
session: SessionDep,
|
||||||
) -> Message:
|
current_user: CurrentUser,
|
||||||
|
event_id: RowId,
|
||||||
|
user_id: RowId,
|
||||||
|
user_in: EventUserLinkUpdate,
|
||||||
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Remove a user from an event.
|
Update a user link within an event.
|
||||||
"""
|
"""
|
||||||
event = session.get(Event, id)
|
|
||||||
|
event = session.get(Event, event_id)
|
||||||
if not event:
|
if not event:
|
||||||
raise HTTPException(status_code=404, detail="Event not found")
|
raise HTTPException(status_code=404, detail="Event not found")
|
||||||
|
|
||||||
if not current_user.has_permissions(
|
|
||||||
module=PermissionModule.EVENT,
|
|
||||||
part=PermissionPart.ADMIN,
|
|
||||||
rights=PermissionRight.MANAGE_USERS,
|
|
||||||
) and not event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_USERS):
|
|
||||||
raise HTTPException(status_code=403, detail="Not enough permissions")
|
|
||||||
|
|
||||||
user = session.get(User, user_id)
|
user = session.get(User, user_id)
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
|
valid_flags = sum(flag.value for flag in PermissionRight)
|
||||||
|
if user_in.rights & ~valid_flags:
|
||||||
|
# FIXME: find a proper richts checker
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid permission rights")
|
||||||
|
|
||||||
|
if not current_user.has_permissions(
|
||||||
|
module=PermissionModule.EVENT,
|
||||||
|
part=PermissionPart.ADMIN,
|
||||||
|
rights=PermissionRight.MANAGE_USERS,
|
||||||
|
) and not (event.user_has_rights(user=current_user, rights=(PermissionRight.MANAGE_USERS | user_in.rights))):
|
||||||
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
|
user_link = event.get_user_link(user)
|
||||||
|
if not user_link:
|
||||||
|
raise HTTPException(status_code=404, detail="User is not part of this event")
|
||||||
|
|
||||||
|
return event.update_user(user=user, rights=user_in.rights, session=session)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{event_id}/users/{user_id}", tags=[ApiTags.USERS])
|
||||||
|
def remove_user_from_event(
|
||||||
|
session: SessionDep, current_user: CurrentUser, event_id: RowId, user_id: RowId
|
||||||
|
) -> Message:
|
||||||
|
"""
|
||||||
|
Remove a user link from an event.
|
||||||
|
"""
|
||||||
|
event = session.get(Event, event_id)
|
||||||
|
if not event:
|
||||||
|
raise HTTPException(status_code=404, detail="Event not found")
|
||||||
|
|
||||||
|
user = session.get(User, user_id)
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
|
if not current_user.has_permissions(
|
||||||
|
module=PermissionModule.EVENT,
|
||||||
|
part=PermissionPart.ADMIN,
|
||||||
|
rights=PermissionRight.MANAGE_USERS,
|
||||||
|
):
|
||||||
|
if current_user.id == user.id:
|
||||||
|
raise HTTPException(status_code=403, detail="Users are not allowed to delete themselves when they are not an super admin")
|
||||||
|
|
||||||
|
if not event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_USERS):
|
||||||
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
|
user_link = event.get_user_link(user)
|
||||||
|
if not user_link:
|
||||||
|
raise HTTPException(status_code=404, detail="User is not part of this event")
|
||||||
|
|
||||||
event.remove_user(user=user, session=session)
|
event.remove_user(user=user, session=session)
|
||||||
return Message(
|
return Message(
|
||||||
message="User removed successfully"
|
message="User removed successfully"
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ def read_team(session: SessionDep, current_user: CurrentUser, id: RowId) -> Any:
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.READ,
|
rights=PermissionRight.READ,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
return team
|
return team
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ def create_team(
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.UPDATE,
|
rights=PermissionRight.UPDATE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
team = Team.create(create_obj=team_in, session=session)
|
team = Team.create(create_obj=team_in, session=session)
|
||||||
return team
|
return team
|
||||||
@@ -146,7 +146,7 @@ def update_team(
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.UPDATE,
|
rights=PermissionRight.UPDATE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
# Check rights for the new event data
|
# Check rights for the new event data
|
||||||
if team_in.event_id:
|
if team_in.event_id:
|
||||||
@@ -159,7 +159,7 @@ def update_team(
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.UPDATE,
|
rights=PermissionRight.UPDATE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
# Update the team
|
# Update the team
|
||||||
team = Team.update(db_obj=team, in_obj=team_in, session=session)
|
team = Team.update(db_obj=team, in_obj=team_in, session=session)
|
||||||
@@ -184,7 +184,7 @@ def delete_team(session: SessionDep,current_user: CurrentUser, id: RowId) -> Mes
|
|||||||
part=PermissionPart.ADMIN,
|
part=PermissionPart.ADMIN,
|
||||||
rights=PermissionRight.DELETE,
|
rights=PermissionRight.DELETE,
|
||||||
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
) and not (event.user_has_rights(user=current_user, rights=PermissionRight.MANAGE_TEAMS)):
|
||||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
raise HTTPException(status_code=403, detail="Not enough permissions")
|
||||||
|
|
||||||
session.delete(team)
|
session.delete(team)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class DocumentedStrEnum(str, Enum):
|
|||||||
|
|
||||||
|
|
||||||
class DocumentedIntFlag(IntFlag):
|
class DocumentedIntFlag(IntFlag):
|
||||||
|
# TODO: Build DB sport to proper store flags and make it possible to store all mutations
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,23 @@ if TYPE_CHECKING:
|
|||||||
# region # Event ###############################################################
|
# region # Event ###############################################################
|
||||||
|
|
||||||
|
|
||||||
# Event auth
|
# Shared properties
|
||||||
class EventUserLink(BaseSQLModel, table=True):
|
class EventUserLinkBase(BaseSQLModel):
|
||||||
|
rights: PermissionRight = Field(default=PermissionRight.READ, nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
# Properties to receive via API on creation
|
||||||
|
class EventUserLinkCreate(EventUserLinkBase):
|
||||||
|
user_id: RowId = Field(default=None, nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
# Properties to receive via API on update, all are optional
|
||||||
|
class EventUserLinkUpdate(EventUserLinkBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Database model, database table inferred from class name
|
||||||
|
class EventUserLink(EventUserLinkBase, table=True):
|
||||||
event_id: RowId = Field(
|
event_id: RowId = Field(
|
||||||
foreign_key="event.id",
|
foreign_key="event.id",
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
@@ -39,12 +54,22 @@ class EventUserLink(BaseSQLModel, table=True):
|
|||||||
ondelete="CASCADE",
|
ondelete="CASCADE",
|
||||||
)
|
)
|
||||||
|
|
||||||
rights: PermissionRight = Field(default=PermissionRight.READ, nullable=False)
|
|
||||||
|
|
||||||
event: "Event" = Relationship(back_populates="user_links")
|
event: "Event" = Relationship(back_populates="user_links")
|
||||||
user: "User" = Relationship(back_populates="event_links")
|
user: "User" = Relationship(back_populates="event_links")
|
||||||
|
|
||||||
|
|
||||||
|
# Properties to return via API
|
||||||
|
class EventUserLinkPublic(EventUserLinkBase):
|
||||||
|
user_id: RowId
|
||||||
|
event_id: RowId
|
||||||
|
|
||||||
|
|
||||||
|
class EventUserLinksPublic(BaseSQLModel):
|
||||||
|
data: list[EventUserLinkPublic]
|
||||||
|
count: int
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
|
|
||||||
|
|
||||||
@@ -102,41 +127,51 @@ class Event(mixin.RowId, EventBase, table=True):
|
|||||||
session.refresh(db_obj)
|
session.refresh(db_obj)
|
||||||
return db_obj
|
return db_obj
|
||||||
|
|
||||||
|
def get_user_link(self, user: User) -> EventUserLink | None:
|
||||||
|
return next(
|
||||||
|
(link for link in self.user_links if link.user == user), None
|
||||||
|
)
|
||||||
|
|
||||||
def add_user(
|
def add_user(
|
||||||
self,
|
self,
|
||||||
user: User,
|
user: User,
|
||||||
rights: PermissionRight = PermissionRight.READ,
|
rights: PermissionRight = PermissionRight.READ,
|
||||||
*,
|
*,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> "Event":
|
) -> "EventUserLink | None":
|
||||||
to_add = next((add for add in self.user_links if add.user == user), None)
|
to_add = self.get_user_link(user=user)
|
||||||
|
|
||||||
if to_add:
|
if to_add is None:
|
||||||
to_add.rights = rights
|
|
||||||
session.add(to_add)
|
|
||||||
else:
|
|
||||||
self.user_links.append(EventUserLink(event=self, user=user, rights=rights))
|
self.user_links.append(EventUserLink(event=self, user=user, rights=rights))
|
||||||
session.add(self.user_links[-1])
|
session.add(self.user_links[-1])
|
||||||
|
session.commit()
|
||||||
|
return self.user_links[-1]
|
||||||
|
|
||||||
session.commit()
|
return None
|
||||||
|
|
||||||
return self
|
def update_user(
|
||||||
|
self,
|
||||||
|
user: User,
|
||||||
|
rights: PermissionRight = PermissionRight.READ,
|
||||||
|
*,
|
||||||
|
session: Session,
|
||||||
|
) -> "EventUserLink | None":
|
||||||
|
to_update = self.get_user_link(user=user)
|
||||||
|
|
||||||
def remove_user(self, user: User, *, session: Session) -> "Event":
|
if to_update:
|
||||||
to_remove = next(
|
to_update.rights = rights
|
||||||
(remove for remove in self.user_links if remove.user == user), None
|
session.add(to_update)
|
||||||
)
|
session.commit()
|
||||||
|
return to_update
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def remove_user(self, user: User, *, session: Session) -> None:
|
||||||
|
to_remove = self.get_user_link(user=user)
|
||||||
if to_remove:
|
if to_remove:
|
||||||
statement = select(EventUserLink).where(
|
session.delete(to_remove)
|
||||||
EventUserLink.event_id == self.id, EventUserLink.user_id == user.id
|
session.commit()
|
||||||
)
|
|
||||||
link_to_remove = session.exec(statement).first()
|
|
||||||
|
|
||||||
if link_to_remove:
|
|
||||||
session.delete(link_to_remove)
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
def user_has_rights(
|
def user_has_rights(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr, field_validator
|
||||||
from sqlmodel import Field, Relationship, Session, select
|
from sqlmodel import Field, Relationship, Session, select
|
||||||
|
|
||||||
from app.core.security import get_password_hash, verify_password
|
from app.core.security import get_password_hash, verify_password
|
||||||
@@ -46,10 +46,6 @@ class PermissionRight(DocumentedIntFlag):
|
|||||||
ADMIN = CREATE | READ | UPDATE | DELETE | MANAGE_USERS | MANAGE_TEAMS
|
ADMIN = CREATE | READ | UPDATE | DELETE | MANAGE_USERS | MANAGE_TEAMS
|
||||||
|
|
||||||
|
|
||||||
class PermissionRightObject(BaseSQLModel):
|
|
||||||
rights: PermissionRight | None = Field(default=PermissionRight.READ, nullable=False)
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
# link to User (many-to-many)
|
# link to User (many-to-many)
|
||||||
class UserRoleLink(BaseSQLModel, table=True):
|
class UserRoleLink(BaseSQLModel, table=True):
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
|
|
||||||
@@ -31,6 +32,22 @@ def test_create_event(client: TestClient, superuser_token_headers: dict[str, str
|
|||||||
assert "end_at" in content
|
assert "end_at" in content
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_event_no_permission(client: TestClient, normal_user_token_headers: dict[str, str]) -> None:
|
||||||
|
data = {
|
||||||
|
"name": "No create permission",
|
||||||
|
"contact": "Someone else",
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/",
|
||||||
|
headers=normal_user_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_read_event(
|
def test_read_event(
|
||||||
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -57,8 +74,7 @@ def test_read_event_not_found(
|
|||||||
headers=superuser_token_headers,
|
headers=superuser_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
content = response.json()
|
assert response.json()["detail"] == "Event not found"
|
||||||
assert content["detail"] == "Event not found"
|
|
||||||
|
|
||||||
|
|
||||||
def test_read_event_not_enough_permissions(
|
def test_read_event_not_enough_permissions(
|
||||||
@@ -69,9 +85,8 @@ def test_read_event_not_enough_permissions(
|
|||||||
f"{settings.API_V1_STR}/events/{event.id}",
|
f"{settings.API_V1_STR}/events/{event.id}",
|
||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
content = response.json()
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
assert content["detail"] == "Not enough permissions"
|
|
||||||
|
|
||||||
|
|
||||||
def test_read_event_with_event_user(
|
def test_read_event_with_event_user(
|
||||||
@@ -163,8 +178,7 @@ def test_update_event_not_found(
|
|||||||
json=data,
|
json=data,
|
||||||
)
|
)
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
content = response.json()
|
assert response.json()["detail"] == "Event not found"
|
||||||
assert content["detail"] == "Event not found"
|
|
||||||
|
|
||||||
|
|
||||||
def test_update_event_not_enough_permissions(
|
def test_update_event_not_enough_permissions(
|
||||||
@@ -177,9 +191,31 @@ def test_update_event_not_enough_permissions(
|
|||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
json=data,
|
json=data,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_with_eventuser(
|
||||||
|
client: TestClient, event_user_token_headers: EventUserHeader, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = event_user_token_headers.event
|
||||||
|
data = {
|
||||||
|
"name": "Updated name from eventuser",
|
||||||
|
"contact": "Updated contact from eventuser",
|
||||||
|
}
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}",
|
||||||
|
headers=event_user_token_headers.headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
content = response.json()
|
content = response.json()
|
||||||
assert content["detail"] == "Not enough permissions"
|
assert content["name"] == data["name"]
|
||||||
|
assert content["contact"] == data["contact"]
|
||||||
|
assert content["id"] == str(event.id)
|
||||||
|
assert content["is_active"] == event.is_active
|
||||||
|
assert str(content["start_at"]) == str(event.start_at)
|
||||||
|
assert str(content["end_at"]) == str(event.end_at)
|
||||||
|
|
||||||
|
|
||||||
def test_delete_event(
|
def test_delete_event(
|
||||||
@@ -191,8 +227,7 @@ def test_delete_event(
|
|||||||
headers=superuser_token_headers,
|
headers=superuser_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
content = response.json()
|
assert response.json()["message"] == "Event deleted successfully"
|
||||||
assert content["message"] == "Event deleted successfully"
|
|
||||||
|
|
||||||
|
|
||||||
def test_delete_event_not_found(
|
def test_delete_event_not_found(
|
||||||
@@ -215,9 +250,8 @@ def test_delete_event_not_enough_permissions(
|
|||||||
f"{settings.API_V1_STR}/events/{event.id}",
|
f"{settings.API_V1_STR}/events/{event.id}",
|
||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
content = response.json()
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
assert content["detail"] == "Not enough permissions"
|
|
||||||
|
|
||||||
|
|
||||||
def test_delete_event_admin_user(
|
def test_delete_event_admin_user(
|
||||||
@@ -246,9 +280,8 @@ def test_delete_event_not_enough_permissions_for_this_event(
|
|||||||
f"{settings.API_V1_STR}/events/{event.id}",
|
f"{settings.API_V1_STR}/events/{event.id}",
|
||||||
headers=authentication_token_from_user(db=db, user=user, client=client),
|
headers=authentication_token_from_user(db=db, user=user, client=client),
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
content = response.json()
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
assert content["detail"] == "Not enough permissions"
|
|
||||||
|
|
||||||
|
|
||||||
def test_delete_event_event_user_read_only_rights(
|
def test_delete_event_event_user_read_only_rights(
|
||||||
@@ -262,13 +295,545 @@ def test_delete_event_event_user_read_only_rights(
|
|||||||
f"{settings.API_V1_STR}/events/{event.id}",
|
f"{settings.API_V1_STR}/events/{event.id}",
|
||||||
headers=authentication_token_from_user(db=db, user=user, client=client),
|
headers=authentication_token_from_user(db=db, user=user, client=client),
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_read_all_event_users(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user1 = create_random_user(db)
|
||||||
|
user2 = create_random_user(db)
|
||||||
|
event.add_user(user=user1, rights=PermissionRight.READ, session=db)
|
||||||
|
event.add_user(user=user2, rights=PermissionRight.ADMIN, session=db)
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
content = response.json()
|
content = response.json()
|
||||||
assert content["detail"] == "Not enough permissions"
|
assert "count" in content
|
||||||
|
assert content["count"] == 2
|
||||||
|
assert "data" in content
|
||||||
|
assert isinstance(content["data"], list)
|
||||||
|
assert len(content["data"]) <= content["count"]
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add user (super, less rights, own rights, more rights) (*** user without rights)
|
def test_read_all_event_users_no_permission(
|
||||||
# TODO: Edit user rights (super, less rights, own rights, more rights) (*** user without rights)
|
client: TestClient, normal_user_token_headers: dict[str, str], db: Session
|
||||||
# TODO: Remove user (*** user without rights)
|
) -> None:
|
||||||
# TODO: Remove own user (is allowed)
|
event = create_random_event(db)
|
||||||
# TODO: Remove not linked user
|
|
||||||
|
response = client.get(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=normal_user_token_headers,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_read_all_event_users_with_event_user(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.MANAGE_USERS, session=db)
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user, client=client),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert "count" in content
|
||||||
|
assert content["count"] == 1
|
||||||
|
assert "data" in content
|
||||||
|
assert isinstance(content["data"], list)
|
||||||
|
assert len(content["data"]) <= content["count"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_read_all_event_users_with_event_user_no_permission(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user, client=client),
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
response = client.get(
|
||||||
|
f"{settings.API_V1_STR}/events/{uuid.uuid4()}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "Event not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(user.id),
|
||||||
|
"rights": PermissionRight.READ,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert "rights" in content
|
||||||
|
assert content["rights"] == PermissionRight.READ
|
||||||
|
assert content["user_id"] == str(user.id)
|
||||||
|
assert content["event_id"] == str(event.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_event_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
user = create_random_user(db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(user.id),
|
||||||
|
"rights": PermissionRight.READ,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{uuid.uuid4()}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "Event not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_user_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(uuid.uuid4()),
|
||||||
|
"rights": PermissionRight.READ,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "User not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_already_exists(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(user.id),
|
||||||
|
"rights": PermissionRight.ADMIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.json()["detail"] == "User already part of this event"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_no_permissions(
|
||||||
|
client: TestClient, normal_user_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(user.id),
|
||||||
|
"rights": PermissionRight.READ,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=normal_user_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_to_event_unknown_rights(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
data = {
|
||||||
|
"user_id": str(user.id),
|
||||||
|
"rights": -1, # Invalid permission value
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.json()["detail"] == "Invalid permission rights"
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_user_with_more_rights_than_current_user(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
limited_user = create_random_user(db)
|
||||||
|
event.add_user(user=limited_user, rights=PermissionRight.MANAGE_USERS, session=db)
|
||||||
|
|
||||||
|
target_user = create_random_user(db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"user_id": str(target_user.id),
|
||||||
|
"rights": PermissionRight.ADMIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=authentication_token_from_user(db=db, user=limited_user, client=client),
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="Combined rights add might not yet be supported")
|
||||||
|
def test_add_user_rights_combined(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.READ | PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert "rights" in content
|
||||||
|
assert content["rights"] == data["rights"]
|
||||||
|
assert content["event_id"] == str(event.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_user_inside_event(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert "rights" in content
|
||||||
|
assert content["rights"] == data["rights"]
|
||||||
|
assert content["user_id"] == str(user.id)
|
||||||
|
assert content["event_id"] == str(event.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_event_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
):
|
||||||
|
user = create_random_user(db)
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{uuid.uuid4()}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "Event not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_user_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
):
|
||||||
|
event = create_random_event(db)
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{uuid.uuid4()}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "User not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_unknown_rights(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
):
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
data = {
|
||||||
|
"rights": -1, # Invalid permission value
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.json()["detail"] == "Invalid permission rights"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_not_enough_permissions(
|
||||||
|
client: TestClient, normal_user_token_headers: dict[str, str], db: Session
|
||||||
|
):
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.ADMIN, session=db)
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.READ
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=normal_user_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_with_event_user_same_event(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user1 = create_random_user(db)
|
||||||
|
user2 = create_random_user(db)
|
||||||
|
|
||||||
|
event.add_user(user=user1, rights=PermissionRight.ADMIN, session=db)
|
||||||
|
event.add_user(user=user2, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
# event_user1 tries to update event_user2 rights
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user2.id}",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user1, client=client),
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert content["rights"] == data["rights"]
|
||||||
|
assert content["user_id"] == str(user2.id)
|
||||||
|
assert content["event_id"] == str(event.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_from_other_event_forbidden(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event1 = create_random_event(db)
|
||||||
|
event2 = create_random_event(db)
|
||||||
|
|
||||||
|
user1 = create_random_user(db)
|
||||||
|
user2 = create_random_user(db)
|
||||||
|
|
||||||
|
event1.add_user(user=user1, rights=PermissionRight.ADMIN, session=db)
|
||||||
|
event2.add_user(user=user2, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event2.id}/users/{user2.id}",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user1, client=client),
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_event_user_from_other_event_thru_own_event(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event1 = create_random_event(db)
|
||||||
|
event2 = create_random_event(db)
|
||||||
|
|
||||||
|
user1 = create_random_user(db)
|
||||||
|
user2 = create_random_user(db)
|
||||||
|
|
||||||
|
event1.add_user(user=user1, rights=PermissionRight.ADMIN, session=db)
|
||||||
|
event2.add_user(user=user2, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event1.id}/users/{user2.id}",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user1, client=client),
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "User is not part of this event"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="Combined rights update might not yet be supported")
|
||||||
|
def test_update_user_rights_combined(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
# Initially assign READ only rights
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"rights": PermissionRight.READ | PermissionRight.UPDATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = client.put(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
content = response.json()
|
||||||
|
assert "rights" in content
|
||||||
|
assert content["rights"] == data["rights"]
|
||||||
|
assert content["user_id"] == str(user.id)
|
||||||
|
assert content["event_id"] == str(event.id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_user_from_event(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json()["message"] == "User removed successfully"
|
||||||
|
# assert not event.get_user_link(user)
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_user_from_event_event_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{uuid.uuid4()}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "Event not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_user_from_event_user_not_found(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{uuid.uuid4()}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "User not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_user_from_event_user_not_in_event(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=superuser_token_headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
assert response.json()["detail"] == "User is not part of this event"
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_user_from_event_insufficient_permissions(
|
||||||
|
client: TestClient, db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
limited_user = create_random_user(db)
|
||||||
|
event.add_user(user=limited_user, rights=PermissionRight.READ, session=db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=authentication_token_from_user(db=db, user=limited_user, client=client),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_own_user_from_event(
|
||||||
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
||||||
|
) -> None:
|
||||||
|
event = create_random_event(db)
|
||||||
|
user = create_random_user(db)
|
||||||
|
event.add_user(user=user, rights=PermissionRight.MANAGE_USERS, session=db)
|
||||||
|
|
||||||
|
response = client.delete(
|
||||||
|
f"{settings.API_V1_STR}/events/{event.id}/users/{user.id}",
|
||||||
|
headers=authentication_token_from_user(db=db, user=user, client=client),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 403
|
||||||
|
assert response.json()["detail"] == "Users are not allowed to delete themselves when they are not an super admin"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ def test_read_event_not_enough_permissions(client: TestClient, normal_user_token
|
|||||||
f"{settings.API_V1_STR}/teams/{team.id}",
|
f"{settings.API_V1_STR}/teams/{team.id}",
|
||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
assert response.json()["detail"] == "Not enough permissions"
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ def test_update_team_not_enough_permissions(client: TestClient, normal_user_toke
|
|||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
json=data,
|
json=data,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
assert response.json()["detail"] == "Not enough permissions"
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ def test_update_team_event_with_event_user_not_enough_permissions(client: TestCl
|
|||||||
json=data,
|
json=data,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
assert response.json()["detail"] == "Not enough permissions"
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ def test_delete_not_enough_permissions(client: TestClient, normal_user_token_hea
|
|||||||
f"{settings.API_V1_STR}/teams/{team.id}",
|
f"{settings.API_V1_STR}/teams/{team.id}",
|
||||||
headers=normal_user_token_headers,
|
headers=normal_user_token_headers,
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 403
|
||||||
assert response.json()["detail"] == "Not enough permissions"
|
assert response.json()["detail"] == "Not enough permissions"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user