mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-05 11:51:16 -06:00
58 lines
2.1 KiB
Go
58 lines
2.1 KiB
Go
package svc
|
|
|
|
import "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
|
|
|
func (g Service) hasPermission(
|
|
roleIDs []string,
|
|
resource *proto.Resource,
|
|
operations []proto.Permission_Operation,
|
|
constraint proto.Permission_Constraint,
|
|
) bool {
|
|
permissions, err := g.manager.ListPermissionsByResource(resource, roleIDs)
|
|
if err != nil {
|
|
g.logger.Debug().Err(err).
|
|
Str("resource-type", resource.Type.String()).
|
|
Str("resource-id", resource.Id).
|
|
Msg("permissions could not be loaded for resource")
|
|
return false
|
|
}
|
|
permissions = getFilteredPermissionsByOperations(permissions, operations)
|
|
return isConstraintFulfilled(permissions, constraint)
|
|
}
|
|
|
|
// filterPermissionsByOperations returns the subset of the given permissions, where at least one of the given operations is fulfilled.
|
|
func getFilteredPermissionsByOperations(permissions []*proto.Permission, operations []proto.Permission_Operation) []*proto.Permission {
|
|
var filteredPermissions []*proto.Permission
|
|
for _, permission := range permissions {
|
|
if isAnyOperationFulfilled(permission, operations) {
|
|
filteredPermissions = append(filteredPermissions, permission)
|
|
}
|
|
}
|
|
return filteredPermissions
|
|
}
|
|
|
|
// isAnyOperationFulfilled checks if the permissions is about any of the operations
|
|
func isAnyOperationFulfilled(permission *proto.Permission, operations []proto.Permission_Operation) bool {
|
|
for _, operation := range operations {
|
|
if operation == permission.Operation {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// isConstraintFulfilled checks if one of the permissions has the same or a parent of the constraint.
|
|
// this is only a comparison on ENUM level. More sophisticated checks cannot happen here...
|
|
func isConstraintFulfilled(permissions []*proto.Permission, constraint proto.Permission_Constraint) bool {
|
|
for _, permission := range permissions {
|
|
// comparing enum by order is not a feasible solution, because `SHARED` is not a superset of `OWN`.
|
|
if permission.Constraint == proto.Permission_CONSTRAINT_ALL {
|
|
return true
|
|
}
|
|
if permission.Constraint != proto.Permission_CONSTRAINT_UNKNOWN && permission.Constraint == constraint {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|