1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 22:05:23 +02:00

fix(performance): optimize performance for edge EE-3311 (#8040)

This commit is contained in:
andres-portainer 2023-01-06 16:25:41 -03:00 committed by GitHub
parent 3d28a6f877
commit dd0d1737b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 577 additions and 164 deletions

View file

@ -49,8 +49,7 @@ func NewRequestBouncer(dataStore dataservices.DataStore, jwtService dataservices
// PublicAccess defines a security check for public API environments(endpoints).
// No authentication is required to access these environments(endpoints).
func (bouncer *RequestBouncer) PublicAccess(h http.Handler) http.Handler {
h = mwSecureHeaders(h)
return h
return mwSecureHeaders(h)
}
// AdminAccess defines a security check for API environments(endpoints) that require an authorization check.
@ -375,8 +374,8 @@ func extractAPIKey(r *http.Request) (apikey string, ok bool) {
// mwSecureHeaders provides secure headers middleware for handlers.
func mwSecureHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-XSS-Protection", "1; mode=block")
w.Header().Add("X-Content-Type-Options", "nosniff")
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("X-Content-Type-Options", "nosniff")
next.ServeHTTP(w, r)
})
}

View file

@ -11,26 +11,28 @@ func FilterUserTeams(teams []portainer.Team, context *RestrictedRequestContext)
return teams
}
teamsAccessableToUser := make([]portainer.Team, 0)
n := 0
for _, membership := range context.UserMemberships {
for _, team := range teams {
if team.ID == membership.TeamID {
teamsAccessableToUser = append(teamsAccessableToUser, team)
teams[n] = team
n++
break
}
}
}
return teamsAccessableToUser
return teams[:n]
}
// FilterLeaderTeams filters teams based on user role.
// Team leaders only have access to team they lead.
func FilterLeaderTeams(teams []portainer.Team, context *RestrictedRequestContext) []portainer.Team {
filteredTeams := []portainer.Team{}
n := 0
if !context.IsTeamLeader {
return filteredTeams
return teams[:n]
}
leaderSet := map[portainer.TeamID]bool{}
@ -42,11 +44,12 @@ func FilterLeaderTeams(teams []portainer.Team, context *RestrictedRequestContext
for _, team := range teams {
if leaderSet[team.ID] {
filteredTeams = append(filteredTeams, team)
teams[n] = team
n++
}
}
return filteredTeams
return teams[:n]
}
// FilterUsers filters users based on user role.
@ -56,14 +59,15 @@ func FilterUsers(users []portainer.User, context *RestrictedRequestContext) []po
return users
}
nonAdmins := make([]portainer.User, 0)
n := 0
for _, user := range users {
if user.Role != portainer.AdministratorRole {
nonAdmins = append(nonAdmins, user)
users[n] = user
n++
}
}
return nonAdmins
return users[:n]
}
// FilterRegistries filters registries based on user role and team memberships.
@ -73,52 +77,53 @@ func FilterRegistries(registries []portainer.Registry, user *portainer.User, tea
return registries
}
filteredRegistries := []portainer.Registry{}
n := 0
for _, registry := range registries {
if AuthorizedRegistryAccess(&registry, user, teamMemberships, endpointID) {
filteredRegistries = append(filteredRegistries, registry)
registries[n] = registry
n++
}
}
return filteredRegistries
return registries[:n]
}
// FilterEndpoints filters environments(endpoints) based on user role and team memberships.
// Non administrator only have access to authorized environments(endpoints) (can be inherited via endpoint groups).
func FilterEndpoints(endpoints []portainer.Endpoint, groups []portainer.EndpointGroup, context *RestrictedRequestContext) []portainer.Endpoint {
filteredEndpoints := endpoints
if context.IsAdmin {
return endpoints
}
if !context.IsAdmin {
filteredEndpoints = make([]portainer.Endpoint, 0)
n := 0
for _, endpoint := range endpoints {
endpointGroup := getAssociatedGroup(&endpoint, groups)
for _, endpoint := range endpoints {
endpointGroup := getAssociatedGroup(&endpoint, groups)
if AuthorizedEndpointAccess(&endpoint, endpointGroup, context.UserID, context.UserMemberships) {
filteredEndpoints = append(filteredEndpoints, endpoint)
}
if AuthorizedEndpointAccess(&endpoint, endpointGroup, context.UserID, context.UserMemberships) {
endpoints[n] = endpoint
n++
}
}
return filteredEndpoints
return endpoints[:n]
}
// FilterEndpointGroups filters environment(endpoint) groups based on user role and team memberships.
// Non administrator users only have access to authorized environment(endpoint) groups.
func FilterEndpointGroups(endpointGroups []portainer.EndpointGroup, context *RestrictedRequestContext) []portainer.EndpointGroup {
filteredEndpointGroups := endpointGroups
if context.IsAdmin {
return endpointGroups
}
if !context.IsAdmin {
filteredEndpointGroups = make([]portainer.EndpointGroup, 0)
for _, group := range endpointGroups {
if authorizedEndpointGroupAccess(&group, context.UserID, context.UserMemberships) {
filteredEndpointGroups = append(filteredEndpointGroups, group)
}
n := 0
for _, group := range endpointGroups {
if authorizedEndpointGroupAccess(&group, context.UserID, context.UserMemberships) {
endpointGroups[n] = group
n++
}
}
return filteredEndpointGroups
return endpointGroups[:n]
}
func getAssociatedGroup(endpoint *portainer.Endpoint, groups []portainer.EndpointGroup) *portainer.EndpointGroup {
@ -127,5 +132,6 @@ func getAssociatedGroup(endpoint *portainer.Endpoint, groups []portainer.Endpoin
return &group
}
}
return nil
}