Skip to content

Commit

Permalink
Merge branch 'main' into resource-access-control
Browse files Browse the repository at this point in the history
  • Loading branch information
DarshitChanpura committed Oct 2, 2024
2 parents 4c913de + 830b341 commit fd8cfd1
Show file tree
Hide file tree
Showing 114 changed files with 1,358 additions and 6,732 deletions.
22 changes: 11 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ plugins {
id 'com.diffplug.spotless' version '6.25.0'
id 'checkstyle'
id 'com.netflix.nebula.ospackage' version "11.10.0"
id "org.gradle.test-retry" version "1.5.10"
id "org.gradle.test-retry" version "1.6.0"
id 'eclipse'
id "com.github.spotbugs" version "5.2.5"
id "com.google.osdetector" version "1.7.3"
Expand Down Expand Up @@ -471,7 +471,7 @@ configurations {
resolutionStrategy {
force 'commons-codec:commons-codec:1.17.1'
force 'org.slf4j:slf4j-api:1.7.36'
force 'org.scala-lang:scala-library:2.13.14'
force 'org.scala-lang:scala-library:2.13.15'
force "com.fasterxml.jackson:jackson-bom:${versions.jackson}"
force "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
force "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${versions.jackson}"
Expand All @@ -482,7 +482,7 @@ configurations {
force "io.netty:netty-transport:${versions.netty}"
force "io.netty:netty-transport-native-unix-common:${versions.netty}"
force "com.github.luben:zstd-jni:${versions.zstd}"
force "org.xerial.snappy:snappy-java:1.1.10.6"
force "org.xerial.snappy:snappy-java:1.1.10.7"
force "com.google.guava:guava:${guava_version}"

// for spotbugs dependency conflict
Expand All @@ -495,7 +495,7 @@ configurations {
// For integrationTest
force "org.apache.httpcomponents:httpclient:4.5.14"
force "org.apache.httpcomponents:httpcore:4.4.16"
force "com.google.errorprone:error_prone_annotations:2.31.0"
force "com.google.errorprone:error_prone_annotations:2.32.0"
force "org.checkerframework:checker-qual:3.47.0"
force "ch.qos.logback:logback-classic:1.5.8"
}
Expand Down Expand Up @@ -580,7 +580,7 @@ dependencies {
implementation 'commons-cli:commons-cli:1.9.0'
implementation "org.bouncycastle:bcprov-jdk18on:${versions.bouncycastle}"
implementation 'org.ldaptive:ldaptive:1.2.3'
implementation 'com.nimbusds:nimbus-jose-jwt:9.40'
implementation 'com.nimbusds:nimbus-jose-jwt:9.41.1'
implementation 'com.rfksystems:blake2b:2.0.0'
implementation 'com.password4j:password4j:1.8.2'
//JWT
Expand All @@ -602,7 +602,7 @@ dependencies {
runtimeOnly 'com.eclipsesource.minimal-json:minimal-json:0.9.5'
runtimeOnly 'commons-codec:commons-codec:1.17.1'
runtimeOnly 'org.cryptacular:cryptacular:1.2.7'
compileOnly 'com.google.errorprone:error_prone_annotations:2.31.0'
compileOnly 'com.google.errorprone:error_prone_annotations:2.32.0'
runtimeOnly 'com.sun.istack:istack-commons-runtime:4.2.0'
runtimeOnly 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.2'
runtimeOnly 'org.ow2.asm:asm:9.7'
Expand Down Expand Up @@ -639,7 +639,7 @@ dependencies {
runtimeOnly 'org.lz4:lz4-java:1.8.0'
runtimeOnly 'org.slf4j:slf4j-api:1.7.36'
runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j}"
runtimeOnly 'org.xerial.snappy:snappy-java:1.1.10.6'
runtimeOnly 'org.xerial.snappy:snappy-java:1.1.10.7'
runtimeOnly 'org.codehaus.woodstox:stax2-api:4.2.2'
runtimeOnly "org.glassfish.jaxb:txw2:${jaxb_version}"
runtimeOnly 'com.fasterxml.woodstox:woodstox-core:6.7.0'
Expand Down Expand Up @@ -679,8 +679,8 @@ dependencies {
testImplementation 'commons-validator:commons-validator:1.9.0'
testImplementation 'org.springframework.kafka:spring-kafka-test:2.9.13'
testImplementation "org.springframework:spring-beans:${spring_version}"
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.1'
testImplementation('org.awaitility:awaitility:4.2.2') {
exclude(group: 'org.hamcrest', module: 'hamcrest')
}
Expand All @@ -696,7 +696,7 @@ dependencies {
testRuntimeOnly ("org.springframework:spring-core:${spring_version}") {
exclude(group:'org.springframework', module: 'spring-jcl' )
}
testRuntimeOnly 'org.scala-lang:scala-library:2.13.14'
testRuntimeOnly 'org.scala-lang:scala-library:2.13.15'
testRuntimeOnly 'com.typesafe.scala-logging:scala-logging_3:3.9.5'
testRuntimeOnly('org.apache.zookeeper:zookeeper:3.9.2') {
exclude(group:'ch.qos.logback', module: 'logback-classic' )
Expand All @@ -718,7 +718,7 @@ dependencies {
integrationTestImplementation 'junit:junit:4.13.2'
integrationTestImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}"
integrationTestImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}"
integrationTestImplementation 'commons-io:commons-io:2.16.1'
integrationTestImplementation 'commons-io:commons-io:2.17.0'
integrationTestImplementation "org.apache.logging.log4j:log4j-core:${versions.log4j}"
integrationTestImplementation "org.apache.logging.log4j:log4j-jul:${versions.log4j}"
integrationTestImplementation 'org.hamcrest:hamcrest:2.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,11 @@ private void verifyAuthInfoApi(final TestRestClient client) throws Exception {

@Test
public void flushCache() throws Exception {
withUser(NEW_USER, client -> {
forbidden(() -> client.get(apiPath("cache")));
forbidden(() -> client.postJson(apiPath("cache"), EMPTY_BODY));
forbidden(() -> client.putJson(apiPath("cache"), EMPTY_BODY));
forbidden(() -> client.delete(apiPath("cache")));
});
withUser(NEW_USER, client -> { forbidden(() -> client.delete(apiPath("cache"))); });
withUser(ADMIN_USER_NAME, localCluster.getAdminCertificate(), client -> {
notImplemented(() -> client.get(apiPath("cache")));
notImplemented(() -> client.postJson(apiPath("cache"), EMPTY_BODY));
notImplemented(() -> client.putJson(apiPath("cache"), EMPTY_BODY));
methodNotAllowed(() -> client.get(apiPath("cache")));
methodNotAllowed(() -> client.postJson(apiPath("cache"), EMPTY_BODY));
methodNotAllowed(() -> client.putJson(apiPath("cache"), EMPTY_BODY));
final var response = ok(() -> client.delete(apiPath("cache")));
assertThat(response.getBody(), response.getTextFromJsonBody("/message"), is("Cache flushed successfully."));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -94,6 +97,13 @@ public class TestSecurityConfig {

private Map<String, ActionGroup> actionGroups = new LinkedHashMap<>();

/**
* A map from document id to a string containing config JSON.
* If this is not null, it will be used ALTERNATIVELY to all other configuration contained in this class.
* Can be used to simulate invalid configuration or legacy configuration.
*/
private Map<String, String> rawConfigurationDocuments;

private String indexName = ".opendistro_security";

public TestSecurityConfig() {
Expand Down Expand Up @@ -212,6 +222,27 @@ public List<ActionGroup> actionGroups() {
return List.copyOf(actionGroups.values());
}

/**
* Specifies raw document content for the configuration index as YAML document. If this method is used,
* then ONLY the raw documents will be written to the configuration index. Any other configuration specified
* by the roles() or users() method will be ignored.
* Can be used to simulate invalid configuration or legacy configuration.
*/
public TestSecurityConfig rawConfigurationDocumentYaml(String configTypeId, String configDocumentAsYaml) {
try {
if (this.rawConfigurationDocuments == null) {
this.rawConfigurationDocuments = new LinkedHashMap<>();
}

JsonNode node = new ObjectMapper(new YAMLFactory()).readTree(configDocumentAsYaml);

this.rawConfigurationDocuments.put(configTypeId, new ObjectMapper().writeValueAsString(node));
return this;
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static class Config implements ToXContentObject {
private boolean anonymousAuth;

Expand Down Expand Up @@ -964,15 +995,24 @@ public void initIndex(Client client) {
}
client.admin().indices().create(new CreateIndexRequest(indexName).settings(settings)).actionGet();

writeSingleEntryConfigToIndex(client, CType.CONFIG, config);
if (auditConfiguration != null) {
writeSingleEntryConfigToIndex(client, CType.AUDIT, "config", auditConfiguration);
if (rawConfigurationDocuments == null) {
writeSingleEntryConfigToIndex(client, CType.CONFIG, config);
if (auditConfiguration != null) {
writeSingleEntryConfigToIndex(client, CType.AUDIT, "config", auditConfiguration);
}
writeConfigToIndex(client, CType.ROLES, roles);
writeConfigToIndex(client, CType.INTERNALUSERS, internalUsers);
writeConfigToIndex(client, CType.ROLESMAPPING, rolesMapping);
writeEmptyConfigToIndex(client, CType.ACTIONGROUPS);
writeEmptyConfigToIndex(client, CType.TENANTS);
} else {
// Write raw configuration alternatively to the normal configuration

for (Map.Entry<String, String> entry : this.rawConfigurationDocuments.entrySet()) {
writeConfigToIndex(client, entry.getKey(), entry.getValue());
}
}
writeConfigToIndex(client, CType.ROLES, roles);
writeConfigToIndex(client, CType.INTERNALUSERS, internalUsers);
writeConfigToIndex(client, CType.ROLESMAPPING, rolesMapping);
writeEmptyConfigToIndex(client, CType.ACTIONGROUPS);
writeEmptyConfigToIndex(client, CType.TENANTS);

}

public void updateInternalUsersConfiguration(Client client, List<User> users) {
Expand All @@ -987,11 +1027,11 @@ static String hashPassword(final String clearTextPassword) {
return passwordHasher.hash(clearTextPassword.toCharArray());
}

private void writeEmptyConfigToIndex(Client client, CType configType) {
private void writeEmptyConfigToIndex(Client client, CType<?> configType) {
writeConfigToIndex(client, configType, Collections.emptyMap());
}

private void writeConfigToIndex(Client client, CType configType, Map<String, ? extends ToXContentObject> config) {
private void writeConfigToIndex(Client client, CType<?> configType, Map<String, ? extends ToXContentObject> config) {
try {
String json = configToJson(configType, config);

Expand All @@ -1008,11 +1048,23 @@ private void writeConfigToIndex(Client client, CType configType, Map<String, ? e
}
}

private void writeConfigToIndex(Client client, String documentId, String jsonString) {
try {
log.info("Writing raw security configuration into index {}:\n{}", documentId, jsonString);

BytesReference bytesReference = toByteReference(jsonString);
client.index(new IndexRequest(indexName).id(documentId).setRefreshPolicy(IMMEDIATE).source(documentId, bytesReference))
.actionGet();
} catch (Exception e) {
throw new RuntimeException("Error while initializing config for " + indexName, e);
}
}

private static BytesReference toByteReference(String string) throws UnsupportedEncodingException {
return BytesReference.fromByteBuffer(ByteBuffer.wrap(string.getBytes("utf-8")));
}

private void updateConfigInIndex(Client client, CType configType, Map<String, ? extends ToXContentObject> config) {
private void updateConfigInIndex(Client client, CType<?> configType, Map<String, ? extends ToXContentObject> config) {
try {
String json = configToJson(configType, config);
BytesReference bytesReference = toByteReference(json);
Expand All @@ -1025,7 +1077,7 @@ private void updateConfigInIndex(Client client, CType configType, Map<String, ?
}
}

private static String configToJson(CType configType, Map<String, ? extends ToXContentObject> config) throws IOException {
private static String configToJson(CType<?> configType, Map<String, ? extends ToXContentObject> config) throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();

builder.startObject();
Expand All @@ -1043,11 +1095,11 @@ private static String configToJson(CType configType, Map<String, ? extends ToXCo
return builder.toString();
}

private void writeSingleEntryConfigToIndex(Client client, CType configType, ToXContentObject config) {
private void writeSingleEntryConfigToIndex(Client client, CType<?> configType, ToXContentObject config) {
writeSingleEntryConfigToIndex(client, configType, configType.toLCString(), config);
}

private void writeSingleEntryConfigToIndex(Client client, CType configType, String configurationRoot, ToXContentObject config) {
private void writeSingleEntryConfigToIndex(Client client, CType<?> configType, String configurationRoot, ToXContentObject config) {
try {
XContentBuilder builder = XContentFactory.jsonBuilder();

Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/opensearch/security/DefaultObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,22 @@ public static <T> T readValue(String string, JavaType jt) throws IOException {
}
}

@SuppressWarnings("removal")
public static <T> T convertValue(JsonNode jsonNode, JavaType jt) throws IOException {

final SecurityManager sm = System.getSecurityManager();

if (sm != null) {
sm.checkPermission(new SpecialPermission());
}

try {
return AccessController.doPrivileged((PrivilegedExceptionAction<T>) () -> objectMapper.convertValue(jsonNode, jt));
} catch (final PrivilegedActionException e) {
throw (IOException) e.getCause();
}
}

public static TypeFactory getTypeFactory() {
return objectMapper.getTypeFactory();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,50 @@ public List<Setting<?>> getSettings() {
)
);

// Internal OpenSearch DataStream
settings.add(
Setting.simpleString(
ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_OPENSEARCH_DATASTREAM_NAME,
Property.NodeScope,
Property.Filtered
)
);
settings.add(
Setting.boolSetting(
ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX
+ ConfigConstants.SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_MANAGE,
true,
Property.NodeScope,
Property.Filtered
)
);
settings.add(
Setting.simpleString(
ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX
+ ConfigConstants.SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NAME,
Property.NodeScope,
Property.Filtered
)
);
settings.add(
Setting.intSetting(
ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX
+ ConfigConstants.SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_SHARDS,
1,
Property.NodeScope,
Property.Filtered
)
);
settings.add(
Setting.intSetting(
ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX
+ ConfigConstants.SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_REPLICAS,
0,
Property.NodeScope,
Property.Filtered
)
);

// External OpenSearch
settings.add(
Setting.listSetting(
Expand Down
Loading

0 comments on commit fd8cfd1

Please sign in to comment.