// Copyright (c) Abstract Machines // SPDX-License-Identifier: Apache-2.0 package atom import ( "context" "github.com/absmach/magistrala/pkg/authn" "github.com/absmach/magistrala/pkg/errors" "github.com/absmach/magistrala/pkg/policies" ) type Authorizer interface { CheckAuthz(ctx context.Context, req AuthzRequest) (AuthzResponse, error) } func Authorize(ctx context.Context, client Authorizer, session authn.Session, action, legacyObjectType, objectID, resourceKind string) error { req := AuthzRequest{ SubjectID: SubjectID(session), Action: CapabilityName(action), ResourceID: resourceID(legacyObjectType, objectID), ObjectKind: ObjectKind(legacyObjectType, resourceKind), ObjectID: objectID, Context: map[string]any{ atomContextDomainID: session.DomainID, atomContextLegacyObjectType: legacyObjectType, }, } res, err := client.CheckAuthz(ctx, req) if err != nil { return errors.Wrap(errors.ErrAuthorization, err) } if !res.Allowed { return errors.ErrAuthorization } return nil } func SubjectID(session authn.Session) string { if session.UserID != "" { return session.UserID } return session.DomainUserID } func ObjectKind(legacyObjectType, resourceKind string) string { switch legacyObjectType { case policies.DomainType: return atomObjectKindTenant case policies.PlatformType: return policies.PlatformType case policies.ClientType: return atomObjectKindEntity case policies.GroupType: return atomObjectKindGroup case policies.ChannelType, policies.RulesType, policies.ReportsType, policies.AlarmsType: return atomObjectKindResource } switch resourceKind { case KindClient, atomKindDevice: return atomObjectKindEntity case atomKindGroup: return atomObjectKindGroup case KindChannel, KindRule, KindReport, KindAlarm: return atomObjectKindResource default: return resourceKind } } func resourceID(legacyObjectType, objectID string) string { if legacyObjectType == policies.DomainType || legacyObjectType == policies.PlatformType { return "" } return objectID }