Skip to content

Commit

Permalink
initial implementation
Browse files Browse the repository at this point in the history
Signed-off-by: nyagamunene <[email protected]>
  • Loading branch information
nyagamunene committed Nov 4, 2024
1 parent 56daa42 commit 618df09
Show file tree
Hide file tree
Showing 2 changed files with 402 additions and 0 deletions.
205 changes: 205 additions & 0 deletions channels/middleware/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"

"github.com/absmach/magistrala/auth"
"github.com/absmach/magistrala/channels"
"github.com/absmach/magistrala/pkg/authn"
"github.com/absmach/magistrala/pkg/authz"
Expand Down Expand Up @@ -78,6 +79,20 @@ func AuthorizationMiddleware(svc channels.Service, repo channels.Repository, aut
}

func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session authn.Session, chs ...channels.Channel) ([]channels.Channel, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, mgauthz.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{}, errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}

// If domain is disabled , then this authorization will fail for all non-admin domain users
if err := am.extAuthorize(ctx, channels.DomainOpCreateChannel, authz.PolicyReq{
Domain: session.DomainID,
Expand Down Expand Up @@ -107,6 +122,20 @@ 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 session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -120,18 +149,59 @@ 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, mgauthz.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
}
return am.svc.ListChannels(ctx, session, pm)
}

func (am *authorizationMiddleware) ListChannelsByThing(ctx context.Context, session authn.Session, thingID string, pm channels.PageMetadata) (channels.Page, error) {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, mgauthz.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.ListChannelsByThing(ctx, session, thingID, pm)
}

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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -145,6 +215,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -158,6 +242,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -171,6 +269,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -184,6 +296,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -197,6 +323,31 @@ func (am *authorizationMiddleware) RemoveChannel(ctx context.Context, session au
}

func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Session, chIDs, thIDs []string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, mgauthz.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, mgauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainThingsScope,
Operation: auth.CreateOp,
EntityIDs: thIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}
//ToDo: This authorization will be changed with Bulk Authorization. For this we need to add bulk authorization API in policies.
for _, chID := range chIDs {
if err := am.authorize(ctx, channels.OpConnectThing, authz.PolicyReq{
Expand Down Expand Up @@ -224,6 +375,32 @@ func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Se
return am.svc.Connect(ctx, session, chIDs, thIDs)
}
func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn.Session, chIDs, thIDs []string) error {
if session.Type == authn.PersonalAccessToken {
if err := am.authz.AuthorizePAT(ctx, mgauthz.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, mgauthz.PatReq{
UserID: session.UserID,
PatID: session.ID,
PlatformEntityType: auth.PlatformDomainsScope,
OptionalDomainID: session.DomainID,
OptionalDomainEntityType: auth.DomainThingsScope,
Operation: auth.DeleteOp,
EntityIDs: thIDs,
}); err != nil {
return errors.Wrap(svcerr.ErrUnauthorizedPAT, err)
}
}

//ToDo: This authorization will be changed with Bulk Authorization. For this we need to add bulk authorization API in policies.
for _, chID := range chIDs {
if err := am.authorize(ctx, channels.OpDisconnectThing, authz.PolicyReq{
Expand Down Expand Up @@ -252,6 +429,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -275,6 +466,20 @@ 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, mgauthz.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, authz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand Down
Loading

0 comments on commit 618df09

Please sign in to comment.