Search in sources :

Example 1 with Resource

use of com.netflix.spinnaker.fiat.model.resources.Resource in project fiat by spinnaker.

the class RedisPermissionsRepository method getFromRedis.

private Optional<UserPermission> getFromRedis(@NonNull String id) {
    try {
        TimeoutContext timeoutContext = new TimeoutContext(String.format("getPermission for user: %s", id), clock, configProps.getRepository().getGetPermissionTimeout());
        boolean userExists = UNRESTRICTED.equals(id) || redisRead(timeoutContext, c -> c.sismember(allUsersKey, SafeEncoder.encode(id)));
        if (!userExists) {
            log.debug("request for user {} not found in redis", id);
            return Optional.empty();
        }
        UserPermission userPermission = new UserPermission().setId(id);
        for (Resource r : resources) {
            ResourceType resourceType = r.getResourceType();
            Map<String, Resource> resourcePermissions = getUserResourceMapFromRedis(id, resourceType);
            if (resourcePermissions != null && !resourcePermissions.isEmpty()) {
                userPermission.addResources(resourcePermissions.values());
            }
        }
        if (!UNRESTRICTED.equals(id)) {
            userPermission.setAdmin(redisRead(timeoutContext, c -> c.sismember(adminKey, SafeEncoder.encode(id))));
            userPermission.merge(getUnrestrictedUserPermission());
        }
        return Optional.of(userPermission);
    } catch (Throwable t) {
        String message = String.format("Storage exception reading %s entry.", id);
        log.error(message, t);
        if (t instanceof SpinnakerException) {
            throw (SpinnakerException) t;
        }
        throw new PermissionReadException(message, t);
    }
}
Also used : java.util(java.util) net.jpountz.lz4(net.jpountz.lz4) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) BinaryJedisCommands(redis.clients.jedis.commands.BinaryJedisCommands) SafeEncoder(redis.clients.jedis.util.SafeEncoder) redis.clients.jedis(redis.clients.jedis) Duration(java.time.Duration) TypeReference(com.fasterxml.jackson.core.type.TypeReference) RetryRegistry(io.github.resilience4j.retry.RetryRegistry) RedisClientDelegate(com.netflix.spinnaker.kork.jedis.RedisClientDelegate) Caffeine(com.github.benmanes.caffeine.cache.Caffeine) LoadingCache(com.github.benmanes.caffeine.cache.LoadingCache) NonNull(lombok.NonNull) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) IOException(java.io.IOException) UnrestrictedResourceConfig(com.netflix.spinnaker.fiat.config.UnrestrictedResourceConfig) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ExecutionException(java.util.concurrent.ExecutionException) Resource(com.netflix.spinnaker.fiat.model.resources.Resource) Slf4j(lombok.extern.slf4j.Slf4j) IntegrationException(com.netflix.spinnaker.kork.exceptions.IntegrationException) ForkJoinPool(java.util.concurrent.ForkJoinPool) Role(com.netflix.spinnaker.fiat.model.resources.Role) Clock(java.time.Clock) SpinnakerException(com.netflix.spinnaker.kork.exceptions.SpinnakerException) UserPermission(com.netflix.spinnaker.fiat.model.UserPermission) SpinnakerException(com.netflix.spinnaker.kork.exceptions.SpinnakerException) Resource(com.netflix.spinnaker.fiat.model.resources.Resource) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) UserPermission(com.netflix.spinnaker.fiat.model.UserPermission)

Example 2 with Resource

use of com.netflix.spinnaker.fiat.model.resources.Resource in project fiat by spinnaker.

the class RedisPermissionsRepository method put.

@Override
public RedisPermissionsRepository put(@NonNull UserPermission permission) {
    String userId = permission.getId();
    byte[] bUserId = SafeEncoder.encode(userId);
    List<ResourceType> resourceTypes = resources.stream().map(Resource::getResourceType).collect(Collectors.toList());
    Map<ResourceType, Map<String, Resource>> resourceTypeToRedisValue = new HashMap<>(resourceTypes.size());
    permission.getAllResources().forEach(resource -> {
        resourceTypeToRedisValue.computeIfAbsent(resource.getResourceType(), key -> new HashMap<>()).put(resource.getName(), resource);
    });
    try {
        Set<Role> existingRoles = new HashSet<>(getUserRoleMapFromRedis(userId).values());
        // These updates are pre-prepared to reduce work done during the multi-key pipeline
        List<PutUpdateData> updateData = new ArrayList<>();
        for (ResourceType rt : resourceTypes) {
            Map<String, Resource> redisValue = resourceTypeToRedisValue.get(rt);
            byte[] userResourceKey = userKey(userId, rt);
            PutUpdateData pud = new PutUpdateData();
            pud.userResourceKey = userResourceKey;
            if (redisValue == null || redisValue.size() == 0) {
                pud.compressedData = null;
            } else {
                pud.compressedData = lz4Compressor.compress(objectMapper.writeValueAsBytes(redisValue));
            }
            updateData.add(pud);
        }
        AtomicReference<Response<List<String>>> serverTime = new AtomicReference<>();
        redisClientDelegate.withMultiKeyPipeline(pipeline -> {
            if (permission.isAdmin()) {
                pipeline.sadd(adminKey, bUserId);
            } else {
                pipeline.srem(adminKey, bUserId);
            }
            permission.getRoles().forEach(role -> pipeline.sadd(roleKey(role), bUserId));
            existingRoles.stream().filter(it -> !permission.getRoles().contains(it)).forEach(role -> pipeline.srem(roleKey(role), bUserId));
            for (PutUpdateData pud : updateData) {
                if (pud.compressedData == null) {
                    pipeline.del(pud.userResourceKey);
                } else {
                    byte[] tempKey = SafeEncoder.encode(UUID.randomUUID().toString());
                    pipeline.set(tempKey, pud.compressedData);
                    pipeline.rename(tempKey, pud.userResourceKey);
                }
            }
            serverTime.set(pipeline.time());
            pipeline.sadd(allUsersKey, bUserId);
            pipeline.sync();
        });
        if (UNRESTRICTED.equals(userId)) {
            String lastModified = serverTime.get().get().get(0);
            redisClientDelegate.withCommandsClient(c -> {
                log.debug("set last modified for user {} to {}", UNRESTRICTED, lastModified);
                c.set(unrestrictedLastModifiedKey(), lastModified);
            });
        }
    } catch (Exception e) {
        log.error("Storage exception writing {} entry.", userId, e);
    }
    return this;
}
Also used : java.util(java.util) net.jpountz.lz4(net.jpountz.lz4) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) BinaryJedisCommands(redis.clients.jedis.commands.BinaryJedisCommands) SafeEncoder(redis.clients.jedis.util.SafeEncoder) redis.clients.jedis(redis.clients.jedis) Duration(java.time.Duration) TypeReference(com.fasterxml.jackson.core.type.TypeReference) RetryRegistry(io.github.resilience4j.retry.RetryRegistry) RedisClientDelegate(com.netflix.spinnaker.kork.jedis.RedisClientDelegate) Caffeine(com.github.benmanes.caffeine.cache.Caffeine) LoadingCache(com.github.benmanes.caffeine.cache.LoadingCache) NonNull(lombok.NonNull) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) IOException(java.io.IOException) UnrestrictedResourceConfig(com.netflix.spinnaker.fiat.config.UnrestrictedResourceConfig) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ExecutionException(java.util.concurrent.ExecutionException) Resource(com.netflix.spinnaker.fiat.model.resources.Resource) Slf4j(lombok.extern.slf4j.Slf4j) IntegrationException(com.netflix.spinnaker.kork.exceptions.IntegrationException) ForkJoinPool(java.util.concurrent.ForkJoinPool) Role(com.netflix.spinnaker.fiat.model.resources.Role) Clock(java.time.Clock) SpinnakerException(com.netflix.spinnaker.kork.exceptions.SpinnakerException) UserPermission(com.netflix.spinnaker.fiat.model.UserPermission) Resource(com.netflix.spinnaker.fiat.model.resources.Resource) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) IntegrationException(com.netflix.spinnaker.kork.exceptions.IntegrationException) SpinnakerException(com.netflix.spinnaker.kork.exceptions.SpinnakerException) Role(com.netflix.spinnaker.fiat.model.resources.Role)

Aggregations

TypeReference (com.fasterxml.jackson.core.type.TypeReference)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 Caffeine (com.github.benmanes.caffeine.cache.Caffeine)2 LoadingCache (com.github.benmanes.caffeine.cache.LoadingCache)2 UnrestrictedResourceConfig (com.netflix.spinnaker.fiat.config.UnrestrictedResourceConfig)2 UserPermission (com.netflix.spinnaker.fiat.model.UserPermission)2 Resource (com.netflix.spinnaker.fiat.model.resources.Resource)2 ResourceType (com.netflix.spinnaker.fiat.model.resources.ResourceType)2 Role (com.netflix.spinnaker.fiat.model.resources.Role)2 IntegrationException (com.netflix.spinnaker.kork.exceptions.IntegrationException)2 SpinnakerException (com.netflix.spinnaker.kork.exceptions.SpinnakerException)2 RedisClientDelegate (com.netflix.spinnaker.kork.jedis.RedisClientDelegate)2 RetryRegistry (io.github.resilience4j.retry.RetryRegistry)2 IOException (java.io.IOException)2 Clock (java.time.Clock)2 Duration (java.time.Duration)2 Instant (java.time.Instant)2 java.util (java.util)2 ExecutionException (java.util.concurrent.ExecutionException)2 ForkJoinPool (java.util.concurrent.ForkJoinPool)2