|
2 | 2 | from typing import Annotated
|
3 | 3 | from uuid import UUID
|
4 | 4 |
|
5 |
| -from fastapi import APIRouter, Depends, HTTPException, Security |
| 5 | +from fastapi import APIRouter, Depends, HTTPException, Security, status |
6 | 6 |
|
7 | 7 | from papermerge.core.db.engine import Session
|
8 | 8 | from papermerge.core import utils
|
9 | 9 | from papermerge.core.features.users import schema as usr_schema
|
10 | 10 | from papermerge.core.features.auth import get_current_user
|
11 | 11 | from papermerge.core.features.auth import scopes
|
12 | 12 |
|
13 |
| -from papermerge.core.routers.params import CommonQueryParams |
14 |
| - |
| 13 | +from papermerge.core.features.users.db import api as users_dbapi |
15 | 14 | from papermerge.core.features.tags.db import api as tags_dbapi
|
16 | 15 | from papermerge.core.features.tags import schema as tags_schema
|
17 | 16 | from papermerge.core.exceptions import EntityNotFound
|
| 17 | +from papermerge.core.routers.common import OPEN_API_GENERIC_JSON_DETAIL |
18 | 18 | from .types import PaginatedQueryParams
|
19 | 19 |
|
| 20 | + |
20 | 21 | router = APIRouter(
|
21 | 22 | prefix="/tags",
|
22 | 23 | tags=["tags"],
|
@@ -88,20 +89,48 @@ def get_tag_details(
|
88 | 89 | return tag
|
89 | 90 |
|
90 | 91 |
|
91 |
| -@router.post("/", status_code=201) |
| 92 | +@router.post( |
| 93 | + "/", |
| 94 | + status_code=201, |
| 95 | + responses={ |
| 96 | + status.HTTP_403_FORBIDDEN: { |
| 97 | + "description": """User does not belong to group""", |
| 98 | + "content": OPEN_API_GENERIC_JSON_DETAIL, |
| 99 | + } |
| 100 | + }, |
| 101 | +) |
92 | 102 | @utils.docstring_parameter(scope=scopes.TAG_CREATE)
|
93 | 103 | def create_tag(
|
94 | 104 | attrs: tags_schema.CreateTag,
|
95 | 105 | user: Annotated[
|
96 | 106 | usr_schema.User, Security(get_current_user, scopes=[scopes.TAG_CREATE])
|
97 | 107 | ],
|
98 | 108 | ) -> tags_schema.Tag:
|
99 |
| - """Creates user tag |
| 109 | + """Creates tag |
| 110 | +
|
| 111 | + If attribute `group_id` is present, tag will be owned |
| 112 | + by respective group, otherwise ownership is set to current user. |
| 113 | + If attribute `group_id` is present then current user should |
| 114 | + belong to that group, otherwise http status 403 (Forbidden) will |
| 115 | + be raised. |
100 | 116 |
|
101 | 117 | Required scope: `{scope}`
|
102 | 118 | """
|
| 119 | + if not attrs.group_id: |
| 120 | + attrs.user_id = user.id |
| 121 | + |
103 | 122 | with Session() as db_session:
|
104 |
| - tag, error = tags_dbapi.create_tag(db_session, attrs=attrs, user_id=user.id) |
| 123 | + if attrs.group_id: |
| 124 | + group_id = attrs.group_id |
| 125 | + ok = users_dbapi.user_belongs_to( |
| 126 | + db_session, user_id=user.id, group_id=group_id |
| 127 | + ) |
| 128 | + if not ok: |
| 129 | + detail = f"User {user.id=} does not belong to group {group_id=}" |
| 130 | + raise HTTPException( |
| 131 | + status_code=status.HTTP_403_FORBIDDEN, detail=detail |
| 132 | + ) |
| 133 | + tag, error = tags_dbapi.create_tag(db_session, attrs=attrs) |
105 | 134 |
|
106 | 135 | if error:
|
107 | 136 | raise HTTPException(status_code=400, detail=error.model_dump())
|
|
0 commit comments