Filter bundles and settings by update permissions as first approach

This commit is contained in:
Benedikt Kulmann
2020-08-19 15:54:32 +02:00
parent be5d9b8aac
commit 26ac04c343
2 changed files with 85 additions and 1 deletions
+52
View File
@@ -0,0 +1,52 @@
package svc
import "github.com/owncloud/ocis-settings/pkg/proto/v0"
func (g Service) hasPermission(
assignments []*proto.UserRoleAssignment,
resource *proto.Resource,
operation proto.Permission_Operation,
constraint proto.Permission_Constraint,
) bool {
for index := range assignments {
if g.isAllowedByRole(assignments[index], resource, operation, constraint) {
return true
}
}
return false
}
func (g Service) isAllowedByRole(
assignment *proto.UserRoleAssignment,
resource *proto.Resource,
operation proto.Permission_Operation,
constraint proto.Permission_Constraint,
) bool {
role, err := g.manager.ReadBundle(assignment.RoleId)
if err != nil {
g.logger.Err(err).Str("bundle", assignment.RoleId).Msg("Failed to fetch role")
return false
}
for _, setting := range role.Settings {
if _, ok := setting.Value.(*proto.Setting_PermissionValue); ok {
value := setting.Value.(*proto.Setting_PermissionValue).PermissionValue
if resource.Type == setting.Resource.Type &&
resource.Id == setting.Resource.Id &&
operation == value.Operation &&
isConstraintMatch(constraint, value.Constraint) {
return true
}
}
}
return false
}
// isConstraintMatch checks if the `given` constraint is the same or a superset of the `required` constraint.
// this is only a comparison on ENUM level. this is not a check about the appropriate constraint for a resource.
func isConstraintMatch(given, required proto.Permission_Constraint) bool {
// comparing enum by order is not a feasible solution, because `SHARED` is not a superset of `OWN`.
if given == proto.Permission_CONSTRAINT_ALL {
return true
}
return given != proto.Permission_CONSTRAINT_UNKNOWN && given == required
}
+33 -1
View File
@@ -86,7 +86,39 @@ func (g Service) ListBundles(c context.Context, req *proto.ListBundlesRequest, r
if err != nil {
return merrors.NotFound("ocis-settings", "%s", err)
}
res.Bundles = bundles
// fetch roles of the user
rolesResponse := &proto.ListRoleAssignmentsResponse{}
err = g.ListRoleAssignments(c, &proto.ListRoleAssignmentsRequest{AccountUuid: req.AccountUuid}, rolesResponse)
if err != nil {
return err
}
// filter settings in bundles that are allowed according to roles
var filteredBundles []*proto.Bundle
for _, bundle := range bundles {
var filteredSettings []*proto.Setting
for _, setting := range bundle.Settings {
settingResource := &proto.Resource{
Type: proto.Resource_TYPE_SETTING,
Id: setting.Id,
}
if g.hasPermission(
rolesResponse.Assignments,
settingResource,
proto.Permission_OPERATION_UPDATE,
proto.Permission_CONSTRAINT_OWN,
) {
filteredSettings = append(filteredSettings, setting)
}
}
bundle.Settings = filteredSettings
if len(filteredSettings) > 0 {
filteredBundles = append(filteredBundles, bundle)
}
}
res.Bundles = filteredBundles
return nil
}