MG-2048 - Authorize groups and channels with PATs (#2501)
Continuous Delivery / Build and Push (push) Waiting to run
Check the consistency of generated files / check-generated-files (push) Waiting to run
Check License Header / check-license (push) Waiting to run
Deploy GitHub Pages / swagger-ui (push) Waiting to run

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
Signed-off-by: Arvindh <arvindh91@gmail.com>
Co-authored-by: Felix Gateru <felix.gateru@gmail.com>
This commit is contained in:
Steve Munene
2025-01-15 14:15:14 +03:00
committed by GitHub
parent 153d230907
commit d02d63d1eb
5 changed files with 428 additions and 32 deletions
+2 -2
View File
@@ -8,6 +8,7 @@ import (
"net/http"
apiutil "github.com/absmach/supermq/api/http/util"
"github.com/absmach/supermq/auth"
smqauthn "github.com/absmach/supermq/pkg/authn"
"github.com/go-chi/chi/v5"
)
@@ -24,7 +25,6 @@ func AuthenticateMiddleware(authn smqauthn.Authentication, domainCheck bool) fun
EncodeError(r.Context(), apiutil.ErrBearerToken, w)
return
}
resp, err := authn.Authenticate(r.Context(), token)
if err != nil {
EncodeError(r.Context(), err, w)
@@ -38,7 +38,7 @@ func AuthenticateMiddleware(authn smqauthn.Authentication, domainCheck bool) fun
return
}
resp.DomainID = domain
resp.DomainUserID = domain + "_" + resp.UserID
resp.DomainUserID = auth.EncodeDomainUserID(domain, resp.UserID)
}
ctx := context.WithValue(r.Context(), SessionKey, resp)
+2 -7
View File
@@ -514,13 +514,8 @@ func (svc service) UpdatePATDescription(ctx context.Context, token, patID, descr
return pat, nil
}
func (svc service) RetrievePAT(ctx context.Context, token, patID string) (PAT, error) {
key, err := svc.Identify(ctx, token)
if err != nil {
return PAT{}, err
}
pat, err := svc.pats.Retrieve(ctx, key.User, patID)
func (svc service) RetrievePAT(ctx context.Context, userID, patID string) (PAT, error) {
pat, err := svc.pats.Retrieve(ctx, userID, patID)
if err != nil {
return PAT{}, errors.Wrap(errRetrievePAT, err)
}
+223 -19
View File
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
"github.com/absmach/supermq/auth"
"github.com/absmach/supermq/channels"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/authz"
smqauthz "github.com/absmach/supermq/pkg/authz"
"github.com/absmach/supermq/pkg/connections"
"github.com/absmach/supermq/pkg/errors"
@@ -82,7 +82,21 @@ func AuthorizationMiddleware(svc channels.Service, repo channels.Repository, aut
}
func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session authn.Session, chs ...channels.Channel) ([]channels.Channel, []roles.RoleProvision, error) {
if err := am.extAuthorize(ctx, channels.DomainOpCreateChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.CreateOp,
EntityIDs: auth.AnyIDs{}.Values(),
}); err != nil {
return []channels.Channel{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.extAuthorize(ctx, channels.DomainOpCreateChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -94,7 +108,7 @@ func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session a
for _, ch := range chs {
if ch.ParentGroup != "" {
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, authz.PolicyReq{
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -109,7 +123,21 @@ func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session a
}
func (am *authorizationMiddleware) ViewChannel(ctx context.Context, session authn.Session, id string) (channels.Channel, error) {
if err := am.authorize(ctx, channels.OpViewChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.ReadOp,
EntityIDs: []string{id},
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpViewChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -122,6 +150,20 @@ func (am *authorizationMiddleware) ViewChannel(ctx context.Context, session auth
}
func (am *authorizationMiddleware) ListChannels(ctx context.Context, session authn.Session, pm channels.PageMetadata) (channels.Page, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.ListOp,
EntityIDs: auth.AnyIDs{}.Values(),
}); err != nil {
return channels.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.checkSuperAdmin(ctx, session.UserID); err != nil {
session.SuperAdmin = true
}
@@ -129,11 +171,38 @@ func (am *authorizationMiddleware) ListChannels(ctx context.Context, session aut
}
func (am *authorizationMiddleware) ListChannelsByClient(ctx context.Context, session authn.Session, clientID string, pm channels.PageMetadata) (channels.Page, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.ListOp,
EntityIDs: auth.AnyIDs{}.Values(),
}); err != nil {
return channels.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
return am.svc.ListChannelsByClient(ctx, session, clientID, pm)
}
func (am *authorizationMiddleware) UpdateChannel(ctx context.Context, session authn.Session, channel channels.Channel) (channels.Channel, error) {
if err := am.authorize(ctx, channels.OpUpdateChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{channel.ID},
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpUpdateChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -146,7 +215,21 @@ 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 err := am.authorize(ctx, channels.OpUpdateChannelTags, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{channel.ID},
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpUpdateChannelTags, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -159,7 +242,21 @@ func (am *authorizationMiddleware) UpdateChannelTags(ctx context.Context, sessio
}
func (am *authorizationMiddleware) EnableChannel(ctx context.Context, session authn.Session, id string) (channels.Channel, error) {
if err := am.authorize(ctx, channels.OpEnableChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpEnableChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -172,7 +269,21 @@ 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 err := am.authorize(ctx, channels.OpDisableChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return channels.Channel{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpDisableChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -185,7 +296,21 @@ func (am *authorizationMiddleware) DisableChannel(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveChannel(ctx context.Context, session authn.Session, id string) error {
if err := am.authorize(ctx, channels.OpDeleteChannel, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpDeleteChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -198,8 +323,33 @@ 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 {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.CreateOp,
EntityIDs: chIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainClientsScope,
Operation: auth.CreateOp,
EntityIDs: thIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
for _, chID := range chIDs {
if err := am.authorize(ctx, channels.OpConnectClient, authz.PolicyReq{
if err := am.authorize(ctx, channels.OpConnectClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -211,7 +361,7 @@ func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Se
}
for _, thID := range thIDs {
if err := am.extAuthorize(ctx, channels.ClientsOpConnectChannel, authz.PolicyReq{
if err := am.extAuthorize(ctx, channels.ClientsOpConnectChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -225,8 +375,34 @@ 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 {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.DeleteOp,
EntityIDs: chIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainClientsScope,
Operation: auth.DeleteOp,
EntityIDs: thIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
for _, chID := range chIDs {
if err := am.authorize(ctx, channels.OpDisconnectClient, authz.PolicyReq{
if err := am.authorize(ctx, channels.OpDisconnectClient, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -238,7 +414,7 @@ func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn
}
for _, thID := range thIDs {
if err := am.extAuthorize(ctx, channels.ClientsOpDisconnectChannel, authz.PolicyReq{
if err := am.extAuthorize(ctx, channels.ClientsOpDisconnectChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -252,7 +428,21 @@ 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 err := am.authorize(ctx, channels.OpSetParentGroup, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpSetParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -262,7 +452,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
return errors.Wrap(err, errSetParentGroup)
}
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, authz.PolicyReq{
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -275,7 +465,21 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
}
func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, session authn.Session, id string) error {
if err := am.authorize(ctx, channels.OpSetParentGroup, authz.PolicyReq{
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, smqauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainChannelsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, channels.OpSetParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -290,7 +494,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
return errors.Wrap(svcerr.ErrRemoveEntity, err)
}
if ch.ParentGroup != "" {
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, authz.PolicyReq{
if err := am.extAuthorize(ctx, channels.GroupOpSetChildChannel, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Subject: session.DomainUserID,
@@ -304,7 +508,7 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Operation, req authz.PolicyReq) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Operation, req smqauthz.PolicyReq) error {
perm, err := am.opp.GetPermission(op)
if err != nil {
return err
@@ -319,7 +523,7 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Ope
return nil
}
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp svcutil.ExternalOperation, req authz.PolicyReq) error {
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp svcutil.ExternalOperation, req smqauthz.PolicyReq) error {
perm, err := am.extOpp.GetPermission(extOp)
if err != nil {
return err
+2
View File
@@ -429,6 +429,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
+199 -4
View File
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
"github.com/absmach/supermq/auth"
"github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/authz"
smqauthz "github.com/absmach/supermq/pkg/authz"
"github.com/absmach/supermq/pkg/errors"
svcerr "github.com/absmach/supermq/pkg/errors/service"
@@ -81,6 +81,19 @@ func AuthorizationMiddleware(entityType string, svc groups.Service, repo groups.
}
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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.CreateOp,
EntityIDs: auth.AnyIDs{}.Values(),
}); err != nil {
return groups.Group{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.extAuthorize(ctx, groups.DomainOpCreateGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -109,6 +122,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{g.ID},
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpUpdateGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -124,6 +151,20 @@ func (am *authorizationMiddleware) UpdateGroup(ctx context.Context, session auth
}
func (am *authorizationMiddleware) ViewGroup(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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.ReadOp,
EntityIDs: []string{id},
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpViewGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -139,6 +180,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.ListOp,
EntityIDs: auth.AnyIDs{}.Values(),
}); err != nil {
return groups.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
err := am.checkSuperAdmin(ctx, session.UserID)
if err == nil {
session.SuperAdmin = true
@@ -177,6 +232,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpEnableGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -191,6 +260,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return groups.Group{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpDisableGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -205,6 +288,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpDeleteGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -219,6 +316,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.ListOp,
EntityIDs: []string{id},
}); err != nil {
return groups.HierarchyPage{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpRetrieveGroupHierarchy, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -232,6 +343,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpAddParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -255,6 +380,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpRemoveParentGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -285,6 +424,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.UpdateOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpAddChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -311,6 +464,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpRemoveChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -325,6 +492,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.DeleteOp,
EntityIDs: []string{id},
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpRemoveAllChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -339,6 +520,20 @@ 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.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainGroupsScope,
Operation: auth.ListOp,
EntityIDs: []string{id},
}); err != nil {
return groups.Page{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
if err := am.authorize(ctx, groups.OpListChildrenGroups, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
@@ -353,7 +548,7 @@ func (am *authorizationMiddleware) ListChildrenGroups(ctx context.Context, sessi
}
func (am *authorizationMiddleware) checkSuperAdmin(ctx context.Context, adminID string) error {
if err := am.authz.Authorize(ctx, authz.PolicyReq{
if err := am.authz.Authorize(ctx, smqauthz.PolicyReq{
SubjectType: policies.UserType,
Subject: adminID,
Permission: policies.AdminPermission,
@@ -365,7 +560,7 @@ func (am *authorizationMiddleware) checkSuperAdmin(ctx context.Context, adminID
return nil
}
func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Operation, pr authz.PolicyReq) error {
func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Operation, pr smqauthz.PolicyReq) error {
perm, err := am.opp.GetPermission(op)
if err != nil {
return err
@@ -378,7 +573,7 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Ope
return nil
}
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp svcutil.ExternalOperation, req authz.PolicyReq) error {
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp svcutil.ExternalOperation, req smqauthz.PolicyReq) error {
perm, err := am.extOpp.GetPermission(extOp)
if err != nil {
return err