Search in sources :

Example 1 with Authorization

use of com.netflix.spinnaker.fiat.model.Authorization in project fiat by spinnaker.

the class ApplicationResourcePermissionSource method getPermissions.

@Override
@Nonnull
public Permissions getPermissions(@Nonnull Application resource) {
    Permissions storedPermissions = resource.getPermissions();
    if (storedPermissions == null || !storedPermissions.isRestricted()) {
        return Permissions.EMPTY;
    }
    Map<Authorization, Set<String>> authorizations = Arrays.stream(Authorization.values()).collect(toMap(identity(), storedPermissions::get));
    // CREATE permissions are not allowed on the resource level.
    authorizations.remove(Authorization.CREATE);
    return Permissions.Builder.factory(authorizations).build();
}
Also used : Authorization(com.netflix.spinnaker.fiat.model.Authorization) Set(java.util.Set) Permissions(com.netflix.spinnaker.fiat.model.resources.Permissions) Nonnull(javax.annotation.Nonnull)

Example 2 with Authorization

use of com.netflix.spinnaker.fiat.model.Authorization in project fiat by spinnaker.

the class FiatPermissionEvaluator method permissionContains.

private boolean permissionContains(UserPermission.View permission, String resourceName, ResourceType resourceType, Authorization authorization) {
    if (permission == null) {
        return false;
    }
    if (permission.isAdmin()) {
        // grant access regardless of whether an explicit permission to the resource exists
        return true;
    }
    Function<Set<? extends Authorizable>, Boolean> containsAuth = resources -> resources.stream().anyMatch(view -> {
        Set<Authorization> authorizations = Optional.ofNullable(view.getAuthorizations()).orElse(Collections.emptySet());
        return view.getName().equalsIgnoreCase(resourceName) && authorizations.contains(authorization);
    });
    if (resourceType.equals(ResourceType.ACCOUNT)) {
        boolean authorized = containsAuth.apply(permission.getAccounts());
        // Todo(jonsie): Debug transitory access denied issue, remove when not necessary
        if (!authorized) {
            Map<String, Set<Authorization>> accounts = permission.getAccounts().stream().collect(Collectors.toMap(Account.View::getName, Account.View::getAuthorizations));
            log.debug("Authorization={} denied to account={} for user permission={}, found={}", authorization.toString(), resourceName, permission.getName(), accounts.toString());
        }
        return authorized;
    } else if (resourceType.equals(ResourceType.APPLICATION)) {
        boolean applicationHasPermissions = permission.getApplications().stream().anyMatch(a -> a.getName().equalsIgnoreCase(resourceName));
        if (!applicationHasPermissions && permission.isAllowAccessToUnknownApplications()) {
            // allow access to any applications w/o explicit permissions
            return true;
        }
        return permission.isLegacyFallback() || containsAuth.apply(permission.getApplications());
    } else if (resourceType.equals(ResourceType.SERVICE_ACCOUNT)) {
        return permission.getServiceAccounts().stream().anyMatch(view -> view.getName().equalsIgnoreCase(resourceName));
    } else if (resourceType.equals(ResourceType.BUILD_SERVICE)) {
        return permission.isLegacyFallback() || containsAuth.apply(permission.getBuildServices());
    } else if (permission.getExtensionResources() != null && permission.getExtensionResources().containsKey(resourceType)) {
        val extensionResources = permission.getExtensionResources().get(resourceType);
        return permission.isLegacyFallback() || containsAuth.apply(extensionResources);
    } else {
        return false;
    }
}
Also used : Arrays(java.util.Arrays) Authorizable(com.netflix.spinnaker.fiat.model.resources.Authorizable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Autowired(org.springframework.beans.factory.annotation.Autowired) Callable(java.util.concurrent.Callable) ExponentialBackOff(org.springframework.util.backoff.ExponentialBackOff) Cache(com.github.benmanes.caffeine.cache.Cache) Id(com.netflix.spectator.api.Id) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) StringUtils(org.apache.commons.lang3.StringUtils) Map(java.util.Map) UserDetails(org.springframework.security.core.userdetails.UserDetails) SecurityContextHolder(org.springframework.security.core.context.SecurityContextHolder) Nonnull(javax.annotation.Nonnull) Caffeine(com.github.benmanes.caffeine.cache.Caffeine) AuthenticatedRequest(com.netflix.spinnaker.security.AuthenticatedRequest) BackOffExecution(org.springframework.util.backoff.BackOffExecution) lombok.val(lombok.val) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) Set(java.util.Set) PermissionEvaluator(org.springframework.security.access.PermissionEvaluator) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) TimeUnit(java.util.concurrent.TimeUnit) HttpStatus(org.springframework.http.HttpStatus) Slf4j(lombok.extern.slf4j.Slf4j) Component(org.springframework.stereotype.Component) CaffeineStatsCounter(com.netflix.spinnaker.kork.telemetry.caffeine.CaffeineStatsCounter) RetrofitError(retrofit.RetrofitError) IntegrationException(com.netflix.spinnaker.kork.exceptions.IntegrationException) Registry(com.netflix.spectator.api.Registry) Optional(java.util.Optional) Account(com.netflix.spinnaker.fiat.model.resources.Account) UserPermission(com.netflix.spinnaker.fiat.model.UserPermission) Authorization(com.netflix.spinnaker.fiat.model.Authorization) Authentication(org.springframework.security.core.Authentication) Collections(java.util.Collections) Authorization(com.netflix.spinnaker.fiat.model.Authorization) lombok.val(lombok.val) Account(com.netflix.spinnaker.fiat.model.resources.Account) Set(java.util.Set) Authorizable(com.netflix.spinnaker.fiat.model.resources.Authorizable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 3 with Authorization

use of com.netflix.spinnaker.fiat.model.Authorization in project fiat by spinnaker.

the class AuthorizeController method getUserAuthorization.

@RequestMapping(value = "/{userId:.+}/{resourceType:.+}/{resourceName:.+}/{authorization:.+}", method = RequestMethod.GET)
public void getUserAuthorization(@PathVariable String userId, @PathVariable String resourceType, @PathVariable String resourceName, @PathVariable String authorization, HttpServletResponse response) throws IOException {
    Authorization a = Authorization.valueOf(authorization.toUpperCase());
    ResourceType r = ResourceType.parse(resourceType);
    Set<Authorization> authorizations = new HashSet<>(0);
    try {
        if (r.equals(ResourceType.ACCOUNT)) {
            authorizations = getUserAccount(userId, resourceName).getAuthorizations();
        } else if (r.equals(ResourceType.APPLICATION)) {
            authorizations = getUserApplication(userId, resourceName).getAuthorizations();
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Resource type " + resourceType + " does not contain authorizations");
            return;
        }
    } catch (NotFoundException nfe) {
    // Ignore. Will return 404 below.
    }
    if (authorizations.contains(a)) {
        response.setStatus(HttpServletResponse.SC_OK);
        return;
    }
    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
Also used : Authorization(com.netflix.spinnaker.fiat.model.Authorization) NotFoundException(com.netflix.spinnaker.kork.web.exceptions.NotFoundException)

Example 4 with Authorization

use of com.netflix.spinnaker.fiat.model.Authorization in project fiat by spinnaker.

the class FiatPermissionEvaluator method hasPermission.

public boolean hasPermission(String username, Serializable resourceName, String resourceType, Object authorization) {
    if (!fiatStatus.isEnabled()) {
        return true;
    }
    if (resourceName == null || resourceType == null || authorization == null) {
        log.warn("Permission denied because at least one of the required arguments was null. resourceName={}, resourceType={}, " + "authorization={}", resourceName, resourceType, authorization);
        return false;
    }
    ResourceType r = ResourceType.parse(resourceType);
    Authorization a = null;
    // Service accounts don't have read/write authorizations.
    if (!r.equals(ResourceType.SERVICE_ACCOUNT)) {
        a = Authorization.valueOf(authorization.toString());
    }
    if (a == Authorization.CREATE) {
        throw new IllegalArgumentException("This method should not be called for `CREATE`. Please call the other implementation");
    }
    if (r.equals(ResourceType.APPLICATION) && StringUtils.isNotEmpty(resourceName.toString())) {
        resourceName = resourceName.toString();
    }
    UserPermission.View permission = getPermission(username);
    boolean hasPermission = permissionContains(permission, resourceName.toString(), r, a);
    authorizationFailure.set(hasPermission ? null : new AuthorizationFailure(a, r, resourceName.toString()));
    if (permission != null && permission.isLegacyFallback() && hasPermission) {
        // log any access that was granted as part of a legacy fallback.
        if (a == Authorization.READ) {
            // purposely logging at 'debug' as 'READ' will be sufficiently more verbose
            log.debug("Legacy fallback granted {} access (type: {}, resource: {})", a, r, resourceName);
        } else {
            log.warn("Legacy fallback granted {} access (type: {}, resource: {})", a, r, resourceName);
        }
    }
    return hasPermission;
}
Also used : Authorization(com.netflix.spinnaker.fiat.model.Authorization) ResourceType(com.netflix.spinnaker.fiat.model.resources.ResourceType) UserPermission(com.netflix.spinnaker.fiat.model.UserPermission)

Aggregations

Authorization (com.netflix.spinnaker.fiat.model.Authorization)4 UserPermission (com.netflix.spinnaker.fiat.model.UserPermission)2 ResourceType (com.netflix.spinnaker.fiat.model.resources.ResourceType)2 Set (java.util.Set)2 Nonnull (javax.annotation.Nonnull)2 Cache (com.github.benmanes.caffeine.cache.Cache)1 Caffeine (com.github.benmanes.caffeine.cache.Caffeine)1 Id (com.netflix.spectator.api.Id)1 Registry (com.netflix.spectator.api.Registry)1 Account (com.netflix.spinnaker.fiat.model.resources.Account)1 Authorizable (com.netflix.spinnaker.fiat.model.resources.Authorizable)1 Permissions (com.netflix.spinnaker.fiat.model.resources.Permissions)1 IntegrationException (com.netflix.spinnaker.kork.exceptions.IntegrationException)1 CaffeineStatsCounter (com.netflix.spinnaker.kork.telemetry.caffeine.CaffeineStatsCounter)1 NotFoundException (com.netflix.spinnaker.kork.web.exceptions.NotFoundException)1 AuthenticatedRequest (com.netflix.spinnaker.security.AuthenticatedRequest)1 Serializable (java.io.Serializable)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Map (java.util.Map)1