Skip to content

Commit

Permalink
Adds service account endpoints + ability for fiat-api module to verif…
Browse files Browse the repository at this point in the history
…y service account authorization. (#108)
  • Loading branch information
Travis Tomsu committed Nov 1, 2016
1 parent f004e6a commit 67282d6
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ public boolean hasPermission(Authentication authentication,

String username = getUsername(authentication);
ResourceType r = ResourceType.parse(resourceType);
Authorization a = Authorization.valueOf(authorization.toString());
Authorization a = null;
// Service accounts don't have read/write authorizations.
if (r != ResourceType.SERVICE_ACCOUNT) {
a = Authorization.valueOf(authorization.toString());
}

if (r == ResourceType.APPLICATION) {
val parsedName = Names.parseName(resourceName.toString()).getApp();
Expand Down Expand Up @@ -184,6 +188,10 @@ private boolean permissionContains(Authentication authentication,
return containsAuth.apply(permission.getAccounts());
case APPLICATION:
return containsAuth.apply(permission.getApplications());
case SERVICE_ACCOUNT:
return permission.getServiceAccounts()
.stream()
.anyMatch(view -> view.getName().equalsIgnoreCase(resourceName));
default:
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.netflix.spinnaker.fiat.model.resources.Account;
import com.netflix.spinnaker.fiat.model.resources.Application;
import com.netflix.spinnaker.fiat.model.resources.ResourceType;
import com.netflix.spinnaker.fiat.model.resources.ServiceAccount;
import com.netflix.spinnaker.fiat.permissions.PermissionsRepository;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -92,6 +93,53 @@ public Account.View getUserAccount(@PathVariable String userId, @PathVariable St
.orElseThrow(NotFoundException::new);
}

@RequestMapping(value = "/{userId:.+}/applications", method = RequestMethod.GET)
public Set<Application.View> getUserApplications(@PathVariable String userId) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getApplications()
.stream()
.map(Application::getView)
.collect(Collectors.toSet());
}

@RequestMapping(value = "/{userId:.+}/applications/{applicationName:.+}", method = RequestMethod.GET)
public Application.View getUserApplication(@PathVariable String userId, @PathVariable String applicationName) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getApplications()
.stream()
.filter(application -> applicationName.equalsIgnoreCase(application.getName()))
.findFirst()
.map(Application::getView)
.orElseThrow(NotFoundException::new);
}

@RequestMapping(value = "/{userId:.+}/serviceAccounts", method = RequestMethod.GET)
public Set<ServiceAccount.View> getServiceAccounts(@PathVariable String userId) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getServiceAccounts()
.stream()
.map(ServiceAccount::getView)
.collect(Collectors.toSet());
}

@RequestMapping(value = "/{userId:.+}/serviceAccounts/{serviceAccountName:.+}", method = RequestMethod.GET)
public ServiceAccount.View getServiceAccount(@PathVariable String userId,
@PathVariable String serviceAccountName) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getServiceAccounts()
.stream()
.filter(serviceAccount ->
serviceAccount.getName()
.equalsIgnoreCase(ControllerSupport.convert(serviceAccountName)))
.findFirst()
.orElseThrow(NotFoundException::new)
.getView();
}

@RequestMapping(value = "/{userId:.+}/{resourceType:.+}/{resourceName:.+}/{authorization:.+}", method = RequestMethod.GET)
public void getUserAuthorization(@PathVariable String userId,
@PathVariable String resourceType,
Expand Down Expand Up @@ -126,26 +174,4 @@ public void getUserAuthorization(@PathVariable String userId,

response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}

@RequestMapping(value = "/{userId:.+}/applications", method = RequestMethod.GET)
public Set<Application.View> getUserApplications(@PathVariable String userId) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getApplications()
.stream()
.map(Application::getView)
.collect(Collectors.toSet());
}

@RequestMapping(value = "/{userId:.+}/applications/{applicationName:.+}", method = RequestMethod.GET)
public Application.View getUserApplication(@PathVariable String userId, @PathVariable String applicationName) {
return permissionsRepository.get(ControllerSupport.convert(userId))
.orElseThrow(NotFoundException::new)
.getApplications()
.stream()
.filter(application -> applicationName.equalsIgnoreCase(application.getName()))
.findFirst()
.map(Application::getView)
.orElseThrow(NotFoundException::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,26 @@ class AuthorizeControllerSpec extends Specification {
1 * repository.get("foo") >> Optional.of(foo)
result == bar.view
}

def "should get service accounts from repo"() {
setup:
permissionsRepository.put(unrestrictedUser)
permissionsRepository.put(roleServiceAccountUser)

when:
def expected = objectMapper.writeValueAsString([serviceAccount.view])

then:
mockMvc.perform(get("/authorize/roleServiceAccountUser/serviceAccounts"))
.andExpect(status().isOk())
.andExpect(content().json(expected))

when:
expected = objectMapper.writeValueAsString(serviceAccount.view)

then:
mockMvc.perform(get("/authorize/roleServiceAccountUser/serviceAccounts/svcAcct%40group.com"))
.andExpect(status().isOk())
.andExpect(content().json(expected))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ class FiatSystemTestSupport {
.setRoles([roleA, roleB] as Set)
.setAccounts([restrictedAccount] as Set)
.setApplications([restrictedApp] as Set)

UserPermission roleServiceAccountUser = new UserPermission().setId("roleServiceAccountUser")
.setRoles([roleServiceAccount] as Set)
.setServiceAccounts([serviceAccount] as Set)
}

0 comments on commit 67282d6

Please sign in to comment.