SMQ-2632 - Remove PAT logics from middleware (#3291)

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
Steve Munene
2025-12-22 13:10:16 +03:00
committed by GitHub
parent f612109f24
commit 0fe5a6d6e8
9 changed files with 269 additions and 850 deletions
+8 -3
View File
@@ -19,12 +19,16 @@ import (
const (
recoveryDuration = 5 * time.Minute
defLimit = 100
randStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&&*|+-="
patPrefix = "pat"
patSecretSeparator = "_"
)
const (
AccessTokenType uint32 = iota
PersonalAccessTokenType
)
var (
// ErrExpiry indicates that the token is expired.
ErrExpiry = errors.New("token is expired")
@@ -195,7 +199,7 @@ func (svc service) Identify(ctx context.Context, token string) (Key, error) {
}
func (svc service) Authorize(ctx context.Context, pr policies.Policy) error {
if pr.PatID != "" && pr.TokenType == uint32(PersonalAccessToken) {
if pr.PatID != "" && pr.TokenType == PersonalAccessTokenType {
if err := svc.AuthorizePAT(ctx, pr.UserID, pr.PatID, EntityType(pr.EntityType), pr.OptionalDomainID, Operation(pr.Operation), pr.EntityID); err != nil {
return err
}
@@ -715,7 +719,8 @@ func (svc service) IdentifyPAT(ctx context.Context, secret string) (PAT, error)
return PAT{}, errors.Wrap(svcerr.ErrAuthentication, err)
}
role := svc.getUserRole(ctx, userID.String())
return PAT{ID: patID.String(), User: userID.String(), Role: role}, nil
pat := PAT{ID: patID.String(), User: userID.String(), Role: role}
return pat, nil
}
func (svc service) AuthorizePAT(ctx context.Context, userID, patID string, entityType EntityType, optionalDomainID string, operation Operation, entityID string) error {
+93 -219
View File
@@ -5,6 +5,7 @@ package middleware
import (
"context"
"fmt"
"github.com/absmach/supermq/auth"
"github.com/absmach/supermq/channels"
@@ -78,51 +79,53 @@ func NewAuthorization(
}
func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session authn.Session, chs ...channels.Channel) ([]channels.Channel, []roles.RoleProvision, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: auth.AnyIDs,
}); err != nil {
return []channels.Channel{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
req := smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
ObjectType: policies.DomainType,
Object: session.DomainID,
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: auth.AnyIDs,
}
if err := am.authorize(ctx, policies.DomainType, domains.OpCreateDomainChannels, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
ObjectType: policies.DomainType,
Object: session.DomainID,
}); err != nil {
if err := am.authorize(ctx, session, policies.DomainType, domains.OpCreateDomainChannels, req); err != nil {
return []channels.Channel{}, []roles.RoleProvision{}, errors.Wrap(err, errDomainCreateChannels)
}
for _, ch := range chs {
if ch.ParentGroup != "" {
if err := am.authorize(ctx, session, policies.GroupType, groups.OpGroupSetChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
ObjectType: policies.GroupType,
Object: ch.ParentGroup,
}); err != nil {
return []channels.Channel{}, []roles.RoleProvision{}, errors.Wrap(err, errors.Wrap(errGroupSetChildChannels, fmt.Errorf("channel name %s parent group id %s", ch.Name, ch.ParentGroup)))
}
}
}
return am.svc.CreateChannels(ctx, session, chs...)
}
func (am *authorizationMiddleware) ViewChannel(ctx context.Context, session authn.Session, id string, withRoles bool) (channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.ReadOp,
EntityID: id,
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpViewChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
ObjectType: policies.ChannelType,
Object: id,
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpViewChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
ObjectType: policies.ChannelType,
Object: id,
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.ReadOp,
EntityID: id,
}); err != nil {
return channels.Channel{}, errors.Wrap(err, errView)
}
@@ -131,19 +134,6 @@ func (am *authorizationMiddleware) ViewChannel(ctx context.Context, session auth
}
func (am *authorizationMiddleware) ListChannels(ctx context.Context, session authn.Session, pm channels.Page) (channels.ChannelsPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: auth.AnyIDs,
}); err != nil {
return channels.ChannelsPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -152,18 +142,6 @@ func (am *authorizationMiddleware) ListChannels(ctx context.Context, session aut
}
func (am *authorizationMiddleware) ListUserChannels(ctx context.Context, session authn.Session, userID string, pm channels.Page) (channels.ChannelsPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: auth.AnyIDs,
}); err != nil {
return channels.ChannelsPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err != nil {
return channels.ChannelsPage{}, errors.Wrap(err, errList)
}
@@ -172,20 +150,7 @@ func (am *authorizationMiddleware) ListUserChannels(ctx context.Context, session
}
func (am *authorizationMiddleware) UpdateChannel(ctx context.Context, session authn.Session, channel channels.Channel) (channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: channel.ID,
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpUpdateChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpUpdateChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -199,20 +164,7 @@ func (am *authorizationMiddleware) UpdateChannel(ctx context.Context, session au
}
func (am *authorizationMiddleware) UpdateChannelTags(ctx context.Context, session authn.Session, channel channels.Channel) (channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: channel.ID,
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpUpdateChannelTags, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpUpdateChannelTags, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -226,20 +178,7 @@ func (am *authorizationMiddleware) UpdateChannelTags(ctx context.Context, sessio
}
func (am *authorizationMiddleware) EnableChannel(ctx context.Context, session authn.Session, id string) (channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpEnableChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpEnableChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -253,20 +192,7 @@ func (am *authorizationMiddleware) EnableChannel(ctx context.Context, session au
}
func (am *authorizationMiddleware) DisableChannel(ctx context.Context, session authn.Session, id string) (channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpDisableChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpDisableChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -280,19 +206,7 @@ func (am *authorizationMiddleware) DisableChannel(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveChannel(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpDeleteChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpDeleteChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -306,34 +220,8 @@ func (am *authorizationMiddleware) RemoveChannel(ctx context.Context, session au
}
func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Session, chIDs, thIDs []string, connTypes []connections.ConnType) error {
if session.Type == authn.PersonalAccessToken {
for _, chID := range chIDs {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: chID,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
for _, thID := range thIDs {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: thID,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
}
for _, chID := range chIDs {
if err := am.authorize(ctx, policies.ChannelType, channels.OpConnectClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpConnectClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -345,7 +233,7 @@ func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Se
}
for _, thID := range thIDs {
if err := am.authorize(ctx, policies.ClientType, clients.OpConnectToChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpConnectToChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -360,35 +248,8 @@ func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Se
}
func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn.Session, chIDs, thIDs []string, connTypes []connections.ConnType) error {
if session.Type == authn.PersonalAccessToken {
for _, chID := range chIDs {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: chID,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
for _, thID := range thIDs {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: thID,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
}
for _, chID := range chIDs {
if err := am.authorize(ctx, policies.ChannelType, channels.OpDisconnectClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpDisconnectClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -400,7 +261,7 @@ func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn
}
for _, thID := range thIDs {
if err := am.authorize(ctx, policies.ClientType, clients.OpDisconnectFromChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpDisconnectFromChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -415,20 +276,7 @@ func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn
}
func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session authn.Session, parentGroupID string, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpSetParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpSetParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -438,7 +286,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
return errors.Wrap(err, errSetParentGroup)
}
if err := am.authorize(ctx, policies.GroupType, groups.OpGroupSetChildChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpGroupSetChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -452,20 +300,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ChannelsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ChannelType, channels.OpRemoveParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ChannelType, channels.OpSetParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -481,7 +316,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
}
if ch.ParentGroup != "" {
if err := am.authorize(ctx, policies.GroupType, groups.OpGroupRemoveChildChannel, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpGroupRemoveChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -496,7 +331,12 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, entityType string, op permissions.Operation, req smqauthz.PolicyReq) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, session authn.Session, entityType string, op permissions.Operation, req smqauthz.PolicyReq) error {
req.TokenType = session.Type
req.UserID = session.UserID
req.PatID = session.PatID
req.OptionalDomainID = session.DomainID
perm, err := am.entitiesOps.GetPermission(entityType, op)
if err != nil {
return err
@@ -504,6 +344,40 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, entityType str
req.Permission = perm.String()
if req.PatID != "" && req.TokenType == authn.PersonalAccessToken {
req.EntityType = auth.ChannelsType
req.EntityID = req.Object
switch op {
case channels.OpViewChannel:
req.Operation = auth.ReadOp
case channels.OpListUserChannels:
req.Operation = auth.ListOp
req.EntityID = auth.AnyIDs
case channels.OpUpdateChannel,
channels.OpUpdateChannelTags,
channels.OpEnableChannel,
channels.OpDisableChannel,
channels.OpSetParentGroup:
req.Operation = auth.UpdateOp
case channels.OpDeleteChannel,
channels.OpRemoveParentGroup:
req.Operation = auth.DeleteOp
case channels.OpConnectClient:
req.Operation = auth.CreateOp
case channels.OpDisconnectClient:
req.Operation = auth.DeleteOp
case domains.OpCreateDomainChannels,
domains.OpListDomainChannels:
if op == domains.OpCreateDomainChannels {
req.Operation = auth.CreateOp
} else {
req.Operation = auth.ListOp
}
req.EntityID = auth.AnyIDs
}
}
if err := am.authz.Authorize(ctx, req); err != nil {
return err
}
+62 -167
View File
@@ -72,19 +72,7 @@ func NewAuthorization(
}
func (am *authorizationMiddleware) CreateClients(ctx context.Context, session authn.Session, client ...clients.Client) ([]clients.Client, []roles.RoleProvision, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: auth.AnyIDs,
}); err != nil {
return []clients.Client{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.DomainType, domains.OpCreateDomainClients, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.DomainType, domains.OpCreateDomainClients, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -98,20 +86,7 @@ func (am *authorizationMiddleware) CreateClients(ctx context.Context, session au
}
func (am *authorizationMiddleware) View(ctx context.Context, session authn.Session, id string, withRoles bool) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.ReadOp,
EntityID: id,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpViewClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpViewClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -125,19 +100,6 @@ func (am *authorizationMiddleware) View(ctx context.Context, session authn.Sessi
}
func (am *authorizationMiddleware) ListClients(ctx context.Context, session authn.Session, pm clients.Page) (clients.ClientsPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: auth.AnyIDs,
}); err != nil {
return clients.ClientsPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -146,19 +108,6 @@ func (am *authorizationMiddleware) ListClients(ctx context.Context, session auth
}
func (am *authorizationMiddleware) ListUserClients(ctx context.Context, session authn.Session, userID string, pm clients.Page) (clients.ClientsPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: auth.AnyIDs,
}); err != nil {
return clients.ClientsPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err != nil {
return clients.ClientsPage{}, err
}
@@ -167,20 +116,7 @@ func (am *authorizationMiddleware) ListUserClients(ctx context.Context, session
}
func (am *authorizationMiddleware) Update(ctx context.Context, session authn.Session, client clients.Client) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: client.ID,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpUpdateClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpUpdateClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -194,20 +130,7 @@ func (am *authorizationMiddleware) Update(ctx context.Context, session authn.Ses
}
func (am *authorizationMiddleware) UpdateTags(ctx context.Context, session authn.Session, client clients.Client) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: client.ID,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpUpdateClientTags, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpUpdateClientTags, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -221,20 +144,7 @@ func (am *authorizationMiddleware) UpdateTags(ctx context.Context, session authn
}
func (am *authorizationMiddleware) UpdateSecret(ctx context.Context, session authn.Session, id, key string) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpUpdateClientSecret, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpUpdateClientSecret, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -248,20 +158,7 @@ func (am *authorizationMiddleware) UpdateSecret(ctx context.Context, session aut
}
func (am *authorizationMiddleware) Enable(ctx context.Context, session authn.Session, id string) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpEnableClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpEnableClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -275,20 +172,7 @@ func (am *authorizationMiddleware) Enable(ctx context.Context, session authn.Ses
}
func (am *authorizationMiddleware) Disable(ctx context.Context, session authn.Session, id string) (clients.Client, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return clients.Client{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpDisableClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpDisableClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -302,19 +186,7 @@ func (am *authorizationMiddleware) Disable(ctx context.Context, session authn.Se
}
func (am *authorizationMiddleware) Delete(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpDeleteClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpDeleteClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -328,20 +200,7 @@ func (am *authorizationMiddleware) Delete(ctx context.Context, session authn.Ses
}
func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session authn.Session, parentGroupID string, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpSetParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpSetParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -351,7 +210,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
return errors.Wrap(err, errSetParentGroup)
}
if err := am.authorize(ctx, policies.GroupType, groups.OpGroupSetChildClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpGroupSetChildClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -365,20 +224,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.ClientsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.ClientType, clients.OpRemoveParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.ClientType, clients.OpRemoveParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -394,7 +240,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
}
if th.ParentGroup != "" {
if err := am.authorize(ctx, policies.GroupType, groups.OpGroupRemoveChildClient, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpGroupRemoveChildClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -409,7 +255,12 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, entityType string, op permissions.Operation, req smqauthz.PolicyReq) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, session authn.Session, entityType string, op permissions.Operation, req smqauthz.PolicyReq) error {
req.TokenType = session.Type
req.UserID = session.UserID
req.PatID = session.PatID
req.OptionalDomainID = session.DomainID
perm, err := am.entitiesOps.GetPermission(entityType, op)
if err != nil {
return err
@@ -417,6 +268,50 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, entityType str
req.Permission = perm.String()
if req.PatID != "" && req.TokenType == authn.PersonalAccessToken {
req.EntityID = req.Object
switch entityType {
case policies.ClientType:
req.EntityType = auth.ClientsType
switch op {
case clients.OpViewClient:
req.Operation = auth.ReadOp
case clients.OpListUserClients:
req.Operation = auth.ListOp
req.EntityID = auth.AnyIDs
case clients.OpUpdateClient,
clients.OpUpdateClientTags,
clients.OpUpdateClientSecret,
clients.OpEnableClient,
clients.OpDisableClient,
clients.OpSetParentGroup:
req.Operation = auth.UpdateOp
case clients.OpDeleteClient,
clients.OpRemoveParentGroup:
req.Operation = auth.DeleteOp
}
case policies.DomainType:
req.EntityType = auth.ClientsType
switch op {
case domains.OpCreateDomainClients:
req.Operation = auth.CreateOp
req.EntityID = auth.AnyIDs
case domains.OpListDomainClients:
req.Operation = auth.ListOp
req.EntityID = auth.AnyIDs
}
case policies.GroupType:
req.EntityType = auth.ClientsType
switch op {
case groups.OpGroupSetChildClient:
req.Operation = auth.UpdateOp
case groups.OpGroupRemoveChildClient:
req.Operation = auth.DeleteOp
}
}
}
if err := am.authz.Authorize(ctx, req); err != nil {
return err
}
+10
View File
@@ -62,6 +62,7 @@ func (am *authorizationMiddleware) RetrieveDomain(ctx context.Context, session a
}
if err := am.authorize(ctx, policies.DomainType, domains.OpRetrieveDomain, authz.PolicyReq{
TokenType: session.Type,
Subject: session.DomainUserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -76,6 +77,7 @@ func (am *authorizationMiddleware) RetrieveDomain(ctx context.Context, session a
func (am *authorizationMiddleware) UpdateDomain(ctx context.Context, session authn.Session, id string, d domains.DomainReq) (domains.Domain, error) {
if err := am.authorize(ctx, policies.DomainType, domains.OpUpdateDomain, authz.PolicyReq{
TokenType: session.Type,
Subject: session.DomainUserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -90,6 +92,7 @@ func (am *authorizationMiddleware) UpdateDomain(ctx context.Context, session aut
func (am *authorizationMiddleware) EnableDomain(ctx context.Context, session authn.Session, id string) (domains.Domain, error) {
if err := am.authorize(ctx, policies.DomainType, domains.OpEnableDomain, authz.PolicyReq{
TokenType: session.Type,
Subject: session.DomainUserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -104,6 +107,7 @@ func (am *authorizationMiddleware) EnableDomain(ctx context.Context, session aut
func (am *authorizationMiddleware) DisableDomain(ctx context.Context, session authn.Session, id string) (domains.Domain, error) {
if err := am.authorize(ctx, policies.DomainType, domains.OpDisableDomain, authz.PolicyReq{
TokenType: session.Type,
Subject: session.DomainUserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -119,6 +123,7 @@ func (am *authorizationMiddleware) DisableDomain(ctx context.Context, session au
func (am *authorizationMiddleware) FreezeDomain(ctx context.Context, session authn.Session, id string) (domains.Domain, error) {
// Only SuperAdmin can freeze the domain
if err := am.authz.Authorize(ctx, authz.PolicyReq{
TokenType: session.Type,
Subject: session.UserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -143,6 +148,7 @@ func (am *authorizationMiddleware) ListDomains(ctx context.Context, session auth
func (am *authorizationMiddleware) SendInvitation(ctx context.Context, session authn.Session, invitation domains.Invitation) (domains.Invitation, error) {
domainUserId := auth.EncodeDomainUserID(invitation.DomainID, invitation.InviteeUserID)
req := authz.PolicyReq{
TokenType: session.Type,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
Subject: domainUserId,
@@ -168,6 +174,7 @@ func (am *authorizationMiddleware) ListInvitations(ctx context.Context, session
func (am *authorizationMiddleware) ListDomainInvitations(ctx context.Context, session authn.Session, page domains.InvitationPageMeta) (invs domains.InvitationPage, err error) {
if err := am.authorize(ctx, policies.DomainType, domains.OpListDomainInvitations, authz.PolicyReq{
TokenType: session.Type,
Subject: session.DomainUserID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -215,6 +222,7 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, entityType str
// checkAdmin checks if the given user is a domain or platform administrator.
func (am *authorizationMiddleware) checkAdmin(ctx context.Context, session authn.Session) error {
req := smqauthz.PolicyReq{
TokenType: session.Type,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
Subject: session.DomainUserID,
@@ -227,6 +235,7 @@ func (am *authorizationMiddleware) checkAdmin(ctx context.Context, session authn
}
req = smqauthz.PolicyReq{
TokenType: session.Type,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
Subject: session.UserID,
@@ -247,6 +256,7 @@ func (am *authorizationMiddleware) checkSuperAdmin(ctx context.Context, session
return svcerr.ErrSuperAdminAction
}
if err := am.authz.Authorize(ctx, smqauthz.PolicyReq{
TokenType: session.Type,
SubjectType: policies.UserType,
Subject: session.UserID,
Permission: policies.AdminPermission,
+59 -215
View File
@@ -77,20 +77,7 @@ func NewAuthorization(
}
func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, []roles.RoleProvision, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.CreateOp,
EntityID: auth.AnyIDs,
}); err != nil {
return groups.Group{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.DomainType, domains.OpCreateDomainGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.DomainType, domains.OpCreateDomainGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -102,7 +89,7 @@ func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session auth
}
if g.Parent != "" {
if err := am.authorize(ctx, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -118,20 +105,7 @@ func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session auth
}
func (am *authorizationMiddleware) UpdateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: g.ID,
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpUpdateGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpUpdateGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -146,20 +120,7 @@ func (am *authorizationMiddleware) UpdateGroup(ctx context.Context, session auth
}
func (am *authorizationMiddleware) UpdateGroupTags(ctx context.Context, session authn.Session, group groups.Group) (groups.Group, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: group.ID,
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpUpdateGroupTags, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpUpdateGroupTags, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -173,20 +134,7 @@ func (am *authorizationMiddleware) UpdateGroupTags(ctx context.Context, session
}
func (am *authorizationMiddleware) ViewGroup(ctx context.Context, session authn.Session, id string, withRoles bool) (groups.Group, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.ReadOp,
EntityID: id,
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpViewGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpViewGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -201,24 +149,11 @@ func (am *authorizationMiddleware) ViewGroup(ctx context.Context, session authn.
}
func (am *authorizationMiddleware) ListGroups(ctx context.Context, session authn.Session, gm groups.PageMeta) (groups.Page, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: auth.AnyIDs,
}); err != nil {
return groups.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
return am.svc.ListGroups(ctx, session, gm)
}
if err := am.authorize(ctx, policies.DomainType, domains.OpListDomainGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.DomainType, domains.OpListDomainGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -237,7 +172,7 @@ func (am *authorizationMiddleware) ListUserGroups(ctx context.Context, session a
session.SuperAdmin = true
return am.svc.ListGroups(ctx, session, pm)
}
if err := am.authorize(ctx, policies.DomainType, domains.OpListDomainGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.DomainType, domains.OpListDomainGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
SubjectKind: policies.UsersKind,
@@ -252,20 +187,7 @@ func (am *authorizationMiddleware) ListUserGroups(ctx context.Context, session a
}
func (am *authorizationMiddleware) EnableGroup(ctx context.Context, session authn.Session, id string) (groups.Group, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpEnableGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpEnableGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -279,20 +201,7 @@ func (am *authorizationMiddleware) EnableGroup(ctx context.Context, session auth
}
func (am *authorizationMiddleware) DisableGroup(ctx context.Context, session authn.Session, id string) (groups.Group, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpDisableGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpDisableGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -306,19 +215,7 @@ func (am *authorizationMiddleware) DisableGroup(ctx context.Context, session aut
}
func (am *authorizationMiddleware) DeleteGroup(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpDeleteGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpDeleteGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -332,20 +229,7 @@ func (am *authorizationMiddleware) DeleteGroup(ctx context.Context, session auth
}
func (am *authorizationMiddleware) RetrieveGroupHierarchy(ctx context.Context, session authn.Session, id string, hm groups.HierarchyPageMeta) (groups.HierarchyPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: id,
}); err != nil {
return groups.HierarchyPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpRetrieveGroupHierarchy, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpRetrieveGroupHierarchy, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -359,20 +243,7 @@ func (am *authorizationMiddleware) RetrieveGroupHierarchy(ctx context.Context, s
}
func (am *authorizationMiddleware) AddParentGroup(ctx context.Context, session authn.Session, id, parentID string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpAddParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpAddParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -382,7 +253,7 @@ func (am *authorizationMiddleware) AddParentGroup(ctx context.Context, session a
return errors.Wrap(errSetParentGroup, err)
}
if err := am.authorize(ctx, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -396,20 +267,7 @@ func (am *authorizationMiddleware) AddParentGroup(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpRemoveParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpRemoveParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -425,7 +283,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
}
if group.Parent != "" {
if err := am.authorize(ctx, policies.GroupType, groups.OpRemoveParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpRemoveParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -440,20 +298,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
}
func (am *authorizationMiddleware) AddChildrenGroups(ctx context.Context, session authn.Session, id string, childrenGroupIDs []string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.UpdateOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -464,7 +309,7 @@ func (am *authorizationMiddleware) AddChildrenGroups(ctx context.Context, sessio
}
for _, childID := range childrenGroupIDs {
if err := am.authorize(ctx, policies.GroupType, groups.OpAddParentGroup, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpAddParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -479,20 +324,7 @@ func (am *authorizationMiddleware) AddChildrenGroups(ctx context.Context, sessio
}
func (am *authorizationMiddleware) RemoveChildrenGroups(ctx context.Context, session authn.Session, id string, childrenGroupIDs []string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpRemoveChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpRemoveChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -506,20 +338,7 @@ func (am *authorizationMiddleware) RemoveChildrenGroups(ctx context.Context, ses
}
func (am *authorizationMiddleware) RemoveAllChildrenGroups(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpRemoveAllChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpRemoveAllChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -533,20 +352,7 @@ func (am *authorizationMiddleware) RemoveAllChildrenGroups(ctx context.Context,
}
func (am *authorizationMiddleware) ListChildrenGroups(ctx context.Context, session authn.Session, id string, startLevel, endLevel int64, pm groups.PageMeta) (groups.Page, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: auth.GroupsType,
OptionalDomainID: session.DomainID,
Operation: auth.ListOp,
EntityID: id,
}); err != nil {
return groups.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, policies.GroupType, groups.OpListChildrenGroups, smqauthz.PolicyReq{
if err := am.authorize(ctx, session, policies.GroupType, groups.OpListChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -575,13 +381,51 @@ func (am *authorizationMiddleware) checkSuperAdmin(ctx context.Context, session
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, entityType string, op permissions.Operation, pr smqauthz.PolicyReq) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, session authn.Session, entityType string, op permissions.Operation, pr smqauthz.PolicyReq) error {
pr.TokenType = session.Type
pr.UserID = session.UserID
pr.PatID = session.PatID
pr.OptionalDomainID = session.DomainID
perm, err := am.entitiesOps.GetPermission(entityType, op)
if err != nil {
return err
}
pr.Permission = perm.String()
if pr.PatID != "" && pr.TokenType == authn.PersonalAccessToken {
pr.EntityType = auth.GroupsType
pr.EntityID = pr.Object
switch op {
case groups.OpViewGroup:
pr.Operation = auth.ReadOp
case groups.OpListUserGroups,
groups.OpRetrieveGroupHierarchy,
groups.OpListChildrenGroups,
domains.OpListDomainGroups:
pr.Operation = auth.ListOp
if op == domains.OpListDomainGroups {
pr.EntityID = auth.AnyIDs
}
case groups.OpUpdateGroup,
groups.OpUpdateGroupTags,
groups.OpEnableGroup,
groups.OpDisableGroup,
groups.OpAddParentGroup,
groups.OpAddChildrenGroups:
pr.Operation = auth.UpdateOp
case groups.OpDeleteGroup,
groups.OpRemoveParentGroup,
groups.OpRemoveChildrenGroups,
groups.OpRemoveAllChildrenGroups:
pr.Operation = auth.DeleteOp
case domains.OpCreateDomainGroups:
pr.Operation = auth.CreateOp
pr.EntityID = auth.AnyIDs
}
}
if err := am.authz.Authorize(ctx, pr); err != nil {
return err
}
+23 -23
View File
@@ -9,6 +9,7 @@ import (
grpcAuthV1 "github.com/absmach/supermq/api/grpc/auth/v1"
"github.com/absmach/supermq/auth/api/grpc/auth"
"github.com/absmach/supermq/domains"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/authz"
pkgDomians "github.com/absmach/supermq/pkg/domains"
"github.com/absmach/supermq/pkg/errors"
@@ -47,6 +48,28 @@ func NewAuthorization(ctx context.Context, cfg grpcclient.Config, domainsAuthz p
}
func (a authorization) Authorize(ctx context.Context, pr authz.PolicyReq) error {
if pr.PatID != "" && pr.TokenType == authn.PersonalAccessToken {
req := grpcAuthV1.AuthZReq{
AuthType: &grpcAuthV1.AuthZReq_Pat{
Pat: &grpcAuthV1.PATReq{
UserId: pr.UserID,
PatId: pr.PatID,
EntityType: uint32(pr.EntityType),
OptionalDomainId: pr.OptionalDomainID,
Operation: uint32(pr.Operation),
EntityId: pr.EntityID,
},
},
}
res, err := a.authSvcClient.Authorize(ctx, &req)
if err != nil {
return errors.Wrap(errors.ErrAuthorization, err)
}
if !res.GetAuthorized() {
return errors.ErrAuthorization
}
}
if pr.SubjectType == policies.UserType && (pr.ObjectType == policies.GroupType || pr.ObjectType == policies.ClientType || pr.ObjectType == policies.DomainType) {
domainID := pr.Domain
if domainID == "" {
@@ -138,26 +161,3 @@ func (a authorization) checkDomain(ctx context.Context, subjectType, subject, do
return svcerr.ErrInvalidStatus
}
}
func (a authorization) AuthorizePAT(ctx context.Context, pr authz.PatReq) error {
req := grpcAuthV1.AuthZReq{
AuthType: &grpcAuthV1.AuthZReq_Pat{
Pat: &grpcAuthV1.PATReq{
UserId: pr.UserID,
PatId: pr.PatID,
EntityType: uint32(pr.EntityType),
OptionalDomainId: pr.OptionalDomainID,
Operation: uint32(pr.Operation),
EntityId: pr.EntityID,
},
},
}
res, err := a.authSvcClient.Authorize(ctx, &req)
if err != nil {
return errors.Wrap(errors.ErrAuthorization, err)
}
if !res.Authorized {
return errors.ErrAuthorization
}
return nil
}
+10 -8
View File
@@ -7,9 +7,13 @@ import (
"context"
"github.com/absmach/supermq/auth"
"github.com/absmach/supermq/pkg/authn"
)
type PolicyReq struct {
// TokenType contains the token type. Used to differentiate between PAT and regular user tokens.
TokenType authn.TokenType `json:"token_type,omitempty"`
// Domain contains the domain ID.
Domain string `json:"domain,omitempty"`
@@ -44,19 +48,17 @@ type PolicyReq struct {
// Permission contains the permission. Supported permissions are admin, delete, edit, share, view,
// membership, create, admin_only, edit_only, view_only, membership_only, ext_admin, ext_edit, ext_view.
Permission string `json:"permission,omitempty"`
}
type PatReq struct {
UserID string `json:"user_id,omitempty"` // UserID
PatID string `json:"pat_id,omitempty"` // UserID
// PAT authorization fields
UserID string `json:"user_id,omitempty"` // UserID who owns the PAT
PatID string `json:"pat_id,omitempty"` // PAT ID
EntityType auth.EntityType `json:"entity_type,omitempty"` // Entity type
OptionalDomainID string `json:"optional_domainID,omitempty"` // Optional domain id
Operation auth.Operation `json:"operation,omitempty"` // Operation
EntityID string `json:"entityID,omitempty"` // EntityID
OptionalDomainID string `json:"optional_domainID,omitempty"` // Optional domain ID for PAT scope checking
Operation auth.Operation `json:"operation,omitempty"` // Operation type
EntityID string `json:"entityID,omitempty"` // Entity ID
}
// Authz is supermq authorization library.
type Authorization interface {
Authorize(ctx context.Context, pr PolicyReq) error
AuthorizePAT(ctx context.Context, pr PatReq) error
}
-57
View File
@@ -98,60 +98,3 @@ func (_c *Authorization_Authorize_Call) RunAndReturn(run func(ctx context.Contex
_c.Call.Return(run)
return _c
}
// AuthorizePAT provides a mock function for the type Authorization
func (_mock *Authorization) AuthorizePAT(ctx context.Context, pr authz.PatReq) error {
ret := _mock.Called(ctx, pr)
if len(ret) == 0 {
panic("no return value specified for AuthorizePAT")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, authz.PatReq) error); ok {
r0 = returnFunc(ctx, pr)
} else {
r0 = ret.Error(0)
}
return r0
}
// Authorization_AuthorizePAT_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthorizePAT'
type Authorization_AuthorizePAT_Call struct {
*mock.Call
}
// AuthorizePAT is a helper method to define mock.On call
// - ctx context.Context
// - pr authz.PatReq
func (_e *Authorization_Expecter) AuthorizePAT(ctx interface{}, pr interface{}) *Authorization_AuthorizePAT_Call {
return &Authorization_AuthorizePAT_Call{Call: _e.mock.On("AuthorizePAT", ctx, pr)}
}
func (_c *Authorization_AuthorizePAT_Call) Run(run func(ctx context.Context, pr authz.PatReq)) *Authorization_AuthorizePAT_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 authz.PatReq
if args[1] != nil {
arg1 = args[1].(authz.PatReq)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *Authorization_AuthorizePAT_Call) Return(err error) *Authorization_AuthorizePAT_Call {
_c.Call.Return(err)
return _c
}
func (_c *Authorization_AuthorizePAT_Call) RunAndReturn(run func(ctx context.Context, pr authz.PatReq) error) *Authorization_AuthorizePAT_Call {
_c.Call.Return(run)
return _c
}
+4 -158
View File
@@ -7,10 +7,8 @@ import (
"context"
grpcTokenV1 "github.com/absmach/supermq/api/grpc/token/v1"
smqauth "github.com/absmach/supermq/auth"
"github.com/absmach/supermq/pkg/authn"
smqauthz "github.com/absmach/supermq/pkg/authz"
"github.com/absmach/supermq/pkg/errors"
svcerr "github.com/absmach/supermq/pkg/errors/service"
"github.com/absmach/supermq/pkg/policies"
"github.com/absmach/supermq/users"
@@ -48,18 +46,6 @@ func (am *authorizationMiddleware) Register(ctx context.Context, session authn.S
}
func (am *authorizationMiddleware) View(ctx context.Context, session authn.Session, id string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.ReadOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -68,32 +54,10 @@ func (am *authorizationMiddleware) View(ctx context.Context, session authn.Sessi
}
func (am *authorizationMiddleware) ViewProfile(ctx context.Context, session authn.Session) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.ReadOp,
EntityID: session.UserID,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
return am.svc.ViewProfile(ctx, session)
}
func (am *authorizationMiddleware) ListUsers(ctx context.Context, session authn.Session, pm users.Page) (users.UsersPage, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.ListOp,
EntityID: smqauth.AnyIDs,
}); err != nil {
return users.UsersPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -106,18 +70,6 @@ func (am *authorizationMiddleware) SearchUsers(ctx context.Context, pm users.Pag
}
func (am *authorizationMiddleware) Update(ctx context.Context, session authn.Session, id string, user users.UserReq) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -126,18 +78,6 @@ func (am *authorizationMiddleware) Update(ctx context.Context, session authn.Ses
}
func (am *authorizationMiddleware) UpdateTags(ctx context.Context, session authn.Session, id string, user users.UserReq) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -146,17 +86,6 @@ func (am *authorizationMiddleware) UpdateTags(ctx context.Context, session authn
}
func (am *authorizationMiddleware) UpdateEmail(ctx context.Context, session authn.Session, id, email string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -165,18 +94,6 @@ func (am *authorizationMiddleware) UpdateEmail(ctx context.Context, session auth
}
func (am *authorizationMiddleware) UpdateUsername(ctx context.Context, session authn.Session, id, username string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -185,18 +102,6 @@ func (am *authorizationMiddleware) UpdateUsername(ctx context.Context, session a
}
func (am *authorizationMiddleware) UpdateProfilePicture(ctx context.Context, session authn.Session, id string, usr users.UserReq) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -209,18 +114,6 @@ func (am *authorizationMiddleware) SendPasswordReset(ctx context.Context, email
}
func (am *authorizationMiddleware) UpdateSecret(ctx context.Context, session authn.Session, oldSecret, newSecret string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: session.UserID,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
return am.svc.UpdateSecret(ctx, session, oldSecret, newSecret)
}
@@ -229,23 +122,11 @@ func (am *authorizationMiddleware) ResetSecret(ctx context.Context, session auth
}
func (am *authorizationMiddleware) UpdateRole(ctx context.Context, session authn.Session, user users.User) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: user.ID,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err != nil {
return users.User{}, err
}
session.SuperAdmin = true
if err := am.authorize(ctx, "", policies.UserType, policies.UsersKind, user.ID, policies.MembershipPermission, policies.PlatformType, policies.SuperMQObject); err != nil {
if err := am.authorize(ctx, session, "", policies.UserType, policies.UsersKind, user.ID, policies.MembershipPermission, policies.PlatformType, policies.SuperMQObject); err != nil {
return users.User{}, err
}
@@ -253,18 +134,6 @@ func (am *authorizationMiddleware) UpdateRole(ctx context.Context, session authn
}
func (am *authorizationMiddleware) Enable(ctx context.Context, session authn.Session, id string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -273,18 +142,6 @@ func (am *authorizationMiddleware) Enable(ctx context.Context, session authn.Ses
}
func (am *authorizationMiddleware) Disable(ctx context.Context, session authn.Session, id string) (users.User, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.UpdateOp,
EntityID: id,
}); err != nil {
return users.User{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -293,18 +150,6 @@ func (am *authorizationMiddleware) Disable(ctx context.Context, session authn.Se
}
func (am *authorizationMiddleware) Delete(ctx context.Context, session authn.Session, id string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.PatID,
EntityType: smqauth.UsersType,
Operation: smqauth.DeleteOp,
EntityID: id,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session); err == nil {
session.SuperAdmin = true
}
@@ -329,7 +174,7 @@ func (am *authorizationMiddleware) OAuthCallback(ctx context.Context, user users
}
func (am *authorizationMiddleware) OAuthAddUserPolicy(ctx context.Context, user users.User) error {
if err := am.authorize(ctx, "", policies.UserType, policies.UsersKind, user.ID, policies.MembershipPermission, policies.PlatformType, policies.SuperMQObject); err == nil {
if err := am.authorize(ctx, authn.Session{}, "", policies.UserType, policies.UsersKind, user.ID, policies.MembershipPermission, policies.PlatformType, policies.SuperMQObject); err == nil {
return nil
}
return am.svc.OAuthAddUserPolicy(ctx, user)
@@ -351,7 +196,7 @@ func (am *authorizationMiddleware) checkSuperAdmin(ctx context.Context, session
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, domain, subjType, subjKind, subj, perm, objType, obj string) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, session authn.Session, domain, subjType, subjKind, subj, perm, objType, obj string) error {
req := smqauthz.PolicyReq{
Domain: domain,
SubjectType: subjType,
@@ -361,6 +206,7 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, domain, subjTy
ObjectType: objType,
Object: obj,
}
if err := am.authz.Authorize(ctx, req); err != nil {
return err
}