mz_frontegg_mock/handlers/
group.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use crate::models::*;
11use crate::server::Context;
12use axum::{
13    Json,
14    extract::{Path, State},
15    http::StatusCode,
16};
17use chrono::Utc;
18use std::sync::Arc;
19use uuid::Uuid;
20
21// https://docs.frontegg.com/reference/groupscontrollerv1_getallgroups
22pub async fn handle_list_groups(
23    State(context): State<Arc<Context>>,
24) -> Result<Json<GroupsResponse>, StatusCode> {
25    let groups = context.groups.lock().unwrap();
26    let groups_vec: Vec<Group> = groups.values().cloned().collect();
27    Ok(Json(GroupsResponse { groups: groups_vec }))
28}
29
30// https://docs.frontegg.com/reference/groupscontrollerv1_creategroup
31pub async fn handle_create_group(
32    State(context): State<Arc<Context>>,
33    Json(params): Json<GroupCreateParams>,
34) -> Result<(StatusCode, Json<Group>), StatusCode> {
35    let now = Utc::now();
36    let new_group = Group {
37        id: Uuid::new_v4().to_string(),
38        name: params.name,
39        description: params.description.unwrap_or_default(),
40        metadata: params.metadata.unwrap_or_default(),
41        roles: Vec::new(),
42        users: Vec::new(),
43        managed_by: "".to_string(),
44        color: params.color.unwrap_or_default(),
45        created_at: now,
46        updated_at: now,
47    };
48
49    let mut groups = context.groups.lock().unwrap();
50    groups.insert(new_group.id.clone(), new_group.clone());
51
52    Ok((StatusCode::CREATED, Json(new_group)))
53}
54
55// https://docs.frontegg.com/reference/groupscontrollerv1_getgroupbyid
56pub async fn handle_get_group(
57    State(context): State<Arc<Context>>,
58    Path(group_id): Path<String>,
59) -> Result<Json<Group>, StatusCode> {
60    let groups = context.groups.lock().unwrap();
61    groups
62        .get(&group_id)
63        .cloned()
64        .map(Json)
65        .ok_or(StatusCode::NOT_FOUND)
66}
67
68// https://docs.frontegg.com/reference/groupscontrollerv1_updategroup
69pub async fn handle_update_group(
70    State(context): State<Arc<Context>>,
71    Path(group_id): Path<String>,
72    Json(params): Json<GroupUpdateParams>,
73) -> Result<Json<Group>, StatusCode> {
74    let mut groups = context.groups.lock().unwrap();
75    if let Some(group) = groups.get_mut(&group_id) {
76        if let Some(name) = params.name {
77            group.name = name;
78        }
79        if let Some(description) = params.description {
80            group.description = description;
81        }
82        if let Some(color) = params.color {
83            group.color = color;
84        }
85        if let Some(metadata) = params.metadata {
86            group.metadata = metadata;
87        }
88        group.updated_at = Utc::now();
89        Ok(Json(group.clone()))
90    } else {
91        Err(StatusCode::NOT_FOUND)
92    }
93}
94
95// https://docs.frontegg.com/reference/groupscontrollerv1_deletegroup
96pub async fn handle_delete_group(
97    State(context): State<Arc<Context>>,
98    Path(group_id): Path<String>,
99) -> StatusCode {
100    let mut groups = context.groups.lock().unwrap();
101    if groups.remove(&group_id).is_some() {
102        StatusCode::OK
103    } else {
104        StatusCode::NOT_FOUND
105    }
106}
107
108// https://docs.frontegg.com/reference/groupscontrollerv1_addrolestogroup
109pub async fn handle_add_roles_to_group(
110    State(context): State<Arc<Context>>,
111    Path(group_id): Path<String>,
112    Json(payload): Json<AddRolesToGroupParams>,
113) -> Result<StatusCode, StatusCode> {
114    let mut groups = context.groups.lock().unwrap();
115    let roles = Arc::clone(&context.roles);
116
117    if let Some(group) = groups.get_mut(&group_id) {
118        for role_id in payload.role_ids {
119            if !group.roles.iter().any(|r| r.id == role_id) {
120                if let Some(role) = roles.iter().find(|r| r.id == role_id) {
121                    group.roles.push(Role {
122                        id: role.id.clone(),
123                        key: role.key.clone(),
124                        name: role.name.clone(),
125                        description: format!("Description for {}", role.name),
126                        is_default: false,
127                    });
128                } else {
129                    return Err(StatusCode::NOT_FOUND);
130                }
131            }
132        }
133        Ok(StatusCode::CREATED)
134    } else {
135        Err(StatusCode::NOT_FOUND)
136    }
137}
138
139// https://docs.frontegg.com/reference/groupscontrollerv1_removerolesfromgroup
140pub async fn handle_remove_roles_from_group(
141    State(context): State<Arc<Context>>,
142    Path(group_id): Path<String>,
143    Json(payload): Json<RemoveRolesFromGroupParams>,
144) -> Result<StatusCode, StatusCode> {
145    let mut groups = context.groups.lock().unwrap();
146
147    if let Some(group) = groups.get_mut(&group_id) {
148        group
149            .roles
150            .retain(|role| !payload.role_ids.contains(&role.id));
151        Ok(StatusCode::OK)
152    } else {
153        Err(StatusCode::NOT_FOUND)
154    }
155}