diff --git a/channels/api/grpc/endpoint.go b/channels/api/grpc/endpoint.go index 6c5740d385..b8e242ca82 100644 --- a/channels/api/grpc/endpoint.go +++ b/channels/api/grpc/endpoint.go @@ -14,6 +14,9 @@ import ( func authorizeEndpoint(svc channels.Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { req := request.(authorizeReq) + if err := req.validate(); err != nil { + return authorizeRes{}, err + } if err := svc.Authorize(ctx, ch.AuthzReq{ DomainID: req.domainID, diff --git a/channels/api/grpc/request.go b/channels/api/grpc/request.go index 2370502ace..699ea5b72b 100644 --- a/channels/api/grpc/request.go +++ b/channels/api/grpc/request.go @@ -3,7 +3,13 @@ package grpc -import "github.com/absmach/supermq/pkg/connections" +import ( + "github.com/absmach/supermq/pkg/connections" + "github.com/absmach/supermq/pkg/errors" + "github.com/absmach/supermq/pkg/policies" +) + +var errDomainID = errors.New("domain id required for user type") type authorizeReq struct { domainID string @@ -12,6 +18,14 @@ type authorizeReq struct { clientType string connType connections.ConnType } + +func (req authorizeReq) validate() error { + if req.clientType == policies.UserType && req.domainID == "" { + return errDomainID + } + return nil +} + type removeClientConnectionsReq struct { clientID string } diff --git a/channels/api/http/transport.go b/channels/api/http/transport.go index 562fe7b945..8f9439e214 100644 --- a/channels/api/http/transport.go +++ b/channels/api/http/transport.go @@ -11,6 +11,7 @@ import ( apiutil "github.com/absmach/supermq/api/http/util" "github.com/absmach/supermq/channels" smqauthn "github.com/absmach/supermq/pkg/authn" + roleManagerHttp "github.com/absmach/supermq/pkg/roles/rolemanager/api" "github.com/go-chi/chi/v5" kithttp "github.com/go-kit/kit/transport/http" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -22,6 +23,9 @@ func MakeHandler(svc channels.Service, authn smqauthn.Authentication, mux *chi.M opts := []kithttp.ServerOption{ kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, api.EncodeError)), } + + d := roleManagerHttp.NewDecoder("channelID") + mux.Route("/{domainID}/channels", func(r chi.Router) { r.Use(api.AuthenticateMiddleware(authn, true)) @@ -60,6 +64,8 @@ func MakeHandler(svc channels.Service, authn smqauthn.Authentication, mux *chi.M opts..., ), "disconnect").ServeHTTP) + r = roleManagerHttp.EntityAvailableActionsRouter(svc, d, r, opts) + r.Route("/{channelID}", func(r chi.Router) { r.Get("/", otelhttp.NewHandler(kithttp.NewServer( viewChannelEndpoint(svc), @@ -130,6 +136,8 @@ func MakeHandler(svc channels.Service, authn smqauthn.Authentication, mux *chi.M api.EncodeResponse, opts..., ), "disconnect_channel_client").ServeHTTP) + + roleManagerHttp.EntityRoleMangerRouter(svc, d, r, opts) }) }) diff --git a/channels/builtinroles.go b/channels/builtinroles.go new file mode 100644 index 0000000000..95bd1dc342 --- /dev/null +++ b/channels/builtinroles.go @@ -0,0 +1,7 @@ +// Copyright (c) Abstract Machines +// SPDX-License-Identifier: Apache-2.0 +package channels + +import "github.com/absmach/supermq/pkg/roles" + +const BuiltInRoleAdmin roles.BuiltInRoleName = "admin" diff --git a/channels/private/service.go b/channels/private/service.go index 364c9ab150..ec06c1c3bf 100644 --- a/channels/private/service.go +++ b/channels/private/service.go @@ -6,6 +6,7 @@ package private import ( "context" + "github.com/absmach/supermq/auth" "github.com/absmach/supermq/channels" "github.com/absmach/supermq/pkg/errors" svcerr "github.com/absmach/supermq/pkg/errors/service" @@ -35,10 +36,15 @@ func New(repo channels.Repository, evaluator policies.Evaluator, policy policies func (svc service) Authorize(ctx context.Context, req channels.AuthzReq) error { switch req.ClientType { case policies.UserType: + permission, err := req.Type.Permission() + if err != nil { + return err + } pr := policies.Policy{ - Subject: req.ClientID, + Subject: auth.EncodeDomainUserID(req.DomainID, req.ClientID), SubjectType: policies.UserType, Object: req.ChannelID, + Permission: permission, ObjectType: policies.ChannelType, } if err := svc.evaluator.CheckPolicy(ctx, pr); err != nil { diff --git a/channels/roleactions.go b/channels/roleactions.go deleted file mode 100644 index 4f81ae233c..0000000000 --- a/channels/roleactions.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Abstract Machines -// SPDX-License-Identifier: Apache-2.0 -package channels - -import "github.com/absmach/supermq/pkg/roles" - -// Below codes should moved out of service, may be can be kept in `cmd//main.go` - -const ( - ChannelUpdate roles.Action = "update" - ChannelRead roles.Action = "read" - ChannelDelete roles.Action = "delete" - ChannelSetParentGroup roles.Action = "set_parent_group" - ChannelConnectToChannel roles.Action = "connect_to_client" - ChannelManageRole roles.Action = "manage_role" - ChannelAddRoleUsers roles.Action = "add_role_users" - ChannelRemoveRoleUsers roles.Action = "remove_role_users" - ChannelViewRoleUsers roles.Action = "view_role_users" -) - -const ( - BuiltInRoleAdmin = "admin" -) - -func AvailableActions() []roles.Action { - return []roles.Action{ - ChannelUpdate, - ChannelRead, - ChannelDelete, - ChannelSetParentGroup, - ChannelConnectToChannel, - ChannelManageRole, - ChannelAddRoleUsers, - ChannelRemoveRoleUsers, - ChannelViewRoleUsers, - } -} - -func BuiltInRoles() map[roles.BuiltInRoleName][]roles.Action { - return map[roles.BuiltInRoleName][]roles.Action{ - BuiltInRoleAdmin: AvailableActions(), - } -} diff --git a/channels/service.go b/channels/service.go index 4faed423b4..c2d614c401 100644 --- a/channels/service.go +++ b/channels/service.go @@ -40,8 +40,8 @@ type service struct { var _ Service = (*service)(nil) -func New(repo Repository, policy policies.Service, idProvider supermq.IDProvider, clients grpcClientsV1.ClientsServiceClient, groups grpcGroupsV1.GroupsServiceClient, sidProvider supermq.IDProvider) (Service, error) { - rpms, err := roles.NewProvisionManageService(policies.ChannelType, repo, policy, sidProvider, AvailableActions(), BuiltInRoles()) +func New(repo Repository, policy policies.Service, idProvider supermq.IDProvider, clients grpcClientsV1.ClientsServiceClient, groups grpcGroupsV1.GroupsServiceClient, sidProvider supermq.IDProvider, availableActions []roles.Action, builtInRoles map[roles.BuiltInRoleName][]roles.Action) (Service, error) { + rpms, err := roles.NewProvisionManageService(policies.ChannelType, repo, policy, sidProvider, availableActions, builtInRoles) if err != nil { return nil, err } diff --git a/channels/service_test.go b/channels/service_test.go index d5dbf4974f..3353946827 100644 --- a/channels/service_test.go +++ b/channels/service_test.go @@ -65,7 +65,11 @@ func newService(t *testing.T) channels.Service { policies = new(policymocks.Service) clientsSvc = new(clmocks.ClientsServiceClient) groupsSvc = new(gpmocks.GroupsServiceClient) - svc, err := channels.New(repo, policies, idProvider, clientsSvc, groupsSvc, idProvider) + availableActions := []roles.Action{} + builtInRoles := map[roles.BuiltInRoleName][]roles.Action{ + clients.BuiltInRoleAdmin: availableActions, + } + svc, err := channels.New(repo, policies, idProvider, clientsSvc, groupsSvc, idProvider, availableActions, builtInRoles) assert.Nil(t, err, fmt.Sprintf(" Unexpected error while creating service %v", err)) return svc } diff --git a/clients/api/http/clients.go b/clients/api/http/clients.go index 29cd6ff32d..abecf0ba85 100644 --- a/clients/api/http/clients.go +++ b/clients/api/http/clients.go @@ -46,6 +46,7 @@ func clientsHandler(svc clients.Service, authn smqauthn.Authentication, r *chi.M api.EncodeResponse, opts..., ), "create_clients").ServeHTTP) + r = roleManagerHttp.EntityAvailableActionsRouter(svc, d, r, opts) r.Route("/{clientID}", func(r chi.Router) { @@ -111,16 +112,10 @@ func clientsHandler(svc clients.Service, authn smqauthn.Authentication, r *chi.M api.EncodeResponse, opts..., ), "delete_client").ServeHTTP) + roleManagerHttp.EntityRoleMangerRouter(svc, d, r, opts) }) }) - - r.Get("/{domainID}/users/{userID}/clients", otelhttp.NewHandler(kithttp.NewServer( - listClientsEndpoint(svc), - decodeListClients, - api.EncodeResponse, - opts..., - ), "list_user_clients").ServeHTTP) }) return r } diff --git a/clients/builtinroles.go b/clients/builtinroles.go new file mode 100644 index 0000000000..a874f97e2a --- /dev/null +++ b/clients/builtinroles.go @@ -0,0 +1,7 @@ +// Copyright (c) Abstract Machines +// SPDX-License-Identifier: Apache-2.0 +package clients + +import "github.com/absmach/supermq/pkg/roles" + +const BuiltInRoleAdmin roles.BuiltInRoleName = "admin" diff --git a/clients/postgres/clients.go b/clients/postgres/clients.go index 5d71aaac35..bc3bb51dcf 100644 --- a/clients/postgres/clients.go +++ b/clients/postgres/clients.go @@ -881,7 +881,7 @@ func ToClient(t DBClient) (clients.Client, error) { updatedAt = t.UpdatedAt.Time } - connTypes := []connections.ConnType{} + var connTypes []connections.ConnType for _, ct := range t.ConnectionTypes { connType, err := connections.NewType(uint(ct)) if err != nil { diff --git a/clients/roleactions.go b/clients/roleactions.go deleted file mode 100644 index 03a2fb5c1a..0000000000 --- a/clients/roleactions.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Abstract Machines -// SPDX-License-Identifier: Apache-2.0 - -package clients - -import "github.com/absmach/supermq/pkg/roles" - -// Below codes should moved out of service, may be can be kept in `cmd//main.go` - -const ( - ClientUpdate roles.Action = "update" - ClientRead roles.Action = "read" - ClientDelete roles.Action = "delete" - ClientSetParentGroup roles.Action = "set_parent_group" - ClientConnectToChannel roles.Action = "connect_to_channel" - ClientManageRole roles.Action = "manage_role" - ClientAddRoleUsers roles.Action = "add_role_users" - ClientRemoveRoleUsers roles.Action = "remove_role_users" - ClientViewRoleUsers roles.Action = "view_role_users" -) - -const ( - ClientBuiltInRoleAdmin = "admin" -) - -func AvailableActions() []roles.Action { - return []roles.Action{ - ClientUpdate, - ClientRead, - ClientDelete, - ClientSetParentGroup, - ClientConnectToChannel, - ClientManageRole, - ClientAddRoleUsers, - ClientRemoveRoleUsers, - ClientViewRoleUsers, - } -} - -func BuiltInRoles() map[roles.BuiltInRoleName][]roles.Action { - return map[roles.BuiltInRoleName][]roles.Action{ - ClientBuiltInRoleAdmin: AvailableActions(), - } -} diff --git a/clients/service.go b/clients/service.go index e563a886fd..5638d91462 100644 --- a/clients/service.go +++ b/clients/service.go @@ -36,8 +36,8 @@ type service struct { } // NewService returns a new Clients service implementation. -func NewService(repo Repository, policy policies.Service, cache Cache, channels grpcChannelsV1.ChannelsServiceClient, groups grpcGroupsV1.GroupsServiceClient, idProvider smq.IDProvider, sIDProvider smq.IDProvider) (Service, error) { - rpms, err := roles.NewProvisionManageService(policies.ClientType, repo, policy, sIDProvider, AvailableActions(), BuiltInRoles()) +func NewService(repo Repository, policy policies.Service, cache Cache, channels grpcChannelsV1.ChannelsServiceClient, groups grpcGroupsV1.GroupsServiceClient, idProvider smq.IDProvider, sIDProvider smq.IDProvider, availableActions []roles.Action, builtInRoles map[roles.BuiltInRoleName][]roles.Action) (Service, error) { + rpms, err := roles.NewProvisionManageService(policies.ClientType, repo, policy, sIDProvider, availableActions, builtInRoles) if err != nil { return service{}, err } @@ -95,7 +95,7 @@ func (svc service) CreateClients(ctx context.Context, session authn.Session, cls }() newBuiltInRoleMembers := map[roles.BuiltInRoleName][]roles.Member{ - ClientBuiltInRoleAdmin: {roles.Member(session.UserID)}, + BuiltInRoleAdmin: {roles.Member(session.UserID)}, } optionalPolicies := []policies.Policy{} diff --git a/clients/service_test.go b/clients/service_test.go index e3e51b6f4f..5adbd75143 100644 --- a/clients/service_test.go +++ b/clients/service_test.go @@ -61,7 +61,11 @@ func newService() clients.Service { repo = new(climocks.Repository) chgRPCClient = new(chmocks.ChannelsServiceClient) gpgRPCClient = new(gpmocks.GroupsServiceClient) - tsv, _ := clients.NewService(repo, pService, cache, chgRPCClient, gpgRPCClient, idProvider, sidProvider) + availableActions := []roles.Action{} + builtInRoles := map[roles.BuiltInRoleName][]roles.Action{ + clients.BuiltInRoleAdmin: availableActions, + } + tsv, _ := clients.NewService(repo, pService, cache, chgRPCClient, gpgRPCClient, idProvider, sidProvider, availableActions, builtInRoles) return tsv } diff --git a/cmd/channels/main.go b/cmd/channels/main.go index c4465a2249..a3f20e908d 100644 --- a/cmd/channels/main.go +++ b/cmd/channels/main.go @@ -41,10 +41,12 @@ import ( pg "github.com/absmach/supermq/pkg/postgres" pgclient "github.com/absmach/supermq/pkg/postgres" "github.com/absmach/supermq/pkg/prometheus" + "github.com/absmach/supermq/pkg/roles" "github.com/absmach/supermq/pkg/server" grpcserver "github.com/absmach/supermq/pkg/server/grpc" httpserver "github.com/absmach/supermq/pkg/server/http" "github.com/absmach/supermq/pkg/sid" + spicedbdecoder "github.com/absmach/supermq/pkg/spicedb" "github.com/absmach/supermq/pkg/uuid" "github.com/authzed/authzed-go/v1" "github.com/authzed/grpcutil" @@ -78,11 +80,12 @@ type config struct { JaegerURL url.URL `env:"SMQ_JAEGER_URL" envDefault:"http://localhost:4318/v1/traces"` SendTelemetry bool `env:"SMQ_SEND_TELEMETRY" envDefault:"true"` ESURL string `env:"SMQ_ES_URL" envDefault:"nats://localhost:4222"` - ESConsumerName string `env:"SMQ_CLIENTS_EVENT_CONSUMER" envDefault:"channels"` + ESConsumerName string `env:"SMQ_CHANNELS_EVENT_CONSUMER" envDefault:"channels"` TraceRatio float64 `env:"SMQ_JAEGER_TRACE_RATIO" envDefault:"1.0"` SpicedbHost string `env:"SMQ_SPICEDB_HOST" envDefault:"localhost"` SpicedbPort string `env:"SMQ_SPICEDB_PORT" envDefault:"50051"` SpicedbPreSharedKey string `env:"SMQ_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"` + SpicedbSchemaFile string `env:"SMQ_SPICEDB_SCHEMA_FILE" envDefault:"schema.zed"` } func main() { @@ -222,7 +225,7 @@ func main() { defer groupsHandler.Close() logger.Info("Groups gRPC client successfully connected to groups gRPC server " + groupsHandler.Secure()) - svc, psvc, err := newService(ctx, db, dbConfig, authz, policyEvaluator, policyService, cfg.ESURL, tracer, clientsClient, groupsClient, logger) + svc, psvc, err := newService(ctx, db, dbConfig, authz, policyEvaluator, policyService, cfg, tracer, clientsClient, groupsClient, logger) if err != nil { logger.Error(fmt.Sprintf("failed to create services: %s", err)) exitCode = 1 @@ -293,7 +296,7 @@ func main() { } func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, authz smqauthz.Authorization, - pe policies.Evaluator, ps policies.Service, esURL string, tracer trace.Tracer, clientsClient grpcClientsV1.ClientsServiceClient, + pe policies.Evaluator, ps policies.Service, cfg config, tracer trace.Tracer, clientsClient grpcClientsV1.ClientsServiceClient, groupsClient grpcGroupsV1.GroupsServiceClient, logger *slog.Logger, ) (channels.Service, pChannels.Service, error) { database := pg.NewDatabase(db, dbConfig, tracer) @@ -305,12 +308,17 @@ func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, auth return nil, nil, err } - svc, err := channels.New(repo, ps, idp, clientsClient, groupsClient, sidp) + availableActions, buildInRoles, err := availableActionsAndBuiltInRoles(cfg.SpicedbSchemaFile) if err != nil { return nil, nil, err } - svc, err = events.NewEventStoreMiddleware(ctx, svc, esURL) + svc, err := channels.New(repo, ps, idp, clientsClient, groupsClient, sidp, availableActions, buildInRoles) + if err != nil { + return nil, nil, err + } + + svc, err = events.NewEventStoreMiddleware(ctx, svc, cfg.ESURL) if err != nil { return nil, nil, err } @@ -344,3 +352,16 @@ func newSpiceDBPolicyServiceEvaluator(cfg config, logger *slog.Logger) (policies pe := spicedb.NewPolicyEvaluator(client, logger) return pe, ps, nil } + +func availableActionsAndBuiltInRoles(spicedbSchemaFile string) ([]roles.Action, map[roles.BuiltInRoleName][]roles.Action, error) { + availableActions, err := spicedbdecoder.GetActionsFromSchema(spicedbSchemaFile, policies.ChannelType) + if err != nil { + return []roles.Action{}, map[roles.BuiltInRoleName][]roles.Action{}, err + } + + builtInRoles := map[roles.BuiltInRoleName][]roles.Action{ + channels.BuiltInRoleAdmin: availableActions, + } + + return availableActions, builtInRoles, err +} diff --git a/cmd/clients/main.go b/cmd/clients/main.go index c33a00dd14..55a065a2dc 100644 --- a/cmd/clients/main.go +++ b/cmd/clients/main.go @@ -44,10 +44,12 @@ import ( pg "github.com/absmach/supermq/pkg/postgres" pgclient "github.com/absmach/supermq/pkg/postgres" "github.com/absmach/supermq/pkg/prometheus" + "github.com/absmach/supermq/pkg/roles" "github.com/absmach/supermq/pkg/server" grpcserver "github.com/absmach/supermq/pkg/server/grpc" httpserver "github.com/absmach/supermq/pkg/server/http" "github.com/absmach/supermq/pkg/sid" + spicedbdecoder "github.com/absmach/supermq/pkg/spicedb" "github.com/absmach/supermq/pkg/uuid" "github.com/authzed/authzed-go/v1" "github.com/authzed/grpcutil" @@ -91,6 +93,7 @@ type config struct { SpicedbHost string `env:"SMQ_SPICEDB_HOST" envDefault:"localhost"` SpicedbPort string `env:"SMQ_SPICEDB_PORT" envDefault:"50051"` SpicedbPreSharedKey string `env:"SMQ_SPICEDB_PRE_SHARED_KEY" envDefault:"12345678"` + SpicedbSchemaFile string `env:"SMQ_SPICEDB_SCHEMA_FILE" envDefault:"schema.zed"` } func main() { @@ -239,7 +242,7 @@ func main() { defer groupsHandler.Close() logger.Info("Groups gRPC client successfully connected to groups gRPC server " + groupsHandler.Secure()) - svc, psvc, err := newService(ctx, db, dbConfig, authz, policyEvaluator, policyService, cacheclient, cfg.CacheKeyDuration, cfg.ESURL, channelsgRPC, groupsClient, tracer, logger) + svc, psvc, err := newService(ctx, db, dbConfig, authz, policyEvaluator, policyService, cacheclient, cfg, channelsgRPC, groupsClient, tracer, logger) if err != nil { logger.Error(fmt.Sprintf("failed to create services: %s", err)) exitCode = 1 @@ -309,7 +312,7 @@ func main() { } } -func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, authz smqauthz.Authorization, pe policies.Evaluator, ps policies.Service, cacheClient *redis.Client, keyDuration time.Duration, esURL string, channels grpcChannelsV1.ChannelsServiceClient, groups grpcGroupsV1.GroupsServiceClient, tracer trace.Tracer, logger *slog.Logger) (clients.Service, pClients.Service, error) { +func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, authz smqauthz.Authorization, pe policies.Evaluator, ps policies.Service, cacheClient *redis.Client, cfg config, channels grpcChannelsV1.ChannelsServiceClient, groups grpcGroupsV1.GroupsServiceClient, tracer trace.Tracer, logger *slog.Logger) (clients.Service, pClients.Service, error) { database := pg.NewDatabase(db, dbConfig, tracer) repo := postgres.NewRepository(database) @@ -320,14 +323,19 @@ func newService(ctx context.Context, db *sqlx.DB, dbConfig pgclient.Config, auth } // Clients service - cache := cache.NewCache(cacheClient, keyDuration) + cache := cache.NewCache(cacheClient, cfg.CacheKeyDuration) - csvc, err := clients.NewService(repo, ps, cache, channels, groups, idp, sidp) + availableActions, builtInRoles, err := availableActionsAndBuiltInRoles(cfg.SpicedbSchemaFile) if err != nil { return nil, nil, err } - csvc, err = events.NewEventStoreMiddleware(ctx, csvc, esURL) + csvc, err := clients.NewService(repo, ps, cache, channels, groups, idp, sidp, availableActions, builtInRoles) + if err != nil { + return nil, nil, err + } + + csvc, err = events.NewEventStoreMiddleware(ctx, csvc, cfg.ESURL) if err != nil { return nil, nil, err } @@ -363,3 +371,16 @@ func newSpiceDBPolicyServiceEvaluator(cfg config, logger *slog.Logger) (policies return pe, ps, nil } + +func availableActionsAndBuiltInRoles(spicedbSchemaFile string) ([]roles.Action, map[roles.BuiltInRoleName][]roles.Action, error) { + availableActions, err := spicedbdecoder.GetActionsFromSchema(spicedbSchemaFile, policies.ClientType) + if err != nil { + return []roles.Action{}, map[roles.BuiltInRoleName][]roles.Action{}, err + } + + builtInRoles := map[roles.BuiltInRoleName][]roles.Action{ + clients.BuiltInRoleAdmin: availableActions, + } + + return availableActions, builtInRoles, err +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index b5623c24c5..37a5dce0df 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -175,7 +175,7 @@ services: - supermq-base-net volumes: - supermq-domains-db-volume:/var/lib/postgresql/data - + domains-redis: image: redis:7.2.4-alpine container_name: supermq-domains-redis @@ -500,12 +500,14 @@ services: SMQ_SPICEDB_PRE_SHARED_KEY: ${SMQ_SPICEDB_PRE_SHARED_KEY} SMQ_SPICEDB_HOST: ${SMQ_SPICEDB_HOST} SMQ_SPICEDB_PORT: ${SMQ_SPICEDB_PORT} + SMQ_SPICEDB_SCHEMA_FILE: ${SMQ_SPICEDB_SCHEMA_FILE} ports: - ${SMQ_CLIENTS_HTTP_PORT}:${SMQ_CLIENTS_HTTP_PORT} - ${SMQ_CLIENTS_AUTH_GRPC_PORT}:${SMQ_CLIENTS_AUTH_GRPC_PORT} networks: - supermq-base-net volumes: + - ./spicedb/schema.zed:${SMQ_SPICEDB_SCHEMA_FILE} # Clients gRPC server certificates - type: bind source: ${SMQ_CLIENTS_AUTH_GRPC_SERVER_CERT:-ssl/certs/dummy/server_cert} @@ -652,12 +654,14 @@ services: SMQ_SPICEDB_PRE_SHARED_KEY: ${SMQ_SPICEDB_PRE_SHARED_KEY} SMQ_SPICEDB_HOST: ${SMQ_SPICEDB_HOST} SMQ_SPICEDB_PORT: ${SMQ_SPICEDB_PORT} + SMQ_SPICEDB_SCHEMA_FILE: ${SMQ_SPICEDB_SCHEMA_FILE} ports: - ${SMQ_CHANNELS_HTTP_PORT}:${SMQ_CHANNELS_HTTP_PORT} - ${SMQ_CHANNELS_GRPC_PORT}:${SMQ_CHANNELS_GRPC_PORT} networks: - supermq-base-net volumes: + - ./spicedb/schema.zed:${SMQ_SPICEDB_SCHEMA_FILE} # Auth gRPC client certificates - type: bind source: ${SMQ_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert} @@ -1309,57 +1313,3 @@ services: - ./nats:/etc/nats networks: - supermq-base-net - - ui: - image: magistrala/ui:${SMQ_RELEASE_TAG} - container_name: supermq-ui - restart: on-failure - environment: - SMQ_UI_LOG_LEVEL: ${SMQ_UI_LOG_LEVEL} - SMQ_UI_PORT: ${SMQ_UI_PORT} - SMQ_HTTP_ADAPTER_URL: ${SMQ_HTTP_ADAPTER_URL} - SMQ_CLIENTS_URL: ${SMQ_CLIENTS_URL} - SMQ_USERS_URL: ${SMQ_USERS_URL} - SMQ_INVITATIONS_URL: ${SMQ_INVITATIONS_URL} - SMQ_DOMAINS_URL: ${SMQ_DOMAINS_URL} - SMQ_UI_HOST_URL: ${SMQ_UI_HOST_URL} - SMQ_UI_VERIFICATION_TLS: ${SMQ_UI_VERIFICATION_TLS} - SMQ_UI_CONTENT_TYPE: ${SMQ_UI_CONTENT_TYPE} - SMQ_UI_INSTANCE_ID: ${SMQ_UI_INSTANCE_ID} - SMQ_UI_DB_HOST: ${SMQ_UI_DB_HOST} - SMQ_UI_DB_PORT: ${SMQ_UI_DB_PORT} - SMQ_UI_DB_USER: ${SMQ_UI_DB_USER} - SMQ_UI_DB_PASS: ${SMQ_UI_DB_PASS} - SMQ_UI_DB_NAME: ${SMQ_UI_DB_NAME} - SMQ_UI_DB_SSL_MODE: ${SMQ_UI_DB_SSL_MODE} - SMQ_UI_DB_SSL_CERT: ${SMQ_UI_DB_SSL_CERT} - SMQ_UI_DB_SSL_KEY: ${SMQ_UI_DB_SSL_KEY} - SMQ_UI_DB_SSL_ROOT_CERT: ${SMQ_UI_DB_SSL_ROOT_CERT} - SMQ_GOOGLE_CLIENT_ID: ${SMQ_GOOGLE_CLIENT_ID} - SMQ_GOOGLE_CLIENT_SECRET: ${SMQ_GOOGLE_CLIENT_SECRET} - SMQ_GOOGLE_REDIRECT_URL: ${SMQ_GOOGLE_REDIRECT_URL} - SMQ_GOOGLE_STATE: ${SMQ_GOOGLE_STATE} - SMQ_UI_HASH_KEY: ${SMQ_UI_HASH_KEY} - SMQ_UI_BLOCK_KEY: ${SMQ_UI_BLOCK_KEY} - SMQ_UI_PATH_PREFIX: ${SMQ_UI_PATH_PREFIX} - ports: - - ${SMQ_UI_PORT}:${SMQ_UI_PORT} - networks: - - supermq-base-net - - ui-db: - image: postgres:16.2-alpine - container_name: supermq-ui-db - restart: on-failure - command: postgres -c "max_connections=${SMQ_POSTGRES_MAX_CONNECTIONS}" - environment: - POSTGRES_USER: ${SMQ_UI_DB_USER} - POSTGRES_PASSWORD: ${SMQ_UI_DB_PASS} - POSTGRES_DB: ${SMQ_UI_DB_NAME} - SMQ_POSTGRES_MAX_CONNECTIONS: ${SMQ_POSTGRES_MAX_CONNECTIONS} - ports: - - 6007:5432 - networks: - - supermq-base-net - volumes: - - supermq-ui-db-volume:/var/lib/postgresql/data diff --git a/pkg/connections/type.go b/pkg/connections/type.go index 3e916c811b..d3f9fd0d62 100644 --- a/pkg/connections/type.go +++ b/pkg/connections/type.go @@ -62,6 +62,17 @@ func (c ConnType) String() string { } } +func (c ConnType) Permission() (string, error) { + switch c { + case Publish: + return "publish_permission", nil + case Subscribe: + return "subscribe_permission", nil + default: + return "", fmt.Errorf("Unknown connection type %d", c) + } +} + func NewType(c uint) (ConnType, error) { if err := CheckConnType(ConnType(c)); err != nil { return Invalid, err diff --git a/pkg/groups/events/consumer/streams.go b/pkg/groups/events/consumer/streams.go index feccb4121e..322c0a4a53 100644 --- a/pkg/groups/events/consumer/streams.go +++ b/pkg/groups/events/consumer/streams.go @@ -5,7 +5,6 @@ package consumer import ( "context" - "fmt" "log/slog" "github.com/absmach/supermq/groups" @@ -210,7 +209,7 @@ func (es *eventHandler) removeParentGroupHandler(ctx context.Context, data map[s if err != nil { return errors.Wrap(errRemoveParentGroupEvent, err) } - fmt.Println(g, g.Parent, g.ID) + if err := es.repo.UnassignParentGroup(ctx, g.Parent, id); err != nil { return errors.Wrap(errRemoveParentGroupEvent, err) }