blob: d4c17d11c02902016d27caba0ea7e607b437e0d4 [file] [log] [blame]
/*
* Copyright 2020 The casbin Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "casbin/pch.h"
#ifndef RBAC_API_CPP
#define RBAC_API_CPP
#include "casbin/enforcer.h"
#include "casbin/exception/casbin_enforcer_exception.h"
#include "casbin/util/util.h"
namespace casbin {
// GetRolesForUser gets the roles that a user has.
std::vector<std::string> Enforcer ::GetRolesForUser(const std::string& name, const std::vector<std::string>& domain) {
std::vector<std::string> res = m_model->m["g"].assertion_map["g"]->rm->GetRoles(name, domain);
return res;
}
// GetUsersForRole gets the users that has a role.
std::vector<std::string> Enforcer ::GetUsersForRole(const std::string& name, const std::vector<std::string>& domain) {
std::vector<std::string> res = m_model->m["g"].assertion_map["g"]->rm->GetUsers(name, domain);
return res;
}
// HasRoleForUser determines whether a user has a role.
bool Enforcer ::HasRoleForUser(const std::string& name, const std::string& role) {
std::vector<std::string> domain;
std::vector<std::string> roles = this->GetRolesForUser(name, domain);
bool has_role = false;
for (int i = 0; i < roles.size(); i++) {
if (roles[i] == role) {
has_role = true;
break;
}
}
return has_role;
}
// AddRoleForUser adds a role for a user.
// Returns false if the user already has the role (aka not affected).
bool Enforcer ::AddRoleForUser(const std::string& user, const std::string& role) {
std::vector<std::string> params{user, role};
return this->AddGroupingPolicy(params);
}
// AddRolesForUser adds roles for a user.
// Returns false if the user already has the roles (aka not affected).
bool Enforcer ::AddRolesForUser(const std::string& user, const std::vector<std::string>& roles) {
bool f = false;
for (int i = 0; i < roles.size(); i++) {
bool b = this->AddGroupingPolicy({user, roles[i]});
if (b)
f = true;
}
return f;
}
// DeleteRoleForUser deletes a role for a user.
// Returns false if the user does not have the role (aka not affected).
bool Enforcer ::DeleteRoleForUser(const std::string& user, const std::string& role) {
std::vector<std::string> params{user, role};
return this->RemoveGroupingPolicy(params);
}
// DeleteRolesForUser deletes all roles for a user.
// Returns false if the user does not have any roles (aka not affected).
bool Enforcer ::DeleteRolesForUser(const std::string& user) {
std::vector<std::string> field_values{user};
return this->RemoveFilteredGroupingPolicy(0, field_values);
}
// DeleteUser deletes a user.
// Returns false if the user does not exist (aka not affected).
bool Enforcer ::DeleteUser(const std::string& user) {
std::vector<std::string> field_values{user};
bool res1 = this->RemoveFilteredGroupingPolicy(0, field_values);
bool res2 = this->RemoveFilteredPolicy(0, field_values);
return res1 || res2;
}
// DeleteRole deletes a role.
// Returns false if the role does not exist (aka not affected).
bool Enforcer ::DeleteRole(const std::string& role) {
std::vector<std::string> field_values{role};
bool res1 = this->RemoveFilteredGroupingPolicy(1, field_values);
bool res2 = this->RemoveFilteredPolicy(0, field_values);
return res1 || res2;
}
// DeletePermission deletes a permission.
// Returns false if the permission does not exist (aka not affected).
bool Enforcer ::DeletePermission(const std::vector<std::string>& permission) {
std::vector<std::string> field_values{permission};
return this->RemoveFilteredPolicy(1, field_values);
}
// AddPermissionForUser adds a permission for a user or role.
// Returns false if the user or role already has the permission (aka not affected).
bool Enforcer ::AddPermissionForUser(const std::string& user, const std::vector<std::string>& permission) {
return this->AddPolicy(JoinSlice(user, permission));
}
// DeletePermissionForUser deletes a permission for a user or role.
// Returns false if the user or role does not have the permission (aka not affected).
bool Enforcer ::DeletePermissionForUser(const std::string& user, const std::vector<std::string>& permission) {
return this->RemovePolicy(JoinSlice(user, permission));
}
// DeletePermissionsForUser deletes permissions for a user or role.
// Returns false if the user or role does not have any permissions (aka not affected).
bool Enforcer ::DeletePermissionsForUser(const std::string& user) {
std::vector<std::string> field_values{user};
return this->RemoveFilteredPolicy(0, field_values);
}
// GetPermissionsForUser gets permissions for a user or role.
PoliciesValues Enforcer ::GetPermissionsForUser(const std::string& user) {
std::vector<std::string> field_values{user};
return this->GetFilteredPolicy(0, field_values);
}
// HasPermissionForUser determines whether a user has a permission.
bool Enforcer ::HasPermissionForUser(const std::string& user, const std::vector<std::string>& permission) {
return this->HasPolicy(JoinSlice(user, permission));
}
// GetImplicitRolesForUser gets implicit roles that a user has.
// Compared to GetRolesForUser(), this function retrieves indirect roles besides direct roles.
// For example:
// g, alice, role:admin
// g, role:admin, role:user
//
// GetRolesForUser("alice") can only get: ["role:admin"].
// But GetImplicitRolesForUser("alice") will get: ["role:admin", "role:user"].
std::vector<std::string> Enforcer ::GetImplicitRolesForUser(const std::string& name, const std::vector<std::string>& domain) {
std::vector<std::string> res;
std::unordered_map<std::string, bool> role_set;
role_set[name] = true;
std::vector<std::string> q;
q.push_back(name);
while (q.size() > 0) {
std::string name = q[0];
q.erase(q.begin());
std::vector<std::string> roles = rm->GetRoles(name, domain);
for (int i = 0; i < roles.size(); i++) {
if (!(role_set.find(roles[i]) != role_set.end())) {
res.push_back(roles[i]);
q.push_back(roles[i]);
role_set[roles[i]] = true;
}
}
}
return res;
}
// GetImplicitPermissionsForUser gets implicit permissions for a user or role.
// Compared to GetPermissionsForUser(), this function retrieves permissions for inherited roles.
// For example:
// p, admin, data1, read
// p, alice, data2, read
// g, alice, admin
//
// GetPermissionsForUser("alice") can only get: [["alice", "data2", "read"]].
// But GetImplicitPermissionsForUser("alice") will get: [["admin", "data1", "read"], ["alice", "data2", "read"]].
PoliciesValues Enforcer ::GetImplicitPermissionsForUser(const std::string& user, const std::vector<std::string>& domain) {
std::vector<std::string> roles = this->GetImplicitRolesForUser(user, domain);
roles.insert(roles.begin(), user);
bool with_domain = false;
if (domain.size() == 1)
with_domain = true;
else if (domain.size() > 1)
throw CasbinEnforcerException("Domain should be 1 parameter");
PoliciesValues res;
PoliciesValues permissions;
for (int i = 0; i < roles.size(); i++) {
if (with_domain)
permissions = this->GetPermissionsForUserInDomain(roles[i], domain[0]);
else
permissions = this->GetPermissionsForUser(roles[i]);
for (auto& permission : permissions)
res.emplace(permission);
}
return res;
}
// GetImplicitUsersForPermission gets implicit users for a permission.
// For example:
// p, admin, data1, read
// p, bob, data1, read
// g, alice, admin
//
// GetImplicitUsersForPermission("data1", "read") will get: ["alice", "bob"].
// Note: only users will be returned, roles (2nd arg in "g") will be excluded.
std::vector<std::string> Enforcer ::GetImplicitUsersForPermission(const std::vector<std::string>& permission) {
std::vector<std::string> p_subjects = this->GetAllSubjects();
std::vector<std::string> g_inherit = m_model->GetValuesForFieldInPolicyAllTypes("g", 1);
std::vector<std::string> g_subjects = m_model->GetValuesForFieldInPolicyAllTypes("g", 0);
std::vector<std::string> subjects(p_subjects);
subjects.insert(subjects.end(), g_subjects.begin(), g_subjects.end());
ArrayRemoveDuplicates(subjects);
std::vector<std::string> res;
for (int i = 0; i < subjects.size(); i++) {
bool allowed = this->Enforce({subjects[i], permission[0], permission[1]});
if (allowed) {
res.push_back(subjects[i]);
}
}
res = SetSubtract(res, g_inherit);
return res;
}
} // namespace casbin
#endif // RBAC_API_CPP