1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! Group identifiers for group-based authorization decisions.
//!
//! Groups model exact membership such as departments, teams, tenants, projects,
//! or other organizational units. Unlike roles, groups do not imply privilege
//! ordering. A user is either a member of the group or not.
//!
//! # Examples
//!
//! Create groups and use them in access policies:
//!
//! ```rust
//! use webgates_core::authz::access_policy::AccessPolicy;
//! use webgates_core::groups::Group;
//! use webgates_core::roles::Role;
//!
//! let engineering = Group::new("engineering");
//! let marketing = Group::new("marketing");
//!
//! let policy = AccessPolicy::<Role, Group>::require_group(engineering.clone())
//! .or_require_group(marketing.clone());
//!
//! assert_eq!(engineering.name(), "engineering");
//! assert_eq!(marketing.name(), "marketing");
//! assert!(!policy.denies_all());
//! ```
//!
//! Common naming patterns:
//!
//! ```rust
//! use webgates_core::groups::Group;
//!
//! let departments = vec![
//! Group::new("engineering"),
//! Group::new("marketing"),
//! Group::new("support"),
//! ];
//!
//! let project_groups = vec![
//! Group::new("project-alpha"),
//! Group::new("project-beta"),
//! ];
//!
//! let teams = vec![
//! Group::new("frontend-team"),
//! Group::new("backend-team"),
//! Group::new("qa-team"),
//! ];
//!
//! assert_eq!(departments.len(), 3);
//! assert_eq!(project_groups.len(), 2);
//! assert_eq!(teams.len(), 3);
//! ```
use Display;
use FromStr;
use ;
/// A group identifier used for exact membership checks.
///
/// Groups are the non-hierarchical companion to roles. Use them when access is
/// based on belonging to something, such as a department, project, tenant, or
/// on-call rotation.
///
/// # Example
/// ```rust
/// use webgates_core::groups::Group;
///
/// let engineering = Group::new("engineering");
/// let backend_team = Group::new("backend-team");
///
/// assert_eq!(engineering.name(), "engineering");
/// assert_eq!(backend_team.name(), "backend-team");
/// ```
;
/// Trait for types that expose a stable group identifier.
///
/// Implement this for your own group types when infrastructure code needs a
/// canonical string identifier but you do not want to use the built-in [`Group`]
/// type directly.
/// Allows the built-in [`Group`] type to be used wherever a [`GroupEntity`]
/// is required.