mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 07:49:41 +02:00
feat(extensions): introduce RBAC extension (#2900)
This commit is contained in:
parent
27a0188949
commit
8057aa45c4
196 changed files with 3321 additions and 1316 deletions
122
api/http/handler/auth/authorization.go
Normal file
122
api/http/handler/auth/authorization.go
Normal file
|
@ -0,0 +1,122 @@
|
|||
package auth
|
||||
|
||||
import portainer "github.com/portainer/portainer/api"
|
||||
|
||||
func getUserEndpointAuthorizations(user *portainer.User, endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup, roles []portainer.Role, userMemberships []portainer.TeamMembership) portainer.EndpointAuthorizations {
|
||||
endpointAuthorizations := make(portainer.EndpointAuthorizations)
|
||||
|
||||
groupUserAccessPolicies := map[portainer.EndpointGroupID]portainer.UserAccessPolicies{}
|
||||
groupTeamAccessPolicies := map[portainer.EndpointGroupID]portainer.TeamAccessPolicies{}
|
||||
for _, endpointGroup := range endpointGroups {
|
||||
groupUserAccessPolicies[endpointGroup.ID] = endpointGroup.UserAccessPolicies
|
||||
groupTeamAccessPolicies[endpointGroup.ID] = endpointGroup.TeamAccessPolicies
|
||||
}
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
authorizations := getAuthorizationsFromUserEndpointPolicy(user, &endpoint, roles)
|
||||
if len(authorizations) > 0 {
|
||||
endpointAuthorizations[endpoint.ID] = authorizations
|
||||
continue
|
||||
}
|
||||
|
||||
authorizations = getAuthorizationsFromUserEndpointGroupPolicy(user, &endpoint, roles, groupUserAccessPolicies)
|
||||
if len(authorizations) > 0 {
|
||||
endpointAuthorizations[endpoint.ID] = authorizations
|
||||
continue
|
||||
}
|
||||
|
||||
authorizations = getAuthorizationsFromTeamEndpointPolicies(userMemberships, &endpoint, roles)
|
||||
if len(authorizations) > 0 {
|
||||
endpointAuthorizations[endpoint.ID] = authorizations
|
||||
continue
|
||||
}
|
||||
|
||||
endpointAuthorizations[endpoint.ID] = getAuthorizationsFromTeamEndpointGroupPolicies(userMemberships, &endpoint, roles, groupTeamAccessPolicies)
|
||||
}
|
||||
|
||||
return endpointAuthorizations
|
||||
}
|
||||
|
||||
func getAuthorizationsFromUserEndpointPolicy(user *portainer.User, endpoint *portainer.Endpoint, roles []portainer.Role) portainer.Authorizations {
|
||||
policyRoles := make([]portainer.RoleID, 0)
|
||||
|
||||
policy, ok := endpoint.UserAccessPolicies[user.ID]
|
||||
if ok {
|
||||
policyRoles = append(policyRoles, policy.RoleID)
|
||||
}
|
||||
|
||||
return getAuthorizationsFromRoles(policyRoles, roles)
|
||||
}
|
||||
|
||||
func getAuthorizationsFromUserEndpointGroupPolicy(user *portainer.User, endpoint *portainer.Endpoint, roles []portainer.Role, groupAccessPolicies map[portainer.EndpointGroupID]portainer.UserAccessPolicies) portainer.Authorizations {
|
||||
policyRoles := make([]portainer.RoleID, 0)
|
||||
|
||||
policy, ok := groupAccessPolicies[endpoint.GroupID][user.ID]
|
||||
if ok {
|
||||
policyRoles = append(policyRoles, policy.RoleID)
|
||||
}
|
||||
|
||||
return getAuthorizationsFromRoles(policyRoles, roles)
|
||||
}
|
||||
|
||||
func getAuthorizationsFromTeamEndpointPolicies(memberships []portainer.TeamMembership, endpoint *portainer.Endpoint, roles []portainer.Role) portainer.Authorizations {
|
||||
policyRoles := make([]portainer.RoleID, 0)
|
||||
|
||||
for _, membership := range memberships {
|
||||
policy, ok := endpoint.TeamAccessPolicies[membership.TeamID]
|
||||
if ok {
|
||||
policyRoles = append(policyRoles, policy.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
return getAuthorizationsFromRoles(policyRoles, roles)
|
||||
}
|
||||
|
||||
func getAuthorizationsFromTeamEndpointGroupPolicies(memberships []portainer.TeamMembership, endpoint *portainer.Endpoint, roles []portainer.Role, groupAccessPolicies map[portainer.EndpointGroupID]portainer.TeamAccessPolicies) portainer.Authorizations {
|
||||
policyRoles := make([]portainer.RoleID, 0)
|
||||
|
||||
for _, membership := range memberships {
|
||||
policy, ok := groupAccessPolicies[endpoint.GroupID][membership.TeamID]
|
||||
if ok {
|
||||
policyRoles = append(policyRoles, policy.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
return getAuthorizationsFromRoles(policyRoles, roles)
|
||||
}
|
||||
|
||||
func getAuthorizationsFromRoles(roleIdentifiers []portainer.RoleID, roles []portainer.Role) portainer.Authorizations {
|
||||
var roleAuthorizations []portainer.Authorizations
|
||||
for _, id := range roleIdentifiers {
|
||||
for _, role := range roles {
|
||||
if role.ID == id {
|
||||
roleAuthorizations = append(roleAuthorizations, role.Authorizations)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processedAuthorizations := make(portainer.Authorizations)
|
||||
if len(roleAuthorizations) > 0 {
|
||||
processedAuthorizations = roleAuthorizations[0]
|
||||
for idx, authorizations := range roleAuthorizations {
|
||||
if idx == 0 {
|
||||
continue
|
||||
}
|
||||
processedAuthorizations = mergeAuthorizations(processedAuthorizations, authorizations)
|
||||
}
|
||||
}
|
||||
|
||||
return processedAuthorizations
|
||||
}
|
||||
|
||||
func mergeAuthorizations(a, b portainer.Authorizations) portainer.Authorizations {
|
||||
c := make(map[portainer.Authorization]bool)
|
||||
|
||||
for k := range b {
|
||||
if _, ok := a[k]; ok {
|
||||
c[k] = true
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue