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
//! Authorization primitives for role-, group-, and permission-based access control.
//!
//! This module is where you define **who should be allowed through** and how to
//! evaluate that decision against an account.
//!
//! If you are new to `webgates-core`, the usual flow is:
//!
//! 1. create or load an [`crate::accounts::Account`]
//! 2. build an [`access_policy::AccessPolicy`] that describes the requirement
//! 3. evaluate it with [`authorization_service::AuthorizationService`]
//!
//! ## Main types
//!
//! - [`access_hierarchy::AccessHierarchy`] defines how custom role types support supervisor checks
//! - [`access_policy::AccessPolicy`] declares role, group, and permission requirements
//! - [`authorization_service::AuthorizationService`] evaluates a policy against an account
//! - [`errors::AuthzError`] contains authorization-related error values
//!
//! Import items directly from their owning submodule for a single canonical path.
//!
//! # Quick start
//!
//! ```rust
//! use webgates_core::accounts::Account;
//! use webgates_core::authz::access_policy::AccessPolicy;
//! use webgates_core::authz::authorization_service::AuthorizationService;
//! use webgates_core::groups::Group;
//! use webgates_core::roles::Role;
//!
//! let account = Account::<Role, Group>::new("user@example.com")
//! .with_groups(vec![Group::new("engineering")]);
//!
//! let policy = AccessPolicy::<Role, Group>::require_group(Group::new("engineering"));
//! let authz = AuthorizationService::new(policy);
//!
//! assert!(authz.is_authorized(&account));
//! ```
//!
//! # Policy composition
//!
//! Policies use **OR semantics**. Authorization succeeds when any configured
//! role, group, or permission requirement matches.
//!
//! ```rust
//! use webgates_core::authz::access_policy::AccessPolicy;
//! use webgates_core::groups::Group;
//! use webgates_core::roles::Role;
//!
//! let policy = AccessPolicy::<Role, Group>::require_role(Role::Admin)
//! .or_require_group(Group::new("security-team"))
//! .or_require_permission("emergency:access");
//!
//! assert!(policy.has_requirements());
//! ```
//!
//! # Hierarchical roles
//!
//! Use [`access_policy::AccessPolicy::<R, G>::require_role_or_supervisor`] when a
//! higher-privileged role should satisfy a lower-privileged requirement.
//!
//! ```rust
//! use webgates_core::authz::access_policy::AccessPolicy;
//! use webgates_core::groups::Group;
//! use webgates_core::roles::Role;
//!
//! let policy = AccessPolicy::<Role, Group>::require_role_or_supervisor(Role::Moderator);
//!
//! assert!(policy.has_requirements());
//! ```
/// Trait that marks a type as participating in role-hierarchy checks.
/// Domain object describing who may access a protected resource.
/// Domain service for evaluating access policies against accounts.
/// Authorization-category error values.