Skip to content

Commit

Permalink
Set the mapped security roles of the user so these can be used by the…
Browse files Browse the repository at this point in the history
… DLS privileges evaluator. Allow security roles to be used for DLS parameter substitution. Fixes opensearch-project/security/#1568 (#1588)

Signed-off-by: Caitlin Harper <[email protected]>
  • Loading branch information
ch-govau authored Mar 28, 2022
1 parent a01b0fe commit 51e492c
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin
final SecurityRoles securityRoles = getSecurityRoles(mappedRoles);

setUserInfoInThreadContext(user, mappedRoles);
// Add the security roles for this user so that they can be used for DLS parameter substitution.
user.addSecurityRoles(mappedRoles);

final boolean isDebugEnabled = log.isDebugEnabled();
if (isDebugEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ private static String replaceProperties(String orig, User user) {

orig = orig.replace("${user.name}", user.getName()).replace("${user_name}", user.getName());
orig = replaceRoles(orig, user);
orig = replaceSecurityRoles(orig, user);
for (Entry<String, String> entry : user.getCustomAttributesMap().entrySet()) {
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
continue;
Expand All @@ -926,6 +927,15 @@ private static String replaceRoles(final String orig, final User user) {
return retVal;
}

private static String replaceSecurityRoles(final String orig, final User user) {
String retVal = orig;
if (orig.contains("${user.securityRoles}") || orig.contains("${user_securityRoles}")) {
final String commaSeparatedRoles = toQuotedCommaSeparatedString(user.getSecurityRoles());
retVal = orig.replace("${user.securityRoles}", commaSeparatedRoles).replace("${user_securityRoles}", commaSeparatedRoles);
}
return retVal;
}

private static String toQuotedCommaSeparatedString(final Set<String> roles) {
return Joiner.on(',').join(Iterables.transform(roles, s -> {
return new StringBuilder(s.length() + 2).append('"').append(s).append('"').toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ protected void populateData(Client tc) {
.source("{\"role\": \"prole2\", \"amount\": 4040}", XContentType.JSON)).actionGet();
tc.index(new IndexRequest("prop2").type("_doc").setRefreshPolicy(RefreshPolicy.IMMEDIATE)
.source("{\"role\": \"prole3\", \"amount\": 5050}", XContentType.JSON)).actionGet();

tc.index(new IndexRequest("prop-mapped").type("_doc").setRefreshPolicy(RefreshPolicy.IMMEDIATE)
.source("{\"securityRole\": \"opendistro_security_mapped\", \"amount\": 6060}", XContentType.JSON)).actionGet();
tc.index(new IndexRequest("prop-mapped").type("_doc").setRefreshPolicy(RefreshPolicy.IMMEDIATE)
.source("{\"securityRole\": \"not_assigned\", \"amount\": 7070}", XContentType.JSON)).actionGet();
}


Expand All @@ -58,5 +61,10 @@ public void testDlsProps() throws Exception {
Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/prop1,prop2/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))).getStatusCode());
System.out.println(res.getBody());
Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation"));

Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/prop-mapped/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))).getStatusCode());
System.out.println(res.getBody());
Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation"));
Assert.assertTrue(res.getBody().contains("\"amount\" : 6060"));
}
}
1 change: 1 addition & 0 deletions src/test/resources/dlsfls/internal_users.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ prop_replace:
backend_roles:
- "prole1"
- "prole2"
- "prolemapped"
attributes: {}
description: "Migrated from v6"
user_masked_custom:
Expand Down
7 changes: 7 additions & 0 deletions src/test/resources/dlsfls/roles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,13 @@ opendistro_security_prop_replace:
masked_fields: null
allowed_actions:
- "OPENDISTRO_SECURITY_READ"
- index_patterns:
- "prop-mapped"
dls: "{\"terms\" : { \"securityRole\" : [${user.securityRoles}]}}"
fls: null
masked_fields: null
allowed_actions:
- "OPENDISTRO_SECURITY_READ"
tenant_permissions: []
opendistro_security_logstash:
reserved: false
Expand Down
9 changes: 9 additions & 0 deletions src/test/resources/dlsfls/roles_mapping.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,12 @@ opendistro_security_date_math:
opendistro_security_fls_exists:
users:
- fls_exists
opendistro_security_mapped:
reserved: false
hidden: false
backend_roles:
- prolemapped
hosts: []
users: []
and_backend_roles: []
description: "Security role mapping to backend role prolemapped"

0 comments on commit 51e492c

Please sign in to comment.