mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 07:10:19 +00:00
NOISSUE - Refactor alarms, reports and rule engines middlewares (#369)
* refactor middleware Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> * update go mod file Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> * fix tests Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> * fix rules tests Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> * revert common code Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> * update supermq version Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> --------- Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
@@ -10,9 +10,17 @@ import (
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/absmach/supermq/pkg/authn"
|
||||
smqauthz "github.com/absmach/supermq/pkg/authz"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
var (
|
||||
errDomainUpdateAlarms = errors.New("not authorized to update alarms in domain")
|
||||
errDomainDeleteAlarms = errors.New("not authorized to delete alarms in domain")
|
||||
errDomainViewAlarms = errors.New("not authorized to view alarms in domain")
|
||||
)
|
||||
|
||||
type authorizationMiddleware struct {
|
||||
svc alarms.Service
|
||||
authz smqauthz.Authorization
|
||||
@@ -32,20 +40,10 @@ func (am *authorizationMiddleware) CreateAlarm(ctx context.Context, alarm alarms
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateAlarm(ctx context.Context, session authn.Session, alarm alarms.Alarm) (dba alarms.Alarm, err error) {
|
||||
// if assignee is present check if assignee is member of domain
|
||||
// If assignee is present, check if assignee is member of domain
|
||||
|
||||
req := smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Permission: policies.AdminPermission,
|
||||
ObjectType: policies.DomainType,
|
||||
Object: session.DomainID,
|
||||
}
|
||||
|
||||
if err := am.authz.Authorize(ctx, req); err != nil {
|
||||
return alarms.Alarm{}, err
|
||||
if err := am.authorize(ctx, alarms.OpUpdateAlarm, session); err != nil {
|
||||
return alarms.Alarm{}, errors.Wrap(errDomainUpdateAlarms, err)
|
||||
}
|
||||
|
||||
if alarm.AssigneeID != "" {
|
||||
@@ -67,17 +65,8 @@ func (am *authorizationMiddleware) UpdateAlarm(ctx context.Context, session auth
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) DeleteAlarm(ctx context.Context, session authn.Session, id string) error {
|
||||
req := smqauthz.PolicyReq{
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Permission: policies.AdminPermission,
|
||||
ObjectType: policies.DomainType,
|
||||
Object: session.DomainID,
|
||||
}
|
||||
|
||||
if err := am.authz.Authorize(ctx, req); err != nil {
|
||||
return err
|
||||
if err := am.authorize(ctx, alarms.OpDeleteAlarm, session); err != nil {
|
||||
return errors.Wrap(errDomainDeleteAlarms, err)
|
||||
}
|
||||
|
||||
return am.svc.DeleteAlarm(ctx, session, id)
|
||||
@@ -88,37 +77,36 @@ func (am *authorizationMiddleware) ListAlarms(ctx context.Context, session authn
|
||||
pm.DomainID = session.DomainID
|
||||
}
|
||||
|
||||
req := smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Permission: policies.MembershipPermission,
|
||||
ObjectType: policies.DomainType,
|
||||
Object: session.DomainID,
|
||||
}
|
||||
|
||||
if err := am.authz.Authorize(ctx, req); err != nil {
|
||||
return alarms.AlarmsPage{}, err
|
||||
if err := am.authorize(ctx, alarms.OpListAlarms, session); err != nil {
|
||||
return alarms.AlarmsPage{}, errors.Wrap(errDomainViewAlarms, err)
|
||||
}
|
||||
|
||||
return am.svc.ListAlarms(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ViewAlarm(ctx context.Context, session authn.Session, id string) (alarms.Alarm, error) {
|
||||
req := smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Permission: policies.MembershipPermission,
|
||||
ObjectType: policies.DomainType,
|
||||
Object: session.DomainID,
|
||||
}
|
||||
|
||||
if err := am.authz.Authorize(ctx, req); err != nil {
|
||||
return alarms.Alarm{}, err
|
||||
if err := am.authorize(ctx, alarms.OpViewAlarm, session); err != nil {
|
||||
return alarms.Alarm{}, errors.Wrap(errDomainViewAlarms, err)
|
||||
}
|
||||
|
||||
return am.svc.ViewAlarm(ctx, session, id)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) authorize(ctx context.Context, op permissions.Operation, session authn.Session) error {
|
||||
perm, err := alarms.GetPermission(op)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr := smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: perm,
|
||||
}
|
||||
|
||||
return am.authz.Authorize(ctx, pr)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package alarms
|
||||
|
||||
import (
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
const (
|
||||
OpAddAlarm = iota
|
||||
OpViewAlarm
|
||||
OpListAlarms
|
||||
OpUpdateAlarm
|
||||
OpDeleteAlarm
|
||||
)
|
||||
|
||||
func GetPermission(op permissions.Operation) (string, error) {
|
||||
if op < OpAddAlarm || op > OpDeleteAlarm {
|
||||
return "", errors.New("invalid operation")
|
||||
}
|
||||
|
||||
if op == OpUpdateAlarm || op == OpDeleteAlarm {
|
||||
return policies.AdminPermission, nil
|
||||
}
|
||||
|
||||
return policies.MembershipPermission, nil
|
||||
}
|
||||
+5
-1
@@ -322,7 +322,11 @@ func newService(ctx context.Context, db pgclient.Database, runInfo chan pkglog.R
|
||||
return nil, fmt.Errorf("failed to init re event store middleware: %w", err)
|
||||
}
|
||||
|
||||
csvc, err = middleware.AuthorizationMiddleware(csvc, authz, callout)
|
||||
csvc, err = middleware.AuthorizationMiddleware(csvc, authz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
csvc, err = middleware.NewCallout(csvc, callout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
module github.com/absmach/magistrala
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/0x6flab/namegenerator v1.4.0
|
||||
github.com/absmach/callhome v0.18.2
|
||||
github.com/absmach/certs v0.18.3
|
||||
github.com/absmach/supermq v0.18.3
|
||||
github.com/absmach/supermq v0.18.4-0.20251223143751-59f8d4e4d7b1
|
||||
github.com/authzed/authzed-go v1.7.0
|
||||
github.com/authzed/grpcutil v0.0.0-20250221190651-1985b19b35b8
|
||||
github.com/caarlos0/env/v11 v11.3.1
|
||||
@@ -74,7 +74,7 @@ require (
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
@@ -134,18 +134,18 @@ require (
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -30,8 +30,8 @@ github.com/absmach/mgate v0.5.0 h1:RV2Aalra3xIm+XTs13TM7iE7v4WTL2SKhKcPbKr22Ac=
|
||||
github.com/absmach/mgate v0.5.0/go.mod h1:0KVq7mxM0wayosmyXPPxp1EL0c2d9kRp5V8NZCKdetA=
|
||||
github.com/absmach/senml v1.0.8 h1:+opem/r4g6c6eA/JLyCIuksyEhj7eBdysY3pEmy1mqo=
|
||||
github.com/absmach/senml v1.0.8/go.mod h1:DRhzHLgvQoIUHroBgpFrSWso+bJZO9E96RlHAHy+VRI=
|
||||
github.com/absmach/supermq v0.18.3 h1:IUIZ/uCZ+ZH1O4/fOZwCZOrrll6kImlLuA6Gbye7HtU=
|
||||
github.com/absmach/supermq v0.18.3/go.mod h1:QAKnqBIYfTMkFfMgWfqGTP0pTIZQxTXCJkTf7Vf7VOo=
|
||||
github.com/absmach/supermq v0.18.4-0.20251223143751-59f8d4e4d7b1 h1:z7WjbHbbgUO0U3ZzFPzmVKFS446+n3YyM4tfc1qENno=
|
||||
github.com/absmach/supermq v0.18.4-0.20251223143751-59f8d4e4d7b1/go.mod h1:euXoe+V0bSYi9bz4ljRl60N6R80Lc2ehkq0Lj/XfePg=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -113,8 +113,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
@@ -382,12 +382,12 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pion/dtls/v3 v3.0.7 h1:bItXtTYYhZwkPFk4t1n3Kkf5TDrfj6+4wG+CZR8uI9Q=
|
||||
github.com/pion/dtls/v3 v3.0.7/go.mod h1:uDlH5VPrgOQIw59irKYkMudSFprY9IEFCqz/eTz16f8=
|
||||
github.com/pion/dtls/v3 v3.0.9 h1:4AijfFRm8mAjd1gfdlB1wzJF3fjjR/VPIpJgkEtvYmM=
|
||||
github.com/pion/dtls/v3 v3.0.9/go.mod h1:abApPjgadS/ra1wvUzHLc3o2HvoxppAh+NZkyApL4Os=
|
||||
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
|
||||
github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=
|
||||
github.com/pion/transport/v3 v3.0.8 h1:oI3myyYnTKUSTthu/NZZ8eu2I5sHbxbUNNFW62olaYc=
|
||||
github.com/pion/transport/v3 v3.0.8/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
|
||||
github.com/pion/transport/v3 v3.1.1 h1:Tr684+fnnKlhPceU+ICdrw6KKkTms+5qHMgw6bIkYOM=
|
||||
github.com/pion/transport/v3 v3.1.1/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -521,16 +521,16 @@ github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
@@ -575,8 +575,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20251017212417-90e834f514db h1:by6IehL4BH5k3e3SJmcoNbOobMey2SLpAF79iPOEBvw=
|
||||
golang.org/x/exp v0.0.0-20251017212417-90e834f514db/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
|
||||
@@ -613,8 +613,8 @@ golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
|
||||
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -676,8 +676,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
@@ -711,10 +711,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846 h1:ZdyUkS9po3H7G0tuh955QVyyotWvOD4W0aEapeGeUYk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846/go.mod h1:Fk4kyraUvqD7i5H6S43sj2W98fbZa75lpZz/eUyhfO0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
|
||||
@@ -412,7 +412,7 @@ func TestListRulesEndpoint(t *testing.T) {
|
||||
token: validToken,
|
||||
query: "offset=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
err: apiutil.ErrValidation,
|
||||
err: apiutil.ErrInvalidQueryParams,
|
||||
},
|
||||
{
|
||||
desc: "list rules with limit",
|
||||
@@ -433,7 +433,7 @@ func TestListRulesEndpoint(t *testing.T) {
|
||||
token: validToken,
|
||||
query: "limit=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
err: apiutil.ErrValidation,
|
||||
err: apiutil.ErrInvalidQueryParams,
|
||||
},
|
||||
{
|
||||
desc: "list rules with invalid direction",
|
||||
@@ -449,7 +449,7 @@ func TestListRulesEndpoint(t *testing.T) {
|
||||
token: validToken,
|
||||
query: "order=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
err: apiutil.ErrInvalidOrder,
|
||||
err: apiutil.ErrValidation,
|
||||
},
|
||||
{
|
||||
desc: "list rule with limit that is too big",
|
||||
@@ -497,7 +497,7 @@ func TestListRulesEndpoint(t *testing.T) {
|
||||
token: validToken,
|
||||
query: "status=invalid",
|
||||
status: http.StatusBadRequest,
|
||||
err: apiutil.ErrValidation,
|
||||
err: svcerr.ErrInvalidStatus,
|
||||
},
|
||||
{
|
||||
desc: "list rules with duplicate status",
|
||||
|
||||
+31
-186
@@ -5,14 +5,13 @@ package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/re"
|
||||
"github.com/absmach/supermq/pkg/authn"
|
||||
smqauthz "github.com/absmach/supermq/pkg/authz"
|
||||
"github.com/absmach/supermq/pkg/callout"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/messaging"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
@@ -23,237 +22,88 @@ var (
|
||||
errDomainDeleteRules = errors.New("not authorized to delete rules in domain")
|
||||
)
|
||||
|
||||
const entityType = "rule"
|
||||
|
||||
type authorizationMiddleware struct {
|
||||
svc re.Service
|
||||
authz smqauthz.Authorization
|
||||
callout callout.Callout
|
||||
svc re.Service
|
||||
authz smqauthz.Authorization
|
||||
}
|
||||
|
||||
// AuthorizationMiddleware adds authorization to the re service.
|
||||
func AuthorizationMiddleware(svc re.Service, authz smqauthz.Authorization, callout callout.Callout) (re.Service, error) {
|
||||
func AuthorizationMiddleware(svc re.Service, authz smqauthz.Authorization) (re.Service, error) {
|
||||
return &authorizationMiddleware{
|
||||
svc: svc,
|
||||
authz: authz,
|
||||
callout: callout,
|
||||
svc: svc,
|
||||
authz: authz,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) AddRule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpAddRule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainCreateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entities": r,
|
||||
"count": 1,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpAddRule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.AddRule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ViewRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpViewRule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainViewRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpViewRule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.ViewRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateRule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpUpdateRule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainUpdateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpUpdateRule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.UpdateRule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateRuleTags(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpUpdateRuleTags, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainUpdateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpUpdateRuleTags, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.UpdateRuleTags(ctx, session, r)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateRuleSchedule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpUpdateRuleSchedule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainUpdateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpUpdateRuleSchedule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.UpdateRuleSchedule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ListRules(ctx context.Context, session authn.Session, pm re.PageMeta) (re.Page, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpListRules, session); err != nil {
|
||||
return re.Page{}, errors.Wrap(errDomainViewRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"pagemeta": pm,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpListRules, params); err != nil {
|
||||
return re.Page{}, err
|
||||
}
|
||||
|
||||
return am.svc.ListRules(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) RemoveRule(ctx context.Context, session authn.Session, id string) error {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpRemoveRule, session); err != nil {
|
||||
return errors.Wrap(errDomainDeleteRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpRemoveRule, params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return am.svc.RemoveRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) EnableRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpEnableRule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainUpdateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpEnableRule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.EnableRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) DisableRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, re.OpDisableRule, session); err != nil {
|
||||
return re.Rule{}, errors.Wrap(errDomainUpdateRules, err)
|
||||
}
|
||||
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := am.callOut(ctx, session, re.OpDisableRule, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return am.svc.DisableRule(ctx, session, id)
|
||||
}
|
||||
|
||||
@@ -269,28 +119,23 @@ func (am *authorizationMiddleware) Cancel() error {
|
||||
return am.svc.Cancel()
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) authorize(ctx context.Context, pr smqauthz.PolicyReq) error {
|
||||
if err := am.authz.Authorize(ctx, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) callOut(ctx context.Context, session authn.Session, op string, params map[string]any) error {
|
||||
req := callout.Request{
|
||||
BaseRequest: callout.BaseRequest{
|
||||
EntityType: entityType,
|
||||
CallerID: session.UserID,
|
||||
CallerType: policies.UserType,
|
||||
DomainID: session.DomainID,
|
||||
Time: time.Now().UTC(),
|
||||
Operation: op,
|
||||
},
|
||||
}
|
||||
|
||||
if err := am.callout.Callout(ctx, req); err != nil {
|
||||
func (am *authorizationMiddleware) authorize(ctx context.Context, op permissions.Operation, session authn.Session) error {
|
||||
perm, err := re.GetPermission(op)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
pr := smqauthz.PolicyReq{
|
||||
TokenType: session.Type,
|
||||
UserID: session.UserID,
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: perm,
|
||||
}
|
||||
|
||||
return am.authz.Authorize(ctx, pr)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/re"
|
||||
"github.com/absmach/supermq/pkg/authn"
|
||||
"github.com/absmach/supermq/pkg/callout"
|
||||
"github.com/absmach/supermq/pkg/messaging"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
var _ re.Service = (*calloutMiddleware)(nil)
|
||||
|
||||
type calloutMiddleware struct {
|
||||
svc re.Service
|
||||
callout callout.Callout
|
||||
}
|
||||
|
||||
const entityType = "rule"
|
||||
|
||||
func NewCallout(svc re.Service, callout callout.Callout) (re.Service, error) {
|
||||
return &calloutMiddleware{
|
||||
svc: svc,
|
||||
callout: callout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) AddRule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entities": r,
|
||||
"count": 1,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpAddRuleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.AddRule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) ViewRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpViewRuleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.ViewRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) UpdateRule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpUpdateRuleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.UpdateRule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) UpdateRuleTags(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpUpdateRuleTagsStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.UpdateRuleTags(ctx, session, r)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) UpdateRuleSchedule(ctx context.Context, session authn.Session, r re.Rule) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": r.ID,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpUpdateRuleScheduleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.UpdateRuleSchedule(ctx, session, r)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) ListRules(ctx context.Context, session authn.Session, pm re.PageMeta) (re.Page, error) {
|
||||
params := map[string]any{
|
||||
"pagemeta": pm,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpListRulesStr, params); err != nil {
|
||||
return re.Page{}, err
|
||||
}
|
||||
|
||||
return cm.svc.ListRules(ctx, session, pm)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) RemoveRule(ctx context.Context, session authn.Session, id string) error {
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpRemoveRuleStr, params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cm.svc.RemoveRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) EnableRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpEnableRuleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.EnableRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) DisableRule(ctx context.Context, session authn.Session, id string) (re.Rule, error) {
|
||||
params := map[string]any{
|
||||
"entity_id": id,
|
||||
}
|
||||
|
||||
if err := cm.callOut(ctx, session, re.OpDisableRuleStr, params); err != nil {
|
||||
return re.Rule{}, err
|
||||
}
|
||||
|
||||
return cm.svc.DisableRule(ctx, session, id)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) StartScheduler(ctx context.Context) error {
|
||||
return cm.svc.StartScheduler(ctx)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) Handle(msg *messaging.Message) error {
|
||||
return cm.svc.Handle(msg)
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) Cancel() error {
|
||||
return cm.svc.Cancel()
|
||||
}
|
||||
|
||||
func (cm *calloutMiddleware) callOut(ctx context.Context, session authn.Session, op string, pld map[string]any) error {
|
||||
var entityID string
|
||||
if id, ok := pld["entity_id"].(string); ok {
|
||||
entityID = id
|
||||
}
|
||||
|
||||
req := callout.Request{
|
||||
BaseRequest: callout.BaseRequest{
|
||||
Operation: op,
|
||||
EntityType: entityType,
|
||||
EntityID: entityID,
|
||||
CallerID: session.UserID,
|
||||
CallerType: policies.UserType,
|
||||
DomainID: session.DomainID,
|
||||
Time: time.Now().UTC(),
|
||||
},
|
||||
Payload: pld,
|
||||
}
|
||||
|
||||
if err := cm.callout.Callout(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package re
|
||||
|
||||
import (
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
const (
|
||||
OpAddRule permissions.Operation = iota
|
||||
OpViewRule
|
||||
OpUpdateRule
|
||||
OpUpdateRuleTags
|
||||
OpUpdateRuleSchedule
|
||||
OpListRules
|
||||
OpRemoveRule
|
||||
OpEnableRule
|
||||
OpDisableRule
|
||||
)
|
||||
|
||||
const (
|
||||
OpAddRuleStr = "OpAddRule"
|
||||
OpViewRuleStr = "OpViewRule"
|
||||
OpUpdateRuleStr = "OpUpdateRule"
|
||||
OpUpdateRuleTagsStr = "OpUpdateRuleTags"
|
||||
OpUpdateRuleScheduleStr = "OpUpdateRuleSchedule"
|
||||
OpListRulesStr = "OpListRules"
|
||||
OpRemoveRuleStr = "OpRemoveRule"
|
||||
OpEnableRuleStr = "OpEnableRule"
|
||||
OpDisableRuleStr = "OpDisableRule"
|
||||
)
|
||||
|
||||
func GetPermission(op permissions.Operation) (string, error) {
|
||||
if op < OpAddRule || op > OpDisableRule {
|
||||
return "", errors.New("invalid operation")
|
||||
}
|
||||
return policies.MembershipPermission, nil
|
||||
}
|
||||
-12
@@ -20,18 +20,6 @@ const (
|
||||
GoType
|
||||
)
|
||||
|
||||
const (
|
||||
OpAddRule = "OpAddRule"
|
||||
OpViewRule = "OpViewRule"
|
||||
OpUpdateRule = "OpUpdateRule"
|
||||
OpUpdateRuleTags = "OpUpdateRuleTags"
|
||||
OpUpdateRuleSchedule = "OpUpdateRuleSchedule"
|
||||
OpListRules = "OpListRules"
|
||||
OpRemoveRule = "OpRemoveRule"
|
||||
OpEnableRule = "OpEnableRule"
|
||||
OpDisableRule = "OpDisableRule"
|
||||
)
|
||||
|
||||
type (
|
||||
// ScriptType indicates Runtime type for the future versions
|
||||
// that will support JS or Go runtimes alongside Lua.
|
||||
|
||||
@@ -235,7 +235,7 @@ func TestReadAll(t *testing.T) {
|
||||
token: "",
|
||||
authResponse: false,
|
||||
authnErr: svcerr.ErrAuthentication,
|
||||
status: http.StatusUnauthorized,
|
||||
status: http.StatusBadRequest,
|
||||
err: svcerr.ErrAuthentication,
|
||||
},
|
||||
{
|
||||
@@ -623,7 +623,7 @@ func TestReadAll(t *testing.T) {
|
||||
url: fmt.Sprintf("%s/%s/channels/%s/messages?offset=0&limit=10", ts.URL, domainID, chanID),
|
||||
token: invalidToken,
|
||||
authResponse: false,
|
||||
status: http.StatusUnauthorized,
|
||||
status: http.StatusForbidden,
|
||||
err: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
@@ -645,7 +645,7 @@ func TestReadAll(t *testing.T) {
|
||||
url: fmt.Sprintf("%s/%s/channels/%s/messages?offset=0&limit=10", ts.URL, domainID, chanID),
|
||||
token: "",
|
||||
authResponse: false,
|
||||
status: http.StatusUnauthorized,
|
||||
status: http.StatusBadRequest,
|
||||
err: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -210,15 +210,14 @@ func encodeResponse(_ context.Context, w http.ResponseWriter, response any) erro
|
||||
}
|
||||
|
||||
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
var wrapper error
|
||||
if errors.Contains(err, apiutil.ErrValidation) {
|
||||
wrapper, err = errors.Unwrap(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
switch {
|
||||
case errors.Contains(err, nil):
|
||||
w.WriteHeader(http.StatusOK)
|
||||
case errors.Contains(err, apiutil.ErrInvalidQueryParams),
|
||||
errors.Contains(err, svcerr.ErrMalformedEntity),
|
||||
errors.Contains(err, apiutil.ErrValidation),
|
||||
errors.Contains(err, apiutil.ErrMissingID),
|
||||
errors.Contains(err, apiutil.ErrLimitSize),
|
||||
errors.Contains(err, apiutil.ErrOffsetSize),
|
||||
@@ -230,20 +229,17 @@ func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
errors.Contains(err, apiutil.ErrMissingDomainID):
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case errors.Contains(err, svcerr.ErrAuthentication),
|
||||
errors.Contains(err, svcerr.ErrAuthorization),
|
||||
errors.Contains(err, apiutil.ErrBearerToken):
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
case errors.Contains(err, svcerr.ErrAuthorization):
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
case errors.Contains(err, readers.ErrReadMessages):
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
default:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if wrapper != nil {
|
||||
err = errors.Wrap(wrapper, err)
|
||||
}
|
||||
if errorVal, ok := err.(errors.Error); ok {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
if err := json.NewEncoder(w).Encode(errorVal); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/absmach/supermq/pkg/authn"
|
||||
smqauthz "github.com/absmach/supermq/pkg/authz"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
@@ -39,15 +40,7 @@ func AuthorizationMiddleware(svc reports.Service, authz smqauthz.Authorization)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) AddReportConfig(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpAddReportConfig, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainCreateConfigs, err)
|
||||
}
|
||||
|
||||
@@ -55,15 +48,7 @@ func (am *authorizationMiddleware) AddReportConfig(ctx context.Context, session
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ViewReportConfig(ctx context.Context, session authn.Session, id string) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpViewReportConfig, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainViewConfigs, err)
|
||||
}
|
||||
|
||||
@@ -71,15 +56,7 @@ func (am *authorizationMiddleware) ViewReportConfig(ctx context.Context, session
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateReportConfig(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpUpdateReportConfig, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainUpdateConfigs, err)
|
||||
}
|
||||
|
||||
@@ -87,15 +64,7 @@ func (am *authorizationMiddleware) UpdateReportConfig(ctx context.Context, sessi
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateReportSchedule(ctx context.Context, session authn.Session, cfg reports.ReportConfig) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpUpdateReportSchedule, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainDeleteConfigs, err)
|
||||
}
|
||||
|
||||
@@ -103,15 +72,7 @@ func (am *authorizationMiddleware) UpdateReportSchedule(ctx context.Context, ses
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) RemoveReportConfig(ctx context.Context, session authn.Session, id string) error {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpRemoveReportConfig, session); err != nil {
|
||||
return errors.Wrap(errDomainDeleteConfigs, err)
|
||||
}
|
||||
|
||||
@@ -119,15 +80,7 @@ func (am *authorizationMiddleware) RemoveReportConfig(ctx context.Context, sessi
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ListReportsConfig(ctx context.Context, session authn.Session, pm reports.PageMeta) (reports.ReportConfigPage, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpListReportsConfig, session); err != nil {
|
||||
return reports.ReportConfigPage{}, errors.Wrap(errDomainViewConfigs, err)
|
||||
}
|
||||
|
||||
@@ -135,15 +88,7 @@ func (am *authorizationMiddleware) ListReportsConfig(ctx context.Context, sessio
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) EnableReportConfig(ctx context.Context, session authn.Session, id string) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpEnableReportConfig, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainUpdateConfigs, err)
|
||||
}
|
||||
|
||||
@@ -151,15 +96,7 @@ func (am *authorizationMiddleware) EnableReportConfig(ctx context.Context, sessi
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) DisableReportConfig(ctx context.Context, session authn.Session, id string) (reports.ReportConfig, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpDisableReportConfig, session); err != nil {
|
||||
return reports.ReportConfig{}, errors.Wrap(errDomainUpdateConfigs, err)
|
||||
}
|
||||
|
||||
@@ -167,15 +104,7 @@ func (am *authorizationMiddleware) DisableReportConfig(ctx context.Context, sess
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) GenerateReport(ctx context.Context, session authn.Session, config reports.ReportConfig, action reports.ReportAction) (reports.ReportPage, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpGenerateReport, session); err != nil {
|
||||
return reports.ReportPage{}, errors.Wrap(errDomainGenerateReports, err)
|
||||
}
|
||||
|
||||
@@ -183,15 +112,7 @@ func (am *authorizationMiddleware) GenerateReport(ctx context.Context, session a
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) UpdateReportTemplate(ctx context.Context, session authn.Session, cfg reports.ReportConfig) error {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpUpdateReportTemplate, session); err != nil {
|
||||
return errors.Wrap(errDomainUpdateTemplates, err)
|
||||
}
|
||||
|
||||
@@ -199,15 +120,7 @@ func (am *authorizationMiddleware) UpdateReportTemplate(ctx context.Context, ses
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) ViewReportTemplate(ctx context.Context, session authn.Session, id string) (reports.ReportTemplate, error) {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpViewReportTemplate, session); err != nil {
|
||||
return "", errors.Wrap(errDomainViewTemplates, err)
|
||||
}
|
||||
|
||||
@@ -215,15 +128,7 @@ func (am *authorizationMiddleware) ViewReportTemplate(ctx context.Context, sessi
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) DeleteReportTemplate(ctx context.Context, session authn.Session, id string) error {
|
||||
if err := am.authorize(ctx, smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: policies.MembershipPermission,
|
||||
}); err != nil {
|
||||
if err := am.authorize(ctx, reports.OpDeleteReportTemplate, session); err != nil {
|
||||
return errors.Wrap(errDomainRemoveTemplates, err)
|
||||
}
|
||||
|
||||
@@ -234,9 +139,21 @@ func (am *authorizationMiddleware) StartScheduler(ctx context.Context) error {
|
||||
return am.svc.StartScheduler(ctx)
|
||||
}
|
||||
|
||||
func (am *authorizationMiddleware) authorize(ctx context.Context, pr smqauthz.PolicyReq) error {
|
||||
if err := am.authz.Authorize(ctx, pr); err != nil {
|
||||
func (am *authorizationMiddleware) authorize(ctx context.Context, op permissions.Operation, session authn.Session) error {
|
||||
perm, err := reports.GetPermission(op)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
pr := smqauthz.PolicyReq{
|
||||
Domain: session.DomainID,
|
||||
SubjectType: policies.UserType,
|
||||
SubjectKind: policies.UsersKind,
|
||||
Subject: session.DomainUserID,
|
||||
Object: session.DomainID,
|
||||
ObjectType: policies.DomainType,
|
||||
Permission: perm,
|
||||
}
|
||||
|
||||
return am.authz.Authorize(ctx, pr)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package reports
|
||||
|
||||
import (
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/permissions"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
)
|
||||
|
||||
const (
|
||||
OpAddReportConfig = iota
|
||||
OpViewReportConfig
|
||||
OpUpdateReportConfig
|
||||
OpUpdateReportSchedule
|
||||
OpRemoveReportConfig
|
||||
OpListReportsConfig
|
||||
OpEnableReportConfig
|
||||
OpDisableReportConfig
|
||||
OpGenerateReport
|
||||
OpUpdateReportTemplate
|
||||
OpViewReportTemplate
|
||||
OpDeleteReportTemplate
|
||||
)
|
||||
|
||||
func GetPermission(op permissions.Operation) (string, error) {
|
||||
if op < OpAddReportConfig || op > OpDeleteReportTemplate {
|
||||
return "", errors.New("invalid operation")
|
||||
}
|
||||
return policies.MembershipPermission, nil
|
||||
}
|
||||
Reference in New Issue
Block a user