Skip to content

Commit 140a447

Browse files
author
Travis Tomsu
authored
Adds Frigga name parsing if the specified resource is an application. This helps when authorizing other objects that conform to the naming convention (namely load balancers, server groups, and instances). (#64)
1 parent de158b3 commit 140a447

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

fiat-api/fiat-api.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies {
2222
compile spinnaker.dependency("korkSecurity")
2323
compile spinnaker.dependency("bootActuator")
2424
compile spinnaker.dependency("bootWeb")
25+
compile spinnaker.dependency('frigga')
2526

2627
compile spinnaker.dependency("springSecurityConfig")
2728
compile spinnaker.dependency("springSecurityCore")

fiat-api/src/main/java/com/netflix/spinnaker/fiat/shared/FiatPermissionEvaluator.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616

1717
package com.netflix.spinnaker.fiat.shared;
1818

19+
import com.netflix.frigga.Names;
1920
import com.netflix.spinnaker.fiat.model.Authorization;
2021
import com.netflix.spinnaker.fiat.model.UserPermission;
2122
import com.netflix.spinnaker.fiat.model.resources.Authorizable;
2223
import com.netflix.spinnaker.fiat.model.resources.ResourceType;
2324
import lombok.Setter;
2425
import lombok.extern.slf4j.Slf4j;
26+
import lombok.val;
27+
import org.apache.commons.lang3.StringUtils;
2528
import org.springframework.beans.factory.annotation.Autowired;
2629
import org.springframework.beans.factory.annotation.Value;
2730
import org.springframework.security.access.PermissionEvaluator;
@@ -58,11 +61,22 @@ public boolean hasPermission(Authentication authentication, Serializable resourc
5861
if (!Boolean.valueOf(fiatEnabled)) {
5962
return true;
6063
}
64+
if (resourceName == null || resourceType == null || authorization == null) {
65+
return false;
66+
}
67+
6168

6269
String username = getUsername(authentication);
6370
ResourceType r = ResourceType.parse(resourceType);
6471
Authorization a = Authorization.valueOf(authorization.toString());
6572

73+
if (r == ResourceType.APPLICATION) {
74+
val parsedName = Names.parseName(resourceName.toString()).getApp();
75+
if (StringUtils.isNotEmpty(parsedName)) {
76+
resourceName = parsedName;
77+
}
78+
}
79+
6680
return isWholePermissionStored(authentication) ?
6781
permissionContains(authentication, resourceName.toString(), r, a) :
6882
isAuthorized(username, r, resourceName.toString(), a);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2016 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.shared
18+
19+
import com.netflix.spinnaker.fiat.model.resources.ResourceType
20+
import org.springframework.security.core.Authentication
21+
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
22+
import retrofit.RetrofitError
23+
import retrofit.client.Response
24+
import spock.lang.Specification
25+
import spock.lang.Unroll
26+
27+
class FiatPermissionEvaluatorSpec extends Specification {
28+
29+
@Unroll
30+
def "should parse application name"() {
31+
setup:
32+
FiatService fiatService = Mock(FiatService)
33+
FiatPermissionEvaluator evaluator = new FiatPermissionEvaluator(fiatEnabled: true,
34+
fiatService: fiatService);
35+
36+
Authentication authentication = new PreAuthenticatedAuthenticationToken("testUser",
37+
null,
38+
new ArrayList<>());
39+
40+
when:
41+
def result = evaluator.hasPermission(authentication,
42+
resource,
43+
resourceType.name(),
44+
authorization)
45+
46+
then:
47+
1 * fiatService.hasAuthorization("testUser", resourceType.name(), resourceName, authorization) >> {
48+
throw RetrofitError.httpError(
49+
"/",
50+
new Response("/", 404, "not found", Collections.emptyList(), null),
51+
null,
52+
null)
53+
}
54+
!result
55+
56+
when:
57+
result = evaluator.hasPermission(authentication,
58+
resource,
59+
resourceType.name(),
60+
authorization)
61+
62+
then:
63+
1 * fiatService.hasAuthorization("testUser", resourceType.name(), resourceName, authorization)
64+
result
65+
66+
where:
67+
resource | resourceName | resourceType
68+
"abc" | "abc" | ResourceType.APPLICATION
69+
"abc-def" | "abc" | ResourceType.APPLICATION
70+
"abc-def-ghi" | "abc" | ResourceType.APPLICATION
71+
"abc-def-ghi-1234" | "abc" | ResourceType.APPLICATION
72+
73+
authorization = 'READ'
74+
}
75+
}

0 commit comments

Comments
 (0)