aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--aai-resources/.gitignore4
-rw-r--r--aai-resources/pom.xml194
-rw-r--r--aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java5
-rw-r--r--aai-resources/src/main/java/org/onap/aai/ResourcesApp.java6
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/AuthProperties.java (renamed from aai-resources/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java)33
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java26
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java159
-rw-r--r--aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java87
-rw-r--r--aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java3
-rw-r--r--aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java83
-rw-r--r--aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java35
-rw-r--r--aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java79
-rw-r--r--aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java113
-rw-r--r--aai-resources/src/main/resources/application-keycloak.properties14
-rw-r--r--aai-resources/src/main/resources/application.properties32
-rw-r--r--aai-resources/src/main/resources/etc/appprops/aaiconfig.properties5
-rw-r--r--aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java25
-rw-r--r--aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java22
-rw-r--r--aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java72
-rw-r--r--aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java45
-rw-r--r--aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java124
-rw-r--r--aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java54
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java3
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java78
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java3
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java71
-rw-r--r--aai-resources/src/test/resources/application-test.properties14
-rw-r--r--aai-resources/src/test/resources/it/application-keycloak-test.properties17
-rw-r--r--aai-resources/src/test/resources/it/multi-tenancy-realm.json173
-rw-r--r--pom.xml6
-rw-r--r--version.properties2
32 files changed, 345 insertions, 1246 deletions
diff --git a/.gitignore b/.gitignore
index e18083c9..ab1b64ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,6 @@
.project
target/
**/logs/
-bundleconfig-local/etc/auth/aai-client-cert.p12
-bundleconfig-local/etc/auth/tomcat_keystore
bundleconfig-local/etc/logback.xml
/.pydevproject
/bin/
@@ -14,4 +12,4 @@ test_csvWriter.csv
*.iml
aai-resources/debug-logs/EELF/
.vscode
-.classpath \ No newline at end of file
+.classpath
diff --git a/aai-resources/.gitignore b/aai-resources/.gitignore
index 47d0f721..9d979909 100644
--- a/aai-resources/.gitignore
+++ b/aai-resources/.gitignore
@@ -1,8 +1,6 @@
.settings
target/
**/logs/
-bundleconfig-local/etc/auth/aai-client-cert.p12
-bundleconfig-local/etc/auth/tomcat_keystore
bundleconfig-local/etc/oxm
src/main/aai_schema
bundleconfig-local/etc/logback.xml
@@ -15,4 +13,4 @@ bundleconfig-local/etc/logback.xml
**/dbedgerules/**
**/oxm/**
**/.classpath
-.classpath \ No newline at end of file
+.classpath
diff --git a/aai-resources/pom.xml b/aai-resources/pom.xml
index d5dacd40..8910d5af 100644
--- a/aai-resources/pom.xml
+++ b/aai-resources/pom.xml
@@ -21,14 +21,14 @@
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.aai.resources</groupId>
<artifactId>aai-resources</artifactId>
<parent>
<groupId>org.onap.aai.resources</groupId>
<artifactId>resources</artifactId>
- <version>1.15.4-SNAPSHOT</version>
+ <version>1.15.5-SNAPSHOT</version>
</parent>
<properties>
<java.version>11</java.version>
@@ -81,9 +81,7 @@
<gremlin.version>3.5.8</gremlin.version> -->
<javax.servlet.version>4.0.1</javax.servlet.version>
- <keycloak.version>11.0.2</keycloak.version>
- <testcontainers.version>1.20.4</testcontainers.version>
- <testcontainers-keycloak.version>1.6.1</testcontainers-keycloak.version>
+ <testcontainers.version>1.19.8</testcontainers.version>
<mockito.core.version>4.4.0</mockito.core.version>
<eclipse.persistence.version>2.7.7</eclipse.persistence.version>
<!-- Setting some default value to not complain by editor but it will be overridden by gmaven plugin -->
@@ -107,15 +105,15 @@
<build>
<plugins>
<plugin>
- <groupId>org.codehaus.groovy.maven</groupId>
- <artifactId>gmaven-plugin</artifactId>
- <version>1.0</version>
- <executions>
- <execution>
- <phase>pre-clean</phase>
- </execution>
- </executions>
- </plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>pre-clean</phase>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
@@ -286,7 +284,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
+ <artifactId>spring-boot-starter-jersey</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -296,12 +294,25 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
+ <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jetty</artifactId>
+ <artifactId>spring-boot-starter-security</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-validation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
@@ -416,15 +427,15 @@
<version>6.6</version>
</dependency>
<dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest</artifactId>
- <version>2.2</version>
- <exclusions>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- </exclusions>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <version>2.2</version>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -441,9 +452,9 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-junit-jupiter</artifactId>
- <scope>test</scope>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>com.beust</groupId>
@@ -470,7 +481,7 @@
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
- <scope>compile</scope>
+ <version>1.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
@@ -535,32 +546,6 @@
</exclusion>
</exclusions>
</dependency>
- <!--
- Explicitly stating the security spring framework and
- exclude the bouncy castle since that is somehow overwriting
- our p12 file decryption that's built into java security
- This will cause the password is incorrect
- This needs to be added back if org.bouncy castle dependency
- sneaks backs in and causing issues with the two way ssl
- -->
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-rsa</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk15on</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- </dependency>
<!-- Only used for the WebTestClient -->
<dependency>
@@ -589,28 +574,8 @@
<artifactId>gremlin-groovy</artifactId>
</dependency>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-spring-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>com.github.dasniko</groupId>
- <artifactId>testcontainers-keycloak</artifactId>
- <version>${testcontainers-keycloak.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-admin-client</artifactId>
- <version>${keycloak.version}</version>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -644,26 +609,19 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.34</version>
- <scope>provided</scope>
- </dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>1.18.34</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-xml</artifactId>
- </dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-xml</artifactId>
+ </dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
- <groupId>org.keycloak.bom</groupId>
- <artifactId>keycloak-adapter-bom</artifactId>
- <version>${keycloak.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
@@ -737,8 +695,6 @@
<resource>
<directory>${project.basedir}/src/main/resources/etc/auth/</directory>
<includes>
- <include>aai-client-cert.p12</include>
- <include>tomcat_keystore</include>
<include>aai_policy.json</include>
</includes>
<targetPath>${project.build.directory}/swm/package/nix/dist_files/opt/app/${project.artifactId}/appconfig</targetPath>
@@ -927,29 +883,29 @@
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>3.0.0</version>
- <executions>
- <execution>
- <id>copy-fat-jar</id>
- <phase>post-integration-test</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <outputDirectory>${aai.build.directory}/lib/</outputDirectory>
- <resources>
- <resource>
- <directory>${project.build.directory}/</directory>
- <includes>
- <include>${project.artifactId}-${project.version}.jar</include>
- </includes>
- <filtering>false</filtering>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.0</version>
+ <executions>
+ <execution>
+ <id>copy-fat-jar</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${aai.build.directory}/lib/</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.build.directory}/</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
diff --git a/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java b/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java
index 9331f2f5..68ed2fb6 100644
--- a/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java
+++ b/aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java
@@ -41,7 +41,6 @@ import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.introspection.ModelType;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
import org.onap.aai.serialization.db.EdgeSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.setup.SchemaVersions;
@@ -76,8 +75,6 @@ public class IncreaseNodesTool {
throws AAIUnknownObjectException, UnsupportedEncodingException, AAIException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
- PropertyPasswordConfiguration initializer = new PropertyPasswordConfiguration();
- initializer.initialize(context);
try {
context.scan("org.onap.aai.config", "org.onap.aai.setup");
context.refresh();
@@ -129,7 +126,7 @@ public class IncreaseNodesTool {
* /cloud-infrastructure/pservers/pserver/
* /network/pnfs/pnf/
* /cloud-infrastructure/pservers/pserver/random-056fd6c4-7313-4fa0-b854-0d9983bdb0ab/p-interfaces/p-interface/
- *
+ *
* @param
* @param
* @param cArgs
diff --git a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
index 51f5609f..7e1bd3a9 100644
--- a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
+++ b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
@@ -30,7 +30,6 @@ import org.onap.aai.dbmap.AAIGraph;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.logging.ErrorLogHelper;
import org.onap.aai.nodes.NodeIngestor;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
import org.onap.aai.util.AAIConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,9 +41,11 @@ import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoCo
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
+@EnableConfigurationProperties
@SpringBootApplication(
exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class})
@@ -105,7 +106,6 @@ public class ResourcesApp {
SpringApplication app = new SpringApplication(ResourcesApp.class);
app.setLogStartupInfo(false);
app.setRegisterShutdownHook(true);
- app.addInitializers(new PropertyPasswordConfiguration());
env = app.run(args).getEnvironment();
} catch (Exception ex) {
AAIException aai = null;
@@ -132,8 +132,6 @@ public class ResourcesApp {
logger.info("Resources MicroService Started");
logger.debug("Resources MicroService Started");
- System.out.println("Resources Microservice Started");
-
}
public static void setDefaultProps() {
diff --git a/aai-resources/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java b/aai-resources/src/main/java/org/onap/aai/config/AuthProperties.java
index 833fd563..1ecffb6f 100644
--- a/aai-resources/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java
+++ b/aai-resources/src/main/java/org/onap/aai/config/AuthProperties.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,28 @@
package org.onap.aai.config;
-import org.eclipse.jetty.util.security.Password;
+import java.util.List;
-public class JettyPasswordDecoder implements PasswordDecoder {
+import javax.validation.constraints.NotEmpty;
- @Override
- public String decode(String input) {
- if (input.startsWith("OBF:")) {
- return Password.deobfuscate(input);
- }
- return Password.deobfuscate("OBF:" + input);
- }
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import lombok.Data;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "aai.basic-auth")
+public class AuthProperties {
+
+ boolean enabled = true;
+
+ @NotEmpty
+ List<User> users;
+
+ @Data
+ public static class User {
+ private String username;
+ private String password;
+ }
}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java b/aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java
deleted file mode 100644
index 8ad75d9d..00000000
--- a/aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.config;
-
-public interface PasswordDecoder {
-
- String decode(String input);
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java b/aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
deleted file mode 100644
index f205804f..00000000
--- a/aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.config;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.springframework.context.ApplicationContextInitializer;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.env.EnumerablePropertySource;
-import org.springframework.core.env.MapPropertySource;
-import org.springframework.core.env.PropertySource;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class PropertyPasswordConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext> {
-
- private static final Pattern decodePasswordPattern = Pattern.compile("password\\((.*?)\\)");
- private PasswordDecoder passwordDecoder = new JettyPasswordDecoder();
-
- @Override
- public void initialize(ConfigurableApplicationContext applicationContext) {
- ConfigurableEnvironment environment = applicationContext.getEnvironment();
- String certPath = environment.getProperty("server.certs.location");
- File passwordFile = null;
- File passphrasesFile = null;
- InputStream passwordStream = null;
- InputStream passphrasesStream = null;
- Map<String, Object> sslProps = new LinkedHashMap<>();
-
- // Override the passwords from application.properties if we find AAF certman files
- if (certPath != null) {
- try {
- passwordFile = new File(certPath + ".password");
- passwordStream = new FileInputStream(passwordFile);
-
- if (passwordStream != null) {
- String keystorePassword = null;
-
- keystorePassword = IOUtils.toString(passwordStream, Charset.defaultCharset());
- if (keystorePassword != null) {
- keystorePassword = keystorePassword.trim();
- }
- sslProps.put("server.ssl.key-store-password", keystorePassword);
- sslProps.put("schema.service.ssl.key-store-password", keystorePassword);
- } else {
- log.info("Not using AAF Certman password file");
- }
- } catch (IOException e) {
- log.warn("Not using AAF Certman password file, e=" + e.getMessage());
- } finally {
- if (passwordStream != null) {
- try {
- passwordStream.close();
- } catch (Exception e) {
- }
- }
- }
- try {
- passphrasesFile = new File(certPath + ".passphrases");
- passphrasesStream = new FileInputStream(passphrasesFile);
-
- if (passphrasesStream != null) {
- String truststorePassword = null;
- Properties passphrasesProps = new Properties();
- passphrasesProps.load(passphrasesStream);
- truststorePassword = passphrasesProps.getProperty("cadi_truststore_password");
- if (truststorePassword != null) {
- truststorePassword = truststorePassword.trim();
- }
- sslProps.put("server.ssl.trust-store-password", truststorePassword);
- sslProps.put("schema.service.ssl.trust-store-password", truststorePassword);
- } else {
- log.info("Not using AAF Certman passphrases file");
- }
- } catch (IOException e) {
- log.warn("Not using AAF Certman passphrases file, e=" + e.getMessage());
- } finally {
- if (passphrasesStream != null) {
- try {
- passphrasesStream.close();
- } catch (Exception e) {
- }
- }
- }
- }
- for (PropertySource<?> propertySource : environment.getPropertySources()) {
- Map<String, Object> propertyOverrides = new LinkedHashMap<>();
- decodePasswords(propertySource, propertyOverrides);
- if (!propertyOverrides.isEmpty()) {
- PropertySource<?> decodedProperties =
- new MapPropertySource("decoded " + propertySource.getName(), propertyOverrides);
- environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties);
- }
-
- }
- if (!sslProps.isEmpty()) {
- log.info("Using AAF Certman files");
- PropertySource<?> additionalProperties = new MapPropertySource("additionalProperties", sslProps);
- environment.getPropertySources().addFirst(additionalProperties);
- }
- }
-
- private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
- if (source instanceof EnumerablePropertySource) {
- EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
- for (String key : enumerablePropertySource.getPropertyNames()) {
- Object rawValue = source.getProperty(key);
- if (rawValue instanceof String) {
- String decodedValue = decodePasswordsInString((String) rawValue);
- propertyOverrides.put(key, decodedValue);
- }
- }
- }
- }
-
- private String decodePasswordsInString(String input) {
- if (input == null)
- return null;
- StringBuffer output = new StringBuffer();
- Matcher matcher = decodePasswordPattern.matcher(input);
- while (matcher.find()) {
- String replacement = passwordDecoder.decode(matcher.group(1));
- matcher.appendReplacement(output, replacement);
- }
- matcher.appendTail(output);
- return output.toString();
- }
-
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java
new file mode 100644
index 00000000..e590d9f6
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java
@@ -0,0 +1,87 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.interceptors.pre;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+import javax.annotation.Priority;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.aai.ResourcesProfiles;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.interceptors.AAIContainerFilter;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.service.AuthorizationService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+
+import lombok.RequiredArgsConstructor;
+
+@Component
+@PreMatching
+@RequiredArgsConstructor
+@Profile(ResourcesProfiles.ONE_WAY_SSL) // this mainly serves the purpose of making the tests work
+@Priority(AAIRequestFilterPriority.AUTHORIZATION)
+public class AuthInterceptor extends AAIContainerFilter implements ContainerRequestFilter {
+
+ private static final Pattern PATTERN_ECHO = Pattern.compile("^.*/util/echo$");
+ private static final Pattern PATTERN_ACTUATOR = Pattern.compile("^.*/actuator/.*$");
+ private static final AAIException AAI_EXCEPTION = new AAIException("AAI_3300");
+ private final AuthorizationService authorizationService;
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ String path = requestContext.getUriInfo().getRequestUri().getPath();
+ if (PATTERN_ECHO.matcher(path).matches() || PATTERN_ACTUATOR.matcher(path).matches()) {
+ return;
+ }
+
+ String basicAuth = requestContext.getHeaders().getFirst("Authorization");
+ if (basicAuth == null || !basicAuth.startsWith("Basic ")) {
+ Response errorResponse = errorResponse("AAI_3300", requestContext.getAcceptableMediaTypes());
+ requestContext.abortWith(errorResponse);
+ return;
+ }
+
+ if (!authorizationService.isAuthorized(basicAuth)) {
+ Response errorResponse = errorResponse("AAI_3300", requestContext.getAcceptableMediaTypes());
+ requestContext.abortWith(errorResponse);
+ return;
+ }
+ }
+
+ private Response errorResponse(String errorCode, List<MediaType> acceptHeaderValues) {
+
+ return Response
+ .status(AAI_EXCEPTION.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, AAI_EXCEPTION, new ArrayList<>()))
+ .build();
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java
index c97e475a..7889a2c9 100644
--- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java
+++ b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java
@@ -41,7 +41,6 @@ import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
-import org.onap.aai.IncreaseNodesTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -67,7 +66,7 @@ import org.xml.sax.InputSource;
@ConditionalOnProperty(value = "aai.remove-xmlns.enabled", havingValue = "true", matchIfMissing = true)
public class NamespaceInterceptor implements ReaderInterceptor {
- private static final Logger log = LoggerFactory.getLogger(IncreaseNodesTool.class);
+ private static final Logger log = LoggerFactory.getLogger(NamespaceInterceptor.class);
private static final String xslStr = String.join("\n",
"<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">",
"<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"no\"/>",
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java
deleted file mode 100644
index b5321052..00000000
--- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.interceptors.pre;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import javax.annotation.Priority;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.PreMatching;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onap.aai.ResourcesProfiles;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.interceptors.AAIContainerFilter;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.service.AuthorizationService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
-
-@Profile(ResourcesProfiles.ONE_WAY_SSL)
-@PreMatching
-@Priority(AAIRequestFilterPriority.AUTHORIZATION)
-public class OneWaySslAuthorization extends AAIContainerFilter implements ContainerRequestFilter {
-
- @Autowired
- private AuthorizationService authorizationService;
-
- @Override
- public void filter(ContainerRequestContext containerRequestContext) throws IOException {
-
- if (containerRequestContext.getUriInfo().getRequestUri().getPath().matches("^.*/util/echo$")) {
- return;
- }
-
- String basicAuth = containerRequestContext.getHeaderString("Authorization");
- List<MediaType> acceptHeaderValues = containerRequestContext.getAcceptableMediaTypes();
-
- if (basicAuth == null || !basicAuth.startsWith("Basic ")) {
- Optional<Response> responseOptional = errorResponse("AAI_3300", acceptHeaderValues);
- containerRequestContext.abortWith(responseOptional.get());
- return;
- }
-
- basicAuth = basicAuth.replaceAll("Basic ", "");
-
- if (!authorizationService.checkIfUserAuthorized(basicAuth)) {
- Optional<Response> responseOptional = errorResponse("AAI_3300", acceptHeaderValues);
- containerRequestContext.abortWith(responseOptional.get());
- return;
- }
-
- }
-
- private Optional<Response> errorResponse(String errorCode, List<MediaType> acceptHeaderValues) {
- AAIException aaie = new AAIException(errorCode);
- return Optional.of(Response.status(aaie.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, aaie, new ArrayList<>())).build());
-
- }
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java b/aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java
index 12839d48..1f66697e 100644
--- a/aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java
+++ b/aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java
@@ -34,8 +34,6 @@ import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.ObjectUtils;
-import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
-import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.onap.aai.concurrent.AaiCallable;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.sideeffect.OwnerCheck;
@@ -65,7 +63,7 @@ public class ResourcesController extends RESTAPI {
@Context HttpHeaders headers,
@Context UriInfo info,
@Context HttpServletRequest req) {
- Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+ Set<String> roles = Collections.emptySet();
MediaType mediaType = headers.getMediaType();
return resourcesService.handleWrites(mediaType, HttpMethod.PUT, content, versionParam, uri, headers, info, roles);
}
@@ -96,7 +94,7 @@ public class ResourcesController extends RESTAPI {
@Context HttpHeaders headers,
@Context UriInfo info,
@Context HttpServletRequest req) {
- Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+ Set<String> roles = Collections.emptySet();
MediaType mediaType = MediaType.APPLICATION_JSON_TYPE;
return resourcesService.handleWrites(mediaType, HttpMethod.MERGE_PATCH, content, versionParam, uri, headers, info, roles);
@@ -134,7 +132,7 @@ public class ResourcesController extends RESTAPI {
@Context HttpHeaders headers,
@Context UriInfo info,
@Context HttpServletRequest req) {
- Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+ Set<String> roles = Collections.emptySet();
Pageable pageable = includeTotalCount == false
? new Pageable(resultIndex -1, resultSize)
: new Pageable(resultIndex -1, resultSize).includeTotalCount();
@@ -159,7 +157,7 @@ public class ResourcesController extends RESTAPI {
@Context UriInfo info,
@QueryParam("resource-version") String resourceVersion,
@Context HttpServletRequest req) {
- Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+ Set<String> roles = Collections.emptySet();
return resourcesService.delete(versionParam, uri, headers, info, req, roles);
}
@@ -210,29 +208,4 @@ public class ResourcesController extends RESTAPI {
protected boolean isEmptyObject(Introspector obj) {
return "{}".equals(obj.marshal(false));
}
-
- private Set<String> getRoles(Principal userPrincipal, String method) {
- KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) userPrincipal;
- if (ObjectUtils.isEmpty(token)) {
- return Collections.emptySet();
- }
- SimpleKeycloakAccount account = (SimpleKeycloakAccount) token.getDetails();
- if (ObjectUtils.isEmpty(account)) {
- return Collections.emptySet();
- }
- // When the request is not a GET, we need to exclude ReadOnly access roles
- if (isNotGetRequest(method)) {
- return getExcludedReadOnlyAccessRoles(account);
- }
- return account.getRoles();
- }
-
- private Set<String> getExcludedReadOnlyAccessRoles(SimpleKeycloakAccount account) {
- return account.getRoles().stream().filter(role -> !role.endsWith(OwnerCheck.READ_ONLY_SUFFIX))
- .collect(Collectors.toSet());
- }
-
- private boolean isNotGetRequest(String method) {
- return !Action.GET.name().equalsIgnoreCase(method);
- }
}
diff --git a/aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java b/aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java
deleted file mode 100644
index c63a70a0..00000000
--- a/aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property.
- * Modifications Copyright (C) 2020 Bell Canada.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.rest.security;
-
-import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
-import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
-import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
-import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Import;
-import org.springframework.context.annotation.Profile;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
-import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
-import org.springframework.security.core.session.SessionRegistryImpl;
-import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
-import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
-import org.springframework.security.web.session.HttpSessionEventPublisher;
-
-@Profile("keycloak")
-@KeycloakConfiguration
-@Import({KeycloakSpringBootConfigResolver.class})
-public class WebSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
-
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) {
- KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
- keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
- auth.authenticationProvider(keycloakAuthenticationProvider);
- }
-
- @Bean
- public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
- return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher());
- }
-
- @Bean
- @Override
- protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
- return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
- }
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- super.configure(http);
- http.authorizeRequests().antMatchers("/**").permitAll().and().csrf().disable();
- }
-
- @Override
- public void configure(WebSecurity web) {
- web.ignoring().regexMatchers("^.*/util/echo$");
- }
-
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java b/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java
index 0c219a75..7b420b9d 100644
--- a/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java
+++ b/aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,92 +20,45 @@
package org.onap.aai.service;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Stream;
+import java.util.Set;
+import java.util.stream.Collectors;
-import javax.annotation.PostConstruct;
-
-import org.eclipse.jetty.util.security.Password;
-import org.onap.aai.ResourcesProfiles;
-import org.onap.aai.util.AAIConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
+import org.onap.aai.config.AuthProperties;
import org.springframework.stereotype.Service;
-@Profile(ResourcesProfiles.ONE_WAY_SSL)
+/**
+ * Should be removed once Spring Security-based auth works
+ */
@Service
public class AuthorizationService {
- private static final Logger logger = LoggerFactory.getLogger(AuthorizationService.class);
-
- private final Map<String, String> authorizedUsers = new HashMap<>();
-
- private static final Base64.Encoder ENCODER = Base64.getEncoder();
-
- @PostConstruct
- public void init() {
-
- String basicAuthFile = getBasicAuthFilePath();
-
- try (Stream<String> stream = Files.lines(Path.of(basicAuthFile))) {
- stream.filter(line -> !line.startsWith("#")).forEach(str -> {
- byte[] bytes = null;
-
- String usernamePassword = null;
- String accessType = null;
-
- try {
- String[] userAccessType = str.split(",");
-
- if (userAccessType == null || userAccessType.length != 2) {
- throw new RuntimeException(
- "Please check the realm.properties file as it is not conforming to the basic auth");
- }
-
- usernamePassword = userAccessType[0];
- accessType = userAccessType[1];
-
- String[] usernamePasswordArray = usernamePassword.split(":");
-
- if (usernamePasswordArray == null || usernamePasswordArray.length != 3) {
- throw new RuntimeException("This username / pwd is not a valid entry in realm.properties");
- }
-
- String username = usernamePasswordArray[0];
- String password = null;
-
- if (str.contains("OBF:")) {
- password = usernamePasswordArray[1] + ":" + usernamePasswordArray[2];
- password = Password.deobfuscate(password);
- }
-
- bytes = ENCODER.encode((username + ":" + password).getBytes("UTF-8"));
-
- authorizedUsers.put(new String(bytes), accessType);
-
- } catch (UnsupportedEncodingException e) {
- logger.error("Unable to support the encoding of the file" + basicAuthFile);
- }
-
- authorizedUsers.put(new String(ENCODER.encode(bytes)), accessType);
- });
- } catch (IOException e) {
- logger.error("IO Exception occurred during the reading of realm.properties", e);
- }
- }
+ // Saved in this format for best performance
+ private final Set<String> authorizedHeaders;
+
+ public AuthorizationService(AuthProperties authProperties) {
+ authorizedHeaders = getAuthorizedHeaders(authProperties);
+ }
+
+ public boolean isAuthorized(String authHeaderValue) {
+ return authorizedHeaders.contains(authHeaderValue);
+ }
+
+ /**
+ * Returns valid Bearer auth headers for all users.
+ * @param authProperties
+ * @param encoder
+ * @return
+ */
+ private Set<String> getAuthorizedHeaders(AuthProperties authProperties) {
+ Base64.Encoder encoder = Base64.getEncoder();
+ return authProperties.getUsers().stream()
+ .map(user -> user.getUsername() + ":" + user.getPassword())
+ .map(usernamePasswordPair -> encoder.encode(usernamePasswordPair.getBytes()))
+ .map(String::new)
+ .map(encodedPair -> "Basic " + encodedPair)
+ .collect(Collectors.toSet());
+ }
- public boolean checkIfUserAuthorized(String authorization) {
- return authorizedUsers.containsKey(authorization) && "admin".equals(authorizedUsers.get(authorization));
- }
- public String getBasicAuthFilePath() {
- return AAIConstants.AAI_HOME_ETC_AUTH + AAIConstants.AAI_FILESEP + "realm.properties";
- }
}
diff --git a/aai-resources/src/main/resources/application-keycloak.properties b/aai-resources/src/main/resources/application-keycloak.properties
deleted file mode 100644
index d398256f..00000000
--- a/aai-resources/src/main/resources/application-keycloak.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-
-spring.autoconfigure.exclude=\
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
- org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
-
-multi.tenancy.enabled=true
-keycloak.auth-server-url=http://localhost:8180/auth
-keycloak.realm=aai-resources
-keycloak.resource=aai-resources-app
-keycloak.public-client=true
-keycloak.principal-attribute=preferred_username
-
-keycloak.ssl-required=external
-keycloak.bearer-only=true \ No newline at end of file
diff --git a/aai-resources/src/main/resources/application.properties b/aai-resources/src/main/resources/application.properties
index f0ef368a..c0c805fc 100644
--- a/aai-resources/src/main/resources/application.properties
+++ b/aai-resources/src/main/resources/application.properties
@@ -20,7 +20,6 @@ server.servlet.context-path=/
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
- org.keycloak.adapters.springboot.KeycloakAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
@@ -37,21 +36,8 @@ server.tomcat.max-idle-time=60000
# If you get an application startup failure that the port is already taken
# If thats not it, please check if the key-store file path makes sense
server.local.startpath=src/main/resources
-server.basic.auth.location=${server.local.startpath}/etc/auth/realm.properties
-server.certs.location=${server.local.startpath}/etc/auth/
-#server.keystore.name=keystore.jks
-server.keystore.name=aai_keystore
-server.truststore.name=aai_keystore
-server.port=8447
-server.ssl.enabled=false
-server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
-server.ssl.key-store=${server.certs.location}${server.keystore.name}
-server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.trust-store=${server.certs.location}${server.truststore.name}
-server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.client-auth=want
-server.ssl.key-store-type=JKS
+server.port=8447
null.db.serialization.enabled=true
@@ -103,10 +89,6 @@ schema.service.nodes.endpoint=nodes?version=
schema.service.edges.endpoint=edgerules?version=
schema.service.versions.endpoint=versions
-schema.service.ssl.key-store=${server.certs.location}${server.keystore.name}
-schema.service.ssl.trust-store=${server.certs.location}${server.truststore.name}
-schema.service.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-schema.service.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
schema.service.versions.override=false
#To Expose the Prometheus scraping endpoint
@@ -134,14 +116,6 @@ delta.events.enabled=false
validation.service.client=one-way-ssl
# Base url for the validation service
validation.service.base.url=https://localhost:9501/services/validation-service
-# Client certificate to use to make the request to validation
-validation.service.ssl.key-store=${server.local.startpath}/etc/auth/aai-client-cert.p12
-# Truststore to use to make the request to validation
-validation.service.ssl.trust-store=${server.local.startpath}/etc/auth/tomcat_keystore
-# Client certificate password for the validation
-validation.service.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-# Truststore password for the validation
-validation.service.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
# Amount of time that the client should wait in milliseconds before request failing
validation.service.timeout-in-milliseconds=3000
# List of aai node types that should be send to the validation microservice
@@ -163,3 +137,7 @@ aai.actuator.echo.enabled=false
aai.notifications.enabled=false
aai.graph.properties.path=${server.local.startpath}/etc/appprops/janusgraph-realtime.properties
+
+aai.basic-auth.enabled=true
+aai.basic-auth.users[0].username=AAI
+aai.basic-auth.users[0].password=AAI
diff --git a/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties b/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
index ecbbcb1c..cd197341 100644
--- a/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
+++ b/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
@@ -48,11 +48,6 @@ aai.server.url.base=https://localhost:8443/aai/
aai.server.url=https://localhost:8443/aai/v20/
aai.global.callback.url=https://localhost:8443/aai/
-aai.truststore.filename=aai_keystore
-aai.truststore.passwd.x=OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0
-aai.keystore.filename=aai-client-cert.p12
-aai.keystore.passwd.x=
-
aai.notification.current.version=v20
aai.notificationEvent.default.status=UNPROCESSED
aai.notificationEvent.default.eventType=AAI-EVENT
diff --git a/aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java b/aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java
index 93b15192..0d7ff7ef 100644
--- a/aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java
+++ b/aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java
@@ -24,7 +24,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.security.KeyStore;
import javax.net.ssl.SSLContext;
@@ -63,20 +62,7 @@ public class ResourcesTestConfiguration {
RestTemplate restTemplate = null;
if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL, ResourcesProfiles.ONE_WAY_SSL))) {
- char[] trustStorePassword = env.getProperty("server.ssl.trust-store-password").toCharArray();
- char[] keyStorePassword = env.getProperty("server.ssl.key-store-password").toCharArray();
-
- String keyStore = env.getProperty("server.ssl.key-store");
- String trustStore = env.getProperty("server.ssl.trust-store");
- SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
-
- if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL))) {
- sslContextBuilder =
- sslContextBuilder.loadKeyMaterial(loadPfx(keyStore, keyStorePassword), keyStorePassword);
- }
-
- SSLContext sslContext =
- sslContextBuilder.loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword).build();
+ SSLContext sslContext = SSLContextBuilder.create().build();
HttpClient client = HttpClients.custom().setSSLContext(sslContext)
.setSSLHostnameVerifier((s, sslSession) -> true).build();
@@ -113,13 +99,4 @@ public class ResourcesTestConfiguration {
return restTemplate;
}
-
- private KeyStore loadPfx(String file, char[] password) throws Exception {
- KeyStore keyStore = KeyStore.getInstance("PKCS12");
- File key = ResourceUtils.getFile(file);
- try (InputStream in = new FileInputStream(key)) {
- keyStore.load(in, password);
- }
- return keyStore;
- }
}
diff --git a/aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java b/aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java
index e412dede..e317ef0d 100644
--- a/aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java
+++ b/aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java
@@ -1,3 +1,23 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
package org.onap.aai.config;
import java.time.Duration;
@@ -7,7 +27,7 @@ import org.onap.aai.setup.SchemaVersions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java
deleted file mode 100644
index 1e47c42d..00000000
--- a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.it.multitenancy;
-
-import com.github.dockerjava.api.model.ExposedPort;
-import com.github.dockerjava.api.model.HostConfig;
-import com.github.dockerjava.api.model.PortBinding;
-import com.github.dockerjava.api.model.Ports;
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-
-import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.KeycloakBuilder;
-import org.keycloak.representations.adapters.config.AdapterConfig;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.context.annotation.Bean;
-
-@TestConfiguration
-class KeycloakTestConfiguration {
-
- @Bean
- public AdapterConfig adapterConfig() {
- return new KeycloakSpringBootProperties();
- }
-
- @Bean
- KeycloakContainer keycloakContainer(KeycloakTestProperties properties) {
- KeycloakContainer keycloak =
- new KeycloakContainer("jboss/keycloak:12.0.4").withRealmImportFile(properties.realmJson)
- .withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(new HostConfig().withPortBindings(
- new PortBinding(Ports.Binding.bindPort(Integer.parseInt(properties.port)),
- new ExposedPort(8080)))));
- keycloak.start();
- return keycloak;
- }
-
- @Bean
- Keycloak keycloakAdminClient(KeycloakContainer keycloak, KeycloakTestProperties properties) {
- return KeycloakBuilder.builder().serverUrl(keycloak.getAuthServerUrl()).realm(properties.realm)
- .clientId(properties.adminCli).username(keycloak.getAdminUsername())
- .password(keycloak.getAdminPassword()).build();
- }
-
- @Bean
- RoleHandler roleHandler(Keycloak adminClient, KeycloakTestProperties properties) {
- return new RoleHandler(adminClient, properties);
- }
-
- @Bean
- KeycloakTestProperties properties() {
- return new KeycloakTestProperties();
- }
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java
deleted file mode 100644
index 7f1e34ce..00000000
--- a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.it.multitenancy;
-
-import org.springframework.beans.factory.annotation.Value;
-
-class KeycloakTestProperties {
-
- @Value("${test.keycloak.realm.json}")
- public String realmJson;
-
- @Value("${keycloak.realm}")
- public String realm;
-
- @Value("${keycloak.resource}")
- public String clientId;
-
- @Value("${test.keycloak.client.secret}")
- public String clientSecret;
-
- @Value("${test.keycloak.admin.cli}")
- public String adminCli;
-
- @Value("${test.keycloak.auth-server-port}")
- public String port;
-
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java
deleted file mode 100644
index 892b8e3e..00000000
--- a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * ============LICENSE_START==================================================
- * org.onap.aai
- * ===========================================================================
- * Copyright © 2017-2020 AT&T Intellectual Property. All rights reserved.
- * ===========================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END====================================================
- */
-
-package org.onap.aai.it.multitenancy;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-import org.junit.jupiter.api.Test;
-
-import java.util.Collections;
-
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.KeycloakBuilder;
-import org.keycloak.representations.AccessTokenResponse;
-import org.onap.aai.PayloadUtil;
-import org.onap.aai.rest.AbstractSpringRestTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Import;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.TestPropertySource;
-
-@Import(KeycloakTestConfiguration.class)
-@TestPropertySource(locations = "classpath:it/application-keycloak-test.properties")
-public class MultiTenancyIT extends AbstractSpringRestTest {
-
- @Autowired
- private KeycloakContainer keycloakContainer;
- @Autowired
- private RoleHandler roleHandler;
- @Autowired
- private KeycloakTestProperties properties;
-
- @Test
- public void testCreateAndGetPnf() throws Exception {
- baseUrl = "http://localhost:" + randomPort;
- String endpoint = baseUrl + "/aai/v23/network/pnfs/pnf/pnf-1";
- ResponseEntity<String> responseEntity = null;
-
- // create pnf with ran (operator)
- String username = "ran", password = "ran";
- headers = this.getHeaders(username, password);
- httpEntity = new HttpEntity<String>(PayloadUtil.getResourcePayload("pnf.json"), headers);
- responseEntity = restTemplate.exchange(endpoint, HttpMethod.PUT, httpEntity, String.class);
- assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode());
-
- // get pnf with bob (operator_readOnly)
- username = "bob";
- password = "bob";
- headers = this.getHeaders(username, password);
- httpEntity = new HttpEntity<String>("", headers);
- responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
- assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
-
- // get pnf with ted (selector)
- username = "ted";
- password = "ted";
- headers = this.getHeaders(username, password);
- httpEntity = new HttpEntity<String>("", headers);
- responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
- assertEquals(HttpStatus.FORBIDDEN, responseEntity.getStatusCode());
-
- // add role to ted and try to get pnf again
- roleHandler.addToUser(RoleHandler.OPERATOR_READ_ONLY, username);
- headers = this.getHeaders(username, password);
- httpEntity = new HttpEntity<String>("", headers);
- responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
- assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
-
- // get pnf with ran
- username = "ran";
- password = "ran";
- headers = this.getHeaders(username, password);
- httpEntity = new HttpEntity<String>("", headers);
- responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
- assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
- }
-
- private HttpHeaders getHeaders(String username, String password) {
- HttpHeaders headers = new HttpHeaders();
-
- headers.setContentType(MediaType.APPLICATION_JSON);
- headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
- headers.add("Real-Time", "true");
- headers.add("X-FromAppId", "JUNIT");
- headers.add("X-TransactionId", "JUNIT");
- headers.add("Authorization", "Bearer " + getStringToken(username, password));
-
- return headers;
- }
-
- private String getStringToken(String username, String password) {
- Keycloak keycloakClient = KeycloakBuilder.builder().serverUrl(keycloakContainer.getAuthServerUrl())
- .realm(properties.realm).clientId(properties.clientId).clientSecret(properties.clientSecret)
- .username(username).password(password).build();
-
- AccessTokenResponse tokenResponse = keycloakClient.tokenManager().getAccessToken();
- assertNotNull(tokenResponse);
- return tokenResponse.getToken();
- }
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java
deleted file mode 100644
index c9c1fd23..00000000
--- a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.it.multitenancy;
-
-import java.util.Collections;
-
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.resource.RealmResource;
-
-class RoleHandler {
-
- /**
- * Following roles should be the same as given roles in multi-tenancy-realm json file
- */
- final static String OPERATOR = "operator";
- final static String OPERATOR_READ_ONLY = "operator_readOnly";
- private final Keycloak adminClient;
- private final KeycloakTestProperties properties;
-
- RoleHandler(Keycloak adminClient, KeycloakTestProperties properties) {
- this.adminClient = adminClient;
- this.properties = properties;
- }
-
- void addToUser(String role, String username) {
- RealmResource realm = adminClient.realm(properties.realm);
- realm.users().get(username).roles().realmLevel()
- .add(Collections.singletonList(realm.roles().get(role).toRepresentation()));
- }
-
- void removeFromUser(String role, String username) {
- RealmResource realm = adminClient.realm(properties.realm);
- realm.users().get(username).roles().realmLevel()
- .remove(Collections.singletonList(realm.roles().get(role).toRepresentation()));
- }
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java b/aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java
index adfa433a..edf905ee 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java
@@ -36,7 +36,6 @@ import org.onap.aai.ResourcesTestConfiguration;
import org.onap.aai.dbmap.AAIGraph;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.nodes.NodeIngestor;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
import org.onap.aai.util.AAIConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -54,7 +53,7 @@ import org.springframework.web.client.RestTemplate;
@Import(ResourcesTestConfiguration.class)
@TestPropertySource(locations = "classpath:application-test.properties")
-@ContextConfiguration(initializers = PropertyPasswordConfiguration.class)
+@ContextConfiguration
@EnableAutoConfiguration(exclude = {CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class}) // there is no running cassandra instance for the test
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ResourcesApp.class)
public abstract class AbstractSpringRestTest {
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java b/aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java
new file mode 100644
index 00000000..446b3757
--- /dev/null
+++ b/aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.rest;
+
+import java.time.Duration;
+import java.util.Collections;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.config.AuthProperties;
+import org.onap.aai.config.WebClientConfiguration;
+import org.onap.aai.setup.SchemaVersions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@Import(WebClientConfiguration.class)
+public class AuthenticationTest {
+
+ @Autowired AuthProperties authProperties;
+ @Autowired SchemaVersions schemaVersions;
+ @LocalServerPort int port;
+
+ WebTestClient webClient;
+
+ @BeforeEach
+ void setup() {
+ webClient = WebTestClient.bindToServer()
+ .baseUrl("http://localhost:" + port + "/aai/" + schemaVersions.getDefaultVersion())
+ .responseTimeout(Duration.ofSeconds(300))
+ .defaultHeaders(headers -> {
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ headers.set("X-FromAppId", "test");
+ headers.set("X-TransactionId", "someTransaction");
+ })
+ .build();
+ }
+
+ @Test
+ void thatServiceIsAuthenticated() {
+ webClient.get()
+ .uri("/cloud-infrastructure/pservers/pserver/pserver-hostname-test")
+ .exchange()
+ .expectStatus()
+ .isForbidden();
+
+ webClient.get()
+ .uri("/cloud-infrastructure/pservers/pserver/pserver-hostname-test")
+ .headers(headers -> headers.setBasicAuth(authProperties.getUsers().get(0).getUsername(), authProperties.getUsers().get(0).getPassword()))
+ .exchange()
+ .expectStatus()
+ .isNotFound();
+ }
+
+}
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java b/aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java
index 15c03cf8..51ab2aa1 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java
@@ -35,7 +35,6 @@ import org.junit.jupiter.api.Test;
import org.onap.aai.ResourcesApp;
import org.onap.aai.ResourcesTestConfiguration;
import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -61,7 +60,7 @@ import org.springframework.web.client.RestTemplate;
@AutoConfigureMetrics
@TestPropertySource(locations = "classpath:application-test.properties")
-@ContextConfiguration(initializers = PropertyPasswordConfiguration.class, classes = {SpringContextAware.class})
+@ContextConfiguration(classes = {SpringContextAware.class})
@EnableAutoConfiguration(exclude={CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class}) // there is no running cassandra instance for the test
@Import(ResourcesTestConfiguration.class)
@SpringBootTest(
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java b/aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java
index da7c0647..6d0dcbf1 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java
@@ -99,71 +99,11 @@ import reactor.core.publisher.Mono;
public class ResourcesControllerTest {
private static final Logger logger = LoggerFactory.getLogger(ResourcesController.class.getName());
- private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
- protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
-
- static {
- VALID_HTTP_STATUS_CODES.add(200);
- VALID_HTTP_STATUS_CODES.add(201);
- VALID_HTTP_STATUS_CODES.add(204);
- }
+ private static final ObjectMapper mapper = new ObjectMapper();
@Autowired WebTestClient webClient;
@Autowired SchemaVersions schemaVersions;
- ObjectMapper mapper = new ObjectMapper();
-
- private ResourcesController resourcesController;
- private HttpHeaders httpHeaders;
- private UriInfo uriInfo;
- private MultivaluedMap<String, String> headersMultiMap;
- private MultivaluedMap<String, String> queryParameters;
- private List<String> aaiRequestContextList;
- private List<MediaType> outputMediaTypes;
- private String defaultSchemaVersion;
-
- @BeforeEach
- public void setup() throws AAIException {
- if(!AAIGraph.isInit()) {
- AAIConfig.init();
- AAIGraph.getInstance();
- }
- logger.info("Starting the setup for the integration tests of Rest Endpoints");
-
- resourcesController = new ResourcesController(new ResourcesService());
- httpHeaders = Mockito.mock(HttpHeaders.class);
- uriInfo = Mockito.mock(UriInfo.class);
-
- headersMultiMap = new MultivaluedHashMap<>();
- queryParameters = Mockito.spy(new MultivaluedHashMap<>());
-
- headersMultiMap.add("X-FromAppId", "JUNIT");
- headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
- headersMultiMap.add("Real-Time", "true");
- headersMultiMap.add("Accept", "application/json");
- headersMultiMap.add("aai-request-context", "");
-
- outputMediaTypes = new ArrayList<>();
- outputMediaTypes.add(APPLICATION_JSON);
-
- aaiRequestContextList = new ArrayList<>();
- aaiRequestContextList.add("");
- defaultSchemaVersion = schemaVersions.getDefaultVersion().toString();
-
- when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
- when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
-
- when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
-
- when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
- when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
-
- // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be very unreasonable
- Mockito.doReturn(null).when(queryParameters).remove(any());
-
- when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
- }
-
@AfterEach
public void tearDown() {
JanusGraph janusGraph = AAIGraph.getInstance().getGraph();
@@ -423,11 +363,6 @@ public class ResourcesControllerTest {
String patchData = "{\"in-maint\": false}";
- headersMultiMap.add("Content-Type", "application/json");
-
- outputMediaTypes.remove(APPLICATION_JSON);
- outputMediaTypes.add(MediaType.valueOf("application/merge-patch+json"));
-
webClient.patch()
.uri(uri)
.header("Content-Type", "application/merge-patch+json")
@@ -496,12 +431,12 @@ public class ResourcesControllerTest {
public String getResourcePayload(String resourceName) throws IOException {
String rawPayload = IOUtils.toString(this.getClass().getResourceAsStream("/payloads/resource/" + resourceName + ".json"), StandardCharsets.UTF_8);
- return String.format(rawPayload, defaultSchemaVersion);
+ return String.format(rawPayload, schemaVersions.getDefaultVersion());
}
public String getRelationshipPayload(String relationshipName) throws IOException {
String rawPayload = IOUtils.toString(this.getClass().getResourceAsStream("/payloads/relationship/" + relationshipName + ".json"), StandardCharsets.UTF_8);
- return String.format(rawPayload, defaultSchemaVersion);
+ return String.format(rawPayload, schemaVersions.getDefaultVersion());
}
public String getUri(String hostname) {
diff --git a/aai-resources/src/test/resources/application-test.properties b/aai-resources/src/test/resources/application-test.properties
index 622715d8..e2b11ad2 100644
--- a/aai-resources/src/test/resources/application-test.properties
+++ b/aai-resources/src/test/resources/application-test.properties
@@ -16,7 +16,6 @@ spring.sleuth.enabled=false
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
- org.keycloak.adapters.springboot.KeycloakAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
@@ -28,17 +27,7 @@ server.tomcat.threads.min-spare=25
server.tomcat.max-idle-time=60000
server.local.startpath=src/main/resources/
-server.basic.auth.location=${server.local.startpath}etc/auth/realm.properties
-
server.port=8447
-server.ssl.enabled=false
-#server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
-#server.ssl.key-store=${server.local.startpath}etc/auth/aai_keystore
-#server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-#server.ssl.trust-store=${server.local.startpath}etc/auth/aai_keystore
-#server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-#server.ssl.client-auth=want
-#server.ssl.key-store-type=JKS
# Removed deprecated DMaaP reference
# dmaap.ribbon.listOfServers=localhost:3904
@@ -82,3 +71,6 @@ scrape.uri.metrics=true
aai.notifications.enabled=false
aai.graph.properties.path=src/test/resources/etc/appprops/janusgraph-realtime.properties
+aai.basic-auth.enabled=true
+aai.basic-auth.users[0].username=AAI
+aai.basic-auth.users[0].password=AAI
diff --git a/aai-resources/src/test/resources/it/application-keycloak-test.properties b/aai-resources/src/test/resources/it/application-keycloak-test.properties
deleted file mode 100644
index 6fff1c1c..00000000
--- a/aai-resources/src/test/resources/it/application-keycloak-test.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-test.keycloak.realm.json=it/multi-tenancy-realm.json
-test.keycloak.client.secret=secret
-test.keycloak.admin.cli=admin-cli
-test.keycloak.auth-server-port=58180
-
-keycloak.auth-server-url=http://localhost:58180/auth
-keycloak.realm=aai-resources
-keycloak.resource=aai-resources-app
-keycloak.public-client=true
-keycloak.principal-attribute=preferred_username
-
-keycloak.ssl-required=external
-keycloak.bearer-only=true
-
-multi.tenancy.enabled=true
-spring.profiles.active=production,keycloak
-schema.version.list=v10,v11,v12,v13,v14,v29,v30
diff --git a/aai-resources/src/test/resources/it/multi-tenancy-realm.json b/aai-resources/src/test/resources/it/multi-tenancy-realm.json
deleted file mode 100644
index 401187b2..00000000
--- a/aai-resources/src/test/resources/it/multi-tenancy-realm.json
+++ /dev/null
@@ -1,173 +0,0 @@
-{
- "id": "aai-resources",
- "realm": "aai-resources",
- "notBefore": 0,
- "revokeRefreshToken": false,
- "refreshTokenMaxReuse": 0,
- "accessTokenLifespan": 300,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "ssoSessionIdleTimeoutRememberMe": 0,
- "ssoSessionMaxLifespanRememberMe": 0,
- "offlineSessionIdleTimeout": 2592000,
- "offlineSessionMaxLifespanEnabled": false,
- "offlineSessionMaxLifespan": 5184000,
- "clientSessionIdleTimeout": 0,
- "clientSessionMaxLifespan": 0,
- "clientOfflineSessionIdleTimeout": 0,
- "clientOfflineSessionMaxLifespan": 0,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "actionTokenGeneratedByAdminLifespan": 43200,
- "actionTokenGeneratedByUserLifespan": 300,
- "enabled": true,
- "sslRequired": "external",
- "registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
- "verifyEmail": false,
- "loginWithEmailAllowed": true,
- "duplicateEmailsAllowed": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "permanentLockout": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "users": [
- {
- "username": "admin",
- "enabled": true,
- "credentials": [
- {
- "type": "password",
- "value": "admin"
- }
- ],
- "clientRoles": {
- "realm-management": ["manage-users", "view-clients", "view-realm", "view-users"]
- }
- },
- {
- "id": "ran",
- "username": "ran",
- "enabled": true,
- "credentials": [
- {
- "type": "password",
- "value": "ran"
- }
- ],
- "realmRoles": [
- "operator"
- ]
- },
- {
- "id": "bob",
- "username": "bob",
- "enabled": true,
- "credentials": [
- {
- "type": "password",
- "value": "bob"
- }
- ],
- "realmRoles": [
- "operator_readOnly"
- ]
- },
- {
- "id": "ted",
- "username": "ted",
- "enabled": true,
- "credentials": [
- {
- "type": "password",
- "value": "ted"
- }
- ],
- "realmRoles": [
- "selector"
- ]
- }
- ],
- "roles": {
- "realm": [
- {
- "name": "operator",
- "description": "Operator privileges"
- },
- {
- "name": "operator_readOnly",
- "description": "Operator's read only privileges"
- },
- {
- "name": "selector",
- "description": "Selector privileges"
- },
- {
- "name": "selector_readOnly",
- "description": "Selector's read only privileges"
- },
- {
- "name": "admin",
- "description": "Administrator privileges"
- }
- ]
- },
- "clients": [
- {
- "clientId": "aai-resources-app",
- "enabled": true,
- "secret": "secret",
- "directAccessGrantsEnabled": true,
- "authorizationServicesEnabled": true,
- "authorizationSettings": {
- "allowRemoteResourceManagement": true,
- "policyEnforcementMode": "ENFORCING"
- }
- }
- ],
- "defaultDefaultClientScopes": [
- "roles",
- "email",
- "web-origins",
- "profile",
- "role_list"
- ],
- "clientScopes": [
- {
- "id": "0f7dfd8b-c230-4664-8d77-da85bcc4fe2a",
- "name": "roles",
- "description": "OpenID Connect scope for add user roles to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${rolesScopeConsentText}"
- },
- "protocolMappers": [
- {
- "id": "4b9f8798-8990-4c0d-87d3-034e72655e3b",
- "name": "realm roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "multivalued": "true",
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "realm_access.roles",
- "jsonType.label": "String"
- }
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c1d916a8..7a63d2b2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,11 +26,11 @@
<parent>
<groupId>org.onap.aai.aai-common</groupId>
<artifactId>aai-parent</artifactId>
- <version>1.15.4</version>
+ <version>1.15.5-SNAPSHOT</version>
</parent>
<groupId>org.onap.aai.resources</groupId>
<artifactId>resources</artifactId>
- <version>1.15.4-SNAPSHOT</version>
+ <version>1.15.5-SNAPSHOT</version>
<name>aai-resources</name>
<packaging>pom</packaging>
<modules>
@@ -49,7 +49,7 @@
<staging.path>/content/repositories/staging/</staging.path>
<!-- GMaven plugin uses this property to figure out the name of the docker tag -->
<aai.project.version>${project.version}</aai.project.version>
- <aai.common.version>1.15.4</aai.common.version>
+ <aai.common.version>1.15.5-SNAPSHOT</aai.common.version>
<aai.schema.service.version>1.12.7</aai.schema.service.version>
</properties>
<build>
diff --git a/version.properties b/version.properties
index 08fc17cd..73ddb41f 100644
--- a/version.properties
+++ b/version.properties
@@ -5,7 +5,7 @@
major_version=1
minor_version=15
-patch_version=3
+patch_version=5
base_version=${major_version}.${minor_version}.${patch_version}