Skip to main content

wire/
auth_context.rs

1// SPDX-License-Identifier: Apache-2.0
2use crate::{Permission, TokenScope, scope_contains};
3
4#[derive(Debug, Clone)]
5pub struct AuthContext {
6    pub user: String,
7    pub permissions: Vec<Permission>,
8    pub token_id: String,
9    pub scope: TokenScope,
10}
11
12impl AuthContext {
13    pub fn has_permission(&self, perm: Permission) -> bool {
14        self.permissions.contains(&perm)
15    }
16
17    pub fn can_read(&self) -> bool {
18        self.has_permission(Permission::Read)
19    }
20
21    pub fn can_write(&self) -> bool {
22        self.has_permission(Permission::Write)
23    }
24
25    pub fn can_push(&self) -> bool {
26        self.has_permission(Permission::Push)
27    }
28
29    pub fn is_admin(&self) -> bool {
30        self.has_permission(Permission::Admin)
31    }
32
33    pub fn can_access_repo(&self, repo: &str) -> bool {
34        match &self.scope {
35            TokenScope::Global => true,
36            TokenScope::Repositories(repos) => repos.iter().any(|candidate| candidate == repo),
37            TokenScope::NamespaceTree(namespace) => scope_contains(namespace, repo),
38        }
39    }
40
41    /// Whether this context may access `namespace`.
42    ///
43    /// `NamespaceTree(scope)` grants access **downward only**: the scope
44    /// namespace itself and any descendant (`scope/...`). It deliberately does
45    /// NOT grant upward access — a token scoped to a child namespace cannot
46    /// reach its parent or ancestors. This mirrors [`Self::can_access_repo`].
47    ///
48    /// Containment is segment-aware via [`scope_contains`]: candidates with
49    /// `.`/`..`/empty segments are denied outright (no check-then-normalize
50    /// bypass).
51    pub fn can_access_namespace(&self, namespace: &str) -> bool {
52        match &self.scope {
53            TokenScope::Global => true,
54            TokenScope::Repositories(_) => false,
55            TokenScope::NamespaceTree(scope) => scope_contains(scope, namespace),
56        }
57    }
58}