SMQ-2893 - Add callout to roles (#2907)

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
Steve Munene
2025-06-03 21:01:44 +03:00
committed by GitHub
parent 5e96516bf6
commit 343a771c4f
6 changed files with 171 additions and 7 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ func AuthorizationMiddleware(
if err := extOpp.Validate(); err != nil {
return nil, err
}
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ChannelType, svc, authz, rolesOpPerm)
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ChannelType, svc, authz, rolesOpPerm, callout)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -65,7 +65,7 @@ func AuthorizationMiddleware(
if err := opp.Validate(); err != nil {
return nil, err
}
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ClientType, svc, authz, rolesOpPerm)
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ClientType, svc, authz, rolesOpPerm, callout)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -45,7 +45,7 @@ func AuthorizationMiddleware(entityType string, svc domains.Service, authz smqau
return nil, err
}
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(entityType, svc, authz, rolesOpPerm)
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(entityType, svc, authz, rolesOpPerm, callout)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -79,7 +79,7 @@ func AuthorizationMiddleware(entityType string,
return nil, err
}
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(entityType, svc, authz, rolesOpPerm)
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(entityType, svc, authz, rolesOpPerm, callout)
if err != nil {
return nil, err
}
@@ -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
}
+4 -2
View File
@@ -201,6 +201,7 @@ const (
OpRoleCheckMembersExists
OpRoleRemoveMembers
OpRoleRemoveAllMembers
OpListAvailableActions
)
var expectedOperations = []svcutil.Operation{
@@ -221,7 +222,7 @@ var expectedOperations = []svcutil.Operation{
OpRoleRemoveAllMembers,
}
var operationNames = []string{
var OperationNames = []string{
"OpAddRole",
"OpRemoveRole",
"OpUpdateRoleName",
@@ -237,8 +238,9 @@ var operationNames = []string{
"OpRoleCheckMembersExists",
"OpRoleRemoveMembers",
"OpRoleRemoveAllMembers",
"OpListAvailableActions",
}
func NewOperationPerm() svcutil.OperationPerm {
return svcutil.NewOperationPerm(expectedOperations, operationNames)
return svcutil.NewOperationPerm(expectedOperations, OperationNames)
}