actor User { }
resource Organization {
roles = ["admin", "member"];
permissions = ["repository.create"];
"member" if "admin";
}
resource Plan { }
resource Feature {
relations = {plan: Plan};
}
# Define the permission check
has_permission(user: User, "repository.create", org: Organization) if
has_role(user, "member", org) and
has_quota_remaining(org, Feature{"repository"});
has_quota_remaining(org: Organization, feature: Feature) if
quota matches Integer and
has_quota(org, feature, quota) and
used matches Integer and
quota_used(org, feature, used) and
used < quota;
has_quota(org: Organization, feature: Feature, quota: Integer) if
plan matches Plan and
has_relation(plan, "subscribed", org) and
plan_quota(plan, feature, quota);
declare plan_quota(Plan, Feature, Integer);
declare quota_used(Organization, Feature, Integer);
plan_quota(Plan{"pro"}, Feature{"repository"}, 10);
plan_quota(Plan{"basic"}, Feature{"repository"}, 0);
test "members can create repositories if they have quota" {
setup {
quota_used(Organization{"apple"}, Feature{"repository"}, 5);
quota_used(Organization{"netflix"}, Feature{"repository"}, 10);
quota_used(Organization{"amazon"}, Feature{"repository"}, 0);
has_relation(Plan{"pro"}, "subscribed", Organization{"apple"});
has_relation(Plan{"pro"}, "subscribed", Organization{"netflix"});
has_relation(Plan{"basic"}, "subscribed", Organization{"amazon"});
has_role(User{"alice"}, "member", Organization{"apple"});
has_role(User{"bob"}, "member", Organization{"netflix"});
has_role(User{"charlie"}, "member", Organization{"amazon"});
}
assert has_quota_remaining(Organization{"apple"}, Feature{"repository"});
# Apple has quota remaining, so all good
assert allow(User{"alice"}, "repository.create", Organization{"apple"});
# Netflix has used all quota
assert_not allow(User{"bob"}, "repository.create", Organization{"netflix"});
# Amazon doesn't have any quota left
assert_not allow(User{"charlie"}, "repository.create", Organization{"amazon"});
}