Skip to content

Commit 432777a

Browse files
author
Travis Tomsu
authored
Adds ability to hardcode group membership to service accounts. This is especially useful in SAML environments, where neither Fiat nor Gate can reach out to an external service to resolve roles/permissions. (#128)
1 parent 8e8beff commit 432777a

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

fiat-core/src/main/java/com/netflix/spinnaker/fiat/model/resources/ServiceAccount.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,31 @@
1717
package com.netflix.spinnaker.fiat.model.resources;
1818

1919
import com.fasterxml.jackson.annotation.JsonIgnore;
20+
import com.netflix.spinnaker.fiat.model.UserPermission;
2021
import lombok.Data;
2122
import lombok.EqualsAndHashCode;
2223
import lombok.NoArgsConstructor;
24+
import lombok.val;
2325
import org.apache.commons.lang3.StringUtils;
2426

27+
import java.util.ArrayList;
2528
import java.util.Collections;
2629
import java.util.List;
30+
import java.util.stream.Collectors;
2731

2832
@Data
2933
public class ServiceAccount implements GroupAccessControlled, Viewable {
3034
private final ResourceType resourceType = ResourceType.SERVICE_ACCOUNT;
3135

3236
private String name;
37+
private List<String> memberOf = new ArrayList<>();
38+
39+
public UserPermission toUserPermission() {
40+
val roles = memberOf.stream()
41+
.map(membership -> new Role(membership).setSource(Role.Source.EXTERNAL))
42+
.collect(Collectors.toSet());
43+
return new UserPermission().setId(name).setRoles(roles);
44+
}
3345

3446
@JsonIgnore
3547
public List<String> getRequiredGroupMembership() {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2017 Google, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License")
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.netflix.spinnaker.fiat.model.resources
18+
19+
import spock.lang.Specification
20+
21+
class ServiceAccountSpec extends Specification {
22+
23+
def 'should convert to UserPermission'() {
24+
setup:
25+
ServiceAccount acct = new ServiceAccount().setName("my-svc-acct")
26+
.setMemberOf(["foo", "bar"])
27+
28+
when:
29+
def result = acct.toUserPermission()
30+
31+
then:
32+
result.id == "my-svc-acct"
33+
result.roles.containsAll([
34+
new Role("foo").setSource(Role.Source.EXTERNAL),
35+
new Role("bar").setSource(Role.Source.EXTERNAL)
36+
])
37+
}
38+
}

fiat-roles/src/main/java/com/netflix/spinnaker/fiat/roles/UserRolesSyncer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.netflix.spinnaker.fiat.config.UnrestrictedResourceConfig;
2222
import com.netflix.spinnaker.fiat.model.UserPermission;
2323
import com.netflix.spinnaker.fiat.model.resources.Role;
24+
import com.netflix.spinnaker.fiat.model.resources.ServiceAccount;
2425
import com.netflix.spinnaker.fiat.permissions.ExternalUser;
2526
import com.netflix.spinnaker.fiat.permissions.PermissionResolutionException;
2627
import com.netflix.spinnaker.fiat.permissions.PermissionsRepository;
@@ -134,7 +135,7 @@ private Map<String, UserPermission> getServiceAccountsAsMap() {
134135
return serviceAccountProvider
135136
.getAll()
136137
.stream()
137-
.map(serviceAccount -> new UserPermission().setId(serviceAccount.getName()))
138+
.map(ServiceAccount::toUserPermission)
138139
.collect(Collectors.toMap(UserPermission::getId, Functions.identity()));
139140
}
140141

fiat-roles/src/test/groovy/com/netflix/spinnaker/fiat/permissions/RedisPermissionsRepositorySpec.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class RedisPermissionsRepositorySpec extends Specification {
9898
jedis.hgetAll("unittests:permissions:testUser:applications") ==
9999
['app': '{"name":"app","requiredGroupMembership":[]}']
100100
jedis.hgetAll("unittests:permissions:testUser:service_accounts") ==
101-
['serviceAccount': '{"name":"serviceAccount"}']
101+
['serviceAccount': '{"name":"serviceAccount","memberOf":[]}']
102102
jedis.hgetAll("unittests:permissions:testUser:roles") ==
103103
['role1': '{"name":"role1"}']
104104
}

0 commit comments

Comments
 (0)