// Copyright (c) Abstract Machines // SPDX-License-Identifier: Apache-2.0 package atom import ( "context" "strings" smqauthz "github.com/absmach/magistrala/pkg/authz" "github.com/absmach/magistrala/pkg/errors" "github.com/absmach/magistrala/pkg/policies" ) type AuthorizationCompat struct { Client Authorizer } func NewAuthorizationCompat(client Authorizer) AuthorizationCompat { return AuthorizationCompat{Client: client} } func (a AuthorizationCompat) Authorize(ctx context.Context, pr smqauthz.PolicyReq, _ *smqauthz.PATReq) error { subjectID := pr.Subject if subjectID == "" { return errors.ErrAuthentication } objectKind := ObjectKind(pr.ObjectType, legacyResourceKind(pr.ObjectKind, pr.ObjectType)) res, err := a.Client.CheckAuthz(ctx, AuthzRequest{ SubjectID: subjectID, Action: CapabilityName(pr.Permission), ResourceID: resourceID(pr.ObjectType, pr.Object), ObjectKind: objectKind, ObjectID: pr.Object, Context: map[string]any{ atomContextDomainID: pr.Domain, "legacy_object_kind": pr.ObjectKind, atomContextLegacyObjectType: pr.ObjectType, "legacy_permission": pr.Permission, "legacy_relation": pr.Relation, "legacy_subject_kind": pr.SubjectKind, "legacy_subject_type": pr.SubjectType, }, }) if err != nil { return errors.Wrap(errors.ErrAuthorization, err) } if !res.Allowed { return errors.ErrAuthorization } return nil } func CapabilityName(action string) string { normalized := strings.ToLower(strings.TrimSpace(action)) switch { case normalized == policies.AdminPermission, normalized == "admin_permission", strings.Contains(normalized, "manage_role"): return atomActionManage case strings.Contains(normalized, atomActionAlarmRead): return atomActionAlarmRead case strings.Contains(normalized, atomActionAlarmUpdate): return atomActionAlarmUpdate case strings.Contains(normalized, atomActionAlarmDelete): return atomActionAlarmDelete case strings.Contains(normalized, atomActionAlarmAssign): return atomActionAlarmAssign case strings.Contains(normalized, atomActionAlarmAcknowledge): return atomActionAlarmAcknowledge case strings.Contains(normalized, atomActionAlarmResolve): return atomActionAlarmResolve case normalized == policies.ViewPermission, normalized == atomActionRead, strings.Contains(normalized, "read"), strings.Contains(normalized, "view"): return atomActionRead case normalized == policies.CreatePermission, normalized == "write", strings.Contains(normalized, "create"), strings.Contains(normalized, "update"), strings.Contains(normalized, "edit"), strings.Contains(normalized, "enable"), strings.Contains(normalized, "disable"), strings.Contains(normalized, "assign"), strings.Contains(normalized, "acknowledge"), strings.Contains(normalized, "resolve"): return atomActionWrite case normalized == policies.DeletePermission, strings.Contains(normalized, "delete"), strings.Contains(normalized, "remove"): return atomActionDelete case normalized == policies.PublishPermission: return atomActionPublish case normalized == policies.SubscribePermission: return atomActionSubscribe case normalized == "generate", normalized == "execute": return atomActionExecute case normalized == atomActionList: return atomActionList default: return normalized } } func legacyResourceKind(objectKind, objectType string) string { switch objectKind { case policies.ChannelsKind, policies.NewChannelKind: return KindChannel case policies.ClientsKind, policies.NewClientKind: return "client" case policies.GroupsKind, policies.NewGroupKind: return atomObjectKindGroup case policies.DomainsKind: return atomObjectKindTenant default: switch objectType { case policies.ChannelType: return KindChannel case policies.ClientType: return "client" case policies.GroupType: return atomObjectKindGroup case policies.DomainType: return atomObjectKindTenant case policies.RulesType: return KindRule case policies.ReportsType: return KindReport case policies.AlarmsType: return KindAlarm default: return objectType } } }