Skip to content

Commit 29e7325

Browse files
zacw7arhimondr
authored andcommitted
Add a configuration based authorizer
1 parent 35e7243 commit 29e7325

File tree

7 files changed

+241
-1
lines changed

7 files changed

+241
-1
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2010 Proofpoint, 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+
package com.facebook.airlift.http.server;
17+
18+
import com.google.common.annotations.VisibleForTesting;
19+
import com.google.inject.Inject;
20+
21+
import java.io.FileInputStream;
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.security.Principal;
25+
import java.util.Map;
26+
import java.util.Properties;
27+
import java.util.Set;
28+
import java.util.regex.Pattern;
29+
30+
import static com.facebook.airlift.http.server.AuthorizationResult.failure;
31+
import static com.facebook.airlift.http.server.AuthorizationResult.success;
32+
import static com.google.common.collect.ImmutableMap.toImmutableMap;
33+
import static com.google.common.collect.Maps.fromProperties;
34+
import static java.lang.String.format;
35+
import static java.util.Objects.requireNonNull;
36+
37+
public class ConfigurationBasedAuthorizer
38+
implements Authorizer
39+
{
40+
private final Map<String, Pattern> roleRegexMap;
41+
42+
@Inject
43+
public ConfigurationBasedAuthorizer(ConfigurationBasedAuthorizerConfig config)
44+
throws IOException
45+
{
46+
this(config.getRoleMapFilePath());
47+
}
48+
49+
@VisibleForTesting
50+
public ConfigurationBasedAuthorizer(String roleMapFilePath)
51+
throws IOException
52+
{
53+
requireNonNull(roleMapFilePath, "roleMapFilePath is null");
54+
Properties properties = new Properties();
55+
try (InputStream inputStream = new FileInputStream(roleMapFilePath)) {
56+
properties.load(inputStream);
57+
}
58+
roleRegexMap = fromProperties(properties)
59+
.entrySet()
60+
.stream()
61+
.collect(toImmutableMap(Map.Entry::getKey, e -> Pattern.compile(e.getValue())));
62+
}
63+
64+
@Override
65+
public AuthorizationResult authorize(Principal principal, Set<String> allowedRoles)
66+
{
67+
for (String role : allowedRoles) {
68+
if (roleRegexMap.containsKey(role) && isPrincipalAuthorized(principal, roleRegexMap.get(role))) {
69+
return success();
70+
}
71+
}
72+
return failure(format("%s is not a member of the allowed roles: %s", principal.getName(), allowedRoles));
73+
}
74+
75+
private boolean isPrincipalAuthorized(Principal principal, Pattern identityRegex)
76+
{
77+
return identityRegex.matcher(principal.getName()).matches();
78+
}
79+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2010 Proofpoint, 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+
package com.facebook.airlift.http.server;
17+
18+
import com.facebook.airlift.configuration.Config;
19+
20+
import javax.validation.constraints.NotNull;
21+
22+
public class ConfigurationBasedAuthorizerConfig
23+
{
24+
private String roleMapFilePath;
25+
26+
@NotNull
27+
public String getRoleMapFilePath()
28+
{
29+
return roleMapFilePath;
30+
}
31+
32+
@Config("configuration-based-authorizer.role-regex-map.file-path")
33+
public ConfigurationBasedAuthorizerConfig setRoleMapFilePath(String roleMapFilePath)
34+
{
35+
this.roleMapFilePath = roleMapFilePath;
36+
return this;
37+
}
38+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2010 Proofpoint, 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+
package com.facebook.airlift.http.server;
17+
18+
import com.google.inject.Binder;
19+
import com.google.inject.Module;
20+
21+
import static com.facebook.airlift.configuration.ConfigBinder.configBinder;
22+
23+
public class ConfigurationBasedAuthorizerModule
24+
implements Module
25+
{
26+
@Override
27+
public void configure(Binder binder)
28+
{
29+
binder.bind(Authorizer.class).to(ConfigurationBasedAuthorizer.class);
30+
configBinder(binder).bindConfig(ConfigurationBasedAuthorizerConfig.class);
31+
}
32+
}

http-server/src/main/java/com/facebook/airlift/http/server/testing/TestingHttpServerModule.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,5 @@ public void configure(Binder binder)
8888
List<Authenticator> getAuthenticatorList(Set<Authenticator> authenticators)
8989
{
9090
return ImmutableList.copyOf(authenticators);
91-
newOptionalBinder(binder, Authorizer.class);
9291
}
9392
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2010 Proofpoint, 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+
package com.facebook.airlift.http.server;
17+
18+
import com.google.common.collect.ImmutableSet;
19+
import org.testng.annotations.Test;
20+
21+
import java.io.IOException;
22+
23+
import static org.testng.Assert.assertFalse;
24+
import static org.testng.Assert.assertTrue;
25+
26+
public class TestConfigurationBasedAuthorizer
27+
{
28+
@Test
29+
public void testAuthorize()
30+
throws IOException
31+
{
32+
Authorizer authorizer = new ConfigurationBasedAuthorizer("src/test/resources/roles.properties");
33+
assertTrue(authorizer.authorize(() -> "tom", ImmutableSet.of("user")).isAllowed());
34+
assertTrue(authorizer.authorize(() -> "jerry", ImmutableSet.of("user")).isAllowed());
35+
assertFalse(authorizer.authorize(() -> "jacob", ImmutableSet.of("user")).isAllowed());
36+
assertTrue(authorizer.authorize(() -> "jacob", ImmutableSet.of("admin")).isAllowed());
37+
assertFalse(authorizer.authorize(() -> "foo.bar", ImmutableSet.of("service")).isAllowed());
38+
assertTrue(authorizer.authorize(() -> "gateway.airlift", ImmutableSet.of("service")).isAllowed());
39+
assertTrue(authorizer.authorize(() -> "logger.airlift", ImmutableSet.of("service")).isAllowed());
40+
}
41+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2010 Proofpoint, 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+
package com.facebook.airlift.http.server;
17+
18+
import com.facebook.airlift.configuration.testing.ConfigAssertions;
19+
import com.google.common.collect.ImmutableMap;
20+
import org.testng.annotations.Test;
21+
22+
import java.util.Map;
23+
24+
import static com.facebook.airlift.configuration.testing.ConfigAssertions.assertFullMapping;
25+
import static com.facebook.airlift.configuration.testing.ConfigAssertions.assertRecordedDefaults;
26+
27+
public class TestConfigurationBasedAuthorizerConfig
28+
{
29+
@Test
30+
public void testDefaults()
31+
{
32+
assertRecordedDefaults(ConfigAssertions.recordDefaults(ConfigurationBasedAuthorizerConfig.class)
33+
.setRoleMapFilePath(null));
34+
}
35+
36+
@Test
37+
public void testExplicitPropertyMappings()
38+
{
39+
Map<String, String> properties = new ImmutableMap.Builder<String, String>()
40+
.put("configuration-based-authorizer.role-regex-map.file-path", "roles.properties")
41+
.build();
42+
43+
ConfigurationBasedAuthorizerConfig expected = new ConfigurationBasedAuthorizerConfig()
44+
.setRoleMapFilePath("roles.properties");
45+
46+
assertFullMapping(properties, expected);
47+
}
48+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
user=tom|jerry
2+
admin=jacob
3+
service=([^\\.]*)\\.airlift

0 commit comments

Comments
 (0)