You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by di...@apache.org on 2026/07/31 13:40:38 UTC
(airavata) branch refactor-single-module updated: Adding spring recurity
This is an automated email from the ASF dual-hosted git repository.
DImuthuUpe pushed a commit to branch refactor-single-module
in repository https://gitbox.apache.org/repos/asf/airavata.git
The following commit(s) were added to refs/heads/refactor-single-module by this push:
new ad4af64124 Adding spring recurity
ad4af64124 is described below
commit ad4af641240db2769c50e3743abfd60b56cbc2bf
Author: DImuthuUpe <di...@gmail.com>
AuthorDate: Fri Jul 31 09:40:31 2026 -0400
Adding spring recurity
---
pom.xml | 10 +
.../api/ApplicationInterfaceController.java | 5 +
...oller.java => ApplicationModuleController.java} | 4 +-
.../ApplicationDeploymentRepository.java | 225 +--------------------
.../repository/ApplicationInputRepository.java | 19 +-
.../repository/ApplicationInterfaceRepository.java | 183 +----------------
.../repository/ApplicationOutputRepository.java | 21 +-
.../service/ApplicationInputService.java | 8 +
.../service/ApplicationInterfaceService.java | 18 ++
.../service/ApplicationModuleService.java | 4 +
.../org/apache/airavata/common/RequestContext.java | 22 +-
.../server/auth/JwtRoleAuthoritiesConverter.java | 58 ++++++
.../server/auth/MockUserRoleLookupService.java | 44 ++++
.../airavata/server/auth/SecurityConfig.java | 81 ++++++++
.../server/auth/UserRoleLookupService.java | 32 +++
15 files changed, 274 insertions(+), 460 deletions(-)
diff --git a/pom.xml b/pom.xml
index 43f25b2df2..7a04ed0ab1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,16 @@ under the License.
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-security</artifactId>
+ <version>${spring.boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
+ <version>${spring.boot.version}</version>
+ </dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
diff --git a/src/main/java/org/apache/airavata/api/ApplicationInterfaceController.java b/src/main/java/org/apache/airavata/api/ApplicationInterfaceController.java
new file mode 100644
index 0000000000..db863bede7
--- /dev/null
+++ b/src/main/java/org/apache/airavata/api/ApplicationInterfaceController.java
@@ -0,0 +1,5 @@
+package org.apache.airavata.api;
+
+public class ApplicationInterfaceController {
+
+}
diff --git a/src/main/java/org/apache/airavata/api/ApplicationController.java b/src/main/java/org/apache/airavata/api/ApplicationModuleController.java
similarity index 93%
rename from src/main/java/org/apache/airavata/api/ApplicationController.java
rename to src/main/java/org/apache/airavata/api/ApplicationModuleController.java
index 0461c86dd7..697b193502 100644
--- a/src/main/java/org/apache/airavata/api/ApplicationController.java
+++ b/src/main/java/org/apache/airavata/api/ApplicationModuleController.java
@@ -13,11 +13,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.service.annotation.DeleteExchange;
@Controller
-public class ApplicationController {
+public class ApplicationModuleController {
private final ApplicationModuleService applicationModuleService;
- public ApplicationController(ApplicationModuleService applicationModuleService) {
+ public ApplicationModuleController(ApplicationModuleService applicationModuleService) {
this.applicationModuleService = applicationModuleService;
}
diff --git a/src/main/java/org/apache/airavata/application/repository/ApplicationDeploymentRepository.java b/src/main/java/org/apache/airavata/application/repository/ApplicationDeploymentRepository.java
index d9fd819815..e9bdef4095 100644
--- a/src/main/java/org/apache/airavata/application/repository/ApplicationDeploymentRepository.java
+++ b/src/main/java/org/apache/airavata/application/repository/ApplicationDeploymentRepository.java
@@ -19,230 +19,11 @@
*/
package org.apache.airavata.application.repository;
-import java.sql.Timestamp;
-import java.util.*;
-import org.apache.airavata.db.AbstractRepository;
-import org.apache.airavata.db.DBConstants;
-import org.apache.airavata.db.QueryConstants;
-import org.apache.airavata.models.appcatalog.appdeployment.ApplicationDeploymentDescription;
-import org.apache.airavata.models.appcatalog.computeresource.ComputeResourceDescription;
-import org.apache.airavata.application.mapper.ApplicationMapper;
-import org.apache.airavata.application.model.ApplicationDeploymentEntity;
-import org.apache.airavata.compute.repository.ComputeResourceRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
+import org.apache.airavata.application.model.ApplicationDeploymentEntity;
@Component
-public class ApplicationDeploymentRepository
- extends AbstractRepository<ApplicationDeploymentDescription, ApplicationDeploymentEntity, String> {
- private static final Logger logger = LoggerFactory.getLogger(ApplicationDeploymentRepository.class);
-
- private final ComputeResourceRepository computeResource;
-
- public ApplicationDeploymentRepository(ComputeResourceRepository computeResource) {
- super(ApplicationDeploymentDescription.class, ApplicationDeploymentEntity.class);
- this.computeResource = computeResource;
- }
-
- @Override
- protected ApplicationDeploymentDescription toModel(ApplicationDeploymentEntity entity) {
- return ApplicationMapper.INSTANCE.appDeploymentToModel(entity);
- }
-
- @Override
- protected ApplicationDeploymentEntity toEntity(ApplicationDeploymentDescription model) {
- return ApplicationMapper.INSTANCE.appDeploymentToEntity(model);
- }
-
- protected String saveApplicationDeploymentDescriptorData(
- ApplicationDeploymentDescription applicationDeploymentDescription, String gatewayId)
- throws Exception {
- ApplicationDeploymentEntity applicationDeploymentEntity = saveApplicationDeployment(
- applicationDeploymentDescription, gatewayId);
- return applicationDeploymentEntity.getAppDeploymentId();
- }
-
- protected ApplicationDeploymentEntity saveApplicationDeployment(
- ApplicationDeploymentDescription applicationDeploymentDescription, String gatewayId)
- throws Exception {
-
- if (applicationDeploymentDescription.appDeploymentId().trim().isEmpty()
- || applicationDeploymentDescription.appDeploymentId().equals("DO_NOT_SET_AT_CLIENTS")) {
- logger.debug(
- "If Application Deployment ID is empty or DEFAULT, set it as the compute host name plus the App Module ID");
- ComputeResourceDescription computeResourceDescription = computeResource
- .getComputeResource(applicationDeploymentDescription.computeHostId());
- applicationDeploymentDescription = applicationDeploymentDescription.toBuilder()
- .setAppDeploymentId(computeResourceDescription.hostName() + "_"
- + applicationDeploymentDescription.appModuleId())
- .build();
- }
-
- String applicationDeploymentId = applicationDeploymentDescription.appDeploymentId();
- ApplicationDeploymentEntity applicationDeploymentEntity = ApplicationMapper.INSTANCE
- .appDeploymentToEntity(applicationDeploymentDescription);
-
- if (gatewayId != null) {
- logger.debug("Setting the gateway ID of the Application Deployment");
- applicationDeploymentEntity.setGatewayId(gatewayId);
- }
-
- if (!isAppDeploymentExists(applicationDeploymentId)) {
- logger.debug("Checking if the Application Deployment already exists");
- applicationDeploymentEntity.setCreationTime(new Timestamp(System.currentTimeMillis()));
- }
-
- applicationDeploymentEntity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
- return execute(entityManager -> entityManager.merge(applicationDeploymentEntity));
- }
-
- public String addApplicationDeployment(
- ApplicationDeploymentDescription applicationDeploymentDescription, String gatewayId)
- throws Exception {
- return saveApplicationDeploymentDescriptorData(applicationDeploymentDescription, gatewayId);
- }
-
- public void updateApplicationDeployment(
- String deploymentId, ApplicationDeploymentDescription updatedApplicationDeploymentDescription)
- throws Exception {
- saveApplicationDeploymentDescriptorData(updatedApplicationDeploymentDescription, null);
- }
-
- public ApplicationDeploymentDescription getApplicationDeployement(String deploymentId) throws Exception {
- return get(deploymentId);
- }
-
- public List<ApplicationDeploymentDescription> getApplicationDeployments(Map<String, String> filters)
- throws Exception {
-
- List<ApplicationDeploymentDescription> deploymentDescriptions = new ArrayList<>();
- try {
- boolean firstTry = true;
- for (String fieldName : filters.keySet()) {
- List<ApplicationDeploymentDescription> tmpDescriptions;
-
- switch (fieldName) {
- case DBConstants.ApplicationDeployment.APPLICATION_MODULE_ID: {
- logger.debug(
- "Fetching all Application Deployments for Application Module ID {}",
- filters.get(DBConstants.ApplicationDeployment.APPLICATION_MODULE_ID));
-
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(
- DBConstants.ApplicationDeployment.APPLICATION_MODULE_ID, filters.get(fieldName));
- tmpDescriptions = select(
- QueryConstants.FIND_APPLICATION_DEPLOYMENTS_FOR_APPLICATION_MODULE_ID,
- -1,
- 0,
- queryParameters);
- break;
- }
-
- case DBConstants.ApplicationDeployment.COMPUTE_HOST_ID: {
- logger.debug(
- "Fetching Application Deployments for Compute Host ID {}",
- filters.get(DBConstants.ApplicationDeployment.COMPUTE_HOST_ID));
-
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationDeployment.COMPUTE_HOST_ID, filters.get(fieldName));
- tmpDescriptions = select(
- QueryConstants.FIND_APPLICATION_DEPLOYMENTS_FOR_COMPUTE_HOST_ID,
- -1,
- 0,
- queryParameters);
- break;
- }
-
- default:
- logger.error("Unsupported field name for app deployment in filters: {}", filters);
- throw new IllegalArgumentException(
- "Unsupported field name for app deployment in filters: " + filters);
- }
-
- if (firstTry) {
- deploymentDescriptions.addAll(tmpDescriptions);
- firstTry = false;
-
- } else {
- List<String> ids = new ArrayList<>();
- for (ApplicationDeploymentDescription applicationDeploymentDescription : deploymentDescriptions) {
- ids.add(applicationDeploymentDescription.appDeploymentId());
- }
- List<ApplicationDeploymentDescription> tmp2Descriptions = new ArrayList<>();
- for (ApplicationDeploymentDescription applicationDeploymentDescription : tmpDescriptions) {
- if (ids.contains(applicationDeploymentDescription.appDeploymentId())) {
- tmp2Descriptions.add(applicationDeploymentDescription);
- }
- }
- deploymentDescriptions.clear();
- deploymentDescriptions.addAll(tmp2Descriptions);
- }
- }
- } catch (Exception e) {
- logger.error("Error while retrieving app deployment list...", e);
- throw new Exception(e);
- }
- return deploymentDescriptions;
- }
-
- public List<ApplicationDeploymentDescription> getAllApplicationDeployements(String gatewayId)
- throws Exception {
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationDeployment.GATEWAY_ID, gatewayId);
- return select(QueryConstants.FIND_APPLICATION_DEPLOYMENTS_FOR_GATEWAY_ID, -1, 0, queryParameters);
- }
-
- public List<ApplicationDeploymentDescription> getAccessibleApplicationDeployments(
- String gatewayId, List<String> accessibleAppIds, List<String> accessibleCompHostIds)
- throws Exception {
- if (accessibleAppIds.isEmpty() || accessibleCompHostIds.isEmpty()) {
- return Collections.emptyList();
- }
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationDeployment.GATEWAY_ID, gatewayId);
- queryParameters.put(DBConstants.ApplicationDeployment.ACCESSIBLE_APPLICATION_DEPLOYMENT_IDS, accessibleAppIds);
- queryParameters.put(DBConstants.ApplicationDeployment.ACCESSIBLE_COMPUTE_HOST_IDS, accessibleCompHostIds);
- return select(QueryConstants.FIND_ACCESSIBLE_APPLICATION_DEPLOYMENTS, -1, 0, queryParameters);
- }
-
- public List<ApplicationDeploymentDescription> getAccessibleApplicationDeployments(
- String gatewayId,
- String appModuleId,
- List<String> accessibleAppIds,
- List<String> accessibleComputeResourceIds)
- throws Exception {
- if (accessibleAppIds.isEmpty() || accessibleComputeResourceIds.isEmpty()) {
- return Collections.emptyList();
- }
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationDeployment.GATEWAY_ID, gatewayId);
- queryParameters.put(DBConstants.ApplicationDeployment.APPLICATION_MODULE_ID, appModuleId);
- queryParameters.put(DBConstants.ApplicationDeployment.ACCESSIBLE_APPLICATION_DEPLOYMENT_IDS, accessibleAppIds);
- queryParameters.put(
- DBConstants.ApplicationDeployment.ACCESSIBLE_COMPUTE_HOST_IDS, accessibleComputeResourceIds);
- return select(QueryConstants.FIND_ACCESSIBLE_APPLICATION_DEPLOYMENTS_FOR_APP_MODULE, -1, 0, queryParameters);
- }
-
- public List<String> getAllApplicationDeployementIds() {
- List<String> applicationDeploymentIds = new ArrayList<>();
- List<ApplicationDeploymentDescription> applicationDeploymentDescriptionList = select(
- QueryConstants.GET_ALL_APPLICATION_DEPLOYMENTS, 0);
-
- if (applicationDeploymentDescriptionList != null && !applicationDeploymentDescriptionList.isEmpty()) {
- logger.debug("The fetched list of Application Deployment is not NULL or empty");
- for (ApplicationDeploymentDescription applicationDeploymentDescription : applicationDeploymentDescriptionList) {
- applicationDeploymentIds.add(applicationDeploymentDescription.appDeploymentId());
- }
- }
- return applicationDeploymentIds;
- }
-
- public boolean isAppDeploymentExists(String deploymentId) {
- return isExists(deploymentId);
- }
+public interface ApplicationDeploymentRepository extends CrudRepository<ApplicationDeploymentEntity, String> {
- public void removeAppDeployment(String deploymentId) throws Exception {
- delete(deploymentId);
- }
}
diff --git a/src/main/java/org/apache/airavata/application/repository/ApplicationInputRepository.java b/src/main/java/org/apache/airavata/application/repository/ApplicationInputRepository.java
index 5fc98f61bb..d37b8b34b9 100644
--- a/src/main/java/org/apache/airavata/application/repository/ApplicationInputRepository.java
+++ b/src/main/java/org/apache/airavata/application/repository/ApplicationInputRepository.java
@@ -19,26 +19,11 @@
*/
package org.apache.airavata.application.repository;
-import org.apache.airavata.db.AbstractRepository;
-import org.apache.airavata.models.application.io.InputDataObjectType;
-import org.apache.airavata.application.mapper.ApplicationMapper;
+import org.springframework.data.repository.CrudRepository;
import org.apache.airavata.application.model.AppIoParamEntity;
import org.springframework.stereotype.Component;
@Component
-public class ApplicationInputRepository extends AbstractRepository<InputDataObjectType, AppIoParamEntity, String> {
+public interface ApplicationInputRepository extends CrudRepository<AppIoParamEntity, String> {
- public ApplicationInputRepository() {
- super(InputDataObjectType.class, AppIoParamEntity.class);
- }
-
- @Override
- protected InputDataObjectType toModel(AppIoParamEntity entity) {
- return ApplicationMapper.INSTANCE.appInputToModel(entity);
- }
-
- @Override
- protected AppIoParamEntity toEntity(InputDataObjectType model) {
- return ApplicationMapper.INSTANCE.appInputToEntity(model);
- }
}
diff --git a/src/main/java/org/apache/airavata/application/repository/ApplicationInterfaceRepository.java b/src/main/java/org/apache/airavata/application/repository/ApplicationInterfaceRepository.java
index baa8bb06a9..2a5787c50a 100644
--- a/src/main/java/org/apache/airavata/application/repository/ApplicationInterfaceRepository.java
+++ b/src/main/java/org/apache/airavata/application/repository/ApplicationInterfaceRepository.java
@@ -19,188 +19,11 @@
*/
package org.apache.airavata.application.repository;
-import java.sql.Timestamp;
-import java.util.*;
-
-import org.apache.airavata.db.AbstractRepository;
-import org.apache.airavata.db.DBConstants;
-import org.apache.airavata.db.QueryConstants;
-import org.apache.airavata.application.mapper.ApplicationMapper;
-import org.apache.airavata.models.appcatalog.appdeployment.ApplicationModule;
-import org.apache.airavata.models.appcatalog.appinterface.ApplicationInterfaceDescription;
-import org.apache.airavata.models.application.io.InputDataObjectType;
-import org.apache.airavata.models.application.io.OutputDataObjectType;
import org.apache.airavata.application.model.ApplicationInterfaceEntity;
-import org.apache.airavata.application.model.ApplicationModuleEntity;
-import org.apache.airavata.common.AiravataUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
@Component
-public class ApplicationInterfaceRepository
- extends AbstractRepository<ApplicationInterfaceDescription, ApplicationInterfaceEntity, String> {
- private static final Logger logger = LoggerFactory.getLogger(ApplicationInterfaceRepository.class);
-
- public ApplicationInterfaceRepository() {
- super(ApplicationInterfaceDescription.class, ApplicationInterfaceEntity.class);
- }
-
- @Override
- protected ApplicationInterfaceDescription toModel(ApplicationInterfaceEntity entity) {
- return ApplicationMapper.INSTANCE.appInterfaceToModel(entity);
- }
-
- @Override
- protected ApplicationInterfaceEntity toEntity(ApplicationInterfaceDescription model) {
- return ApplicationMapper.INSTANCE.appInterfaceToEntity(model);
- }
-
- protected String saveApplicationInterfaceDescriptorData(
- ApplicationInterfaceDescription applicationInterfaceDescription, String gatewayId)
- throws Exception {
- ApplicationInterfaceEntity applicationInterfaceEntity = saveApplicationInterface(
- applicationInterfaceDescription, gatewayId);
- return applicationInterfaceEntity.getApplicationInterfaceId();
- }
-
- protected ApplicationInterfaceEntity saveApplicationInterface(
- ApplicationInterfaceDescription applicationInterfaceDescription, String gatewayId)
- throws Exception {
-
- if (applicationInterfaceDescription.applicationInterfaceId().trim().equals("")
- || applicationInterfaceDescription.applicationInterfaceId().equals("DO_NOT_SET_AT_CLIENTS")) {
- logger.debug(
- "If Application Interface ID is empty or DEFAULT, set it as the Application Interface Name plus random UUID");
- applicationInterfaceDescription = applicationInterfaceDescription.toBuilder()
- .setApplicationInterfaceId(
- AiravataUtils.getId(applicationInterfaceDescription.applicationName()))
- .build();
- }
-
- String applicationInterfaceId = applicationInterfaceDescription.applicationInterfaceId();
- ApplicationInterfaceEntity applicationInterfaceEntity = ApplicationMapper.INSTANCE
- .appInterfaceToEntity(applicationInterfaceDescription);
-
- if (gatewayId != null) {
- logger.debug("Setting the gateway ID of the Application Interface");
- applicationInterfaceEntity.setGatewayId(gatewayId);
- }
-
- if (applicationInterfaceEntity.getApplicationInputs() != null) {
- logger.debug("Populating the Primary Key of ApplicationInputs objects for the Application Interface");
- applicationInterfaceEntity
- .getApplicationInputs()
- .forEach(applicationInputEntity -> applicationInputEntity.setInterfaceId(applicationInterfaceId));
- }
-
- if (applicationInterfaceEntity.getApplicationOutputs() != null) {
- logger.debug("Populating the Primary Key of ApplicationOutputs objects for the Application Interface");
- applicationInterfaceEntity
- .getApplicationOutputs()
- .forEach(applicationOutputEntity -> applicationOutputEntity.setInterfaceId(applicationInterfaceId));
- }
-
- if (!isApplicationInterfaceExists(applicationInterfaceId)) {
- logger.debug("Checking if the Application Interface already exists");
- applicationInterfaceEntity.setCreationTime(new Timestamp(System.currentTimeMillis()));
- }
-
- applicationInterfaceEntity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
- return execute(entityManager -> entityManager.merge(applicationInterfaceEntity));
- }
-
- public String addApplicationInterface(
- ApplicationInterfaceDescription applicationInterfaceDescription, String gatewayId)
- throws Exception {
- return saveApplicationInterfaceDescriptorData(applicationInterfaceDescription, gatewayId);
- }
-
- public void updateApplicationInterface(
- String interfaceId, ApplicationInterfaceDescription updatedApplicationInterfaceDescription)
- throws Exception {
- saveApplicationInterfaceDescriptorData(updatedApplicationInterfaceDescription, null);
- }
-
- public ApplicationInterfaceDescription getApplicationInterface(String interfaceId) throws Exception {
- return get(interfaceId);
- }
-
- public List<ApplicationInterfaceDescription> getApplicationInterfaces(Map<String, String> filters)
- throws Exception {
- if (filters.containsKey(DBConstants.ApplicationInterface.APPLICATION_NAME)) {
- logger.debug("Fetching Application Interfaces for given Application Name");
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(
- DBConstants.ApplicationInterface.APPLICATION_NAME,
- filters.get(DBConstants.ApplicationInterface.APPLICATION_NAME));
- List<ApplicationInterfaceDescription> applicationInterfaceDescriptionList = select(
- QueryConstants.FIND_APPLICATION_INTERFACES_FOR_APPLICATION_NAME, -1, 0, queryParameters);
- return applicationInterfaceDescriptionList;
- } else {
- logger.error("Unsupported field name for app interface.");
- throw new IllegalArgumentException("Unsupported field name for app interface.");
- }
- }
-
- public List<ApplicationInterfaceDescription> getAllApplicationInterfaces(String gatewayId)
- throws Exception {
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationInterface.GATEWAY_ID, gatewayId);
- List<ApplicationInterfaceDescription> applicationInterfaceDescriptionList = select(
- QueryConstants.FIND_APPLICATION_INTERFACES_FOR_GATEWAY_ID, -1, 0, queryParameters);
- return applicationInterfaceDescriptionList;
- }
-
- public List<String> getAllApplicationInterfaceIds() throws Exception {
- List<String> applicationInterfaceIds = new ArrayList<>();
- List<ApplicationInterfaceDescription> applicationInterfaceDescriptionList = select(
- QueryConstants.GET_ALL_APPLICATION_INTERFACES, 0);
-
- if (applicationInterfaceDescriptionList != null && !applicationInterfaceDescriptionList.isEmpty()) {
- logger.debug("The fetched list of Application Interfaces is not NULL or empty");
- for (ApplicationInterfaceDescription applicationDeploymentDescription : applicationInterfaceDescriptionList) {
- applicationInterfaceIds.add(applicationDeploymentDescription.applicationInterfaceId());
- }
- }
-
- return applicationInterfaceIds;
- }
-
- public List<InputDataObjectType> getApplicationInputs(String interfaceId) throws Exception {
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationInput.APPLICATION_INTERFACE_ID, interfaceId);
- ApplicationInputRepository applicationInputRepository = new ApplicationInputRepository();
- List<InputDataObjectType> applicationInputsList = applicationInputRepository.select(
- "SELECT p FROM AppIoParamEntity p WHERE p.interfaceId LIKE :"
- + DBConstants.ApplicationInput.APPLICATION_INTERFACE_ID
- + " AND p.direction = 'INPUT'",
- -1,
- 0,
- queryParameters);
- return applicationInputsList;
- }
-
- public List<OutputDataObjectType> getApplicationOutputs(String interfaceId) throws Exception {
- Map<String, Object> queryParameters = new HashMap<>();
- queryParameters.put(DBConstants.ApplicationOutput.APPLICATION_INTERFACE_ID, interfaceId);
- ApplicationOutputRepository applicationOutputRepository = new ApplicationOutputRepository();
- List<OutputDataObjectType> applicationOutputsList = applicationOutputRepository.select(
- "SELECT p FROM AppIoParamEntity p WHERE p.interfaceId LIKE :"
- + DBConstants.ApplicationOutput.APPLICATION_INTERFACE_ID
- + " AND p.direction = 'OUTPUT'",
- -1,
- 0,
- queryParameters);
- return applicationOutputsList;
- }
-
- public boolean removeApplicationInterface(String interfaceId) throws Exception {
- return delete(interfaceId);
- }
-
- public boolean isApplicationInterfaceExists(String interfaceId) throws Exception {
- return isExists(interfaceId);
- }
-
+public interface ApplicationInterfaceRepository
+ extends CrudRepository<ApplicationInterfaceEntity, String> {
}
diff --git a/src/main/java/org/apache/airavata/application/repository/ApplicationOutputRepository.java b/src/main/java/org/apache/airavata/application/repository/ApplicationOutputRepository.java
index 123634b224..037e3d4681 100644
--- a/src/main/java/org/apache/airavata/application/repository/ApplicationOutputRepository.java
+++ b/src/main/java/org/apache/airavata/application/repository/ApplicationOutputRepository.java
@@ -19,26 +19,9 @@
*/
package org.apache.airavata.application.repository;
-import org.apache.airavata.db.AbstractRepository;
-import org.apache.airavata.models.application.io.OutputDataObjectType;
-import org.apache.airavata.application.mapper.ApplicationMapper;
+import org.springframework.data.repository.CrudRepository;
import org.apache.airavata.application.model.AppIoParamEntity;
-import org.springframework.stereotype.Component;
-@Component
-public class ApplicationOutputRepository extends AbstractRepository<OutputDataObjectType, AppIoParamEntity, String> {
+public interface ApplicationOutputRepository extends CrudRepository<AppIoParamEntity, String> {
- public ApplicationOutputRepository() {
- super(OutputDataObjectType.class, AppIoParamEntity.class);
- }
-
- @Override
- protected OutputDataObjectType toModel(AppIoParamEntity entity) {
- return ApplicationMapper.INSTANCE.appOutputToModel(entity);
- }
-
- @Override
- protected AppIoParamEntity toEntity(OutputDataObjectType model) {
- return ApplicationMapper.INSTANCE.appOutputToEntity(model);
- }
}
diff --git a/src/main/java/org/apache/airavata/application/service/ApplicationInputService.java b/src/main/java/org/apache/airavata/application/service/ApplicationInputService.java
new file mode 100644
index 0000000000..fbf90dcfd1
--- /dev/null
+++ b/src/main/java/org/apache/airavata/application/service/ApplicationInputService.java
@@ -0,0 +1,8 @@
+package org.apache.airavata.application.service;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationInputService {
+
+}
diff --git a/src/main/java/org/apache/airavata/application/service/ApplicationInterfaceService.java b/src/main/java/org/apache/airavata/application/service/ApplicationInterfaceService.java
new file mode 100644
index 0000000000..54dc8f7bba
--- /dev/null
+++ b/src/main/java/org/apache/airavata/application/service/ApplicationInterfaceService.java
@@ -0,0 +1,18 @@
+package org.apache.airavata.application.service;
+
+import org.apache.airavata.application.mapper.ApplicationMapper;
+import org.apache.airavata.application.model.ApplicationInterfaceEntity;
+import org.apache.airavata.models.appcatalog.appinterface.ApplicationInterfaceDescription;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationInterfaceService {
+
+ protected ApplicationInterfaceDescription toModel(ApplicationInterfaceEntity entity) {
+ return ApplicationMapper.INSTANCE.appInterfaceToModel(entity);
+ }
+
+ protected ApplicationInterfaceEntity toEntity(ApplicationInterfaceDescription model) {
+ return ApplicationMapper.INSTANCE.appInterfaceToEntity(model);
+ }
+}
diff --git a/src/main/java/org/apache/airavata/application/service/ApplicationModuleService.java b/src/main/java/org/apache/airavata/application/service/ApplicationModuleService.java
index 50c5655f2d..0ecbe8ea37 100644
--- a/src/main/java/org/apache/airavata/application/service/ApplicationModuleService.java
+++ b/src/main/java/org/apache/airavata/application/service/ApplicationModuleService.java
@@ -9,6 +9,7 @@ import org.apache.airavata.application.model.ApplicationModuleEntity;
import org.apache.airavata.application.repository.ApplicationModuleRepository;
import org.apache.airavata.common.AiravataUtils;
import org.apache.airavata.common.RequestContext;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.apache.airavata.models.appcatalog.appdeployment.ApplicationModule;
@@ -57,6 +58,9 @@ public class ApplicationModuleService {
return toModel(savedEntity);
}
+ // Demo of the JWT -> role-lookup -> @PreAuthorize wiring: deleting a module now
+ // requires the caller's bearer token to resolve to the ADMIN authority.
+ @PreAuthorize("hasAuthority('ADMIN')")
public void deleteApplicationModule(RequestContext requestContext, String moduleId) throws Exception {
if (!applicationModuleRepository.existsById(moduleId)) {
throw new Exception("Application module not found: " + moduleId);
diff --git a/src/main/java/org/apache/airavata/common/RequestContext.java b/src/main/java/org/apache/airavata/common/RequestContext.java
index 2221b8dcc1..19c981b5c4 100644
--- a/src/main/java/org/apache/airavata/common/RequestContext.java
+++ b/src/main/java/org/apache/airavata/common/RequestContext.java
@@ -21,27 +21,17 @@ package org.apache.airavata.common;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
public class RequestContext {
private final String userId;
private final String gatewayId;
- private final String accessToken;
- private final Map<String, String> claims;
private final List<String> roles;
- public RequestContext(String userId, String gatewayId, String accessToken, Map<String, String> claims) {
- this(userId, gatewayId, accessToken, claims, List.of());
- }
-
- public RequestContext(
- String userId, String gatewayId, String accessToken, Map<String, String> claims, List<String> roles) {
+ public RequestContext(String userId, String gatewayId, List<String> roles) {
this.userId = userId;
this.gatewayId = gatewayId;
- this.accessToken = accessToken;
- this.claims = Collections.unmodifiableMap(claims);
- this.roles = roles == null ? List.of() : List.copyOf(roles);
+ this.roles = roles != null ? Collections.unmodifiableList(roles) : Collections.emptyList();
}
public String getUserId() {
@@ -52,14 +42,6 @@ public class RequestContext {
return gatewayId;
}
- public String getAccessToken() {
- return accessToken;
- }
-
- public Map<String, String> getClaims() {
- return claims;
- }
-
/** Realm roles from the verified access token. */
public List<String> getRoles() {
return roles;
diff --git a/src/main/java/org/apache/airavata/server/auth/JwtRoleAuthoritiesConverter.java b/src/main/java/org/apache/airavata/server/auth/JwtRoleAuthoritiesConverter.java
new file mode 100644
index 0000000000..60bae8d80e
--- /dev/null
+++ b/src/main/java/org/apache/airavata/server/auth/JwtRoleAuthoritiesConverter.java
@@ -0,0 +1,58 @@
+/**
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+*/
+package org.apache.airavata.server.auth;
+
+import java.util.Collection;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.stereotype.Component;
+
+/**
+ * Derives Spring Security authorities for a validated JWT by looking up the
+ * token's username against {@link UserRoleLookupService}, rather than trusting
+ * roles embedded in the token itself.
+ *
+ * <p>Authorities are plain role names (e.g. {@code "ADMIN"}), matching
+ * {@code @PreAuthorize("hasAuthority('ADMIN')")} rather than {@code hasRole(...)},
+ * which expects a {@code ROLE_} prefix.
+ */
+@Component
+public class JwtRoleAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
+
+ private final UserRoleLookupService userRoleLookupService;
+
+ public JwtRoleAuthoritiesConverter(UserRoleLookupService userRoleLookupService) {
+ this.userRoleLookupService = userRoleLookupService;
+ }
+
+ @Override
+ public Collection<GrantedAuthority> convert(Jwt jwt) {
+ String username = jwt.getClaimAsString("preferred_username");
+ if (username == null) {
+ username = jwt.getSubject();
+ }
+ return userRoleLookupService.getRoles(username).stream()
+ .map(SimpleGrantedAuthority::new)
+ .map(GrantedAuthority.class::cast)
+ .toList();
+ }
+}
diff --git a/src/main/java/org/apache/airavata/server/auth/MockUserRoleLookupService.java b/src/main/java/org/apache/airavata/server/auth/MockUserRoleLookupService.java
new file mode 100644
index 0000000000..cd88dbdf76
--- /dev/null
+++ b/src/main/java/org/apache/airavata/server/auth/MockUserRoleLookupService.java
@@ -0,0 +1,44 @@
+/**
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+*/
+package org.apache.airavata.server.auth;
+
+import java.util.Map;
+import java.util.Set;
+import org.springframework.stereotype.Service;
+
+/**
+ * Hardcoded stand-in for a database-backed user/role lookup.
+ * TODO: replace with a repository-backed {@link UserRoleLookupService} once a
+ * user/role schema exists.
+ */
+@Service
+public class MockUserRoleLookupService implements UserRoleLookupService {
+
+ private static final Map<String, Set<String>> USER_ROLES = Map.of(
+ "admin", Set.of("ADMIN"),
+ "default-admin", Set.of("ADMIN"));
+
+ private static final Set<String> DEFAULT_ROLES = Set.of("USER");
+
+ @Override
+ public Set<String> getRoles(String username) {
+ return USER_ROLES.getOrDefault(username, DEFAULT_ROLES);
+ }
+}
diff --git a/src/main/java/org/apache/airavata/server/auth/SecurityConfig.java b/src/main/java/org/apache/airavata/server/auth/SecurityConfig.java
new file mode 100644
index 0000000000..9f119191be
--- /dev/null
+++ b/src/main/java/org/apache/airavata/server/auth/SecurityConfig.java
@@ -0,0 +1,81 @@
+/**
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+*/
+package org.apache.airavata.server.auth;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.oauth2.jwt.JwtDecoder;
+import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
+import org.springframework.security.web.SecurityFilterChain;
+
+/**
+ * Validates bearer JWTs issued by Keycloak and populates the security context with
+ * authorities resolved via {@link JwtRoleAuthoritiesConverter} (looked up by
+ * username, not trusted from the token), so that {@code @PreAuthorize(...)} works
+ * on service methods.
+ *
+ * <p>The JWK set is fetched lazily on first token verification (rather than via
+ * Spring Boot's {@code issuer-uri} auto-configuration, which eagerly calls the
+ * OIDC discovery endpoint at startup) so the server still starts when Keycloak
+ * isn't running locally; only requests bearing a token fail until it is.
+ *
+ * <p>The filter chain itself permits all requests — enforcement happens at the
+ * method level via {@code @PreAuthorize}, so unannotated endpoints remain
+ * reachable without a token during this bootstrap phase.
+ */
+@Configuration
+@EnableMethodSecurity
+public class SecurityConfig {
+
+ private final String jwkSetUri;
+ private final JwtRoleAuthoritiesConverter jwtRoleAuthoritiesConverter;
+
+ public SecurityConfig(
+ @Value("${airavata.security.openid-url}") String openIdUrl,
+ JwtRoleAuthoritiesConverter jwtRoleAuthoritiesConverter) {
+ this.jwkSetUri = openIdUrl + "/protocol/openid-connect/certs";
+ this.jwtRoleAuthoritiesConverter = jwtRoleAuthoritiesConverter;
+ }
+
+ @Bean
+ public JwtDecoder jwtDecoder() {
+ return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
+ }
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
+ authenticationConverter.setJwtGrantedAuthoritiesConverter(jwtRoleAuthoritiesConverter);
+ authenticationConverter.setPrincipalClaimName("preferred_username");
+
+ http.csrf(csrf -> csrf.disable())
+ .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
+ .oauth2ResourceServer(oauth2 ->
+ oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter)));
+
+ return http.build();
+ }
+}
diff --git a/src/main/java/org/apache/airavata/server/auth/UserRoleLookupService.java b/src/main/java/org/apache/airavata/server/auth/UserRoleLookupService.java
new file mode 100644
index 0000000000..48be1ef6df
--- /dev/null
+++ b/src/main/java/org/apache/airavata/server/auth/UserRoleLookupService.java
@@ -0,0 +1,32 @@
+/**
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.
+*/
+package org.apache.airavata.server.auth;
+
+import java.util.Set;
+
+/**
+ * Resolves the authorities granted to an authenticated username.
+ * {@link MockUserRoleLookupService} is the current implementation; a database-backed
+ * implementation is expected to replace it once a user/role schema exists.
+ */
+public interface UserRoleLookupService {
+
+ Set<String> getRoles(String username);
+}