Add LDAP policy entities API (#15908)

This commit is contained in:
Aditya Manthramurthy
2022-11-07 14:35:09 -08:00
committed by GitHub
parent ddeca9f12a
commit 76d822bf1e
7 changed files with 288 additions and 6 deletions

View File

@@ -23,6 +23,7 @@ import (
"encoding/json"
"errors"
"fmt"
"sort"
"strings"
"time"
@@ -1252,6 +1253,169 @@ func (store *IAMStoreSys) GetUsers() map[string]madmin.UserInfo {
return result
}
// Assumes store is locked by caller. If users is empty, returns all user mappings.
func (store *IAMStoreSys) listLDAPUserPolicyMappings(cache *iamCache, users []string,
isLDAPUserDN func(string) bool,
) []madmin.UserPolicyEntities {
var r []madmin.UserPolicyEntities
usersSet := set.CreateStringSet(users...)
for user, mappedPolicy := range cache.iamUserPolicyMap {
if !isLDAPUserDN(user) {
continue
}
if !usersSet.IsEmpty() && !usersSet.Contains(user) {
continue
}
ps := mappedPolicy.toSlice()
sort.Strings(ps)
r = append(r, madmin.UserPolicyEntities{
User: user,
Policies: ps,
})
}
sort.Slice(r, func(i, j int) bool {
return r[i].User < r[j].User
})
return r
}
// Assumes store is locked by caller. If groups is empty, returns all group mappings.
func (store *IAMStoreSys) listLDAPGroupPolicyMappings(cache *iamCache, groups []string,
isLDAPGroupDN func(string) bool,
) []madmin.GroupPolicyEntities {
var r []madmin.GroupPolicyEntities
groupsSet := set.CreateStringSet(groups...)
for group, mappedPolicy := range cache.iamGroupPolicyMap {
if !isLDAPGroupDN(group) {
continue
}
if !groupsSet.IsEmpty() && !groupsSet.Contains(group) {
continue
}
ps := mappedPolicy.toSlice()
sort.Strings(ps)
r = append(r, madmin.GroupPolicyEntities{
Group: group,
Policies: ps,
})
}
sort.Slice(r, func(i, j int) bool {
return r[i].Group < r[j].Group
})
return r
}
// Assumes store is locked by caller. If policies is empty, returns all policy mappings.
func (store *IAMStoreSys) listLDAPPolicyMappings(cache *iamCache, policy []string,
isLDAPUserDN, isLDAPGroupDN func(string) bool,
) []madmin.PolicyEntities {
queryPolSet := set.CreateStringSet(policy...)
policyToUsersMap := make(map[string]set.StringSet)
for user, mappedPolicy := range cache.iamUserPolicyMap {
if !isLDAPUserDN(user) {
continue
}
commonPolicySet := mappedPolicy.policySet()
if !queryPolSet.IsEmpty() {
commonPolicySet = commonPolicySet.Intersection(queryPolSet)
}
for _, policy := range commonPolicySet.ToSlice() {
s, ok := policyToUsersMap[policy]
if !ok {
policyToUsersMap[policy] = set.CreateStringSet(user)
} else {
s.Add(user)
policyToUsersMap[policy] = s
}
}
}
policyToGroupsMap := make(map[string]set.StringSet)
for group, mappedPolicy := range cache.iamGroupPolicyMap {
if !isLDAPGroupDN(group) {
continue
}
commonPolicySet := mappedPolicy.policySet()
if !queryPolSet.IsEmpty() {
commonPolicySet = commonPolicySet.Intersection(queryPolSet)
}
for _, policy := range commonPolicySet.ToSlice() {
s, ok := policyToUsersMap[policy]
if !ok {
policyToGroupsMap[policy] = set.CreateStringSet(group)
} else {
s.Add(group)
policyToGroupsMap[policy] = s
}
}
}
m := make(map[string]madmin.PolicyEntities, len(policyToGroupsMap))
for policy, groups := range policyToGroupsMap {
s := groups.ToSlice()
sort.Strings(s)
m[policy] = madmin.PolicyEntities{
Policy: policy,
Groups: s,
}
}
for policy, users := range policyToUsersMap {
s := users.ToSlice()
sort.Strings(s)
// Update existing value in map
pe := m[policy]
pe.Policy = policy
pe.Users = s
m[policy] = pe
}
policyEntities := make([]madmin.PolicyEntities, 0, len(m))
for _, v := range m {
policyEntities = append(policyEntities, v)
}
sort.Slice(policyEntities, func(i, j int) bool {
return policyEntities[i].Policy < policyEntities[j].Policy
})
return policyEntities
}
// ListLDAPPolicyMappings - return LDAP users/groups mapped to policies.
func (store *IAMStoreSys) ListLDAPPolicyMappings(q madmin.PolicyEntitiesQuery,
isLDAPUserDN, isLDAPGroupDN func(string) bool,
) madmin.PolicyEntitiesResult {
cache := store.rlock()
defer store.runlock()
var result madmin.PolicyEntitiesResult
isAllPoliciesQuery := len(q.Users) == 0 && len(q.Groups) == 0 && len(q.Policy) == 0
if len(q.Users) > 0 {
result.UserMappings = store.listLDAPUserPolicyMappings(cache, q.Users, isLDAPUserDN)
}
if len(q.Groups) > 0 {
result.GroupMappings = store.listLDAPGroupPolicyMappings(cache, q.Groups, isLDAPGroupDN)
}
if len(q.Policy) > 0 || isAllPoliciesQuery {
result.PolicyMappings = store.listLDAPPolicyMappings(cache, q.Policy, isLDAPUserDN, isLDAPGroupDN)
}
return result
}
// GetUsersWithMappedPolicies - safely returns the name of access keys with associated policies
func (store *IAMStoreSys) GetUsersWithMappedPolicies() map[string]string {
cache := store.rlock()