| /* |
| * 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 |