Skip to content

Commit

Permalink
groups: return role provisioned on create
Browse files Browse the repository at this point in the history
Signed-off-by: Arvindh <[email protected]>
  • Loading branch information
arvindh123 committed Dec 26, 2024
1 parent 094827a commit 4141dc8
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 33 deletions.
2 changes: 1 addition & 1 deletion groups/api/http/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func CreateGroupEndpoint(svc groups.Service) endpoint.Endpoint {
return createGroupRes{created: false}, svcerr.ErrAuthentication
}

group, err := svc.CreateGroup(ctx, session, req.Group)
group, _, err := svc.CreateGroup(ctx, session, req.Group)
if err != nil {
return createGroupRes{created: false}, err
}
Expand Down
11 changes: 7 additions & 4 deletions groups/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

groups "github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/events"
"github.com/absmach/supermq/pkg/roles"
)

var (
Expand Down Expand Up @@ -49,14 +50,16 @@ var (

type createGroupEvent struct {
groups.Group
rolesProvisioned []roles.RoleProvision
}

func (cge createGroupEvent) Encode() (map[string]interface{}, error) {
val := map[string]interface{}{
"operation": groupCreate,
"id": cge.ID,
"status": cge.Status.String(),
"created_at": cge.CreatedAt,
"operation": groupCreate,
"id": cge.ID,
"roles_provisioned": cge.rolesProvisioned,
"status": cge.Status.String(),
"created_at": cge.CreatedAt,
}

if cge.Domain != "" {
Expand Down
14 changes: 8 additions & 6 deletions groups/events/streams.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/events"
"github.com/absmach/supermq/pkg/events/store"
"github.com/absmach/supermq/pkg/roles"
rmEvents "github.com/absmach/supermq/pkg/roles/rolemanager/events"
)

Expand Down Expand Up @@ -39,21 +40,22 @@ func New(ctx context.Context, svc groups.Service, url string) (groups.Service, e
}, nil
}

func (es eventStore) CreateGroup(ctx context.Context, session authn.Session, group groups.Group) (groups.Group, error) {
group, err := es.svc.CreateGroup(ctx, session, group)
func (es eventStore) CreateGroup(ctx context.Context, session authn.Session, group groups.Group) (groups.Group, []roles.RoleProvision, error) {
group, rps, err := es.svc.CreateGroup(ctx, session, group)
if err != nil {
return group, err
return group, rps, err
}

event := createGroupEvent{
group,
Group: group,
rolesProvisioned: rps,
}

if err := es.Publish(ctx, event); err != nil {
return group, err
return group, rps, err
}

return group, nil
return group, rps, nil
}

func (es eventStore) UpdateGroup(ctx context.Context, session authn.Session, group groups.Group) (groups.Group, error) {
Expand Down
2 changes: 1 addition & 1 deletion groups/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ type Repository interface {
//go:generate mockery --name Service --output=./mocks --filename service.go --quiet --note "Copyright (c) Abstract Machines" --unroll-variadic=false
type Service interface {
// CreateGroup creates new group.
CreateGroup(ctx context.Context, session authn.Session, g Group) (Group, error)
CreateGroup(ctx context.Context, session authn.Session, g Group) (Group, []roles.RoleProvision, error)

// UpdateGroup updates the group identified by the provided ID.
UpdateGroup(ctx context.Context, session authn.Session, g Group) (Group, error)
Expand Down
7 changes: 4 additions & 3 deletions groups/middleware/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/absmach/supermq/pkg/errors"
svcerr "github.com/absmach/supermq/pkg/errors/service"
"github.com/absmach/supermq/pkg/policies"
"github.com/absmach/supermq/pkg/roles"
rmMW "github.com/absmach/supermq/pkg/roles/rolemanager/middleware"
"github.com/absmach/supermq/pkg/svcutil"
)
Expand Down Expand Up @@ -79,7 +80,7 @@ func AuthorizationMiddleware(entityType string, svc groups.Service, repo groups.
}, nil
}

func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, error) {
func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, []roles.RoleProvision, error) {
if err := am.extAuthorize(ctx, groups.DomainOpCreateGroup, smqauthz.PolicyReq{
Domain: session.DomainID,
SubjectType: policies.UserType,
Expand All @@ -88,7 +89,7 @@ func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session auth
Object: session.DomainID,
ObjectType: policies.DomainType,
}); err != nil {
return groups.Group{}, errors.Wrap(errDomainCreateGroups, err)
return groups.Group{}, []roles.RoleProvision{}, errors.Wrap(errDomainCreateGroups, err)
}

if g.Parent != "" {
Expand All @@ -100,7 +101,7 @@ func (am *authorizationMiddleware) CreateGroup(ctx context.Context, session auth
Object: g.Parent,
ObjectType: policies.GroupType,
}); err != nil {
return groups.Group{}, errors.Wrap(errParentGroupSetChildGroup, err)
return groups.Group{}, []roles.RoleProvision{}, errors.Wrap(errParentGroupSetChildGroup, err)
}
}

Expand Down
3 changes: 2 additions & 1 deletion groups/middleware/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/roles"
rmMW "github.com/absmach/supermq/pkg/roles/rolemanager/middleware"
)

Expand All @@ -28,7 +29,7 @@ func LoggingMiddleware(svc groups.Service, logger *slog.Logger) groups.Service {

// CreateGroup logs the create_group request. It logs the group name, id and token and the time it took to complete the request.
// If the request fails, it logs the error.
func (lm *loggingMiddleware) CreateGroup(ctx context.Context, session authn.Session, group groups.Group) (g groups.Group, err error) {
func (lm *loggingMiddleware) CreateGroup(ctx context.Context, session authn.Session, group groups.Group) (g groups.Group, rps []roles.RoleProvision, err error) {
defer func(begin time.Time) {
args := []any{
slog.String("duration", time.Since(begin).String()),
Expand Down
3 changes: 2 additions & 1 deletion groups/middleware/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/roles"
rmMW "github.com/absmach/supermq/pkg/roles/rolemanager/middleware"
"github.com/go-kit/kit/metrics"
)
Expand All @@ -34,7 +35,7 @@ func MetricsMiddleware(svc groups.Service, counter metrics.Counter, latency metr
}

// CreateGroup instruments CreateGroup method with metrics.
func (ms *metricsMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, error) {
func (ms *metricsMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, []roles.RoleProvision, error) {
defer func(begin time.Time) {
ms.counter.With("method", "create_group").Add(1)
ms.latency.With("method", "create_group").Observe(time.Since(begin).Seconds())
Expand Down
21 changes: 15 additions & 6 deletions groups/mocks/service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions groups/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ func NewService(repo Repository, policy policies.Service, idp supermq.IDProvider
}, nil
}

func (svc service) CreateGroup(ctx context.Context, session smqauthn.Session, g Group) (gr Group, retErr error) {
func (svc service) CreateGroup(ctx context.Context, session smqauthn.Session, g Group) (retGr Group, retRps []roles.RoleProvision, retErr error) {
groupID, err := svc.idProvider.ID()
if err != nil {
return Group{}, err
return Group{}, []roles.RoleProvision{}, err
}
if g.Status != EnabledStatus && g.Status != DisabledStatus {
return Group{}, svcerr.ErrInvalidStatus
return Group{}, []roles.RoleProvision{}, svcerr.ErrInvalidStatus
}

g.ID = groupID
Expand All @@ -62,7 +62,7 @@ func (svc service) CreateGroup(ctx context.Context, session smqauthn.Session, g

saved, err := svc.repo.Save(ctx, g)
if err != nil {
return Group{}, errors.Wrap(svcerr.ErrCreateEntity, err)
return Group{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrCreateEntity, err)
}

defer func() {
Expand Down Expand Up @@ -97,11 +97,12 @@ func (svc service) CreateGroup(ctx context.Context, session smqauthn.Session, g
newBuiltInRoleMembers := map[roles.BuiltInRoleName][]roles.Member{
BuiltInRoleAdmin: {roles.Member(session.UserID)},
}
if _, err := svc.AddNewEntitiesRoles(ctx, session.DomainID, session.UserID, []string{saved.ID}, oprs, newBuiltInRoleMembers); err != nil {
return Group{}, errors.Wrap(svcerr.ErrAddPolicies, err)
nrps, err := svc.AddNewEntitiesRoles(ctx, session.DomainID, session.UserID, []string{saved.ID}, oprs, newBuiltInRoleMembers)
if err != nil {
return Group{}, []roles.RoleProvision{}, errors.Wrap(svcerr.ErrAddPolicies, err)
}

return saved, nil
return saved, nrps, nil
}

func (svc service) ViewGroup(ctx context.Context, session smqauthn.Session, id string) (Group, error) {
Expand Down
4 changes: 2 additions & 2 deletions groups/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ func TestCreateGroup(t *testing.T) {
repoCall := repo.On("Save", context.Background(), mock.Anything).Return(tc.saveResp, tc.saveErr)
policyCall := policies.On("AddPolicies", context.Background(), mock.Anything).Return(tc.addPoliciesErr)
policyCall1 := policies.On("DeletePolicies", context.Background(), mock.Anything).Return(tc.deletePoliciesErr)
repoCall1 := repo.On("AddRoles", context.Background(), mock.Anything).Return([]roles.Role{}, tc.addRoleErr)
repoCall1 := repo.On("AddRoles", context.Background(), mock.Anything).Return([]roles.RoleProvision{}, tc.addRoleErr)
repoCall2 := repo.On("Delete", context.Background(), mock.Anything).Return(tc.deleteErr)
got, err := svc.CreateGroup(context.Background(), validSession, tc.group)
got, _, err := svc.CreateGroup(context.Background(), validSession, tc.group)
assert.Equal(t, tc.err, err, fmt.Sprintf("expected error %v but got %v", tc.err, err))
if err == nil {
assert.NotEmpty(t, got.ID)
Expand Down
3 changes: 2 additions & 1 deletion groups/tracing/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/absmach/supermq/groups"
"github.com/absmach/supermq/pkg/authn"
"github.com/absmach/supermq/pkg/roles"
rmTrace "github.com/absmach/supermq/pkg/roles/rolemanager/tracing"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
Expand All @@ -28,7 +29,7 @@ func New(svc groups.Service, tracer trace.Tracer) groups.Service {
}

// CreateGroup traces the "CreateGroup" operation of the wrapped groups.Service.
func (tm *tracingMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, error) {
func (tm *tracingMiddleware) CreateGroup(ctx context.Context, session authn.Session, g groups.Group) (groups.Group, []roles.RoleProvision, error) {
ctx, span := tm.tracer.Start(ctx, "svc_create_group")
defer span.End()

Expand Down

0 comments on commit 4141dc8

Please sign in to comment.