backend/controller/
map_collaborators.rs

1use actix_web::{
2    delete, get, post,
3    web::{Json, Path},
4    HttpResponse, Result,
5};
6
7use crate::{
8    config::{
9        auth::user_info::UserInfo,
10        data::{SharedHttpClient, SharedKeycloakApi, SharedPool},
11    },
12    model::dto::{DeleteMapCollaboratorDto, NewMapCollaboratorDto},
13    service::{
14        map_access_control::{check_permissions, AccessRights},
15        map_collaborator,
16    },
17};
18
19/// Endpoint for getting all [`MapCollaborator`](crate::model::entity::MapCollaborator)s of a map.
20///
21/// # Errors
22/// * If the connection to the database could not be established.
23/// * If the connection to the Keycloak API could not be established.
24/// * If the current user does not have the appropriate permissions.
25#[utoipa::path(
26    context_path = "/api/maps/{map_id}/collaborators",
27    params(
28        ("map_id" = i32, Path, description = "The id of the map on which to collaborate"),
29    ),
30    responses(
31        (status = 200, description = "The collaborators of this map", body = Vec<MapCollaboratorDto>),
32    ),
33    security(
34        ("oauth2" = [])
35    )
36)]
37#[get("")]
38pub async fn find(
39    map_id: Path<i32>,
40    pool: SharedPool,
41    keycloak_api: SharedKeycloakApi,
42    http_client: SharedHttpClient,
43    user_info: UserInfo,
44) -> Result<HttpResponse> {
45    let id = map_id.into_inner();
46    check_permissions(id, &pool, user_info, AccessRights::Read).await?;
47    let response = map_collaborator::get_all(id, &pool, &keycloak_api, &http_client).await?;
48
49    Ok(HttpResponse::Ok().json(response))
50}
51
52/// Endpoint for creating a new [`MapCollaborator`](crate::model::entity::MapCollaborator).
53///
54/// # Errors
55/// * If the connection to the database could not be established.
56/// * If the connection to the Keycloak API could not be established.
57/// * If the current user does not have the appropriate permissions.
58#[utoipa::path(
59    context_path = "/api/maps/{map_id}/collaborators",
60    params(
61        ("map_id" = i32, Path, description = "The id of the map on which to collaborate"),
62    ),
63    request_body = NewMapCollaboratorDto,
64    responses(
65        (status = 201, description = "Add a new map collaborator", body = MapCollaboratorDto),
66    ),
67    security(
68        ("oauth2" = [])
69    )
70)]
71#[post("")]
72pub async fn create(
73    json: Json<NewMapCollaboratorDto>,
74    map_id: Path<i32>,
75    user_info: UserInfo,
76    pool: SharedPool,
77    keycloak_api: SharedKeycloakApi,
78    http_client: SharedHttpClient,
79) -> Result<HttpResponse> {
80    let id = map_id.into_inner();
81    let user_id = user_info.id;
82    check_permissions(id, &pool, user_info, AccessRights::Write).await?;
83    let response = map_collaborator::create(
84        (id, json.into_inner()),
85        user_id,
86        &pool,
87        &keycloak_api,
88        &http_client,
89    )
90    .await?;
91
92    Ok(HttpResponse::Created().json(response))
93}
94
95/// Endpoint for deleting a collaborator from a map.
96///
97/// # Errors
98/// * If the user is not the creator of the map.
99/// * If the connection to the database could not be established.
100/// * If the current user does not have the appropriate permissions.
101#[utoipa::path(
102    context_path = "/api/maps/{map_id}/collaborators",
103    params(
104        ("map_id" = i32, Path, description = "The id of the map on which to collaborate"),
105    ),
106    request_body = DeleteMapCollaboratorDto,
107    responses(
108        (status = 204, description = "The collaborator was removed from the map"),
109    ),
110    security(
111        ("oauth2" = [])
112    )
113)]
114#[delete("")]
115pub async fn delete(
116    map_id: Path<i32>,
117    dto: Json<DeleteMapCollaboratorDto>,
118    user_info: UserInfo,
119    pool: SharedPool,
120) -> Result<HttpResponse> {
121    let id = map_id.into_inner();
122    let user_id = user_info.id;
123    check_permissions(id, &pool, user_info, AccessRights::Write).await?;
124    map_collaborator::delete((id, dto.into_inner()), user_id, &pool).await?;
125
126    Ok(HttpResponse::NoContent().finish())
127}