mirror of
https://github.com/absmach/magistrala.git
synced 2026-08-07 07:14:46 +00:00
61d0427898
Signed-off-by: dusan <borovcanindusan1@gmail.com>
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package cache
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/absmach/magistrala/auth"
|
|
"github.com/absmach/magistrala/pkg/errors"
|
|
repoerr "github.com/absmach/magistrala/pkg/errors/repository"
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type patCache struct {
|
|
client *redis.Client
|
|
duration time.Duration
|
|
}
|
|
|
|
func NewPatsCache(client *redis.Client, duration time.Duration) auth.Cache {
|
|
return &patCache{
|
|
client: client,
|
|
duration: duration,
|
|
}
|
|
}
|
|
|
|
func (pc *patCache) Save(ctx context.Context, userID string, scopes []auth.Scope) error {
|
|
for _, sc := range scopes {
|
|
key := generateKey(userID, sc.PatID, sc.DomainID, sc.EntityType, sc.Operation, sc.EntityID)
|
|
if err := pc.client.Set(ctx, key, sc.ID, pc.duration).Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrCreateEntity, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (pc *patCache) CheckScope(ctx context.Context, userID, patID, domainID string, entityType auth.EntityType, operation string, entityID string) bool {
|
|
exactKey := fmt.Sprintf("pat:%s:%s:%s:%s:%s:%s", userID, patID, entityType, domainID, operation, entityID)
|
|
wildcardKey := fmt.Sprintf("pat:%s:%s:%s:%s:%s:*", userID, patID, entityType, domainID, operation)
|
|
|
|
res, err := pc.client.Exists(ctx, exactKey, wildcardKey).Result()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return res > 0
|
|
}
|
|
|
|
func (pc *patCache) Remove(ctx context.Context, userID string, scopeIDs []string) error {
|
|
if len(scopeIDs) == 0 {
|
|
return repoerr.ErrRemoveEntity
|
|
}
|
|
|
|
pattern := fmt.Sprintf("pat:%s:*", userID)
|
|
iter := pc.client.Scan(ctx, 0, pattern, 0).Iterator()
|
|
|
|
for iter.Next(ctx) {
|
|
key := iter.Val()
|
|
val, err := pc.client.Get(ctx, key).Result()
|
|
if err != nil {
|
|
if err == redis.Nil {
|
|
continue
|
|
}
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
|
|
for _, scopeID := range scopeIDs {
|
|
if val == scopeID {
|
|
if err := pc.client.Del(ctx, key).Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := iter.Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (pc *patCache) RemoveUserAllScope(ctx context.Context, userID string) error {
|
|
pattern := fmt.Sprintf("pat:%s:*", userID)
|
|
iter := pc.client.Scan(ctx, 0, pattern, 0).Iterator()
|
|
for iter.Next(ctx) {
|
|
if err := pc.client.Del(ctx, iter.Val()).Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
}
|
|
if err := iter.Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (pc *patCache) RemoveAllScope(ctx context.Context, userID, patID string) error {
|
|
pattern := fmt.Sprintf("pat:%s:%s", userID, patID)
|
|
|
|
iter := pc.client.Scan(ctx, 0, pattern, 0).Iterator()
|
|
for iter.Next(ctx) {
|
|
if err := pc.client.Del(ctx, iter.Val()).Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
}
|
|
|
|
if err := iter.Err(); err != nil {
|
|
return errors.Wrap(repoerr.ErrRemoveEntity, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func generateKey(userID, patID, domainId string, entityType auth.EntityType, operation string, entityID string) string {
|
|
return fmt.Sprintf("pat:%s:%s:%s:%s:%s:%s", userID, patID, entityType, domainId, operation, entityID)
|
|
}
|