manta_server/backend_dispatcher/
group.rs

1//! [`GroupTrait`] impl for [`StaticBackendDispatcher`].
2//!
3//! Forwards to HSM's `/apis/smd/hsm/v2/groups` endpoints plus the
4//! per-group `/members` subresource. Both CSM and Ochami implement
5//! this trait natively.
6//!
7//! Method names come from the external `manta-backend-dispatcher`
8//! crate's `GroupTrait`. Can't be renamed locally; cleaner names
9//! would have to land upstream first.
10
11use super::*;
12
13impl GroupTrait for StaticBackendDispatcher {
14  /// RBAC-filtered group listing: the subset of HSM groups the
15  /// caller's JWT roles grant access to. Returns full `Group`
16  /// objects.
17  async fn get_group_available(
18    &self,
19    auth_token: &str,
20  ) -> Result<Vec<Group>, Error> {
21    dispatch!(self, get_group_available, auth_token)
22  }
23
24  /// RBAC-filtered group listing, names only — faster path used when
25  /// the caller only needs the group label set (e.g. to validate a
26  /// filter argument).
27  async fn get_group_name_available(
28    &self,
29    jwt_token: &str,
30  ) -> Result<Vec<String>, Error> {
31    dispatch!(self, get_group_name_available, jwt_token)
32  }
33
34  /// `POST /groups` — create a group. Returns the persisted group
35  /// echoed back by HSM.
36  async fn add_group(
37    &self,
38    auth_token: &str,
39    group_name: Group,
40  ) -> Result<Group, Error> {
41    dispatch!(self, add_group, auth_token, group_name)
42  }
43
44  /// Union of `/groups/{name}/members` across `group_name_vec`,
45  /// deduplicated.
46  async fn get_member_vec_from_group_name_vec(
47    &self,
48    auth_token: &str,
49    group_name_vec: &[String],
50  ) -> Result<Vec<String>, Error> {
51    dispatch!(
52      self,
53      get_member_vec_from_group_name_vec,
54      auth_token,
55      group_name_vec
56    )
57  }
58
59  /// Map of `group_name -> [member xnames]` restricted to the groups
60  /// named in `group_name_vec`. One HSM call per group plus a
61  /// merge.
62  async fn get_group_map_and_filter_by_group_vec(
63    &self,
64    auth_token: &str,
65    group_name_vec: &[&str],
66  ) -> Result<HashMap<String, Vec<String>>, Error> {
67    dispatch!(
68      self,
69      get_group_map_and_filter_by_group_vec,
70      auth_token,
71      group_name_vec
72    )
73  }
74
75  /// Map of `group_name -> [member xnames]` restricted to groups
76  /// that contain any xname in `member_vec`. The dual of
77  /// `get_group_map_and_filter_by_group_vec`.
78  async fn get_group_map_and_filter_by_member_vec(
79    &self,
80    auth_token: &str,
81    member_vec: &[&str],
82  ) -> Result<HashMap<String, Vec<String>>, Error> {
83    dispatch!(
84      self,
85      get_group_map_and_filter_by_member_vec,
86      auth_token,
87      member_vec
88    )
89  }
90
91  /// `GET /groups/{name}` — one group by exact label.
92  async fn get_group(
93    &self,
94    auth_token: &str,
95    group_name: &str,
96  ) -> Result<Group, Error> {
97    dispatch!(self, get_group, auth_token, group_name)
98  }
99
100  /// `GET /groups` — every group when `group_name_vec` is `None`,
101  /// otherwise the named subset.
102  async fn get_groups(
103    &self,
104    auth_token: &str,
105    group_name_vec: Option<&[String]>,
106  ) -> Result<Vec<Group>, Error> {
107    dispatch!(self, get_groups, auth_token, group_name_vec)
108  }
109
110  /// `DELETE /groups/{name}`. Returns HSM's action-summary
111  /// (records affected).
112  async fn delete_group(
113    &self,
114    auth_token: &str,
115    group_name: &str,
116  ) -> Result<HsmActionResponse, Error> {
117    dispatch!(self, delete_group, auth_token, group_name)
118  }
119
120  /// Alias for `get_group_map_and_filter_by_group_vec` kept for
121  /// upstream-trait shape compatibility.
122  async fn get_group_map_and_filter_by_group_name_vec(
123    &self,
124    auth_token: &str,
125    group_name_vec: &[&str],
126  ) -> Result<HashMap<String, Vec<String>>, Error> {
127    dispatch!(
128      self,
129      get_group_map_and_filter_by_group_name_vec,
130      auth_token,
131      group_name_vec
132    )
133  }
134
135  /// `POST /groups/{name}/members` — add one xname.
136  async fn post_member(
137    &self,
138    auth_token: &str,
139    group_name: &str,
140    xname: &str,
141  ) -> Result<HsmActionResponse, Error> {
142    dispatch!(self, post_member, auth_token, group_name, xname)
143  }
144
145  /// Batched [`post_member`](Self::post_member). Returns the xnames
146  /// the backend reported as successfully added (some entries may
147  /// be skipped if already members).
148  async fn add_members_to_group(
149    &self,
150    auth_token: &str,
151    group_name: &str,
152    xnames: &[&str],
153  ) -> Result<Vec<String>, Error> {
154    dispatch!(self, add_members_to_group, auth_token, group_name, xnames)
155  }
156
157  /// `DELETE /groups/{name}/members/{xname}`.
158  async fn delete_member_from_group(
159    &self,
160    auth_token: &str,
161    group_name: &str,
162    xname: &str,
163  ) -> Result<(), Error> {
164    dispatch!(
165      self,
166      delete_member_from_group,
167      auth_token,
168      group_name,
169      xname
170    )
171  }
172
173  /// Move `new_target_group_members` from `parent_group_name` into
174  /// `target_group_name`. Returns `(added, removed)` xname lists.
175  /// When `dryrun` the backend computes the diff without mutating
176  /// either group.
177  async fn migrate_group_members(
178    &self,
179    auth_token: &str,
180    target_group_name: &str,
181    parent_group_name: &str,
182    new_target_group_members: &[&str],
183    dryrun: bool,
184  ) -> Result<(Vec<String>, Vec<String>), Error> {
185    dispatch!(
186      self,
187      migrate_group_members,
188      auth_token,
189      target_group_name,
190      parent_group_name,
191      new_target_group_members,
192      dryrun
193    )
194  }
195
196  /// In-place edit of a single group's membership — applies
197  /// `members_to_remove` then `members_to_add` to `group_name` as
198  /// two HSM calls. Used by the `manta group set-members` path
199  /// where the caller has pre-computed the diff.
200  async fn update_group_members(
201    &self,
202    auth_token: &str,
203    group_name: &str,
204    members_to_remove: &[&str],
205    members_to_add: &[&str],
206  ) -> Result<(), Error> {
207    dispatch!(
208      self,
209      update_group_members,
210      auth_token,
211      group_name,
212      members_to_remove,
213      members_to_add
214    )
215  }
216}