|
|
|
@@ -5,9 +5,12 @@ package middleware
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"maps"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/absmach/supermq/pkg/authn"
|
|
|
|
|
smqauthz "github.com/absmach/supermq/pkg/authz"
|
|
|
|
|
"github.com/absmach/supermq/pkg/callout"
|
|
|
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
|
|
|
"github.com/absmach/supermq/pkg/policies"
|
|
|
|
|
"github.com/absmach/supermq/pkg/roles"
|
|
|
|
@@ -20,11 +23,12 @@ type RoleManagerAuthorizationMiddleware struct {
|
|
|
|
|
entityType string
|
|
|
|
|
svc roles.RoleManager
|
|
|
|
|
authz smqauthz.Authorization
|
|
|
|
|
callout callout.Callout
|
|
|
|
|
opp svcutil.OperationPerm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AuthorizationMiddleware adds authorization to the clients service.
|
|
|
|
|
func NewRoleManagerAuthorizationMiddleware(entityType string, svc roles.RoleManager, authz smqauthz.Authorization, opPerm map[svcutil.Operation]svcutil.Permission) (RoleManagerAuthorizationMiddleware, error) {
|
|
|
|
|
func NewRoleManagerAuthorizationMiddleware(entityType string, svc roles.RoleManager, authz smqauthz.Authorization, opPerm map[svcutil.Operation]svcutil.Permission, callout callout.Callout) (RoleManagerAuthorizationMiddleware, error) {
|
|
|
|
|
opp := roles.NewOperationPerm()
|
|
|
|
|
if err := opp.AddOperationPermissionMap(opPerm); err != nil {
|
|
|
|
|
return RoleManagerAuthorizationMiddleware{}, err
|
|
|
|
@@ -38,6 +42,7 @@ func NewRoleManagerAuthorizationMiddleware(entityType string, svc roles.RoleMana
|
|
|
|
|
svc: svc,
|
|
|
|
|
authz: authz,
|
|
|
|
|
opp: opp,
|
|
|
|
|
callout: callout,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.validate(); err != nil {
|
|
|
|
|
return RoleManagerAuthorizationMiddleware{}, err
|
|
|
|
@@ -66,6 +71,16 @@ func (ram RoleManagerAuthorizationMiddleware) AddRole(ctx context.Context, sessi
|
|
|
|
|
if err := ram.validateMembers(ctx, session, optionalMembers); err != nil {
|
|
|
|
|
return roles.RoleProvision{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_name": roleName,
|
|
|
|
|
"optional_actions": optionalActions,
|
|
|
|
|
"optional_members": optionalMembers,
|
|
|
|
|
"count": 1,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpAddRole.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.RoleProvision{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.AddRole(ctx, session, entityID, roleName, optionalActions, optionalMembers)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -80,6 +95,13 @@ func (ram RoleManagerAuthorizationMiddleware) RemoveRole(ctx context.Context, se
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRemoveRole.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RemoveRole(ctx, session, entityID, roleID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -94,6 +116,14 @@ func (ram RoleManagerAuthorizationMiddleware) UpdateRoleName(ctx context.Context
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return roles.Role{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"new_role_name": newRoleName,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpUpdateRoleName.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.Role{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.UpdateRoleName(ctx, session, entityID, roleID, newRoleName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -108,6 +138,13 @@ func (ram RoleManagerAuthorizationMiddleware) RetrieveRole(ctx context.Context,
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return roles.Role{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRetrieveRole.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.Role{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RetrieveRole(ctx, session, entityID, roleID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -122,10 +159,22 @@ func (ram RoleManagerAuthorizationMiddleware) RetrieveAllRoles(ctx context.Conte
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return roles.RolePage{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"limit": limit,
|
|
|
|
|
"offset": offset,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRetrieveAllRoles.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.RolePage{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RetrieveAllRoles(ctx, session, entityID, limit, offset)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ram RoleManagerAuthorizationMiddleware) ListAvailableActions(ctx context.Context, session authn.Session) ([]string, error) {
|
|
|
|
|
params := map[string]any{}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpListAvailableActions.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.ListAvailableActions(ctx, session)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -141,6 +190,15 @@ func (ram RoleManagerAuthorizationMiddleware) RoleAddActions(ctx context.Context
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"actions": actions,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleAddActions.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ram.svc.RoleAddActions(ctx, session, entityID, roleID, actions)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -156,6 +214,14 @@ func (ram RoleManagerAuthorizationMiddleware) RoleListActions(ctx context.Contex
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleListActions.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ram.svc.RoleListActions(ctx, session, entityID, roleID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -170,6 +236,14 @@ func (ram RoleManagerAuthorizationMiddleware) RoleCheckActionsExists(ctx context
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"actions": actions,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleCheckActionsExists.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleCheckActionsExists(ctx, session, entityID, roleID, actions)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -184,6 +258,15 @@ func (ram RoleManagerAuthorizationMiddleware) RoleRemoveActions(ctx context.Cont
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"actions": actions,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleRemoveActions.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ram.svc.RoleRemoveActions(ctx, session, entityID, roleID, actions)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -198,6 +281,13 @@ func (ram RoleManagerAuthorizationMiddleware) RoleRemoveAllActions(ctx context.C
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleRemoveAllActions.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleRemoveAllActions(ctx, session, entityID, roleID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -216,6 +306,14 @@ func (ram RoleManagerAuthorizationMiddleware) RoleAddMembers(ctx context.Context
|
|
|
|
|
if err := ram.validateMembers(ctx, session, members); err != nil {
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"members": members,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleAddMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return []string{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleAddMembers(ctx, session, entityID, roleID, members)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -230,6 +328,15 @@ func (ram RoleManagerAuthorizationMiddleware) RoleListMembers(ctx context.Contex
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return roles.MembersPage{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"limit": limit,
|
|
|
|
|
"offset": offset,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleListMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.MembersPage{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleListMembers(ctx, session, entityID, roleID, limit, offset)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -244,6 +351,14 @@ func (ram RoleManagerAuthorizationMiddleware) RoleCheckMembersExists(ctx context
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"members": members,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleCheckMembersExists.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleCheckMembersExists(ctx, session, entityID, roleID, members)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -258,6 +373,13 @@ func (ram RoleManagerAuthorizationMiddleware) RoleRemoveAllMembers(ctx context.C
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleRemoveAllMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleRemoveAllMembers(ctx, session, entityID, roleID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -272,6 +394,13 @@ func (ram RoleManagerAuthorizationMiddleware) ListEntityMembers(ctx context.Cont
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return roles.MembersRolePage{}, err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"page_query": pageQuery,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleListMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return roles.MembersRolePage{}, err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.ListEntityMembers(ctx, session, entityID, pageQuery)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -286,6 +415,13 @@ func (ram RoleManagerAuthorizationMiddleware) RemoveEntityMembers(ctx context.Co
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"members": members,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleRemoveAllMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RemoveEntityMembers(ctx, session, entityID, members)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -300,6 +436,14 @@ func (ram RoleManagerAuthorizationMiddleware) RoleRemoveMembers(ctx context.Cont
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
params := map[string]any{
|
|
|
|
|
"entity_id": entityID,
|
|
|
|
|
"role_id": roleID,
|
|
|
|
|
"members": members,
|
|
|
|
|
}
|
|
|
|
|
if err := ram.callOut(ctx, session, roles.OpRoleRemoveMembers.String(roles.OperationNames), params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return ram.svc.RoleRemoveMembers(ctx, session, entityID, roleID, members)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -355,3 +499,21 @@ func (ram RoleManagerAuthorizationMiddleware) validateMembers(ctx context.Contex
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ram RoleManagerAuthorizationMiddleware) callOut(ctx context.Context, session authn.Session, op string, params map[string]interface{}) error {
|
|
|
|
|
pl := map[string]any{
|
|
|
|
|
"entity_type": ram.entityType,
|
|
|
|
|
"subject_type": policies.UserType,
|
|
|
|
|
"subject_id": session.UserID,
|
|
|
|
|
"domain": session.DomainID,
|
|
|
|
|
"time": time.Now().UTC(),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
maps.Copy(params, pl)
|
|
|
|
|
|
|
|
|
|
if err := ram.callout.Callout(ctx, op, params); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|