Skip to content

Commit

Permalink
feat(serviceAccounts): enable customization of service account resour…
Browse files Browse the repository at this point in the history
…ce provider (#668)

introduces BaseServiceAccountResourceProvider to capture service account specific
access checks"
  • Loading branch information
cfieber committed May 5, 2020
1 parent 31ede09 commit 0d58386
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.netflix.spinnaker.fiat.providers;

import com.netflix.spinnaker.fiat.config.FiatRoleConfig;
import com.netflix.spinnaker.fiat.model.resources.Role;
import com.netflix.spinnaker.fiat.model.resources.ServiceAccount;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.NonNull;

public abstract class BaseServiceAccountResourceProvider
extends BaseResourceProvider<ServiceAccount> {
private final FiatRoleConfig fiatRoleConfig;

public BaseServiceAccountResourceProvider(FiatRoleConfig fiatRoleConfig) {
this.fiatRoleConfig = fiatRoleConfig;
}

@Override
public Set<ServiceAccount> getAllRestricted(@NonNull Set<Role> roles, boolean isAdmin)
throws ProviderException {
List<String> roleNames = roles.stream().map(Role::getName).collect(Collectors.toList());
return getAll().stream()
.filter(svcAcct -> !svcAcct.getMemberOf().isEmpty())
.filter(getServiceAccountPredicate(isAdmin, roleNames))
.collect(Collectors.toSet());
}

private Predicate<ServiceAccount> getServiceAccountPredicate(
boolean isAdmin, List<String> roleNames) {
if (isAdmin) {
return svcAcct -> true;
}
if (fiatRoleConfig.isOrMode()) {
return svcAcct -> svcAcct.getMemberOf().stream().anyMatch(roleNames::contains);
} else {
return svcAcct -> roleNames.containsAll(svcAcct.getMemberOf());
}
}

@Override
public Set<ServiceAccount> getAllUnrestricted() throws ProviderException {
return Collections.emptySet();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,21 @@
package com.netflix.spinnaker.fiat.providers;

import com.netflix.spinnaker.fiat.config.FiatRoleConfig;
import com.netflix.spinnaker.fiat.model.resources.Role;
import com.netflix.spinnaker.fiat.model.resources.ServiceAccount;
import com.netflix.spinnaker.fiat.providers.internal.Front50Service;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class DefaultServiceAccountResourceProvider extends BaseResourceProvider<ServiceAccount>
implements ResourceProvider<ServiceAccount> {
public class DefaultServiceAccountResourceProvider extends BaseServiceAccountResourceProvider {

private final Front50Service front50Service;

private final FiatRoleConfig fiatRoleConfig;

@Autowired
public DefaultServiceAccountResourceProvider(
Front50Service front50Service, FiatRoleConfig fiatRoleConfig) {
super();
super(fiatRoleConfig);
this.front50Service = front50Service;
this.fiatRoleConfig = fiatRoleConfig;
}

@Override
Expand All @@ -56,31 +42,4 @@ protected Set<ServiceAccount> loadAll() throws ProviderException {
throw new ProviderException(this.getClass(), e.getCause());
}
}

@Override
public Set<ServiceAccount> getAllRestricted(@NonNull Set<Role> roles, boolean isAdmin)
throws ProviderException {
List<String> roleNames = roles.stream().map(Role::getName).collect(Collectors.toList());
return getAll().stream()
.filter(svcAcct -> !svcAcct.getMemberOf().isEmpty())
.filter(getServiceAccountPredicate(isAdmin, roleNames))
.collect(Collectors.toSet());
}

private Predicate<ServiceAccount> getServiceAccountPredicate(
boolean isAdmin, List<String> roleNames) {
if (isAdmin) {
return svcAcct -> true;
}
if (fiatRoleConfig.isOrMode()) {
return svcAcct -> svcAcct.getMemberOf().stream().anyMatch(roleNames::contains);
} else {
return svcAcct -> roleNames.containsAll(svcAcct.getMemberOf());
}
}

@Override
public Set<ServiceAccount> getAllUnrestricted() throws ProviderException {
return Collections.emptySet();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.netflix.spinnaker.fiat.permissions.ExternalUser;
import com.netflix.spinnaker.fiat.permissions.FallbackPermissionsResolver;
import com.netflix.spinnaker.fiat.providers.DefaultApplicationResourceProvider;
import com.netflix.spinnaker.fiat.providers.DefaultServiceAccountResourceProvider;
import com.netflix.spinnaker.fiat.providers.ResourcePermissionProvider;
import com.netflix.spinnaker.fiat.providers.internal.ClouddriverService;
import com.netflix.spinnaker.fiat.providers.internal.Front50Service;
Expand All @@ -24,6 +25,7 @@
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -88,6 +90,15 @@ DefaultApplicationResourceProvider applicationProvider(
properties.isAllowAccessToUnknownApplications());
}

@Bean
@ConditionalOnProperty(
value = "fiat.service-account-resource-provider.default.enabled",
matchIfMissing = true)
DefaultServiceAccountResourceProvider serviceAccountResourceProvider(
Front50Service front50Service, FiatRoleConfig fiatRoleConfig) {
return new DefaultServiceAccountResourceProvider(front50Service, fiatRoleConfig);
}

@Bean
DefaultFallbackPermissionsResolver executeFallbackPermissionsResolver(
FiatServerConfigurationProperties properties) {
Expand Down

0 comments on commit 0d58386

Please sign in to comment.