Skip to main content

joy_core/
capabilities.rs

1// Copyright (c) 2026 Joydev GmbH (joydev.com)
2// SPDX-License-Identifier: MIT
3
4use std::path::Path;
5
6use crate::identity;
7use crate::model::item::Capability;
8use crate::model::project::{is_ai_member, Project};
9use crate::store;
10
11/// Check whether the current user has a management capability.
12/// Prints a warning to stderr if denied or not registered.
13/// Blocks AI members from manage-level actions entirely.
14/// Returns true if allowed, false if denied.
15pub fn warn_unless_capable(root: &Path, required: Capability) -> bool {
16    let member_id = match identity::resolve_identity(root) {
17        Ok(id) => id.member,
18        Err(_) => return true, // Cannot determine user, allow
19    };
20    if member_id.is_empty() {
21        return true;
22    }
23
24    // AI members are never allowed to perform manage actions
25    if is_ai_member(&member_id) && required == Capability::Manage {
26        eprintln!(
27            "Error: AI member {} cannot perform manage actions.",
28            member_id
29        );
30        return false;
31    }
32
33    let project_path = store::joy_dir(root).join(store::PROJECT_FILE);
34    let project: Project = match store::read_yaml(&project_path) {
35        Ok(p) => p,
36        Err(_) => return true, // No project.yaml, allow
37    };
38
39    // No members configured means no restrictions
40    if project.members.is_empty() {
41        return true;
42    }
43
44    match project.members.get(&member_id) {
45        Some(member) => {
46            if member.has_capability(&required) {
47                true
48            } else {
49                eprintln!(
50                    "Warning: {} does not have '{}' capability. This action may be rejected by Joy Judge.",
51                    member_id, required
52                );
53                false
54            }
55        }
56        None => {
57            eprintln!(
58                "Warning: {} is not a registered project member. Run `joy project member add {}`.",
59                member_id, member_id
60            );
61            false
62        }
63    }
64}