Skip to content

Commit 58f51fc

Browse files
authored
[Resource Sharing] Keep track of list ofall_shared_principals for which sharable resource is visible for searching (#5596)
Signed-off-by: Craig Perkins <cwperx@amazon.com>
1 parent c51ce46 commit 58f51fc

File tree

8 files changed

+217
-80
lines changed

8 files changed

+217
-80
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
99

1010
### Enhancements
1111

12+
- [Resource Sharing] Keep track of list of principals for which sharable resource is visible for searching ([#5596](https://github.com/opensearch-project/security/pull/5596))
1213
- [Resource Sharing] Keep track of tenant for sharable resources by persisting user requested tenant with sharing info ([#5588](https://github.com/opensearch-project/security/pull/5588))
1314

1415
### Bug Fixes

sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/MigrateApiTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.junit.runner.RunWith;
2727

2828
import org.opensearch.Version;
29-
import org.opensearch.painless.PainlessModulePlugin;
3029
import org.opensearch.plugins.PluginInfo;
3130
import org.opensearch.sample.SampleResourcePlugin;
3231
import org.opensearch.security.OpenSearchSecurityPlugin;
@@ -64,7 +63,6 @@ public class MigrateApiTests {
6463

6564
@ClassRule
6665
public static LocalCluster cluster = new LocalCluster.Builder().clusterManager(ClusterManager.DEFAULT)
67-
.plugin(PainlessModulePlugin.class)
6866
.plugin(
6967
new PluginInfo(
7068
SampleResourcePlugin.class.getName(),

sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/SecurityDisabledTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.junit.runner.RunWith;
2020

2121
import org.opensearch.Version;
22-
import org.opensearch.painless.PainlessModulePlugin;
2322
import org.opensearch.plugins.PluginInfo;
2423
import org.opensearch.sample.SampleResourcePlugin;
2524
import org.opensearch.security.OpenSearchSecurityPlugin;
@@ -65,7 +64,6 @@ public class SecurityDisabledTests {
6564
false
6665
)
6766
)
68-
.plugin(PainlessModulePlugin.class)
6967
.loadConfigurationIntoIndex(false)
7068
.nodeSettings(Map.of("plugins.security.disabled", true, "plugins.security.ssl.http.enabled", false))
7169
.build();

sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/resource/TestUtils.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.opensearch.common.xcontent.XContentFactory;
2424
import org.opensearch.core.xcontent.ToXContent;
2525
import org.opensearch.core.xcontent.XContentBuilder;
26-
import org.opensearch.painless.PainlessModulePlugin;
2726
import org.opensearch.plugins.PluginInfo;
2827
import org.opensearch.sample.SampleResourcePlugin;
2928
import org.opensearch.security.OpenSearchSecurityPlugin;
@@ -113,7 +112,6 @@ public static LocalCluster newCluster(boolean featureEnabled, boolean systemInde
113112
false
114113
)
115114
)
116-
.plugin(PainlessModulePlugin.class)
117115
.anonymousAuth(true)
118116
.authc(AUTHC_HTTPBASIC_INTERNAL)
119117
.users(USER_ADMIN, FULL_ACCESS_USER, LIMITED_ACCESS_USER, NO_ACCESS_USER)

sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/secure/SecurePluginTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import org.opensearch.Version;
2121
import org.opensearch.core.rest.RestStatus;
22-
import org.opensearch.painless.PainlessModulePlugin;
2322
import org.opensearch.plugins.PluginInfo;
2423
import org.opensearch.sample.SampleResourcePlugin;
2524
import org.opensearch.security.OpenSearchSecurityPlugin;
@@ -47,7 +46,6 @@ public class SecurePluginTests {
4746
.anonymousAuth(false)
4847
.authc(AUTHC_DOMAIN)
4948
.users(USER_ADMIN)
50-
.plugin(PainlessModulePlugin.class)
5149
.plugin(
5250
new PluginInfo(
5351
SampleResourcePlugin.class.getName(),

spi/src/main/java/org/opensearch/security/spi/resources/sharing/ResourceSharing.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
package org.opensearch.security.spi.resources.sharing;
1010

1111
import java.io.IOException;
12+
import java.util.ArrayList;
1213
import java.util.Collections;
1314
import java.util.HashSet;
15+
import java.util.List;
1416
import java.util.Map;
1517
import java.util.Objects;
1618
import java.util.Set;
@@ -267,4 +269,47 @@ public Set<String> fetchAccessLevels(Recipient recipientType, Set<String> entiti
267269
}
268270
return matchingGroups;
269271
}
272+
273+
/**
274+
* Returns all principals (users, roles, backend_roles) that have access to this resource,
275+
* including the creator and all shared recipients, formatted with appropriate prefixes.
276+
*
277+
* @return List of principals in format ["user:username", "role:rolename", "backend:backend_role"]
278+
*/
279+
public List<String> getAllPrincipals() {
280+
List<String> principals = new ArrayList<>();
281+
282+
// Add creator
283+
if (createdBy != null) {
284+
principals.add("user:" + createdBy.getUsername());
285+
}
286+
287+
// Add shared recipients
288+
if (shareWith != null) {
289+
// shared with at any access level
290+
for (Recipients recipients : shareWith.getSharingInfo().values()) {
291+
Map<Recipient, Set<String>> recipientMap = recipients.getRecipients();
292+
293+
// Add users
294+
Set<String> users = recipientMap.getOrDefault(Recipient.USERS, Collections.emptySet());
295+
for (String user : users) {
296+
principals.add("user:" + user);
297+
}
298+
299+
// Add roles
300+
Set<String> roles = recipientMap.getOrDefault(Recipient.ROLES, Collections.emptySet());
301+
for (String role : roles) {
302+
principals.add("role:" + role);
303+
}
304+
305+
// Add backend roles
306+
Set<String> backendRoles = recipientMap.getOrDefault(Recipient.BACKEND_ROLES, Collections.emptySet());
307+
for (String backendRole : backendRoles) {
308+
principals.add("backend:" + backendRole);
309+
}
310+
}
311+
}
312+
313+
return principals;
314+
}
270315
}

src/main/java/org/opensearch/security/resources/ResourceIndexListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void postIndex(ShardId shardId, Engine.Index index, Engine.IndexResult re
5454
String resourceId = index.id();
5555

5656
// Only proceed if this was a create operation and for primary shard
57-
if (!result.isCreated() && index.origin().equals(Engine.Operation.Origin.PRIMARY)) {
57+
if (!result.isCreated() || !index.origin().equals(Engine.Operation.Origin.PRIMARY)) {
5858
log.debug("Skipping resource sharing entry creation as this was an update operation for resource {}", resourceId);
5959
return;
6060
}

0 commit comments

Comments
 (0)