1use actix_web::web::Query;
4use actix_web::{
5 delete, get, patch, post,
6 web::{Json, Path},
7 HttpResponse, Result,
8};
9use uuid::Uuid;
10
11use crate::service::map_access_control::AccessRights;
12use crate::{
13 config::{
14 auth::user_info::UserInfo,
15 data::{SharedBroadcaster, SharedPool},
16 },
17 model::dto::{
18 actions::{Action, ActionType, UpdateMapGeometryActionPayload},
19 MapSearchParameters, NewMapDto, PageParameters, UpdateMapDto, UpdateMapGeometryDto,
20 },
21 service,
22 service::map_access_control::check_permissions,
23};
24
25#[utoipa::path(
32 context_path = "/api/maps",
33 params(
34 MapSearchParameters,
35 PageParameters
36 ),
37 responses(
38 (status = 200, description = "Fetch or search all maps", body = PageMapDto)
39 ),
40 security(
41 ("oauth2" = [])
42 )
43)]
44#[get("")]
45pub async fn find(
46 search_query: Query<MapSearchParameters>,
47 page_query: Query<PageParameters>,
48 pool: SharedPool,
49 user_info: UserInfo,
50) -> Result<HttpResponse> {
51 let response = service::map::find(
52 search_query.into_inner(),
53 page_query.into_inner(),
54 &pool,
55 user_info,
56 )
57 .await?;
58 Ok(HttpResponse::Ok().json(response))
59}
60
61#[utoipa::path(
67 context_path = "/api/maps",
68 responses(
69 (status = 200, description = "Fetch a map by id", body = MapDto)
70 ),
71 security(
72 ("oauth2" = [])
73 )
74)]
75#[get("/{map_id}")]
76pub async fn find_by_id(
77 map_id: Path<i32>,
78 pool: SharedPool,
79 user_info: UserInfo,
80) -> Result<HttpResponse> {
81 let id = map_id.into_inner();
82 check_permissions(id, &pool, user_info, AccessRights::Read).await?;
83 let response = service::map::find_by_id(id, &pool).await?;
84 Ok(HttpResponse::Ok().json(response))
85}
86
87#[utoipa::path(
92 context_path = "/api/maps",
93 request_body = NewMapDto,
94 responses(
95 (status = 201, description = "Create a new map", body = MapDto)
96 ),
97 security(
98 ("oauth2" = [])
99 )
100)]
101#[post("")]
102pub async fn create(
103 new_map_json: Json<NewMapDto>,
104 user_info: UserInfo,
105 pool: SharedPool,
106) -> Result<HttpResponse> {
107 let response = service::map::create(new_map_json.0, user_info.id, &pool).await?;
108 Ok(HttpResponse::Created().json(response))
109}
110
111#[utoipa::path(
117 context_path = "/api/maps",
118 request_body = UpdateMapDto,
119 responses(
120 (status = 200, description = "Update a map", body = MapDto)
121 ),
122 security(
123 ("oauth2" = [])
124 )
125)]
126#[patch("/{map_id}")]
127pub async fn update(
128 map_update_json: Json<UpdateMapDto>,
129 map_id: Path<i32>,
130 user_info: UserInfo,
131 pool: SharedPool,
132) -> Result<HttpResponse> {
133 let id = map_id.into_inner();
134 check_permissions(id, &pool, user_info, AccessRights::Write).await?;
135 let response = service::map::update(map_update_json.0, id, &pool).await?;
136 Ok(HttpResponse::Ok().json(response))
137}
138#[utoipa::path(
144context_path = "/api/maps",
145request_body = UpdateMapDto,
146responses(
147(status = 200, description = "Update a map", body = MapDto)
148),
149security(
150("oauth2" = [])
151)
152)]
153#[patch("/{map_id}/geometry")]
154pub async fn update_geometry(
155 map_update_geometry_json: Json<UpdateMapGeometryDto>,
156 map_id: Path<i32>,
157 user_info: UserInfo,
158 pool: SharedPool,
159 broadcaster: SharedBroadcaster,
160) -> Result<HttpResponse> {
161 let map_id_inner = map_id.into_inner();
162 let user_id = user_info.id;
163 check_permissions(map_id_inner, &pool, user_info, AccessRights::Write).await?;
164
165 let response =
166 service::map::update_geometry(map_update_geometry_json.0.clone(), map_id_inner, &pool)
167 .await?;
168
169 broadcaster
170 .broadcast(
171 map_id_inner,
172 Action {
173 action_id: Uuid::new_v4(),
174 user_id,
175 action: ActionType::UpdateMapGeometry(UpdateMapGeometryActionPayload::new(
176 map_update_geometry_json.0,
177 map_id_inner,
178 )),
179 },
180 )
181 .await;
182
183 Ok(HttpResponse::Ok().json(response))
184}
185
186#[utoipa::path(
192 context_path = "/api/maps",
193 responses(
194 (status = 200, description = "Delete a map by id")
195 ),
196 security(
197 ("oauth2" = [])
198 )
199)]
200#[delete("/{map_id}")]
201pub async fn delete_by_id(
202 map_id: Path<i32>,
203 user_info: UserInfo,
204 pool: SharedPool,
205) -> Result<HttpResponse> {
206 let m_id = map_id.into_inner();
207 check_permissions(m_id, &pool, user_info, AccessRights::Write).await?;
208 service::map::delete_by_id(m_id, &pool).await?;
209 Ok(HttpResponse::Ok().finish())
210}