Merge branch 'pr/revert/feature/no/sync/ui/sp-apps' into 'master'

Add identity server service provider app integration

See merge request entgra/carbon-device-mgt!849
temp
Pahansith Gunathilake 3 years ago
commit 270904102d

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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 io.entgra.application.mgt.common;
public class Base64File {
private String name;
private String base64String;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBase64String() {
return base64String;
}
public void setBase64String(String base64String) {
this.base64String = base64String;
}
}

@ -0,0 +1,50 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common;
import java.io.InputStream;
public class FileDataHolder {
private String name;
private InputStream file;
public FileDataHolder(String name, InputStream file) {
this.name = name;
this.file = file;
}
public FileDataHolder() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public InputStream getFile() {
return file;
}
public void setFile(InputStream file) {
this.file = file;
}
}

@ -0,0 +1,102 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class IdentityServerResponse {
private int id;
private String providerName;
private String name;
private String description;
private String url;
private String serviceProviderAppsUrl;
private String username;
private List<Map<String, String>> apiParamList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public String getServiceProviderAppsUrl() {
return serviceProviderAppsUrl;
}
public void setServiceProviderAppsUrl(String serviceProviderAppsUrl) {
this.serviceProviderAppsUrl = serviceProviderAppsUrl;
}
public List<Map<String, String>> getApiParamList() {
return apiParamList;
}
public void setApiParamList(Map<String, String> apiParams) {
this.apiParamList = apiParams.entrySet().stream().map(param -> {
Map<String, String> paramMap = new HashMap<>();
paramMap.put(param.getKey(), param.getValue());
return paramMap;
}).collect(Collectors.toList());
}
}

@ -0,0 +1,98 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common;
import io.entgra.application.mgt.common.response.Application;
import java.util.List;
public class SPApplication {
private String id;
private String name;
private String description;
private String image;
private String accessUrl;
private String access;
private String self;
private List<Application> existingApplications;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getAccessUrl() {
return accessUrl;
}
public void setAccessUrl(String accessUrl) {
this.accessUrl = accessUrl;
}
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
public String getSelf() {
return self;
}
public void setSelf(String self) {
this.self = self;
}
public List<Application> getExistingApplications() {
return existingApplications;
}
public void setExistingApplications(List<Application> existingApplications) {
this.existingApplications = existingApplications;
}
}

@ -0,0 +1,59 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common;
import java.util.List;
public class SPApplicationListResponse {
private int totalResults;
private int startIndex;
private int count;
private List<SPApplication> applications;
public int getTotalResults() {
return totalResults;
}
public void setTotalResults(int totalResults) {
this.totalResults = totalResults;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<SPApplication> getApplications() {
return applications;
}
public void setApplications(List<SPApplication> applications) {
this.applications = applications;
}
}

@ -0,0 +1,112 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common.dto;
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class IdentityServerDTO {
private int id;
private String providerName;
private String name;
private String description;
private String url;
private String username;
private String password;
private Map<String, String> apiParams;
public IdentityServerDTO() {
this.apiParams = new HashMap<>();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public String constructApiParamsJsonString() {
return new Gson().toJson(apiParams);
}
public Set<String> getApiParamKeys() {
return apiParams.keySet();
}
public Map<String, String> getApiParams() {
return apiParams;
}
public void setApiParams(Map<String, String> apiParams) {
this.apiParams = apiParams;
}
}

@ -0,0 +1,41 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common.dto;
import java.util.List;
public class IdentityServiceProviderDTO {
private String name;
private List<String> requiredApiParams;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getRequiredApiParams() {
return requiredApiParams;
}
public void setRequiredApiParams(List<String> requiredApiParams) {
this.requiredApiParams = requiredApiParams;
}
}

@ -0,0 +1,34 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common.exception;
/**
* Exception that will be thrown if any error occurs while calling identity server services .
*/
public class IdentityServerManagementException extends ApplicationManagementException {
public IdentityServerManagementException(String message, Throwable throwable) {
super(message, throwable);
setMessage(message);
}
public IdentityServerManagementException(String message) {
super(message);
setMessage(message);
}
}

@ -16,6 +16,10 @@
*/
package io.entgra.application.mgt.common.services;
import io.entgra.application.mgt.common.ApplicationType;
import io.entgra.application.mgt.common.Base64File;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.ResourceManagementException;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import io.entgra.application.mgt.common.ApplicationArtifact;
import io.entgra.application.mgt.common.LifecycleChanger;
@ -30,15 +34,10 @@ import io.entgra.application.mgt.common.response.ApplicationRelease;
import io.entgra.application.mgt.common.response.Category;
import io.entgra.application.mgt.common.response.Tag;
import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppWrapper;
import io.entgra.application.mgt.common.wrapper.EntAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.ApplicationUpdateWrapper;
import io.entgra.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppWrapper;
import java.util.List;
/**
@ -46,21 +45,95 @@ import java.util.List;
*/
public interface ApplicationManager {
/***
* The method is responsible to add new application into entgra App Manager.
/**
* This method is responsible for handling application creation
*
* @param applicationWrapper Application that need to be created.
* @param applicationArtifact contains artifact data. i.e image name and stream, icon name and stream etc.
* @param isPublished checks if application should be published
* @return {@link Application}
* @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException}
* @param appId application id of the application to which the release should be created
* @param releaseWrapper {@link EntAppReleaseWrapper} of the release to be created
* @param isPublished If the app should be added in PUBLISHED state instead of initial state
* @return Created application release bean
* @throws ApplicationManagementException if any error occurred while creating the application
*/
Application createEntApp(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact, boolean isPublished)
ApplicationRelease createEntAppRelease(int appId, EntAppReleaseWrapper releaseWrapper, boolean isPublished)
throws ApplicationManagementException;
Application createWebClip(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact, boolean isPublished)
throws ApplicationManagementException;
/**
* This method is responsible for handling application creation
*
* @param appId application id of the application to which the release should be created
* @param releaseWrapper {@link WebAppReleaseWrapper} of the release to be created
* @param isPublished If the app should be added in PUBLISHED state instead of initial state
* @return Created application release bean
* @throws ApplicationManagementException if any error occurred while creating the application
*/
ApplicationRelease createWebAppRelease(int appId, WebAppReleaseWrapper releaseWrapper, boolean isPublished)
throws ApplicationManagementException, ResourceManagementException;
/**
* This method is responsible for handling application creation
*
* @param appId application id of the application to which the release should be created
* @param releaseWrapper {@link PublicAppReleaseWrapper} of the release to be created
* @param isPublished If the app should be added in PUBLISHED state instead of initial state
* @return Created application release bean
* @throws ApplicationManagementException if any error occurred while creating the application
*/
ApplicationRelease createPubAppRelease(int appId, PublicAppReleaseWrapper releaseWrapper, boolean isPublished)
throws ApplicationManagementException, ResourceManagementException;
/**
* This method is responsible for handling application creation
*
* @param appId application id of the application to which the release should be created
* @param releaseWrapper {@link CustomAppReleaseWrapper} of the release to be created
* @param isPublished If the app should be added in PUBLISHED state instead of initial state
* @return Created application release bean
* @throws ApplicationManagementException if any error occurred while creating the application
*/
ApplicationRelease createCustomAppRelease(int appId, CustomAppReleaseWrapper releaseWrapper, boolean isPublished)
throws ResourceManagementException, ApplicationManagementException;
/**
* Checks if release is available for a given application wrapper, and if exists it uploads
* the artifacts of the release
*
* @param app Application wrapper bean of the application
* @param <T> Application Wrapper class
* @return constructed ApplicationDTO after uploading the release artifacts if exist
* @throws ApplicationManagementException if any error occurred while uploading release artifacts
*/
<T> ApplicationDTO uploadReleaseArtifactIfExist(T app) throws ApplicationManagementException;
/**
* Check if public app release packageName is valid (I.E invalid if packageName already exists)
*
* @param packageName name of the application release package
* @throws ApplicationManagementException if package name is invalid
*/
void validatePublicAppReleasePackageName(String packageName) throws ApplicationManagementException;
/**
* This method is responsible to add application data into APPM database. However, before call this method it is
* required to do the validation of request and check the existence of application releaseDTO.
*
* @param applicationDTO Application DTO object.
* @param isPublished Wether the app should be added in PUBLISHED state instead of initial state
* @return {@link Application}
* @throws ApplicationManagementException which throws if error occurs while during application management.
*/
Application addAppDataIntoDB(ApplicationDTO applicationDTO, boolean isPublished) throws
ApplicationManagementException;
/**
* This method is responsible for handling application creation
*
* @param app Application wrapper object which depends on the application type
* @param isPublished If the app should be created in PUBLISHED state
* @param <T> Application wrapper class which depends on the application type
* @return Created application bean
* @throws ApplicationManagementException if any error occurred while creating the application
*/
<T> Application createApplication(T app, boolean isPublished) throws ApplicationManagementException;
/**
* Add an application to favourites
* @param appId id of the application
@ -82,12 +155,6 @@ public interface ApplicationManager {
*/
boolean isFavouriteApp(int appId) throws ApplicationManagementException;
Application createPublicApp(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact, boolean isPublished)
throws ApplicationManagementException;
Application createCustomApp(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact, boolean isPublished)
throws ApplicationManagementException;
/**
* Check the existence of an application for given application name and the device type.
*
@ -136,6 +203,15 @@ public interface ApplicationManager {
ApplicationList getFavouriteApplications(Filter filter) throws ApplicationManagementException;
/**
* Use to delete application artifact files (For example this is useful to delete application release artifacts
* (I.E screenshots) when an application is deleted)
*
* @param directoryPaths directory paths that contains release artifacts (I.E screenshots)
* @throws ApplicationManagementException if error occurred while deleting artifacts
*/
void deleteApplicationArtifacts(List<String> directoryPaths) throws ApplicationManagementException;
/**
* To get the applications based on the search filter.
*
@ -145,6 +221,24 @@ public interface ApplicationManager {
*/
ApplicationList getApplications(Filter filter) throws ApplicationManagementException;
/**
*
* @param applicationReleaseDTOs application releases of the application
* @return if application is hide-able
* @throws ApplicationManagementException if any error occurred while checking if hide-able
*/
boolean isHideableApp(List<ApplicationReleaseDTO> applicationReleaseDTOs)
throws ApplicationManagementException;
/**
*
* @param applicationReleaseDTOs application releases of the application
* @return if application is deletable
* @throws ApplicationManagementException if any error occurred while checking if deletable
*/
boolean isDeletableApp(List<ApplicationReleaseDTO> applicationReleaseDTOs)
throws ApplicationManagementException;
/**
* To get list of applications that application releases has given package names.
*
@ -155,6 +249,28 @@ public interface ApplicationManager {
*/
List<Application> getApplications(List<String> packageNames) throws ApplicationManagementException;
/**
* To create an application release for an ApplicationDTO.
*
* @param applicationDTO ApplicationDTO of the release
* @param applicationReleaseDTO ApplicatonRelease that need to be be created.
* @param type {@link ApplicationType}
* @param isPublished if the app should be added in PUBLISHED state instead of initial state
* @return the unique id of the application release, if the application release succeeded else -1
*/
<T> ApplicationRelease createRelease(ApplicationDTO applicationDTO, ApplicationReleaseDTO applicationReleaseDTO,
ApplicationType type, boolean isPublished)
throws ApplicationManagementException;
/**
* Get application and all application releases associated to the application for the given application Id
*
* @param applicationId Application Id
* @return {@link ApplicationDTO}
* @throws ApplicationManagementException if error occurred application data from the database.
*/
ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException;
/**
* To get the Application for given Id.
*
@ -225,7 +341,6 @@ public interface ApplicationManager {
void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact)
throws ApplicationManagementException;
/**
* To update release images.
*
@ -238,17 +353,7 @@ public interface ApplicationManager {
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/**
* To create an application release for an ApplicationDTO.
*
* @param applicationId ID of the ApplicationDTO
* @param entAppReleaseWrapper ApplicatonRelease that need to be be created.
* @param isPublished checks if application should be published
* @return the unique id of the application release, if the application release succeeded else -1
*/
ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper,
ApplicationArtifact applicationArtifact, boolean isPublished) throws ApplicationManagementException;
/***
* Use to update existing enterprise app release
*
* @param releaseUuid UUID of the application release.
* @param entAppReleaseWrapper {@link ApplicationReleaseDTO}
@ -258,26 +363,96 @@ public interface ApplicationManager {
ApplicationRelease updateEntAppRelease(String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/**
* Use to update existing public app release
*
* @param releaseUuid UUID of the application release.
* @param publicAppReleaseWrapper {@link ApplicationReleaseDTO}
* @param applicationArtifact {@link ApplicationArtifact}
* @return If the application release is updated correctly True returns, otherwise retuen False
*/
ApplicationRelease updatePubAppRelease(String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/**
* Use to update existing web app release
*
* @param releaseUuid UUID of the application release.
* @param webAppReleaseWrapper {@link ApplicationReleaseDTO}
* @param applicationArtifact {@link ApplicationArtifact}
* @return If the application release is updated correctly True returns, otherwise retuen False
*/
ApplicationRelease updateWebAppRelease(String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/**
* Use to update existing custom app release
*
* @param releaseUuid UUID of the application release.
* @param customAppReleaseWrapper {@link ApplicationReleaseDTO}
* @param applicationArtifact {@link ApplicationArtifact}
* @return If the application release is updated correctly True returns, otherwise retuen False
*/
ApplicationRelease updateCustomAppRelease(String releaseUuid, CustomAppReleaseWrapper customAppReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/***
/**
* To validate the application creating request
*
*/
<T> void validateAppCreatingRequest(T param) throws ApplicationManagementException;
<T> void validateAppCreatingRequest(T param) throws ApplicationManagementException, RequestValidatingException;
/***
/**
*
* @throws ApplicationManagementException throws if payload does not satisfy requirements.
*/
<T> void validateReleaseCreatingRequest(T param, String deviceType) throws ApplicationManagementException;
<T> void validateReleaseCreatingRequest(T releases, String deviceType) throws ApplicationManagementException;
/**
* Validate enterprise application release
*
*/
void validateEntAppReleaseCreatingRequest(EntAppReleaseWrapper releaseWrapper, String deviceType)
throws RequestValidatingException, ApplicationManagementException;
/**
* Validate custom application release
*
*/
void validateCustomAppReleaseCreatingRequest(CustomAppReleaseWrapper releaseWrapper, String deviceType)
throws RequestValidatingException, ApplicationManagementException;
/**
* Validate web application release
*
*/
void validateWebAppReleaseCreatingRequest(WebAppReleaseWrapper releaseWrapper)
throws RequestValidatingException, ApplicationManagementException;
/**
* Validate public application release
*
*/
void validatePublicAppReleaseCreatingRequest(PublicAppReleaseWrapper releaseWrapper, String deviceType)
throws RequestValidatingException, ApplicationManagementException;
/**
* Validates image files of the application release
*
* @param iconFile icon of the application release
* @param screenshots screenshots of the application release
* @throws RequestValidatingException if any image is invalid
*/
void validateImageArtifacts(Base64File iconFile, List<Base64File> screenshots) throws RequestValidatingException;
/**
* Validates any base64 files, for example a base64file may an empty file name which is invalid
*
* @param file Base64 File to be validated
* @throws RequestValidatingException if the file is invalid
*/
void validateBase64File(Base64File file) throws RequestValidatingException;
/***
*
@ -289,6 +464,14 @@ public interface ApplicationManager {
void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, List<Attachment> attachmentList)
throws RequestValidatingException;
/**
* Validates binary file of the application release
*
* @param binaryFile binary file of the application release
* @throws RequestValidatingException if binary file is invalid
*/
void validateBinaryArtifact(Base64File binaryFile) throws RequestValidatingException;
void validateBinaryArtifact(Attachment binaryFile) throws RequestValidatingException;
void addApplicationCategories(List<String> categories) throws ApplicationManagementException;
@ -331,7 +514,6 @@ public interface ApplicationManager {
void updateSubsStatus(int deviceId, int operationId, String status) throws ApplicationManagementException;
/**
* Get plist content to download and install the application.
*

@ -0,0 +1,165 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.common.services;
import io.entgra.application.mgt.common.IdentityServerResponse;
import io.entgra.application.mgt.common.SPApplicationListResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.IdentityServiceProviderDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException;
import io.entgra.application.mgt.common.response.Application;
import java.util.List;
public interface SPApplicationManager {
/**
* Removes consumer application from service provider
*
* @param identityServerId of the service provider
* @param spUID uid of the service provider
* @param appIds List of application ids to be removed
* @throws ApplicationManagementException if errors while removing appIds from service provider
*/
void detachSPApplications(int identityServerId, String spUID, List<Integer> appIds) throws ApplicationManagementException;
/**
* Maps consumer applications to service provider
*
* @param identityServerId of the service provider
* @param spUID uid of the service provider
* @param appIds List of application ids to be mapped
* @throws ApplicationManagementException if errors while mapping appIds to service provider
*/
void attachSPApplications(int identityServerId, String spUID, List<Integer> appIds) throws ApplicationManagementException;
/**
*
* @param identityServerId of the identity server that is to be retrieved
* @return Identity server for the given ID
* @throws ApplicationManagementException if error occurred while getting identity server
*/
IdentityServerResponse getIdentityServerResponse(int identityServerId) throws ApplicationManagementException;
/**
*
* @return Available identity servers
* @throws ApplicationManagementException if error occurred while getting identity servers
*/
List<IdentityServerResponse> getIdentityServers() throws ApplicationManagementException;
/**
* Create a new Identity Server
*
* @return {@link IdentityServerResponse}
* @throws ApplicationManagementException if error occurred while getting identity servers
*/
IdentityServerResponse createIdentityServer(IdentityServerDTO identityServerDTO) throws ApplicationManagementException;
/**
* Update existing Identity Server
*
* @param id of the identity server to be updated
* @param updateIdentityServerDTO identity server dto bean with updated fields
* @throws ApplicationManagementException if error occurred while getting identity servers
*/
IdentityServerResponse updateIdentityServer(IdentityServerDTO updateIdentityServerDTO, int id) throws ApplicationManagementException;
/**
* Delete Identity Server
*
* @param id of the identity server to be deleted
* @throws ApplicationManagementException if error occurred while getting identity servers
*/
void deleteIdentityServer(int id) throws ApplicationManagementException;
/**
* Check if Identity Server exists with the same name
*
* @param name of the identity server
* @return if name already exists for identity server
*/
boolean isIdentityServerNameExist(String name) throws ApplicationManagementException;
/**
* Check if Identity Server exists with the same url
*
* @param url of the identity server
* @return if url already exists for identity server
*/
boolean isIdentityServerUrlExist(String url) throws ApplicationManagementException;
/**
* Retrieve service provider apps from identity server
*
* @param identityServerId Id of the identity server
* @return {@link SPApplicationListResponse}
* @throws ApplicationManagementException if error while retrieving sp applications
*/
SPApplicationListResponse retrieveSPApplicationFromIdentityServer(int identityServerId, Integer offset, Integer limit)
throws ApplicationManagementException;
/**
*
* @param identityServerId of the service provider
* @param spUID uid of the service provider
* @return Applications that are mapped to given service provider uid and identity server id
* @throws ApplicationManagementException
*/
List<Application> getSPApplications(int identityServerId, String spUID) throws ApplicationManagementException;
/**
* This method is responsible for creating a new application and mapping it the given service provider uid
* and identity server id
*
* @param app Application wrapper of the application that should be created
* @param identityServerId id of the identity server to which the created application should be mapped
* @param spId uid of the service provder to which the created application should be mapped
* @param <T> Application wrapper class which depends on application type (PUBLIC, ENTERPRISE & etc)
* @param isPublished If the app should be added in PUBLISHED state instead of initial state
* @return Application bean of the created application
* @throws ApplicationManagementException if errors while creating and mapping the application
* @throws RequestValidatingException if app contains any invalid payload
*/
<T> Application createSPApplication(T app, int identityServerId, String spId, boolean isPublished) throws ApplicationManagementException, RequestValidatingException;
/**
* Validates application ids of the applications that should be attached
*
* @param appIds application ids to be validated
* @throws ApplicationManagementException if invalid service provider, identity server Id or app Ids provided
*/
void validateAttachAppsRequest(int identityServerId, String serviceProviderId, List<Integer> appIds) throws ApplicationManagementException;
/**
* Validates application ids of the applications that should be detached
*
* @param identityServerId id of identity server
* @param spId uid of service provider from which applications should be detached
* @param appIds applications ids to be detached
* @throws ApplicationManagementException
*/
void validateDetachAppsRequest(int identityServerId, String spId, List<Integer> appIds) throws ApplicationManagementException;
/**
* Get available identity service providers
*
* @return list of available service providers' names
*/
List<IdentityServiceProviderDTO> getIdentityServiceProviders() throws ApplicationManagementException;
}

@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@ApiModel(value = "ApplicationWrapper", description = "ApplicationWrapper represents the an ApplicationDTO in ApplicationDTO Store")
@ -80,7 +81,7 @@ public class ApplicationWrapper {
value = "List of application releases",
required = true)
@NotNull
private List<EntAppReleaseWrapper> entAppReleaseWrappers;
private List<EntAppReleaseWrapper> entAppReleaseWrappers = new ArrayList<>();
public String getName() {

@ -16,10 +16,12 @@
*/
package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel(value = "CustomAppReleaseWrapper", description = "This class holds the details when releasing an Custom app release to application store")
public class CustomAppReleaseWrapper {
@ -65,6 +67,22 @@ public class CustomAppReleaseWrapper {
@NotNull
private String packageName;
@ApiModelProperty(name = "screenshots",
value = "screenshots of the application")
private List<Base64File> screenshots;
@ApiModelProperty(name = "icon",
value = "icon of the application")
private Base64File icon;
@ApiModelProperty(name = "binaryFile",
value = "binary file of the application")
private Base64File binaryFile;
@ApiModelProperty(name = "icon",
value = "banner of the application")
private Base64File banner;
public String getReleaseType() {
return releaseType;
}
@ -122,4 +140,36 @@ public class CustomAppReleaseWrapper {
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public List<Base64File> getScreenshots() {
return screenshots;
}
public void setScreenshots(List<Base64File> screenshots) {
this.screenshots = screenshots;
}
public Base64File getIcon() {
return icon;
}
public void setIcon(Base64File icon) {
this.icon = icon;
}
public Base64File getBinaryFile() {
return binaryFile;
}
public void setBinaryFile(Base64File binaryFile) {
this.binaryFile = binaryFile;
}
public Base64File getBanner() {
return banner;
}
public void setBanner(Base64File banner) {
this.banner = banner;
}
}

@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@ApiModel(value = "CustomAppWrapper", description = "CustomAppWrapper represents an Application used to install in IoT devices")
@ -78,7 +79,7 @@ public class CustomAppWrapper {
value = "List of custom app releases",
required = true)
@NotNull
private List<CustomAppReleaseWrapper> customAppReleaseWrappers;
private List<CustomAppReleaseWrapper> customAppReleaseWrappers = new ArrayList<>();
public String getName() {
return name;

@ -16,10 +16,12 @@
*/
package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store")
public class EntAppReleaseWrapper {
@ -68,6 +70,22 @@ public class EntAppReleaseWrapper {
value = "PackageName of the application installer specifically for windows")
private String packageName;
@ApiModelProperty(name = "screenshots",
value = "screenshots of the application")
private List<Base64File> screenshots;
@ApiModelProperty(name = "icon",
value = "icon of the application")
private Base64File icon;
@ApiModelProperty(name = "binaryFile",
value = "binary file of the application")
private Base64File binaryFile;
@ApiModelProperty(name = "icon",
value = "banner of the application")
private Base64File banner;
public String getReleaseType() {
return releaseType;
}
@ -123,4 +141,36 @@ public class EntAppReleaseWrapper {
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public List<Base64File> getScreenshots() {
return screenshots;
}
public void setScreenshots(List<Base64File> screenshots) {
this.screenshots = screenshots;
}
public Base64File getIcon() {
return icon;
}
public void setIcon(Base64File icon) {
this.icon = icon;
}
public Base64File getBinaryFile() {
return binaryFile;
}
public void setBinaryFile(Base64File binaryFile) {
this.binaryFile = binaryFile;
}
public Base64File getBanner() {
return banner;
}
public void setBanner(Base64File banner) {
this.banner = banner;
}
}

@ -16,10 +16,12 @@
*/
package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel(value = "Public App Release Wrapper", description = "This class holds the details when releasing an Public App"
+ " Release to application store")
@ -72,6 +74,18 @@ public class PublicAppReleaseWrapper {
@NotNull
private String supportedOsVersions;
@ApiModelProperty(name = "screenshots",
value = "screenshots of the application")
private List<Base64File> screenshots;
@ApiModelProperty(name = "icon",
value = "icon of the application")
private Base64File icon;
@ApiModelProperty(name = "icon",
value = "banner of the application")
private Base64File banner;
public String getReleaseType() {
return releaseType;
}
@ -123,4 +137,28 @@ public class PublicAppReleaseWrapper {
public String getSupportedOsVersions() { return supportedOsVersions; }
public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; }
public Base64File getIcon() {
return icon;
}
public void setIcon(Base64File icon) {
this.icon = icon;
}
public List<Base64File> getScreenshots() {
return screenshots;
}
public void setScreenshots(List<Base64File> screenshots) {
this.screenshots = screenshots;
}
public Base64File getBanner() {
return banner;
}
public void setBanner(Base64File banner) {
this.banner = banner;
}
}

@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@ApiModel(value = "PublicAppWrapper", description = "PublicAppWrapper represents an Application in App Store")
@ -77,8 +78,7 @@ public class PublicAppWrapper {
@ApiModelProperty(name = "applicationReleaseWrappers",
value = "List of public app releases",
required = true)
@NotNull
private List<PublicAppReleaseWrapper> publicAppReleaseWrappers;
private List<PublicAppReleaseWrapper> publicAppReleaseWrappers = new ArrayList<>();
public String getName() {
return name;

@ -16,10 +16,12 @@
*/
package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store")
public class WebAppReleaseWrapper {
@ -63,6 +65,18 @@ public class WebAppReleaseWrapper {
@NotNull
private String url;
@ApiModelProperty(name = "screenshots",
value = "screenshots of the application")
private List<Base64File> screenshots;
@ApiModelProperty(name = "icon",
value = "icon of the application")
private Base64File icon;
@ApiModelProperty(name = "icon",
value = "banner of the application")
private Base64File banner;
public String getReleaseType() {
return releaseType;
}
@ -114,4 +128,28 @@ public class WebAppReleaseWrapper {
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public List<Base64File> getScreenshots() {
return screenshots;
}
public void setScreenshots(List<Base64File> screenshots) {
this.screenshots = screenshots;
}
public Base64File getIcon() {
return icon;
}
public void setIcon(Base64File icon) {
this.icon = icon;
}
public Base64File getBanner() {
return banner;
}
public void setBanner(Base64File banner) {
this.banner = banner;
}
}

@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@ApiModel(value = "WebAppWrapper", description = "WebAppWrapper represents an ApplicationDTO in ApplicationDTO Store")
@ -78,7 +79,7 @@ public class WebAppWrapper {
value = "List of web clip releases",
required = true)
@NotNull
private List<WebAppReleaseWrapper> webAppReleaseWrappers;
private List<WebAppReleaseWrapper> webAppReleaseWrappers = new ArrayList<>();
public String getName() {
return name;

@ -90,6 +90,7 @@
!io.entgra.application.mgt.core.internal.*,
io.entgra.application.mgt.core.*
</Export-Package>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>

@ -36,8 +36,12 @@ public class ConfigurationManager {
private Configuration configuration;
private IdentityServiceProviderConfiguration identityServiceProviderConfiguration;
private static String configPath;
private static String identityServerConfigPath;
private static volatile ConfigurationManager configurationManager;
private ConfigurationManager() {
@ -54,12 +58,26 @@ public class ConfigurationManager {
} catch (ApplicationManagementException e) {
log.error(e);
}
} else {
try {
configurationManager.initConfig();
} catch (ApplicationManagementException e) {
log.error(e);
}
}
}
}
return configurationManager;
}
public static synchronized void setIdentityServerConfigPathConfigLocation(String configPath) throws InvalidConfigurationException {
if (identityServerConfigPath == null) {
identityServerConfigPath = configPath;
} else {
throw new InvalidConfigurationException("Configuration path " + configPath + " is already defined");
}
}
public static synchronized void setConfigLocation(String configPath) throws InvalidConfigurationException {
if (ConfigurationManager.configPath == null) {
ConfigurationManager.configPath = configPath;
@ -71,16 +89,21 @@ public class ConfigurationManager {
private void initConfig() throws ApplicationManagementException {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class);
JAXBContext jaxbISConfigContext = JAXBContext.newInstance(IdentityServiceProviderConfiguration.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Unmarshaller identityServerConfigUnmarshaller = jaxbISConfigContext.createUnmarshaller();
if (configPath == null) {
configPath = Constants.DEFAULT_CONFIG_FILE_LOCATION;
}
if (identityServerConfigPath == null) {
identityServerConfigPath = Constants.DEFAULT_IDENTITY_SERVERS_CONFIG_FILE_LOCATION;
}
//TODO: Add validation for the configurations
this.configuration = (Configuration) unmarshaller.unmarshal(new File(configPath));
this.identityServiceProviderConfiguration = (IdentityServiceProviderConfiguration) identityServerConfigUnmarshaller.unmarshal(new File(identityServerConfigPath));
} catch (Exception e) {
log.error(e);
throw new InvalidConfigurationException("Error occurred while initializing application config: "
+ configPath, e);
throw new InvalidConfigurationException("Error occurred while initializing application managements configs: ", e);
}
}
@ -88,6 +111,10 @@ public class ConfigurationManager {
return configuration;
}
public IdentityServiceProviderConfiguration getIdentityServerConfiguration() {
return identityServiceProviderConfiguration;
}
public Extension getExtension(Extension.Name extName) throws InvalidConfigurationException {
for (Extension extension : configuration.getExtensions()) {
if (extension.getName().contentEquals(extName.toString())) {

@ -77,6 +77,7 @@ public class Extension {
* ApplicationManagement Extensions.
*/
public enum Name {
SPApplicationManager,
ApplicationManager,
ApplicationReleaseManager,
CategoryManager,

@ -0,0 +1,55 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "IdentityServiceProvider")
public class IdentityServiceProvider {
private String providerName;
private String providerClassName;
private String serviceProvidersPageUri;
@XmlElement(name = "ProviderName")
public String getProviderName() {
return providerName;
}
@XmlElement(name = "ProviderClassName")
public String getProviderClassName() {
return providerClassName;
}
@XmlElement(name = "ServiceProvidersPageUri")
public String getServiceProvidersPageUri() {
return serviceProvidersPageUri;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public void setServiceProvidersPageUri(String serviceProvidersPageUri) {
this.serviceProvidersPageUri = serviceProvidersPageUri;
}
public void setProviderClassName(String providerClassName) {
this.providerClassName = providerClassName;
}
}

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. 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 io.entgra.application.mgt.core.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
* Represents the Application Management Configuration.
*/
@XmlRootElement(name = "IdentityServiceProviderConfiguration")
public class IdentityServiceProviderConfiguration {
private List<IdentityServiceProvider> identityServiceProviders;
@XmlElementWrapper(name = "IdentityServiceProviders")
@XmlElement(name = "IdentityServiceProvider")
public List<IdentityServiceProvider> getIdentityServiceProviders() {
return identityServiceProviders;
}
public IdentityServiceProvider getIdentityServerDetailByProviderName(String identityServiceProviderName) {
for (IdentityServiceProvider identityServiceProvider : identityServiceProviders) {
if (identityServiceProvider.getProviderName().equals(identityServiceProviderName)) {
return identityServiceProvider;
}
}
return null;
}
public void setIdentityServiceProviders(List<IdentityServiceProvider> identityServiceProviders) {
this.identityServiceProviders = identityServiceProviders;
}
}

@ -0,0 +1,130 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.dao;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import java.util.List;
public interface SPApplicationDAO {
/**
* Use to check if an identity server exists with the same name
*
* @param name name of the identity server
* @return if identity server with the given name exists
*/
boolean isExistingIdentityServerName(String name, int tenantId) throws ApplicationManagementDAOException;
/**
* Use to check if an identity server exists with the same url
*
* @param url name of the identity server
* @return if identity server with the given url exists
*/
boolean isExistingIdentityServerUrl(String url, int tenantId) throws ApplicationManagementDAOException;
/**
* Update existing identity server in the database
*
* @param updatedIdentityServerDTO bean with the updated fields of the identity server
*/
void updateIdentityServer(IdentityServerDTO updatedIdentityServerDTO, int tenantId, int identityServerId)
throws ApplicationManagementDAOException;
/**
* Create new identity server in the database
*
* @param identityServerDTO DTO bean with the details of identity server to be created
* @return id of the newly created identity server
*/
int createIdentityServer(IdentityServerDTO identityServerDTO, int tenantId) throws ApplicationManagementDAOException;
/**
*
* @param identityServerId Id of identity server in which the service provider is in
* @param spUID Service provider uid of which the applications to be retrieved
* @return the service provider applications for the given service provider
* @throws ApplicationManagementDAOException if any db error occurred
*/
List<ApplicationDTO> getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException;
/**
*
* @param identityServerId Id of identity server in which the service provider is in
* @param spUID Id of the service provider to which the application should be mapped
* @param appId Id of the application that should be mapped
* @return Primary key of the new service provider and application mapping entry
* @throws ApplicationManagementDAOException if any db error occurred
*/
int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException;
/**
*
* @param identityServerId Id of identity server in which the service provider is in
* @param spUID Id of the service provider from which the application should be removed
* @param appId Id of the application that should be removed
* @throws ApplicationManagementDAOException if any db error occurred
*/
void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException;
/**
*
* @return All available identity servers
* @throws ApplicationManagementDAOException if any db error occurred
*/
List<IdentityServerDTO> getIdentityServers(int tenantId) throws ApplicationManagementDAOException;
/**
*
* @param id Id of the Identity Server to be retrieved
* @return Identity Server of the given id
* @throws ApplicationManagementDAOException if any db error occurred
*/
IdentityServerDTO getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException;
/**
* Verify whether application exist for given identity server id, service provider id and application id.
* Because if an application does not exist for those, it should not be mapped
*
* @param appId Id of the application.
* @param identityServerId Id of the identity server.
* @param spUID UID of the service provider.
* @throws ApplicationManagementDAOException Application Management DAO Exception.
*/
boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException;
/**
* Delete application from all service providers if exists. When an application is deleted from the database
* it shoulbe be deleted from mapping table as well
*
* @param applicationId Id of the application to be deleted
* @throws ApplicationManagementDAOException if any db error occurred
*/
void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException;
/**
* Delete identity server from db
*
* @param id of the identity server to be deleted
* @throws ApplicationManagementDAOException if any db error occurred
*/
void deleteIdentityServer(int id, int tenantId) throws ApplicationManagementDAOException;
}

@ -17,6 +17,11 @@
*/
package io.entgra.application.mgt.core.dao.common;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.impl.application.spapplication.GenericSPApplicationDAOImpl;
import io.entgra.application.mgt.core.dao.impl.application.spapplication.OracleSPApplicationDAOImpl;
import io.entgra.application.mgt.core.dao.impl.application.spapplication.PostgreSQLSPApplicationDAOImpl;
import io.entgra.application.mgt.core.dao.impl.application.spapplication.SQLServerSPApplicationDAOImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.application.mgt.common.exception.UnsupportedDatabaseEngineException;
@ -101,6 +106,25 @@ public class ApplicationManagementDAOFactory {
throw new IllegalStateException("Database engine has not initialized properly.");
}
public static SPApplicationDAO getSPApplicationDAO() {
if (databaseEngine != null) {
switch (databaseEngine) {
case Constants.DataBaseTypes.DB_TYPE_H2:
case Constants.DataBaseTypes.DB_TYPE_MYSQL:
return new GenericSPApplicationDAOImpl();
case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL:
return new PostgreSQLSPApplicationDAOImpl();
case Constants.DataBaseTypes.DB_TYPE_MSSQL:
return new SQLServerSPApplicationDAOImpl();
case Constants.DataBaseTypes.DB_TYPE_ORACLE:
return new OracleSPApplicationDAOImpl();
default:
throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine);
}
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
public static LifecycleStateDAO getLifecycleStateDAO() {
if (databaseEngine != null) {
switch (databaseEngine) {

@ -140,12 +140,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
sql += "INNER JOIN AP_APP_FAVOURITES ON "
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
}
sql += "INNER JOIN AP_APP_RELEASE ON "
sql += "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|| StringUtils.isNotEmpty(filter.getAppReleaseType())) {
sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
}
sql += "WHERE AP_APP.TENANT_ID = ? ";
@ -186,7 +186,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
sql += "LIMIT ? OFFSET ? ";
}
sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "LEFT JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "
@ -266,9 +266,9 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = "SELECT count(AP_APP.ID) AS APP_COUNT "
String sql = "SELECT count(DISTINCT AP_APP.ID) AS APP_COUNT "
+ "FROM AP_APP "
+ "INNER JOIN AP_APP_RELEASE ON "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
+ "INNER JOIN (SELECT ID FROM AP_APP) AS app_data ON app_data.ID = AP_APP.ID "
+ "WHERE AP_APP.TENANT_ID = ?";
@ -360,6 +360,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
}
}
@Override
public ApplicationDTO getApplication(String releaseUuid, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
@ -618,7 +619,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "INNER JOIN AP_APP_RELEASE ON "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND "
+ "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID "
+ "WHERE "

@ -87,12 +87,12 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl {
sql += "INNER JOIN AP_APP_FAVOURITES ON "
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
}
sql += "INNER JOIN AP_APP_RELEASE ON "
sql += "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ORDER BY ID ";
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|| StringUtils.isNotEmpty(filter.getAppReleaseType())) {
sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
}
if (StringUtils.isNotEmpty(filter.getAppType())) {
sql += "AND AP_APP.TYPE = ? ";
@ -131,7 +131,7 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl {
sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
}
sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "LEFT JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "

@ -86,12 +86,12 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl {
sql += "INNER JOIN AP_APP_FAVOURITES ON "
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
}
sql += "INNER JOIN AP_APP_RELEASE ON "
sql += "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|| StringUtils.isNotEmpty(filter.getAppReleaseType())) {
sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
}
if (StringUtils.isNotEmpty(filter.getAppType())) {
sql += "AND AP_APP.TYPE = ? ";
@ -130,7 +130,7 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl {
sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
}
sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "LEFT JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "

@ -0,0 +1,486 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.dao.impl.application.spapplication;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.DBConnectionException;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.application.mgt.core.dao.impl.application.GenericApplicationDAOImpl;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.application.mgt.core.util.DAOUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
public class GenericSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO {
private static final Log log = LogFactory.getLog(GenericApplicationDAOImpl.class);
@Override
public List<IdentityServerDTO> getIdentityServers(int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServers(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public IdentityServerDTO getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ? AND "
+ "ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
stmt.setInt(2, id);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServer(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one identity server for id: " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerName(String name, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(NAME) = LOWER(?) AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, name);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server name: " + name +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the name " + name +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerUrl(String url, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(URL) = LOWER(?) AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, url);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server url: " + url +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the url " + url +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void updateIdentityServer(IdentityServerDTO updatedIdentityServerDTO, int tenantId, int identityServerId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_IDENTITY_SERVER " +
"SET ";
if (updatedIdentityServerDTO.getName() != null) {
sql += "NAME = ?, ";
}
if (updatedIdentityServerDTO.getUrl() != null) {
sql += "URL = ?, ";
}
if (updatedIdentityServerDTO.getProviderName() != null) {
sql += "PROVIDER_NAME = ?, ";
}
if (updatedIdentityServerDTO.getUsername() != null) {
sql += "USERNAME = ?, ";
}
if (updatedIdentityServerDTO.getPassword() != null) {
sql += "PASSWORD = ?, ";
}
if (updatedIdentityServerDTO.getDescription() != null) {
sql += "DESCRIPTION = ?, ";
}
sql += "API_PARAMS = ? " +
"WHERE ID = ? AND TENANT_ID = ?";
try {
int index = 1;
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
if (updatedIdentityServerDTO.getName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getName());
}
if (updatedIdentityServerDTO.getUrl() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUrl());
}
if (updatedIdentityServerDTO.getProviderName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getProviderName());
}
if (updatedIdentityServerDTO.getUsername() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUsername());
}
if (updatedIdentityServerDTO.getPassword() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getPassword());
}
if (updatedIdentityServerDTO.getDescription() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getDescription());
}
stmt.setString(index++, updatedIdentityServerDTO.constructApiParamsJsonString());
stmt.setInt(index++, identityServerId);
stmt.setInt(index, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update identity server.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when executing SQL to update identity server. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int createIdentityServer(IdentityServerDTO identityServerDTO, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to create an identity server");
}
String sql = "INSERT INTO AP_IDENTITY_SERVER "
+ "(PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, identityServerDTO.getProviderName());
stmt.setString(2, identityServerDTO.getName());
stmt.setString(3, identityServerDTO.getDescription());
stmt.setString(4, identityServerDTO.getUrl());
stmt.setString(5, identityServerDTO.constructApiParamsJsonString());
stmt.setString(6, identityServerDTO.getUsername());
stmt.setString(7, identityServerDTO.getPassword());
stmt.setInt(8, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while creating identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<ApplicationDTO> getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting identity server applications from the database");
}
String sql = "SELECT "
+ "AP_APP.ID AS APP_ID, "
+ "AP_APP.NAME AS APP_NAME, "
+ "AP_APP.DESCRIPTION AS APP_DESCRIPTION, "
+ "AP_APP.TYPE AS APP_TYPE, "
+ "AP_APP.STATUS AS APP_STATUS, "
+ "AP_APP.SUB_TYPE AS APP_SUB_TYPE, "
+ "AP_APP.CURRENCY AS APP_CURRENCY, "
+ "AP_APP.RATING AS APP_RATING, "
+ "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, "
+ "AP_APP_RELEASE.ID AS RELEASE_ID, "
+ "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, "
+ "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, "
+ "AP_APP_RELEASE.UUID AS RELEASE_UUID, "
+ "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, "
+ "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, "
+ "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, "
+ "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, "
+ "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, "
+ "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, "
+ "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, "
+ "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, "
+ "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, "
+ "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, "
+ "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, "
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND "
+ "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID "
+ "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID "
+ "WHERE "
+ "SP_APPS.SP_UID = ? "
+ "AND SP_APPS.IS_ID = ? "
+ "AND AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, identityServerId);
stmt.setInt(3, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved basic details of the identity server applications");
}
return DAOUtil.loadApplications(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP_ID AS ID "
+ "FROM AP_IS_SP_APP_MAPPING SP_MAPPING "
+ "WHERE "
+ "SP_UID = ? AND AP_APP_ID = ? "
+ "AND IS_ID = ? AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check whether the existence of "
+ "sp application with id " + appId + " for service provider which has UID " + spUID;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check whether the existence of service provider application " +
"with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING "
+ "WHERE SP_UID = ? "
+ "AND AP_APP_ID = ? "
+ "AND IS_ID = ? "
+ "AND TENANT_ID = ? ";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "INSERT INTO AP_IS_SP_APP_MAPPING "
+ "(SP_UID, "
+ "AP_APP_ID, "
+ "IS_ID, TENANT_ID) "
+ "VALUES (?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers");
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, applicationId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteIdentityServer(int id, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete identity server with the id: " + id);
}
String sql = "DELETE FROM AP_IDENTITY_SERVER WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, id);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to delete an identity server with the id " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to delete an identity server which has the id "
+ id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,487 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.dao.impl.application.spapplication;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.DBConnectionException;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.application.mgt.core.util.DAOUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
public class OracleSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO {
private static final Log log = LogFactory.getLog(OracleSPApplicationDAOImpl.class);
@Override
public List<IdentityServerDTO> getIdentityServers(int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServers(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public IdentityServerDTO getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ? AND "
+ "ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
stmt.setInt(2, id);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServer(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one identity server for id: " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerUrl(String url, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(URL) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, url);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server url: " + url +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the url " + url +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerName(String name, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(NAME) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, name);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server name: " + name +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the name " + name +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void updateIdentityServer(IdentityServerDTO updatedIdentityServerDTO, int tenantId, int identityServerId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_IDENTITY_SERVER " +
"SET ";
if (updatedIdentityServerDTO.getName() != null) {
sql += "NAME = ?, ";
}
if (updatedIdentityServerDTO.getUrl() != null) {
sql += "URL = ?, ";
}
if (updatedIdentityServerDTO.getProviderName() != null) {
sql += "PROVIDER_NAME = ?, ";
}
if (updatedIdentityServerDTO.getUsername() != null) {
sql += "USERNAME = ?, ";
}
if (updatedIdentityServerDTO.getPassword() != null) {
sql += "PASSWORD = ?, ";
}
if (updatedIdentityServerDTO.getDescription() != null) {
sql += "DESCRIPTION = ?, ";
}
sql += "API_PARAMS = ? " +
"WHERE ID = ? AND TENANT_ID = ?";
try {
int index = 1;
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
if (updatedIdentityServerDTO.getName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getName());
}
if (updatedIdentityServerDTO.getUrl() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUrl());
}
if (updatedIdentityServerDTO.getProviderName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getProviderName());
}
if (updatedIdentityServerDTO.getUsername() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUsername());
}
if (updatedIdentityServerDTO.getPassword() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getPassword());
}
if (updatedIdentityServerDTO.getDescription() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getDescription());
}
stmt.setString(index++, updatedIdentityServerDTO.constructApiParamsJsonString());
stmt.setInt(index++, identityServerId);
stmt.setInt(index, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update identity server.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when executing SQL to update identity server. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int createIdentityServer(IdentityServerDTO identityServerDTO, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to create an identity server");
}
String sql = "INSERT INTO AP_IDENTITY_SERVER "
+ "(PROVIDER_NAME, "
+ "NAME, "
+ "DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, identityServerDTO.getProviderName());
stmt.setString(2, identityServerDTO.getName());
stmt.setString(3, identityServerDTO.getDescription());
stmt.setString(4, identityServerDTO.getUrl());
stmt.setString(5, identityServerDTO.constructApiParamsJsonString());
stmt.setString(6, identityServerDTO.getUsername());
stmt.setString(7, identityServerDTO.getPassword());
stmt.setInt(8, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while creating identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<ApplicationDTO> getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting identity server applications from the database");
}
String sql = "SELECT "
+ "AP_APP.ID AS APP_ID, "
+ "AP_APP.NAME AS APP_NAME, "
+ "AP_APP.DESCRIPTION AS APP_DESCRIPTION, "
+ "AP_APP.TYPE AS APP_TYPE, "
+ "AP_APP.STATUS AS APP_STATUS, "
+ "AP_APP.SUB_TYPE AS APP_SUB_TYPE, "
+ "AP_APP.CURRENCY AS APP_CURRENCY, "
+ "AP_APP.RATING AS APP_RATING, "
+ "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, "
+ "AP_APP_RELEASE.ID AS RELEASE_ID, "
+ "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, "
+ "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, "
+ "AP_APP_RELEASE.UUID AS RELEASE_UUID, "
+ "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, "
+ "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, "
+ "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, "
+ "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, "
+ "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, "
+ "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, "
+ "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, "
+ "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, "
+ "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, "
+ "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, "
+ "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, "
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND "
+ "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID "
+ "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID "
+ "WHERE "
+ "SP_APPS.SP_UID = ? "
+ "AND SP_APPS.IS_ID = ? "
+ "AND AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, identityServerId);
stmt.setInt(3, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved basic details of the identity server applications");
}
return DAOUtil.loadApplications(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP_ID AS ID "
+ "FROM AP_IS_SP_APP_MAPPING SP_MAPPING "
+ "WHERE "
+ "SP_UID = ? AND AP_APP_ID = ? "
+ "AND IS_ID = ? AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check whether the existence of "
+ "sp application with id " + appId + " for service provider which has UID " + spUID;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check whether the existence of service provider application " +
"with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING "
+ "WHERE SP_UID = ? "
+ "AND AP_APP_ID = ? "
+ "AND IS_ID = ? "
+ "AND TENANT_ID = ? ";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "INSERT INTO AP_IS_SP_APP_MAPPING "
+ "(SP_UID, "
+ "AP_APP_ID, "
+ "IS_ID, TENANT_ID) "
+ "VALUES (?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers");
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, applicationId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteIdentityServer(int id, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete identity server with the id: " + id);
}
String sql = "DELETE FROM AP_IDENTITY_SERVER WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, id);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to delete an identity server with the id " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to delete an identity server which has the id "
+ id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,487 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.dao.impl.application.spapplication;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.DBConnectionException;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.application.mgt.core.util.DAOUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
public class PostgreSQLSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO {
private static final Log log = LogFactory.getLog(PostgreSQLSPApplicationDAOImpl.class);
@Override
public List<IdentityServerDTO> getIdentityServers(int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServers(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public IdentityServerDTO getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ? AND "
+ "ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
stmt.setInt(2, id);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServer(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one identity server for id: " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerUrl(String url, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(URL) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, url);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server url: " + url +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the url " + url +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerName(String name, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(NAME) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, name);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server name: " + name +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the name " + name +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void updateIdentityServer(IdentityServerDTO updatedIdentityServerDTO, int tenantId, int identityServerId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_IDENTITY_SERVER " +
"SET ";
if (updatedIdentityServerDTO.getName() != null) {
sql += "NAME = ?, ";
}
if (updatedIdentityServerDTO.getUrl() != null) {
sql += "URL = ?, ";
}
if (updatedIdentityServerDTO.getProviderName() != null) {
sql += "PROVIDER_NAME = ?, ";
}
if (updatedIdentityServerDTO.getUsername() != null) {
sql += "USERNAME = ?, ";
}
if (updatedIdentityServerDTO.getPassword() != null) {
sql += "PASSWORD = ?, ";
}
if (updatedIdentityServerDTO.getDescription() != null) {
sql += "DESCRIPTION = ?, ";
}
sql += "API_PARAMS = ? " +
"WHERE ID = ? AND TENANT_ID = ?";
try {
int index = 1;
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
if (updatedIdentityServerDTO.getName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getName());
}
if (updatedIdentityServerDTO.getUrl() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUrl());
}
if (updatedIdentityServerDTO.getProviderName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getProviderName());
}
if (updatedIdentityServerDTO.getUsername() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUsername());
}
if (updatedIdentityServerDTO.getPassword() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getPassword());
}
if (updatedIdentityServerDTO.getDescription() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getDescription());
}
stmt.setString(index++, updatedIdentityServerDTO.constructApiParamsJsonString());
stmt.setInt(index++, identityServerId);
stmt.setInt(index, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update identity server.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when executing SQL to update identity server. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int createIdentityServer(IdentityServerDTO identityServerDTO, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to create an identity server");
}
String sql = "INSERT INTO AP_IDENTITY_SERVER "
+ "(PROVIDER_NAME, "
+ "NAME, "
+ "DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, identityServerDTO.getProviderName());
stmt.setString(2, identityServerDTO.getName());
stmt.setString(3, identityServerDTO.getDescription());
stmt.setString(4, identityServerDTO.getUrl());
stmt.setString(5, identityServerDTO.constructApiParamsJsonString());
stmt.setString(6, identityServerDTO.getUsername());
stmt.setString(7, identityServerDTO.getPassword());
stmt.setInt(8, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while creating identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<ApplicationDTO> getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting identity server applications from the database");
}
String sql = "SELECT "
+ "AP_APP.ID AS APP_ID, "
+ "AP_APP.NAME AS APP_NAME, "
+ "AP_APP.DESCRIPTION AS APP_DESCRIPTION, "
+ "AP_APP.TYPE AS APP_TYPE, "
+ "AP_APP.STATUS AS APP_STATUS, "
+ "AP_APP.SUB_TYPE AS APP_SUB_TYPE, "
+ "AP_APP.CURRENCY AS APP_CURRENCY, "
+ "AP_APP.RATING AS APP_RATING, "
+ "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, "
+ "AP_APP_RELEASE.ID AS RELEASE_ID, "
+ "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, "
+ "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, "
+ "AP_APP_RELEASE.UUID AS RELEASE_UUID, "
+ "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, "
+ "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, "
+ "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, "
+ "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, "
+ "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, "
+ "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, "
+ "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, "
+ "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, "
+ "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, "
+ "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, "
+ "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, "
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND "
+ "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID "
+ "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID "
+ "WHERE "
+ "SP_APPS.SP_UID = ? "
+ "AND SP_APPS.IS_ID = ? "
+ "AND AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, identityServerId);
stmt.setInt(3, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved basic details of the identity server applications");
}
return DAOUtil.loadApplications(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP_ID AS ID "
+ "FROM AP_IS_SP_APP_MAPPING SP_MAPPING "
+ "WHERE "
+ "SP_UID = ? AND AP_APP_ID = ? "
+ "AND IS_ID = ? AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check whether the existence of "
+ "sp application with id " + appId + " for service provider which has UID " + spUID;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check whether the existence of service provider application " +
"with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING "
+ "WHERE SP_UID = ? "
+ "AND AP_APP_ID = ? "
+ "AND IS_ID = ? "
+ "AND TENANT_ID = ? ";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "INSERT INTO AP_IS_SP_APP_MAPPING "
+ "(SP_UID, "
+ "AP_APP_ID, "
+ "IS_ID, TENANT_ID) "
+ "VALUES (?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers");
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, applicationId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteIdentityServer(int id, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete identity server with the id: " + id);
}
String sql = "DELETE FROM AP_IDENTITY_SERVER WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, id);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to delete an identity server with the id " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to delete an identity server which has the id "
+ id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,487 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.dao.impl.application.spapplication;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.DBConnectionException;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.application.mgt.core.util.DAOUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
public class SQLServerSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO {
private static final Log log = LogFactory.getLog(SQLServerSPApplicationDAOImpl.class);
@Override
public List<IdentityServerDTO> getIdentityServers(int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServers(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public IdentityServerDTO getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT ID, PROVIDER_NAME, NAME, DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE TENANT_ID = ? AND "
+ "ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setInt(1, tenantId);
stmt.setInt(2, id);
try (ResultSet rs = stmt.executeQuery()){
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved available identity servers" );
}
return DAOUtil.loadIdentityServer(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to retrieve available identity servers";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one identity server for id: " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerUrl(String url, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(URL) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, url);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server url: " + url +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the url " + url +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isExistingIdentityServerName(String name, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP.ID AS ID "
+ "FROM AP_IDENTITY_SERVER "
+ "WHERE "
+ "LOWER(NAME) = LOWER(?) AND "
+ "AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, name);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check if identity server name: " + name +
" already exist";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check if identity server with the name " + name +
" already exists.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void updateIdentityServer(IdentityServerDTO updatedIdentityServerDTO, int tenantId, int identityServerId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_IDENTITY_SERVER " +
"SET ";
if (updatedIdentityServerDTO.getName() != null) {
sql += "NAME = ?, ";
}
if (updatedIdentityServerDTO.getUrl() != null) {
sql += "URL = ?, ";
}
if (updatedIdentityServerDTO.getProviderName() != null) {
sql += "PROVIDER_NAME = ?, ";
}
if (updatedIdentityServerDTO.getUsername() != null) {
sql += "USERNAME = ?, ";
}
if (updatedIdentityServerDTO.getPassword() != null) {
sql += "PASSWORD = ?, ";
}
if (updatedIdentityServerDTO.getDescription() != null) {
sql += "DESCRIPTION = ?, ";
}
sql += "API_PARAMS = ? " +
"WHERE ID = ? AND TENANT_ID = ?";
try {
int index = 1;
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
if (updatedIdentityServerDTO.getName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getName());
}
if (updatedIdentityServerDTO.getUrl() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUrl());
}
if (updatedIdentityServerDTO.getProviderName() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getProviderName());
}
if (updatedIdentityServerDTO.getUsername() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getUsername());
}
if (updatedIdentityServerDTO.getPassword() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getPassword());
}
if (updatedIdentityServerDTO.getDescription() != null) {
stmt.setString(index++, updatedIdentityServerDTO.getDescription());
}
stmt.setString(index++, updatedIdentityServerDTO.constructApiParamsJsonString());
stmt.setInt(index++, identityServerId);
stmt.setInt(index, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to update identity server.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when executing SQL to update identity server. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int createIdentityServer(IdentityServerDTO identityServerDTO, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to create an identity server");
}
String sql = "INSERT INTO AP_IDENTITY_SERVER "
+ "(PROVIDER_NAME, "
+ "NAME, "
+ "DESCRIPTION, URL, API_PARAMS, USERNAME, PASSWORD, TENANT_ID) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, identityServerDTO.getProviderName());
stmt.setString(2, identityServerDTO.getName());
stmt.setString(3, identityServerDTO.getDescription());
stmt.setString(4, identityServerDTO.getUrl());
stmt.setString(5, identityServerDTO.constructApiParamsJsonString());
stmt.setString(6, identityServerDTO.getUsername());
stmt.setString(7, identityServerDTO.getPassword());
stmt.setInt(8, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while creating identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an identity server ";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<ApplicationDTO> getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting identity server applications from the database");
}
String sql = "SELECT "
+ "AP_APP.ID AS APP_ID, "
+ "AP_APP.NAME AS APP_NAME, "
+ "AP_APP.DESCRIPTION AS APP_DESCRIPTION, "
+ "AP_APP.TYPE AS APP_TYPE, "
+ "AP_APP.STATUS AS APP_STATUS, "
+ "AP_APP.SUB_TYPE AS APP_SUB_TYPE, "
+ "AP_APP.CURRENCY AS APP_CURRENCY, "
+ "AP_APP.RATING AS APP_RATING, "
+ "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, "
+ "AP_APP_RELEASE.ID AS RELEASE_ID, "
+ "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, "
+ "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, "
+ "AP_APP_RELEASE.UUID AS RELEASE_UUID, "
+ "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, "
+ "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, "
+ "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, "
+ "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, "
+ "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, "
+ "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, "
+ "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, "
+ "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, "
+ "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, "
+ "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, "
+ "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, "
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "LEFT JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND "
+ "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID "
+ "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID "
+ "WHERE "
+ "SP_APPS.SP_UID = ? "
+ "AND SP_APPS.IS_ID = ? "
+ "AND AP_APP.TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, identityServerId);
stmt.setInt(3, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved basic details of the identity server applications");
}
return DAOUtil.loadApplications(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
String sql = "SELECT AP_APP_ID AS ID "
+ "FROM AP_IS_SP_APP_MAPPING SP_MAPPING "
+ "WHERE "
+ "SP_UID = ? AND AP_APP_ID = ? "
+ "AND IS_ID = ? AND "
+ "TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)){
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
try (ResultSet rs = stmt.executeQuery()){
return rs.next();
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to check whether the existence of "
+ "sp application with id " + appId + " for service provider which has UID " + spUID;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing query to check whether the existence of service provider application " +
"with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING "
+ "WHERE SP_UID = ? "
+ "AND AP_APP_ID = ? "
+ "AND IS_ID = ? "
+ "AND TENANT_ID = ? ";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to map an application wit identity server:service provider");
log.debug("Application Details : ");
log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId);
}
String sql = "INSERT INTO AP_IS_SP_APP_MAPPING "
+ "(SP_UID, "
+ "AP_APP_ID, "
+ "IS_ID, TENANT_ID) "
+ "VALUES (?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, spUID);
stmt.setInt(2, appId);
stmt.setInt(3, identityServerId);
stmt.setInt(4, tenantId);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
return rs.getInt(1);
}
return -1;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has "
+ "application id " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to create an application which has application id "
+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers");
}
String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, applicationId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to delete an sp application mapping which has "
+ "application id " + applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to delete an application which has application id "
+ applicationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public void deleteIdentityServer(int id, int tenantId) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to delete identity server with the id: " + id);
}
String sql = "DELETE FROM AP_IDENTITY_SERVER WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, id);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to delete an identity server with the id " + id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while executing SQL to delete an identity server which has the id "
+ id;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,85 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.identityserver.serviceprovider;
import io.entgra.application.mgt.common.SPApplication;
import io.entgra.application.mgt.common.SPApplicationListResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.InvalidConfigurationException;
import io.entgra.application.mgt.core.config.ConfigurationManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.lang.reflect.Constructor;
import java.util.List;
public interface ISServiceProviderApplicationService {
Log log = LogFactory.getLog(ISServiceProviderApplicationService.class);
static ISServiceProviderApplicationService of(String identityServerName) throws InvalidConfigurationException {
String className = ConfigurationManager.getInstance().getIdentityServerConfiguration().
getIdentityServerDetailByProviderName(identityServerName).getProviderClassName();
try {
Class theClass = Class.forName(className);
Constructor<ISServiceProviderApplicationService> constructor = theClass.getConstructor();
return constructor.newInstance();
} catch (Exception e) {
String msg = "Unable to get instance of " + className;
log.error(msg, e);
throw new InvalidConfigurationException(msg, e);
}
}
/**
* Use to get IS Service specific api params
*
* @return IS Service specific api params
*/
List<String> getRequiredApiParams();
/**
* Check if service provider application exists
*
* @param identityServer {@link IdentityServerDTO}
* @param spAppId uid of the service provider
* @return if service provider exist
* @throws ApplicationManagementException
*/
boolean isSPApplicationExist(IdentityServerDTO identityServer, String spAppId) throws ApplicationManagementException;
/**
* Get service provider by identity server id and service provider uid
* @param identityServer {@link IdentityServerDTO}
* @param spAppId uid of service provider to be retrieved
* @return {@link SPApplication}
* @throws ApplicationManagementException
*/
SPApplication retrieveSPApplication(IdentityServerDTO identityServer, String spAppId) throws ApplicationManagementException;
/**
* Retrieve service provider apps from identity server
*
* @param identityServer {@link IdentityServerDTO}
* @return {@link SPApplicationListResponse}
* @throws ApplicationManagementException
*/
SPApplicationListResponse retrieveSPApplications(IdentityServerDTO identityServer, Integer limit, Integer offset)
throws ApplicationManagementException;
}

@ -0,0 +1,170 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.identityserver.serviceprovider.impl;
import com.google.gson.Gson;
import io.entgra.application.mgt.common.SPApplication;
import io.entgra.application.mgt.common.SPApplicationListResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.IdentityServerManagementException;
import io.entgra.application.mgt.core.identityserver.serviceprovider.ISServiceProviderApplicationService;
import io.entgra.application.mgt.core.util.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class WSO2IAMSPApplicationService implements ISServiceProviderApplicationService {
private static final List<String> REQUIRED_API_PARAM_LIST;
private static final String TENANT_DOMAIN = "Tenant domain";
private static final String SP_APPLICATION_API_CONTEXT = "/t/%s/api/server/v1/applications";
private static final Log log = LogFactory.getLog(WSO2IAMSPApplicationService.class);
static {
REQUIRED_API_PARAM_LIST = Collections.singletonList(TENANT_DOMAIN);
}
public List<String> getRequiredApiParams() {
return REQUIRED_API_PARAM_LIST;
}
public boolean isSPApplicationExist(IdentityServerDTO identityServer, String spAppId) throws ApplicationManagementException {
SPApplication application = retrieveSPApplication(identityServer, spAppId);
return application != null;
}
public SPApplication retrieveSPApplication(IdentityServerDTO identityServer, String spAppId) throws ApplicationManagementException {
HttpGet req = new HttpGet();
String uriString = constructAPIUrl(identityServer);
uriString += Constants.FORWARD_SLASH + spAppId;
req.setURI(HttpUtil.createURI(uriString));
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpResponse response = invokeISAPI(identityServer, client, req);
String responseBody = HttpUtil.getResponseString(response);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
return new Gson().fromJson(responseBody,
SPApplication.class);
}
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
return null;
}
String msg = constructErrorMessage(response);
log.error(msg);
throw new IdentityServerManagementException(msg);
} catch (IOException e) {
String msg = "Error occurred while calling SP Applications API. Make sure identity server is up and running";
log.error(msg, e);
throw new IdentityServerManagementException(msg, e);
}
}
/**
* Construct error message string depending on service providers api response
* (I.E If unauthorized a different message will be returned)
*
* @param response of the service provider api call
* @return constructed error message
*/
private String constructErrorMessage(HttpResponse response) {
String msg = "Error occurred while calling SP Applications API";
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
msg += ". Make sure provided identity Server credentials are valid";
}
return msg;
}
public SPApplicationListResponse retrieveSPApplications(IdentityServerDTO identityServer, Integer limit, Integer offset)
throws ApplicationManagementException {
HttpGet req = new HttpGet();
String uriString = constructAPIUrl(identityServer);
uriString += Constants.URI_QUERY_SEPARATOR + Constants.LIMIT_QUERY_PARAM + Constants.QUERY_KEY_VALUE_SEPARATOR
+ limit;
uriString += Constants.QUERY_STRING_SEPARATOR + Constants.OFFSET_QUERY_PARAM + Constants.QUERY_KEY_VALUE_SEPARATOR
+ offset;
req.setURI(HttpUtil.createURI(uriString));
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpResponse response = invokeISAPI(identityServer, client, req);
String responseBody = HttpUtil.getResponseString(response);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
return new Gson().fromJson(responseBody,
SPApplicationListResponse.class);
}
String msg = constructErrorMessage(response);
log.error(msg);
throw new IdentityServerManagementException(msg);
} catch (IOException e) {
String msg = "Error occurred while calling SP Applications API. Make sure identity server is up and running";
log.error(msg, e);
throw new IdentityServerManagementException(msg, e);
}
}
/**
* Takes essential prerequisite steps (I.E setting authorization header),
* invokes provided GET request and returns the response
*
* @param identityServer {@link IdentityServerDTO}
* @param client httpClient that should be used to invoke
* @param request GET request to be invoked
* @return response of the invoked api
*/
private HttpResponse invokeISAPI(IdentityServerDTO identityServer, HttpClient client, HttpGet request) throws IOException {
setBasicAuthHeader(identityServer, request);
return client.execute(request);
}
/**
* Add basic auth header to provided service provider api request by getting the username and password
* from identity server bean
*
* @param identityServer {@link IdentityServerDTO}
* @param request service provider api request
*/
private void setBasicAuthHeader(IdentityServerDTO identityServer, HttpRequestBase request) {
String basicAuthHeader = HttpUtil.getBasicAuthBase64Header(identityServer.getUsername(),
identityServer.getPassword());
request.setHeader(HttpHeaders.AUTHORIZATION, basicAuthHeader);
}
/**
* Helps to construct service provider api base url
*
* @param identityServer {@link IdentityServerDTO}
* @return constructed service providers api url
*/
private String constructAPIUrl(IdentityServerDTO identityServer) {
String identityServerUrl = identityServer.getUrl();
// add "/" at the end, if the server url doesn't contain "/" at the end
if (identityServerUrl.charAt(identityServerUrl.length() - 1) != Constants.FORWARD_SLASH.charAt(0)) {
identityServerUrl += Constants.FORWARD_SLASH;
}
return identityServerUrl + String.format(SP_APPLICATION_API_CONTEXT, identityServer.getApiParams().get(TENANT_DOMAIN));
}
}

@ -0,0 +1,699 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.core.impl;
import io.entgra.application.mgt.common.IdentityServerResponse;
import io.entgra.application.mgt.common.SPApplicationListResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.SPApplication;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.dto.IdentityServiceProviderDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.DBConnectionException;
import io.entgra.application.mgt.common.exception.TransactionManagementException;
import io.entgra.application.mgt.common.response.Application;
import io.entgra.application.mgt.common.services.ApplicationManager;
import io.entgra.application.mgt.common.services.SPApplicationManager;
import io.entgra.application.mgt.core.config.ConfigurationManager;
import io.entgra.application.mgt.core.config.IdentityServiceProvider;
import io.entgra.application.mgt.core.dao.ApplicationDAO;
import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.dao.VisibilityDAO;
import io.entgra.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.application.mgt.core.exception.BadRequestException;
import io.entgra.application.mgt.core.exception.NotFoundException;
import io.entgra.application.mgt.core.identityserver.serviceprovider.ISServiceProviderApplicationService;
import io.entgra.application.mgt.core.internal.DataHolder;
import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.application.mgt.core.util.APIUtil;
import io.entgra.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.application.mgt.core.util.ConnectionManagerUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.routines.UrlValidator;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class SPApplicationManagerImpl implements SPApplicationManager {
private static final Log log = LogFactory.getLog(SPApplicationManagerImpl.class);
private ApplicationDAO applicationDAO;
private SPApplicationDAO spApplicationDAO;
private VisibilityDAO visibilityDAO;
private final LifecycleStateManager lifecycleStateManager;
public SPApplicationManagerImpl() {
initDataAccessObjects();
lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager();
}
private void initDataAccessObjects() {
this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO();
this.visibilityDAO = ApplicationManagementDAOFactory.getVisibilityDAO();
this.spApplicationDAO = ApplicationManagementDAOFactory.getSPApplicationDAO();
}
@Override
public IdentityServerResponse getIdentityServerResponse(int identityServerId) throws ApplicationManagementException {
IdentityServerDTO identityServerDTO = getIdentityServer(identityServerId);
return APIUtil.identityServerDtoToIdentityServerResponse(identityServerDTO);
}
/**
* This is similar to getIdentityServerFromDB method except throws {@link NotFoundException} if identity server
* does not exist for the given id
*
* @param identityServerId id of identity server
* @return {@link IdentityServerDTO}
*/
private IdentityServerDTO getIdentityServer(int identityServerId) throws ApplicationManagementException {
IdentityServerDTO identityServerDTO = getIdentityServerFromDB(identityServerId);
if (identityServerDTO == null) {
String msg = "Identity server with the id: " + identityServerId + " does not exist";
log.error(msg);
throw new NotFoundException(msg);
}
return identityServerDTO;
}
/**
* Use to get {@link IdentityServerDTO} bean from database. Returns null if does not exist
*
* @param identityServerId id of identity server
* @return {@link IdentityServerDTO}
*/
private IdentityServerDTO getIdentityServerFromDB(int identityServerId) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
return spApplicationDAO.getIdentityServerById(identityServerId, tenantId);
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection to get identity server with the id: " + identityServerId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg =
"DAO exception while getting identity server with the id " + identityServerId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public List<IdentityServerResponse> getIdentityServers() throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
return spApplicationDAO.getIdentityServers(tenantId).stream().
map(APIUtil::identityServerDtoToIdentityServerResponse).collect(Collectors.toList());
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection to get identity servers";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg =
"DAO exception while getting identity servers";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public IdentityServerResponse createIdentityServer(IdentityServerDTO identityServerDTO) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
validateIdentityServerCreateRequest(identityServerDTO);
try {
ConnectionManagerUtil.beginDBTransaction();
int id = spApplicationDAO.createIdentityServer(identityServerDTO, tenantId);
identityServerDTO.setId(id);
ConnectionManagerUtil.commitDBTransaction();
return APIUtil.identityServerDtoToIdentityServerResponse(identityServerDTO);
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while creating identity server " + identityServerDTO.getName();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public IdentityServerResponse updateIdentityServer(IdentityServerDTO updateIdentityServerDTO, int id)
throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
IdentityServerDTO existingIdentityServerDTO = getIdentityServer(id);
validateIdentityServerUpdateRequest(updateIdentityServerDTO, existingIdentityServerDTO);
Map<String, String> updatedApiParams = constructUpdatedApiParams(updateIdentityServerDTO, existingIdentityServerDTO);
updateIdentityServerDTO.setApiParams(updatedApiParams);
try {
ConnectionManagerUtil.beginDBTransaction();
spApplicationDAO.updateIdentityServer(updateIdentityServerDTO, tenantId, id);
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while creating identity server " + updateIdentityServerDTO.getName();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return getIdentityServerResponse(id);
}
@Override
public void deleteIdentityServer(int id) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
validateIdentityServerDeleteRequest(id);
try {
ConnectionManagerUtil.beginDBTransaction();
spApplicationDAO.deleteIdentityServer(id, tenantId);
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while creating identity server with the id " + id;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
/**
* Validate the identity server delete request
*
* @param identityServerId identity server id
* @throws BadRequestException if provided identity server id is invalid
*/
private void validateIdentityServerDeleteRequest(int identityServerId) throws ApplicationManagementException {
IdentityServerDTO identityServerDTO = getIdentityServerFromDB(identityServerId);
if (identityServerDTO == null) {
String msg = "Identity server with the id: " + identityServerId + " does not exist to delete";
log.error(msg);
throw new BadRequestException(msg);
}
}
/**
* This method is useful to re-construct the api params Map using updated identity server bean {@link IdentityServerDTO}
* For example updated identity server bean may contain only updated api param, in which case the existing api param values
* should be re-added to updated identity server bean
*
* @param updatedIdentityServerDTO updated identity server request payload
* @param existingIdentityServerDTO corresponding existing identity server of updated identity server
* @return Constructed api param map
*/
private Map<String, String> constructUpdatedApiParams(IdentityServerDTO updatedIdentityServerDTO,
IdentityServerDTO existingIdentityServerDTO) {
Map<String, String> updatedApiParams = updatedIdentityServerDTO.getApiParams();
Map<String, String> existingApiParams = existingIdentityServerDTO.getApiParams();
if (updatedIdentityServerDTO.getProviderName().equals(existingIdentityServerDTO.getProviderName())) {
existingApiParams.putAll(updatedApiParams);
return existingApiParams;
}
return updatedApiParams;
}
/**
* Validate the identity server update request payload
*
* @param updateIdentityServerDTO of identity server update request
* @throws BadRequestException if any invalid payload found
*/
private void validateIdentityServerUpdateRequest(IdentityServerDTO updateIdentityServerDTO,
IdentityServerDTO existingIdentityServerDTO) throws ApplicationManagementException {
if (updateIdentityServerDTO.getProviderName() != null &&
isIdentityServiceProviderNotConfigured(updateIdentityServerDTO.getProviderName())) {
String msg = "No such providers configured. Provider name: " + updateIdentityServerDTO.getProviderName();
log.error(msg);
throw new BadRequestException(msg);
}
if (updateIdentityServerDTO.getName() != null) {
if (!updateIdentityServerDTO.getName().equalsIgnoreCase(existingIdentityServerDTO.getName())
&& isIdentityServerNameExist(updateIdentityServerDTO.getName())) {
String msg = "Identity server already exist with the given name. Identity server name: " + updateIdentityServerDTO.getName();
log.error(msg);
throw new BadRequestException(msg);
}
}
if (updateIdentityServerDTO.getUrl() != null) {
validateIdentityServerUrl(updateIdentityServerDTO.getUrl());
if(!updateIdentityServerDTO.getUrl().equalsIgnoreCase(existingIdentityServerDTO.getUrl()) &&
isIdentityServerUrlExist(updateIdentityServerDTO.getUrl())) {
String msg = "Identity server already exist with the given url. Identity server url: " + updateIdentityServerDTO.getUrl();
log.error(msg);
throw new BadRequestException(msg);
}
}
validateUpdateIdentityServerRequestApiParam(updateIdentityServerDTO, existingIdentityServerDTO);
}
/**
* Validate the identity server create request payload
*
* @param identityServerDTO of identity server create request
* @throws BadRequestException if any invalid payload found
*/
private void validateIdentityServerCreateRequest(IdentityServerDTO identityServerDTO) throws ApplicationManagementException {
if (identityServerDTO.getUsername() == null) {
String msg = "Identity server username can not be null";
log.error(msg);
throw new BadRequestException(msg);
}
if (identityServerDTO.getPassword() == null) {
String msg = "Identity server password can not be null";
log.error(msg);
throw new BadRequestException(msg);
}
if (identityServerDTO.getName() == null) {
String msg = "Identity server name can not be null";
log.error(msg);
throw new BadRequestException(msg);
}
if (identityServerDTO.getUrl() == null) {
String msg = "Identity server url can not be null";
log.error(msg);
throw new BadRequestException(msg);
}
if (isIdentityServiceProviderNotConfigured(identityServerDTO.getProviderName())) {
String msg = "No such providers configured. Provider name: " + identityServerDTO.getProviderName();
log.error(msg);
throw new BadRequestException(msg);
}
if (isIdentityServerNameExist(identityServerDTO.getName())) {
String msg = "Identity server already exist with the given name. Identity server name: " + identityServerDTO.getName();
log.error(msg);
throw new BadRequestException(msg);
}
if (isIdentityServerUrlExist(identityServerDTO.getUrl())) {
String msg = "Identity server already exist with the given url. Identity server url: " + identityServerDTO.getUrl();
log.error(msg);
throw new BadRequestException(msg);
}
validateCreateIdentityServerRequestApiParams(identityServerDTO);
validateIdentityServerUrl(identityServerDTO.getUrl());
}
/**
* Validate provided identity server url (For example make sure it uses http/https protocol)
*
* @param url url of the identity server
* @throws BadRequestException if url is invalid
*/
private void validateIdentityServerUrl(String url) throws BadRequestException {
String[] schemes = {"http","https"};
UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_LOCAL_URLS);
if (!urlValidator.isValid(url)) {
String msg = "Identity server url is not a valid url";
log.error(msg);
throw new BadRequestException(msg);
}
}
/**
* Validate provided api params map in a identity server updated request
* For example the updated api param map may not contain all the required api params
*
* @param updatedIdentityServerDto Identity server update request payload bean
* @param existingIdentityServerDTO Corresponding existing identity server bean of the updated identity server
* @throws ApplicationManagementException if any api param is invalid
*/
private void validateUpdateIdentityServerRequestApiParam(IdentityServerDTO updatedIdentityServerDto,
IdentityServerDTO existingIdentityServerDTO) throws ApplicationManagementException {
ISServiceProviderApplicationService serviceProviderApplicationService =
ISServiceProviderApplicationService.of(existingIdentityServerDTO.getProviderName());
List<String> requiredApiParams = serviceProviderApplicationService.getRequiredApiParams();
if (!updatedIdentityServerDto.getProviderName().equals(existingIdentityServerDTO.getProviderName())) {
validateAllRequiredParamsExists(updatedIdentityServerDto, requiredApiParams);
}
validateIfAnyInvalidParamExists(updatedIdentityServerDto, requiredApiParams);
}
/**
* Validate api params map of identity server create request payload
* For example the api param map may not contain all the required api params
*
* @param identityServerDTO {@link IdentityServerDTO}
* @throws ApplicationManagementException if any api param is invalid
*/
private void validateCreateIdentityServerRequestApiParams(IdentityServerDTO identityServerDTO) throws ApplicationManagementException {
ISServiceProviderApplicationService serviceProviderApplicationService =
ISServiceProviderApplicationService.of(identityServerDTO.getProviderName());
List<String> requiredApiParams = serviceProviderApplicationService.getRequiredApiParams();
validateAllRequiredParamsExists(identityServerDTO, requiredApiParams);
validateIfAnyInvalidParamExists(identityServerDTO, requiredApiParams);
}
/**
* Make sure if all required api params exists for the given identity server bean
*
* @param identityServerDTO {@link IdentityServerDTO}
* @param requiredApiParams all mandatory api params
* @throws BadRequestException if a required api param does not exist
*/
private void validateAllRequiredParamsExists(IdentityServerDTO identityServerDTO, List<String> requiredApiParams)
throws BadRequestException {
for (String param : requiredApiParams) {
if (identityServerDTO.getApiParams().get(param) == null) {
String msg = param + " api parameter is required for " + identityServerDTO.getProviderName() + ". " +
"Required api parameters: " + StringUtils.join(requiredApiParams, ",");
log.error(msg);
throw new BadRequestException(msg);
}
}
}
/**
* Make sure if all api params are valid
* For example it may contain an unwanted api param
*
* @param identityServerDTO {@link IdentityServerDTO}
* @param requiredApiParams all required api params
* @throws BadRequestException if an unwanted api param exist
*/
private void validateIfAnyInvalidParamExists(IdentityServerDTO identityServerDTO, List<String> requiredApiParams)
throws BadRequestException {
for (String param : identityServerDTO.getApiParamKeys()) {
if (!requiredApiParams.contains(param)) {
String msg = "Invalid api parameter. " + param + " is not required for " + identityServerDTO.getProviderName() + ". " +
"Required api parameters: " + StringUtils.join(requiredApiParams, ",");
throw new BadRequestException(msg);
}
}
}
/**
* If the given providerName does not exist in the identity server config file
*
* @param providerName Name of the identity service provider
* @return if provider name exist in identity server config
*/
private boolean isIdentityServiceProviderNotConfigured(String providerName) {
List<IdentityServiceProvider> identityServiceProviders = ConfigurationManager.getInstance().getIdentityServerConfiguration().
getIdentityServiceProviders();
return identityServiceProviders.stream().noneMatch(provider -> provider.getProviderName().equals(providerName));
}
@Override
public boolean isIdentityServerNameExist(String name) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
return spApplicationDAO.isExistingIdentityServerName(name, tenantId);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error occurred while checking if identity server with the name " + name + " exists.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public boolean isIdentityServerUrlExist(String url) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
return spApplicationDAO.isExistingIdentityServerUrl(url, tenantId);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error occurred while checking if identity server with the url " + url + " exists.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SPApplicationListResponse retrieveSPApplicationFromIdentityServer(int identityServerId, Integer offset, Integer limit)
throws ApplicationManagementException {
IdentityServerDTO identityServer = getIdentityServer(identityServerId);
ISServiceProviderApplicationService serviceProviderApplicationService = ISServiceProviderApplicationService.of(identityServer.getProviderName());
SPApplicationListResponse spApplicationListResponse = serviceProviderApplicationService.retrieveSPApplications(identityServer, offset, limit);
addExistingApps(identityServerId, spApplicationListResponse.getApplications());
return spApplicationListResponse;
}
/**
* This method adds existing consumer applications of service providers to the SPApplication bean
*
* @param identityServerId identity server id of the service provider
* @param spApplications Service providers list to which the existing applications should be added
* @throws ApplicationManagementException if error occurred while adding existing applications
*/
private void addExistingApps(int identityServerId, List<SPApplication> spApplications) throws ApplicationManagementException {
for (SPApplication spApplication : spApplications) {
List<Application> existingApplications = getSPApplications(identityServerId, spApplication.getId());
spApplication.setExistingApplications(existingApplications);
}
}
@Override
public List<Application> getSPApplications(int identityServerId, String spUID) throws
ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Application> applications = new ArrayList<>();
try {
ConnectionManagerUtil.openDBConnection();
List<ApplicationDTO> appDTOs = spApplicationDAO.getSPApplications(identityServerId, spUID, tenantId);
for (ApplicationDTO applicationDTO : appDTOs) {
if (lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) {
continue;
}
boolean isHideableApp = applicationManager.isHideableApp(applicationDTO.getApplicationReleaseDTOs());
boolean isDeletableApp = applicationManager.isDeletableApp(applicationDTO.getApplicationReleaseDTOs());
//Set application categories, tags and unrestricted roles to the application DTO.
applicationDTO
.setUnrestrictedRoles(visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId));
applicationDTO.setAppCategories(applicationDAO.getAppCategories(applicationDTO.getId(), tenantId));
applicationDTO.setTags(applicationDAO.getAppTags(applicationDTO.getId(), tenantId));
applicationDTO.setApplicationReleaseDTOs(applicationDTO.getApplicationReleaseDTOs());
Application application = APIUtil.appDtoToAppResponse(applicationDTO);
application.setDeletableApp(isDeletableApp);
application.setHideableApp(isHideableApp);
applications.add(application);
}
return applications;
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection to get applications by filtering from "
+ "requested filter.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg =
"DAO exception while getting applications of tenant " + tenantId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
public void validateAttachAppsRequest(int identityServerId, String serviceProviderId, List<Integer> appIds) throws ApplicationManagementException {
validateServiceProviderUID(identityServerId, serviceProviderId);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
for (int appId : appIds) {
try {
ApplicationDTO appDTO = applicationDAO.getApplication(appId, tenantId);
if (appDTO == null) {
String msg = "Payload contains invalid an app id. " + "No app exist with the appId: " + appId + ".";
throw new BadRequestException(msg);
}
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while trying to retrieve application with the id:" + appId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
public void validateDetachAppsRequest(int identityServerId, String spId, List<Integer> appIds) throws ApplicationManagementException {
validateServiceProviderUID(identityServerId, spId);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
for (int id : appIds) {
try {
boolean isSPAppExist = spApplicationDAO.isSPApplicationExist(identityServerId, spId, id, tenantId);
if (!isSPAppExist) {
String msg = "No service provider app exist with the appId: " + id + " for service provider with the " +
"UID " + spId;
throw new ApplicationManagementException(msg);
}
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while checking if application exists with the id:" + id;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public List<IdentityServiceProviderDTO> getIdentityServiceProviders() throws ApplicationManagementException {
List<IdentityServiceProvider> identityServiceProviders = ConfigurationManager.getInstance().
getIdentityServerConfiguration().getIdentityServiceProviders();
List<IdentityServiceProviderDTO> identityServiceProviderDTOS = new ArrayList<>();
for (IdentityServiceProvider identityServiceProvider : identityServiceProviders) {
try {
identityServiceProviderDTOS.add(APIUtil.identityServiceProviderToDTO(identityServiceProvider));
} catch (ApplicationManagementException e) {
String msg = "Identity service provider configuration file is invalid. Hence failed to proceed.";
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
}
return identityServiceProviderDTOS;
}
/**
* Responsible for validating service provider in requests
*
* @param identityServerId identity server id of the service provider
* @param spUID uid of the service provider
* @throws ApplicationManagementException if invalid service provider
*/
private void validateServiceProviderUID(int identityServerId, String spUID) throws
ApplicationManagementException {
IdentityServerDTO identityServer = getIdentityServer(identityServerId);
ISServiceProviderApplicationService serviceProviderApplicationService = ISServiceProviderApplicationService.of(identityServer.getProviderName());
try {
boolean isSPAppExists = serviceProviderApplicationService.
isSPApplicationExist(identityServer, spUID);
if (!isSPAppExists) {
String errMsg = "Service provider with the uid " + spUID + " does not exist.";
log.error(errMsg);
throw new BadRequestException(errMsg);
}
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to validate service provider uid";
log.error(errMsg, e);
throw new ApplicationManagementException(errMsg, e);
}
}
public void attachSPApplications(int identityServerId, String spUID, List<Integer> appIds) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.beginDBTransaction();
for (int appId : appIds) {
spApplicationDAO.attachSPApplication(identityServerId, spUID, appId, tenantId);
}
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e){
ConnectionManagerUtil.rollbackDBTransaction();
String msg =
"DAO exception while getting applications of tenant " + tenantId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
public void detachSPApplications(int identityServerId, String spUID, List<Integer> appIds) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.beginDBTransaction();
for (int id : appIds) {
spApplicationDAO.detachSPApplication(identityServerId, spUID, id, tenantId);
}
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e){
ConnectionManagerUtil.rollbackDBTransaction();
String msg =
"DAO exception while getting applications of tenant " + tenantId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public <T> Application createSPApplication(T app, int identityServerId, String spId, boolean isPublished) throws ApplicationManagementException {
validateServiceProviderUID(identityServerId, spId);
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
ApplicationDTO applicationDTO = applicationManager.uploadReleaseArtifactIfExist(app);
if (log.isDebugEnabled()) {
log.debug("Application release create request is received. Application name: " + applicationDTO.getName()
+ " Device type ID: " + applicationDTO.getDeviceTypeId());
}
try {
ConnectionManagerUtil.beginDBTransaction();
Application createdApp = applicationManager.addAppDataIntoDB(applicationDTO, isPublished);
attachCreatedSPApplication(createdApp, identityServerId, spId);
ConnectionManagerUtil.commitDBTransaction();
return createdApp;
} catch (DBConnectionException e) {
String msg = "Error occurred while getting database connection.";
log.error(msg, e);
ApplicationManagementUtil.deleteArtifactIfExist(applicationDTO);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while disabling AutoCommit.";
log.error(msg, e);
ApplicationManagementUtil.deleteArtifactIfExist(applicationDTO);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while creating and attaching application with the name " + applicationDTO.getName() ;
log.error(msg, e);
ApplicationManagementUtil.deleteArtifactIfExist(applicationDTO);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
public void attachCreatedSPApplication(Application createdApp, int identityServerId, String spUID) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
spApplicationDAO.attachSPApplication(identityServerId, spUID, createdApp.getId(), tenantId);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while attaching application with the id " + createdApp.getId();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
}

@ -17,6 +17,7 @@
*/
package io.entgra.application.mgt.core.internal;
import io.entgra.application.mgt.common.services.SPApplicationManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
@ -88,6 +89,10 @@ public class ApplicationManagementServiceComponent {
DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManager);
bundleContext.registerService(LifecycleStateManager.class.getName(), lifecycleStateManager, null);
SPApplicationManager SPApplicationManager = ApplicationManagementUtil.getSPApplicationManagerInstance();
DataHolder.getInstance().setISApplicationManager(SPApplicationManager);
bundleContext.registerService(SPApplicationManager.class.getName(), SPApplicationManager, null);
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
applicationManager
.addApplicationCategories(ConfigurationManager.getInstance().getConfiguration().getAppCategories());

@ -20,6 +20,7 @@ package io.entgra.application.mgt.core.internal;
import io.entgra.application.mgt.common.services.ApplicationManager;
import io.entgra.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.application.mgt.common.services.AppmDataHandler;
import io.entgra.application.mgt.common.services.SPApplicationManager;
import io.entgra.application.mgt.common.services.ReviewManager;
import io.entgra.application.mgt.common.services.SubscriptionManager;
import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager;
@ -36,6 +37,8 @@ public class DataHolder {
private RealmService realmService;
private SPApplicationManager SPApplicationManager;
private ApplicationManager applicationManager;
private ReviewManager reviewManager;
@ -131,4 +134,12 @@ public class DataHolder {
public void setTaskService(TaskService taskService) {
this.taskService = taskService;
}
public SPApplicationManager getISApplicationManager() {
return SPApplicationManager;
}
public void setISApplicationManager(SPApplicationManager SPApplicationManager) {
this.SPApplicationManager = SPApplicationManager;
}
}

@ -18,6 +18,12 @@
package io.entgra.application.mgt.core.util;
import io.entgra.application.mgt.common.IdentityServerResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.dto.IdentityServiceProviderDTO;
import io.entgra.application.mgt.common.exception.InvalidConfigurationException;
import io.entgra.application.mgt.core.config.IdentityServiceProvider;
import io.entgra.application.mgt.core.identityserver.serviceprovider.ISServiceProviderApplicationService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -59,12 +65,31 @@ public class APIUtil {
private static Log log = LogFactory.getLog(APIUtil.class);
private static volatile SPApplicationManager SPApplicationManager;
private static volatile ApplicationManager applicationManager;
private static volatile ApplicationStorageManager applicationStorageManager;
private static volatile SubscriptionManager subscriptionManager;
private static volatile ReviewManager reviewManager;
private static volatile AppmDataHandler appmDataHandler;
public static SPApplicationManager getSPApplicationManager() {
if (SPApplicationManager == null) {
synchronized (APIUtil.class) {
if (SPApplicationManager == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
SPApplicationManager =
(SPApplicationManager) ctx.getOSGiService(SPApplicationManager.class, null);
if (SPApplicationManager == null) {
String msg = "ApplicationDTO Manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
return SPApplicationManager;
}
public static ApplicationManager getApplicationManager() {
if (applicationManager == null) {
synchronized (APIUtil.class) {
@ -231,6 +256,7 @@ public class APIUtil {
public static <T> ApplicationDTO convertToAppDTO(T param)
throws BadRequestException, UnexpectedServerErrorException {
ApplicationDTO applicationDTO = new ApplicationDTO();
List<ApplicationReleaseDTO> applicationReleaseEntities;
if (param instanceof ApplicationWrapper){
ApplicationWrapper applicationWrapper = (ApplicationWrapper) param;
@ -244,7 +270,7 @@ public class APIUtil {
applicationDTO.setTags(applicationWrapper.getTags());
applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles());
applicationDTO.setDeviceTypeId(deviceType.getId());
List<ApplicationReleaseDTO> applicationReleaseEntities = applicationWrapper.getEntAppReleaseWrappers()
applicationReleaseEntities = applicationWrapper.getEntAppReleaseWrappers()
.stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList());
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
} else if (param instanceof WebAppWrapper){
@ -257,7 +283,7 @@ public class APIUtil {
applicationDTO.setType(webAppWrapper.getType());
applicationDTO.setTags(webAppWrapper.getTags());
applicationDTO.setUnrestrictedRoles(webAppWrapper.getUnrestrictedRoles());
List<ApplicationReleaseDTO> applicationReleaseEntities = webAppWrapper.getWebAppReleaseWrappers()
applicationReleaseEntities = webAppWrapper.getWebAppReleaseWrappers()
.stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList());
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
} else if (param instanceof PublicAppWrapper) {
@ -272,7 +298,7 @@ public class APIUtil {
applicationDTO.setTags(publicAppWrapper.getTags());
applicationDTO.setUnrestrictedRoles(publicAppWrapper.getUnrestrictedRoles());
applicationDTO.setDeviceTypeId(deviceType.getId());
List<ApplicationReleaseDTO> applicationReleaseEntities = publicAppWrapper.getPublicAppReleaseWrappers()
applicationReleaseEntities = publicAppWrapper.getPublicAppReleaseWrappers()
.stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList());
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
} else if (param instanceof CustomAppWrapper){
@ -287,7 +313,7 @@ public class APIUtil {
applicationDTO.setTags(customAppWrapper.getTags());
applicationDTO.setUnrestrictedRoles(customAppWrapper.getUnrestrictedRoles());
applicationDTO.setDeviceTypeId(deviceType.getId());
List<ApplicationReleaseDTO> applicationReleaseEntities = customAppWrapper.getCustomAppReleaseWrappers()
applicationReleaseEntities = customAppWrapper.getCustomAppReleaseWrappers()
.stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList());
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
}
@ -343,6 +369,32 @@ public class APIUtil {
return applicationReleaseDTO;
}
public static IdentityServiceProviderDTO identityServiceProviderToDTO(IdentityServiceProvider identityServiceProvider)
throws InvalidConfigurationException {
ISServiceProviderApplicationService serviceProviderApplicationService =
ISServiceProviderApplicationService.of(identityServiceProvider.getProviderName());
IdentityServiceProviderDTO identityServiceProviderDTO = new IdentityServiceProviderDTO();
identityServiceProviderDTO.setName(identityServiceProvider.getProviderName());
identityServiceProviderDTO.setRequiredApiParams(serviceProviderApplicationService.getRequiredApiParams());
return identityServiceProviderDTO;
}
public static IdentityServerResponse identityServerDtoToIdentityServerResponse(IdentityServerDTO identityServerDTO) {
IdentityServerResponse identityServer = new IdentityServerResponse();
identityServer.setId(identityServerDTO.getId());
identityServer.setProviderName(identityServerDTO.getProviderName());
identityServer.setName(identityServerDTO.getName());
identityServer.setDescription(identityServerDTO.getDescription());
identityServer.setUrl(identityServerDTO.getUrl());
identityServer.setApiParamList(identityServerDTO.getApiParams());
identityServer.setUsername(identityServerDTO.getUsername());
IdentityServiceProvider identityServiceProvider = ConfigurationManager.getInstance().getIdentityServerConfiguration()
.getIdentityServerDetailByProviderName(identityServerDTO.getProviderName());
String serviceProviderAppsUrl = identityServerDTO.getUrl() + identityServiceProvider.getServiceProvidersPageUri();
identityServer.setServiceProviderAppsUrl(serviceProviderAppsUrl);
return identityServer;
}
public static Application appDtoToAppResponse(ApplicationDTO applicationDTO) throws ApplicationManagementException {
Application application = new Application();
@ -363,7 +415,9 @@ public class APIUtil {
application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles());
application.setRating(applicationDTO.getAppRating());
application.setFavourite(applicationDTO.isFavourite());
if (applicationDTO.getApplicationReleaseDTOs() != null && !applicationDTO.getApplicationReleaseDTOs().isEmpty()) {
application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName());
}
List<ApplicationRelease> applicationReleases = new ArrayList<>();
if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories()
.contains("GooglePlaySyncedApp")) {

@ -17,6 +17,24 @@
*/
package io.entgra.application.mgt.core.util;
import io.entgra.application.mgt.common.ApplicationArtifact;
import io.entgra.application.mgt.common.Base64File;
import io.entgra.application.mgt.common.FileDataHolder;
import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException;
import io.entgra.application.mgt.common.exception.ResourceManagementException;
import io.entgra.application.mgt.common.services.SPApplicationManager;
import io.entgra.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppWrapper;
import io.entgra.application.mgt.common.wrapper.EntAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppReleaseWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppWrapper;
import io.entgra.application.mgt.core.exception.BadRequestException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.application.mgt.common.exception.InvalidConfigurationException;
@ -27,8 +45,15 @@ import io.entgra.application.mgt.common.services.SubscriptionManager;
import io.entgra.application.mgt.core.config.ConfigurationManager;
import io.entgra.application.mgt.core.config.Extension;
import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager;
import org.wso2.carbon.device.mgt.core.common.util.FileUtil;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* This DAOUtil class is responsible for making sure single instance of each Extension Manager is used throughout for
@ -38,6 +63,97 @@ public class ApplicationManagementUtil {
private static Log log = LogFactory.getLog(ApplicationManagementUtil.class);
/**
* Construct ApplicationArtifact from given base64 artifact files
*
* @param iconBase64 icon of the application
* @param screenshotsBase64 screenshots of the application
* @param binaryFileBase64 binary file of the application
* @param bannerFileBase64 banner of the application
* @return ApplicationArtifact the give base64 release artifact files
* @throws BadRequestException if any invalid payload is found
*/
public static ApplicationArtifact constructApplicationArtifact(Base64File iconBase64, List<Base64File> screenshotsBase64,
Base64File binaryFileBase64, Base64File bannerFileBase64)
throws BadRequestException {
ApplicationArtifact applicationArtifact = new ApplicationArtifact();
ApplicationManager applicationManager = APIUtil.getApplicationManager();
if (binaryFileBase64 != null) {
try {
applicationManager.validateBase64File(binaryFileBase64);
} catch (RequestValidatingException e) {
String msg = "Invalid base64 binary file payload found";
log.error(msg, e);
throw new BadRequestException(msg, e);
}
FileDataHolder binaryFile = base64FileToFileDataHolder(binaryFileBase64);
applicationArtifact.setInstallerName(binaryFile.getName());
applicationArtifact.setInstallerStream(binaryFile.getFile());
}
if (iconBase64 != null) {
try {
applicationManager.validateBase64File(iconBase64);
} catch (RequestValidatingException e) {
String msg = "Invalid base64 icon file payload found";
log.error(msg, e);
throw new BadRequestException(msg, e);
}
FileDataHolder iconFile = base64FileToFileDataHolder(iconBase64);
applicationArtifact.setIconName(iconFile.getName());
applicationArtifact.setIconStream(iconFile.getFile());
}
if (bannerFileBase64 != null) {
try {
applicationManager.validateBase64File(bannerFileBase64);
} catch (RequestValidatingException e) {
String msg = "Invalid base64 banner file payload found";
log.error(msg, e);
throw new BadRequestException(msg, e);
}
FileDataHolder bannerFile = base64FileToFileDataHolder(bannerFileBase64);
applicationArtifact.setBannerName(bannerFile.getName());
applicationArtifact.setBannerStream(bannerFile.getFile());
}
if (screenshotsBase64 != null) {
Map<String, InputStream> screenshotData = new TreeMap<>();
// This is to handle cases in which multiple screenshots have the same name
Map<String, Integer> screenshotNameCount = new HashMap<>();
for (Base64File screenshot : screenshotsBase64) {
try {
applicationManager.validateBase64File(screenshot);
} catch (RequestValidatingException e) {
String msg = "Invalid base64 screenshot file payload found";
log.error(msg, e);
throw new BadRequestException(msg, e);
}
FileDataHolder screenshotFile = base64FileToFileDataHolder(screenshot);
String screenshotName = screenshotFile.getName();
screenshotNameCount.put(screenshotName, screenshotNameCount.getOrDefault(screenshotName, 0) + 1);
screenshotName = FileUtil.generateDuplicateFileName(screenshotName, screenshotNameCount.get(screenshotName));
screenshotData.put(screenshotName, screenshotFile.getFile());
}
applicationArtifact.setScreenshots(screenshotData);
}
return applicationArtifact;
}
/**
*
* @param base64File Base64File that should be converted to FileDataHolder bean
* @return FileDataHolder bean which contains input stream and name of the file
*/
public static FileDataHolder base64FileToFileDataHolder(Base64File base64File) {
InputStream stream = FileUtil.base64ToInputStream(base64File.getBase64String());
return new FileDataHolder(base64File.getName(), stream);
}
public static SPApplicationManager getSPApplicationManagerInstance() throws InvalidConfigurationException {
ConfigurationManager configurationManager = ConfigurationManager.getInstance();
Extension extension = configurationManager.getExtension(Extension.Name.SPApplicationManager);
return getInstance(extension, SPApplicationManager.class);
}
public static ApplicationManager getApplicationManagerInstance() throws InvalidConfigurationException {
ConfigurationManager configurationManager = ConfigurationManager.getInstance();
Extension extension = configurationManager.getExtension(Extension.Name.ApplicationManager);
@ -69,7 +185,48 @@ public class ApplicationManagementUtil {
return getInstance(extension, LifecycleStateManager.class);
}
private static <T> T getInstance(Extension extension, Class<T> cls) throws InvalidConfigurationException {
/**
* This is useful to delete application artifacts if any error occurred while creating release/application
* after uploading the artifacts
*
* @param app ApplicationDTO of the application of which the artifacts should be deleted
* @throws ApplicationManagementException if error occurred while deleting artifacts
*/
public static <T> void deleteArtifactIfExist(ApplicationDTO app) throws ApplicationManagementException {
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
if (!app.getApplicationReleaseDTOs().isEmpty()) {
applicationManager.deleteApplicationArtifacts(Collections.singletonList(app.getApplicationReleaseDTOs().get(0).getAppHashValue()));
}
}
/**
* Check if application release available for a given application wrapper. This is useful since
* if a release is available for an application that needs to handled separately
*
* @param appWrapper Application wrapper bean of the application
* @return if release is available or not
*/
public static <T> boolean isReleaseAvailable(T appWrapper) {
if (appWrapper instanceof ApplicationWrapper) {
List<EntAppReleaseWrapper> entAppReleaseWrappers = ((ApplicationWrapper) appWrapper).getEntAppReleaseWrappers();
return entAppReleaseWrappers != null && !entAppReleaseWrappers.isEmpty();
}
if (appWrapper instanceof PublicAppWrapper) {
List<PublicAppReleaseWrapper> publicAppReleaseWrappers = ((PublicAppWrapper) appWrapper).getPublicAppReleaseWrappers();
return publicAppReleaseWrappers != null && !publicAppReleaseWrappers.isEmpty();
}
if (appWrapper instanceof WebAppWrapper) {
List<WebAppReleaseWrapper> webAppReleaseWrappers = ((WebAppWrapper) appWrapper).getWebAppReleaseWrappers();
return webAppReleaseWrappers != null && !webAppReleaseWrappers.isEmpty();
}
if (appWrapper instanceof CustomAppWrapper) {
List<CustomAppReleaseWrapper> customAppReleaseWrappers = ((CustomAppWrapper) appWrapper).getCustomAppReleaseWrappers();
return customAppReleaseWrappers != null && !((CustomAppWrapper) appWrapper).getCustomAppReleaseWrappers().isEmpty();
}
throw new IllegalArgumentException("Provided bean does not belong to an Application Wrapper");
}
public static <T> T getInstance(Extension extension, Class<T> cls) throws InvalidConfigurationException {
try {
Class theClass = Class.forName(extension.getClassName());
if (extension.getParameters() != null && extension.getParameters().size() > 0) {

@ -31,10 +31,15 @@ import java.util.Map;
public class Constants {
public static final String APPLICATION_CONFIG_XML_FILE = "application-mgt.xml";
public static final String IDENTITY_SERVERS_CONFIG_XML_FILE = "identity-service-provider-config.xml";
public static final String DEFAULT_CONFIG_FILE_LOCATION = CarbonUtils.getCarbonConfigDirPath() + File.separator +
Constants.APPLICATION_CONFIG_XML_FILE;
public static final String DEFAULT_IDENTITY_SERVERS_CONFIG_FILE_LOCATION = CarbonUtils.getCarbonConfigDirPath() + File.separator +
IDENTITY_SERVERS_CONFIG_XML_FILE;
public static final String DEFAULT_VERSION = "1.0.0";
public static final String SCREENSHOT_NAME = "screenshot";
public static final String ICON_NAME = "icon";
public static final String PAYLOAD = "Payload";
public static final String PLIST_NAME = "Info.plist";
public static final String CF_BUNDLE_VERSION = "CFBundleVersion";
@ -48,8 +53,20 @@ public class Constants {
public static final String OPERATION_STATUS_UPDATE_API_BASE = "/api/device-mgt/v1.0/devices";
public static final String OPERATION_STATUS_UPDATE_API_URI = "/operation";
public static final String LIMIT_QUERY_PARAM = "limit";
public static final String OFFSET_QUERY_PARAM = "offset";
public static final String IS_APPS_API_CONTEXT_PATH = "identity-server-applications";
public static final String IS_APPS_API_BASE_PATH = "identity-server-applications";
public static final Double IS_APP_DEFAULT_PRICE = 0.0;
public static final String SP_APP_CATEGORY = "SPApp";
public static final String IS_APP_RELEASE_TYPE = "stable";
public static final String IS_APP_DEFAULT_PAYMENT_CURRENCY = "$";
public static final String IS_APP_DEFAULT_VERSION = "1.0";
public static final String COLON = ":";
public static final String FORWARD_SLASH = "/";
public static final String URI_QUERY_SEPARATOR = "?";
public static final String QUERY_STRING_SEPARATOR = "&";
public static final String QUERY_KEY_VALUE_SEPARATOR = "=";
public static final String ANY = "ANY";
public static final String DEFAULT_PCK_NAME = "default.app.com";
public static final String ALL = "ALL";

@ -19,6 +19,7 @@ package io.entgra.application.mgt.core.util;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
@ -38,11 +39,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -86,12 +86,18 @@ public class DAOUtil {
application.setAppRating(rs.getDouble("APP_RATING"));
application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID"));
application.setPackageName(rs.getString("PACKAGE_NAME"));
ApplicationReleaseDTO releaseDTO = constructAppReleaseDTO(rs);
if (releaseDTO != null) {
application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs));
}
} else {
if (application != null && application.getApplicationReleaseDTOs() != null) {
ApplicationReleaseDTO releaseDTO = constructAppReleaseDTO(rs);
if (releaseDTO != null) {
application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs));
}
}
}
hasNext = rs.next();
if (!hasNext) {
applications.add(application);
@ -139,6 +145,7 @@ public class DAOUtil {
*/
public static ApplicationReleaseDTO constructAppReleaseDTO(ResultSet rs) throws SQLException {
ApplicationReleaseDTO appRelease = new ApplicationReleaseDTO();
if (rs.getString("RELEASE_UUID") != null) {
appRelease.setId(rs.getInt("RELEASE_ID"));
appRelease.setDescription(rs.getString("RELEASE_DESCRIPTION"));
appRelease.setUuid(rs.getString("RELEASE_UUID"));
@ -160,7 +167,57 @@ public class DAOUtil {
appRelease.setRatedUsers(rs.getInt("RATED_USER_COUNT"));
return appRelease;
}
return null;
}
/**
* To create application object from the result set retrieved from the Database.
*
* @param rs ResultSet
* @return IdentityServerDTO that is retrieved from the Database.
* @throws SQLException SQL Exception
* @throws JSONException JSONException.
*/
public static IdentityServerDTO loadIdentityServer(ResultSet rs)
throws SQLException, JSONException, UnexpectedServerErrorException {
List<IdentityServerDTO> identityServerDTOS = loadIdentityServers(rs);
if (identityServerDTOS.isEmpty()) {
return null;
}
if (identityServerDTOS.size() > 1) {
String msg = "Internal server error. Found more than one identity server for requested ID";
log.error(msg);
throw new UnexpectedServerErrorException(msg);
}
return identityServerDTOS.get(0);
}
/**
* To create application object from the result set retrieved from the Database.
*
* @param rs ResultSet
* @return List of Identity Servers that is retrieved from the Database.
* @throws SQLException SQL Exception
* @throws JSONException JSONException.
*/
public static List<IdentityServerDTO> loadIdentityServers(ResultSet rs) throws SQLException, JSONException {
List<IdentityServerDTO> identityServerDTOS = new ArrayList<>();
while (rs.next()) {
IdentityServerDTO identityServerDTO = new IdentityServerDTO();
identityServerDTO.setId(rs.getInt("ID"));
identityServerDTO.setProviderName(rs.getString("PROVIDER_NAME"));
identityServerDTO.setName(rs.getString("NAME"));
identityServerDTO.setDescription(rs.getString("DESCRIPTION"));
identityServerDTO.setUrl(rs.getString("URL"));
String apiParamsJson = rs.getString("API_PARAMS");
Map<String, String> apiParams = new Gson().fromJson(apiParamsJson, new TypeToken<HashMap<String, String>>() {}.getType());
identityServerDTO.setApiParams(apiParams);
identityServerDTO.setUsername(rs.getString("USERNAME"));
identityServerDTO.setPassword(rs.getString("PASSWORD"));
identityServerDTOS.add(identityServerDTO);
}
return identityServerDTOS;
}
/**
* To create application object from the result set retrieved from the Database.

@ -121,7 +121,7 @@ public class ApplicationManagementTest extends BaseTestCase {
applicationArtifact.setScreenshots(screenshots);
ApplicationManager manager = new ApplicationManagerImpl();
manager.createEntApp(applicationWrapper, applicationArtifact, false);
manager.createApplication(applicationWrapper, false);
}
@DataProvider(name = "applicationIdDataProvider")

@ -17,6 +17,7 @@
*/
package io.entgra.application.mgt.publisher.api.services;
import io.entgra.application.mgt.common.Base64File;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -27,8 +28,6 @@ import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import io.entgra.application.mgt.common.ApplicationList;
@ -284,7 +283,7 @@ public interface ApplicationManagementPublisherAPI {
@POST
@Path("/ent-app")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
@ -318,47 +317,17 @@ public interface ApplicationManagementPublisherAPI {
name = "application",
value = "The application that need to be created.",
required = true)
@Multipart("application") ApplicationWrapper application,
ApplicationWrapper application,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("is-Published") boolean isPublished,
@ApiParam(
name = "binaryFile",
value = "Binary file of uploading application",
required = true)
@Multipart(value = "binaryFile") Attachment binaryFile,
@ApiParam(
name = "icon",
value = "Icon of the uploading application",
required = true)
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "Banner of the uploading application")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading application",
required = true)
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot3") Attachment screenshot3
);
@QueryParam("isPublished") boolean isPublished);
@POST
@Path("/web-app")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
@ -392,42 +361,18 @@ public interface ApplicationManagementPublisherAPI {
name = "webapp",
value = "The web app that need to be created.",
required = true)
@Multipart("webapp") WebAppWrapper webAppWrapper,
WebAppWrapper webAppWrapper,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("is-Published") boolean isPublished,
@ApiParam(
name = "icon",
value = "Icon of the uploading web app",
required = true)
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "Banner of the uploading web app")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading web app",
required = true)
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading web app",
required = false)
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading web app",
required = false)
@Multipart(value = "screenshot3") Attachment screenshot3
@QueryParam("isPublished") boolean isPublished
);
@POST
@Path("/public-app")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
@ -461,40 +406,18 @@ public interface ApplicationManagementPublisherAPI {
name = "public-app",
value = "The public app that need to be created.",
required = true)
@Multipart("public-app") PublicAppWrapper publicAppWrapper,
PublicAppWrapper publicAppWrapper,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("is-Published") boolean isPublished,
@ApiParam(
name = "icon",
value = "Icon of the uploading public app",
required = true)
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "Banner of the uploading public app")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading public app",
required = true)
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading public app")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading public app")
@Multipart(value = "screenshot3") Attachment screenshot3
@QueryParam("isPublished") boolean isPublished
);
@POST
@Path("/custom-app")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
@ -528,53 +451,79 @@ public interface ApplicationManagementPublisherAPI {
name = "application",
value = "The application that need to be created.",
required = true)
@Multipart("application") CustomAppWrapper customAppWrapper,
CustomAppWrapper customAppWrapper,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("is-Published") boolean isPublished,
@QueryParam("isPublished") boolean isPublished
);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/ent-app/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create an application",
notes = "This will create a new application",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "OK. \n Successfully created an application.",
response = ApplicationRelease.class),
@ApiResponse(
code = 400,
message = "Bad Request. \n " +
"ApplicationDTO creating payload contains unacceptable or vulnerable data"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while creating the application.",
response = ErrorResponse.class)
})
Response createEntAppRelease(
@ApiParam(
name = "binaryFile",
value = "Binary file of uploading application",
name = "deviceType",
value = "Device type that application is compatible with.",
required = true)
@Multipart(value = "binaryFile") Attachment binaryFile,
@PathParam("deviceType") String deviceType,
@ApiParam(
name = "icon",
value = "Icon of the uploading application",
name = "appId",
value = "Id of the application.",
required = true)
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "Banner of the uploading application")
@Multipart(value = "banner") Attachment bannerFile,
@PathParam("appId") int appId,
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading application",
name = "applicationRelease",
value = "The application release that need to be created.",
required = true)
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot2") Attachment screenshot2,
EntAppReleaseWrapper entAppReleaseWrapper,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot3") Attachment screenshot3
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished
);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Path("/{deviceType}/ent-app/{appId}")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/public-app/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create an application",
notes = "This will create a new application",
notes = "This will create a new public application release",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ -597,7 +546,7 @@ public interface ApplicationManagementPublisherAPI {
message = "Internal Server Error. \n Error occurred while creating the application.",
response = ErrorResponse.class)
})
Response createEntAppRelease(
Response createPubAppRelease(
@ApiParam(
name = "deviceType",
value = "Device type that application is compatible with.",
@ -612,47 +561,123 @@ public interface ApplicationManagementPublisherAPI {
name = "applicationRelease",
value = "The application release that need to be created.",
required = true)
@Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper,
PublicAppReleaseWrapper publicAppReleaseWrapper,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("is-Published") boolean isPublished,
@QueryParam("isPublished") boolean isPublished
);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/web-app/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create an application",
notes = "This will create a new web application release",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "OK. \n Successfully created an application.",
response = ApplicationRelease.class),
@ApiResponse(
code = 400,
message = "Bad Request. \n " +
"ApplicationDTO creating payload contains unacceptable or vulnerable data"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while creating the application.",
response = ErrorResponse.class)
})
Response createWebAppRelease(
@ApiParam(
name = "binaryFile",
value = "Binary file of uploading application",
name = "appId",
value = "Id of the application.",
required = true)
@Multipart(value = "binaryFile") Attachment binaryFile,
@PathParam("appId") int appId,
@ApiParam(
name = "icon",
value = "Icon of the uploading application",
name = "applicationRelease",
value = "The application release that need to be created.",
required = true)
@Multipart(value = "icon") Attachment iconFile,
WebAppReleaseWrapper webAppReleaseWrapper,
@ApiParam(
name = "banner",
value = "Banner of the uploading application")
@Multipart(value = "banner") Attachment bannerFile,
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished
);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/custom-app/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create an application",
notes = "This will create a new custom application release",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 201,
message = "OK. \n Successfully created an application.",
response = ApplicationRelease.class),
@ApiResponse(
code = 400,
message = "Bad Request. \n " +
"ApplicationDTO creating payload contains unacceptable or vulnerable data"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while creating the application.",
response = ErrorResponse.class)
})
Response createCustomAppRelease(
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading application",
name = "deviceType",
value = "Device type that application is compatible with.",
required = true)
@Multipart(value = "screenshot1") Attachment screenshot1,
@PathParam("deviceType") String deviceType,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot2") Attachment screenshot2,
name = "appId",
value = "Id of the application.",
required = true)
@PathParam("appId") int appId,
@ApiParam(
name = "applicationRelease",
value = "The application release that need to be created.",
required = true)
CustomAppReleaseWrapper customAppReleaseWrapper,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading application",
required = false)
@Multipart(value = "screenshot3") Attachment screenshot3
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished
);
@PUT
@Path("/image-artifacts/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -688,23 +713,15 @@ public interface ApplicationManagementPublisherAPI {
@ApiParam(
name = "icon",
value = "Icon of the uploading application")
@Multipart(value = "icon") Attachment iconFile,
Base64File iconFile,
@ApiParam(
name = "banner",
value = "Banner of the uploading application")
@Multipart(value = "banner") Attachment bannerFile,
Base64File bannerFile,
@ApiParam(
name = "screenshot1",
value = "Screen Shots of the uploading application")
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Screen Shots of the uploading application")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Screen Shots of the uploading application")
@Multipart(value = "screenshot3") Attachment screenshot3
List<Base64File> screenshots
);
@GET
@ -754,7 +771,7 @@ public interface ApplicationManagementPublisherAPI {
@PUT
@Path("/ent-app-artifacts/{deviceType}/{appId}/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -797,13 +814,13 @@ public interface ApplicationManagementPublisherAPI {
value = "UUID of the application",
required = true)
@PathParam("uuid") String applicationUUID,
@Multipart("binaryFile") Attachment binaryFile
Base64File binaryFile
);
@PUT
@Path("/ent-app-release/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -842,39 +859,12 @@ public interface ApplicationManagementPublisherAPI {
name = "entAppReleaseWrapper",
value = "Application release wrapper which is going to update.",
required = true)
@Multipart(
value = "entAppReleaseWrapper",
type = "application/json") EntAppReleaseWrapper entAppReleaseWrapper,
@ApiParam(
name = "binaryFile",
value = "Application installer file.",
required = true)
@Multipart(value = "binaryFile") Attachment binaryFile,
@ApiParam(
name = "icon",
value = "Icon file of the application release.")
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "banner file of the application release.")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "First screenshot of the uploading application")
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Second screenshot 2 of the uploading application")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Third screenshot of the uploading application")
@Multipart(value = "screenshot3") Attachment screenshot3);
EntAppReleaseWrapper entAppReleaseWrapper);
@PUT
@Path("/public-app-release/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -913,34 +903,12 @@ public interface ApplicationManagementPublisherAPI {
name = "pubAppReleaseWrapper",
value = "Application release wrapper which is going to update.",
required = true)
@Multipart(
value = "pubAppReleaseWrapper",
type = "application/json") PublicAppReleaseWrapper publicAppReleaseWrapper,
@ApiParam(
name = "icon",
value = "Icon file of the application release.")
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "banner file of the application release.")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "First screenshot of the uploading application")
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Second screenshot 2 of the uploading application")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Third screenshot of the uploading application")
@Multipart(value = "screenshot3") Attachment screenshot3);
PublicAppReleaseWrapper publicAppReleaseWrapper);
@PUT
@Path("/web-app-release/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -979,34 +947,13 @@ public interface ApplicationManagementPublisherAPI {
name = "pubAppReleaseWrapper",
value = "Application release wrapper which is going to update.",
required = true)
@Multipart(
value = "pubAppReleaseWrapper",
type = "application/json") WebAppReleaseWrapper webAppReleaseWrapper,
@ApiParam(
name = "icon",
value = "Icon file of the application release.")
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "banner file of the application release.")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "First screenshot of the uploading application")
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Second screenshot 2 of the uploading application")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Third screenshot of the uploading application")
@Multipart(value = "screenshot3") Attachment screenshot3);
WebAppReleaseWrapper webAppReleaseWrapper
);
@PUT
@Path("/custom-app-release/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.MULTIPART_FORM_DATA,
produces = MediaType.APPLICATION_JSON,
@ -1045,34 +992,7 @@ public interface ApplicationManagementPublisherAPI {
name = "entAppReleaseWrapper",
value = "Application release wrapper which is going to update.",
required = true)
@Multipart(
value = "entAppReleaseWrapper",
type = "application/json") CustomAppReleaseWrapper customAppReleaseWrapper,
@ApiParam(
name = "binaryFile",
value = "Application installer file.",
required = true)
@Multipart(value = "binaryFile") Attachment binaryFile,
@ApiParam(
name = "icon",
value = "Icon file of the application release.")
@Multipart(value = "icon") Attachment iconFile,
@ApiParam(
name = "banner",
value = "banner file of the application release.")
@Multipart(value = "banner") Attachment bannerFile,
@ApiParam(
name = "screenshot1",
value = "First screenshot of the uploading application")
@Multipart(value = "screenshot1") Attachment screenshot1,
@ApiParam(
name = "screenshot2",
value = "Second screenshot 2 of the uploading application")
@Multipart(value = "screenshot2") Attachment screenshot2,
@ApiParam(
name = "screenshot3",
value = "Third screenshot of the uploading application")
@Multipart(value = "screenshot3") Attachment screenshot3);
CustomAppReleaseWrapper customAppReleaseWrapper);
@GET
@Path("/life-cycle/state-changes/{uuid}")

@ -0,0 +1,393 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.publisher.api.services;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "Service Provider Application Management Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "SPApplicationService"),
@ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/identity-server-applications"),
})
}
),
tags = {
@Tag(name = "application_management, device_management", description = "App publisher related APIs")
}
)
@Scopes(
scopes = {
@Scope(
name = "view a service provider applications",
description = "Get service provider application details",
key = "perm:app:publisher:service-provider:view",
roles = {"Internal/devicemgt-user"},
permissions = {"/app-mgt/publisher/service-provider/application/view"}
),
@Scope(
name = "Create new identity server",
description = "Connect to new identity server",
key = "perm:app:publisher:service-provider:connect",
roles = {"Internal/devicemgt-user"},
permissions = {"/app-mgt/publisher/service-provider/application/connect"}
),
@Scope(
name = "Create a service provider application",
description = "Create an application and attach (map) to service provider",
key = "perm:app:publisher:service-provider:create",
roles = {"Internal/devicemgt-user"},
permissions = {"/app-mgt/publisher/service-provider/application/create"}
),
@Scope(
name = "Attach a service provider application",
description = "Map an application to service provider",
key = "perm:app:publisher:service-provider:attach",
roles = {"Internal/devicemgt-user"},
permissions = {"/app-mgt/publisher/service-provider/application/attach"}
),
@Scope(
name = "Detach a service provider application",
description = "Remove an application from service provider",
key = "perm:app:publisher:service-provider:detach",
roles = {"Internal/devicemgt-user"},
permissions = {"/app-mgt/publisher/service-provider/application/detach"}
)
}
)
@Path("/identity-server-applications")
@Api(value = "SPApplication Management")
@Produces(MediaType.APPLICATION_JSON)
public interface SPApplicationService {
String SCOPE = "scope";
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-servers/identity-service-providers")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get available identity service providers",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response getIdentityServiceProviders();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-servers")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get all identity servers",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response getIdentityServers();
@Path("/identity-servers/{id}")
@DELETE
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "DELETE",
value = "get identity server by id",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:connect")
})
}
)
Response deleteIdentityServer(@PathParam("id") int id);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-servers/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get identity server by id",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response getIdentityServer(@PathParam("id") int id);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-servers")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "create new identity server",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:connect")
})
}
)
Response createIdentityServer(IdentityServerDTO identityServerDTO);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-servers/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "edit existing identity server",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:connect")
})
}
)
Response updateIdentityServer(IdentityServerDTO identityServerDTO, @PathParam("id") int id);
@GET
@Path("/identity-servers/identity-server-name")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Check if identity server name is already exists",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response isIdentityServerNameExists(
@QueryParam("identityServerName") String identityServerName);
@GET
@Path("/identity-servers/identity-server-url")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Check if identity server url is already exists",
tags = "Identity Server Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response isIdentityServerUrlExists(
@QueryParam("identityServerUrl") String identityServerUrl);
/**
* This method is used to register an APIM application for tenant domain.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{identity-server-id}/service-providers")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get service providers by identity server id",
notes = "This will get service providers with the existing applications",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view")
})
}
)
Response getServiceProviders(@QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset,
@PathParam("identity-server-id") int identityServerId);
@Path("/{identity-server-id}/service-provider/{service-provider-id}/attach")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "map application to service provider",
notes = "This will map a given list application ids with the given service provider id",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:attach")
})
}
)
Response attachApps(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, List<Integer> appIds);
/**
* This method is used to register an APIM application for tenant domain.
*/
@Path("/{identity-server-id}/service-provider/{service-provider-id}/detach")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Remove mapping with service provider of the given application ids",
notes = "This will remove applications from service provider",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:detach")
})
}
)
Response detachApps(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, List<Integer> appIds);
/**
* This method is used to register an APIM application for tenant domain.
*/
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/ent-app")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create enterprise application and attach to service provider",
notes = "This will get create an enterprise application and map with service provider",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create")
})
}
)
Response createEntApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, ApplicationWrapper app,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished);
/**
* This method is used to register an APIM application for tenant domain.
*/
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/public-app")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create public application and attach to service provider",
notes = "This will get create a public application and map with service provider",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create")
})
}
)
Response createPubApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, PublicAppWrapper app,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished);
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/web-app")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create web application and attach to service provider",
notes = "This will get create a web application and map with service provider",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create")
})
}
)
Response createWebApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, WebAppWrapper app,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished);
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/custom-app")
@POST
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Create custom application and attach to service provider",
notes = "This will get create an custom application and map with service provider",
tags = "Service Provider Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create")
})
}
)
Response createCustomApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, CustomAppWrapper app,
@ApiParam(
name = "isPublished",
value = "Published state of the application"
)
@QueryParam("isPublished") boolean isPublished);
}

@ -16,11 +16,15 @@
*/
package io.entgra.application.mgt.publisher.api.services.impl;
import io.entgra.application.mgt.common.ApplicationArtifact;
import io.entgra.application.mgt.common.ApplicationList;
import io.entgra.application.mgt.common.Base64File;
import io.entgra.application.mgt.common.Filter;
import io.entgra.application.mgt.common.LifecycleChanger;
import io.entgra.application.mgt.common.exception.ResourceManagementException;
import io.entgra.application.mgt.core.util.ApplicationManagementUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import io.entgra.application.mgt.common.*;
import io.entgra.application.mgt.common.LifecycleState;
import io.entgra.application.mgt.common.exception.LifecycleManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException;
@ -42,19 +46,12 @@ import io.entgra.application.mgt.core.exception.BadRequestException;
import io.entgra.application.mgt.core.exception.ForbiddenException;
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.application.mgt.core.util.APIUtil;
import io.entgra.application.mgt.core.util.Constants;
import io.entgra.application.mgt.publisher.api.services.ApplicationManagementPublisherAPI;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.services.ApplicationManager;
import io.entgra.application.mgt.core.exception.NotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.activation.DataHandler;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@ -169,36 +166,12 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
@POST
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/ent-app")
public Response createEntApp(
@Multipart("application") ApplicationWrapper applicationWrapper,
@QueryParam("is-published") boolean isPublished,
@Multipart("binaryFile") Attachment binaryFile,
@Multipart("icon") Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart("screenshot1") Attachment screenshot1,
@Multipart("screenshot2") Attachment screenshot2,
@Multipart("screenshot3") Attachment screenshot3) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
ApplicationWrapper applicationWrapper, @QueryParam("is-published") boolean isPublished) {
try {
applicationManager.validateAppCreatingRequest(applicationWrapper);
applicationManager.validateReleaseCreatingRequest(applicationWrapper.getEntAppReleaseWrappers().get(0),
applicationWrapper.getDeviceType());
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new Ent App
Application application = applicationManager.createEntApp(applicationWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList), isPublished);
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "Application creation is failed";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return createApplication(applicationWrapper, isPublished);
} catch (BadRequestException e) {
String msg = "Found incompatible payload with ent. app creating request.";
log.error(msg, e);
@ -215,34 +188,12 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
@POST
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/web-app")
public Response createWebApp(
@Multipart("webapp") WebAppWrapper webAppWrapper,
@QueryParam("is-published") boolean isPublished,
@Multipart("icon") Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart("screenshot1") Attachment screenshot1,
@Multipart("screenshot2") Attachment screenshot2,
@Multipart("screenshot3") Attachment screenshot3) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
WebAppWrapper webAppWrapper, @QueryParam("is-published") boolean isPublished) {
try {
applicationManager.validateAppCreatingRequest(webAppWrapper);
applicationManager
.validateReleaseCreatingRequest(webAppWrapper.getWebAppReleaseWrappers().get(0), Constants.ANY);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new Web App
Application application = applicationManager.createWebClip(webAppWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, attachmentList), isPublished);
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "Web app creation is failed";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return createApplication(webAppWrapper, isPublished);
} catch (BadRequestException e) {
String msg = "Found incompatible payload with web app creating request.";
log.error(msg, e);
@ -259,34 +210,12 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
@POST
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/public-app")
public Response createPubApp(
@Multipart("public-app") PublicAppWrapper publicAppWrapper,
@QueryParam("is-published") boolean isPublished,
@Multipart("icon") Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart("screenshot1") Attachment screenshot1,
@Multipart("screenshot2") Attachment screenshot2,
@Multipart("screenshot3") Attachment screenshot3) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
PublicAppWrapper publicAppWrapper, @QueryParam("is-published") boolean isPublished) {
try {
applicationManager.validateAppCreatingRequest(publicAppWrapper);
applicationManager.validateReleaseCreatingRequest(publicAppWrapper.getPublicAppReleaseWrappers().get(0),
publicAppWrapper.getDeviceType());
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new Public App
Application application = applicationManager.createPublicApp(publicAppWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, attachmentList), isPublished);
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "Public app creation is failed";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return createApplication(publicAppWrapper, isPublished);
} catch (BadRequestException e) {
String msg = "Found incompatible payload with pub app creating request.";
log.error(msg, e);
@ -303,36 +232,12 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
@POST
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/custom-app")
public Response createCustomApp(
@Multipart("application") CustomAppWrapper customAppWrapper,
@QueryParam("is-published") boolean isPublished,
@Multipart("binaryFile") Attachment binaryFile,
@Multipart("icon") Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart("screenshot1") Attachment screenshot1,
@Multipart("screenshot2") Attachment screenshot2,
@Multipart("screenshot3") Attachment screenshot3) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
CustomAppWrapper customAppWrapper, @QueryParam("is-published") boolean isPublished) {
try {
applicationManager.validateAppCreatingRequest(customAppWrapper);
applicationManager.validateReleaseCreatingRequest(customAppWrapper.getCustomAppReleaseWrappers().get(0),
customAppWrapper.getDeviceType());
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new Custom App
Application application = applicationManager.createCustomApp(customAppWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList), isPublished);
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "Custom app creation is failed";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return createApplication(customAppWrapper, isPublished);
} catch (BadRequestException e) {
String msg = "Found incompatible payload with custom app creating request.";
log.error(msg, e);
@ -349,47 +254,110 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
@POST
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/ent-app/{appId}")
public Response createEntAppRelease(
@PathParam("deviceType") String deviceType,
@PathParam("deviceType") String deviceTypeName,
@PathParam("appId") int appId,
@Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper,
@QueryParam("is-published") boolean isPublished,
@Multipart("binaryFile") Attachment binaryFile,
@Multipart("icon") Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart("screenshot1") Attachment screenshot1,
@Multipart("screenshot2") Attachment screenshot2,
@Multipart("screenshot3") Attachment screenshot3) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
EntAppReleaseWrapper entAppReleaseWrapper,
@QueryParam("isPublished") boolean isPublished) {
try {
applicationManager.validateReleaseCreatingRequest(entAppReleaseWrapper, deviceType);
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new Ent App release
ApplicationRelease release = applicationManager.createEntAppRelease(appId, entAppReleaseWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList), isPublished);
if (release != null) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateEntAppReleaseCreatingRequest(entAppReleaseWrapper, deviceTypeName);
ApplicationRelease release = applicationManager.createEntAppRelease(appId, entAppReleaseWrapper, isPublished);
return Response.status(Response.Status.CREATED).entity(release).build();
} else {
log.error("ApplicationDTO Creation Failed");
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (RequestValidatingException e) {
String msg = "Error occurred while validating binaryArtifact";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating application release for the application with the id " + appId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} catch (BadRequestException e) {
String msg = "Found incompatible payload with enterprise app release creating request.";
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/public-app/{appId}")
@Override
public Response createPubAppRelease(
@PathParam("deviceType") String deviceTypeName,
@PathParam("appId") int appId,
PublicAppReleaseWrapper publicAppReleaseWrapper, @QueryParam("isPublished") boolean isPublished) {
try {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validatePublicAppReleaseCreatingRequest(publicAppReleaseWrapper, deviceTypeName);
ApplicationRelease applicationRelease = applicationManager.createPubAppRelease(appId, publicAppReleaseWrapper, isPublished);
return Response.status(Response.Status.CREATED).entity(applicationRelease).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating application release for the application with the id " + appId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ResourceManagementException e) {
String msg = "Error occurred while uploading application release artifacts";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (RequestValidatingException e) {
String msg = "Invalid payload found in public app release create request";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/web-app/{appId}")
@Override
public Response createWebAppRelease(
@PathParam("appId") int appId,
WebAppReleaseWrapper webAppReleaseWrapper, @QueryParam("isPublished") boolean isPublished) {
try {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateWebAppReleaseCreatingRequest(webAppReleaseWrapper);
ApplicationRelease applicationRelease= applicationManager.createWebAppRelease(appId, webAppReleaseWrapper, isPublished);
return Response.status(Response.Status.CREATED).entity(applicationRelease).build();
} catch (ResourceManagementException e) {
String msg = "Error occurred while uploading application release artifacts";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating the application";
String msg = "Error occurred while creating application release for the application with the id " + appId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (RequestValidatingException e) {
String msg = "Error occurred while handling the application creating request";
String msg = "Invalid payload found in web app release create request";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{deviceType}/custom-app/{appId}")
@Override
public Response createCustomAppRelease(
@PathParam("deviceType") String deviceTypeName,
@PathParam("appId") int appId,
CustomAppReleaseWrapper customAppReleaseWrapper, @QueryParam("isPublished") boolean isPublished) {
try {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateCustomAppReleaseCreatingRequest(customAppReleaseWrapper, deviceTypeName);
ApplicationRelease release = applicationManager.createCustomAppRelease(appId, customAppReleaseWrapper, isPublished);
return Response.status(Response.Status.CREATED).entity(release).build();
} catch (RequestValidatingException e) {
String msg = "Error occurred while validating binaryArtifact";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ResourceManagementException e) {
String msg = "Error occurred while uploading application release artifacts";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating application release for the application with the id " + appId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@ -421,21 +389,20 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Override
@PUT
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/image-artifacts/{uuid}")
public Response updateApplicationImageArtifacts(
@PathParam("uuid") String applicationReleaseUuid,
@Multipart(value = "icon", required = false) Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart(value = "screenshot1", required = false) Attachment screenshot1,
@Multipart(value = "screenshot2", required = false) Attachment screenshot2,
@Multipart(value = "screenshot3", required = false) Attachment screenshot3) {
Base64File iconFile,
Base64File bannerFile,
List<Base64File> screenshots) {
try {
List<Attachment> attachments = constructAttachmentList(screenshot1, screenshot2, screenshot3);
ApplicationArtifact artifact = ApplicationManagementUtil.constructApplicationArtifact(iconFile, screenshots,
null, bannerFile);
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.updateApplicationImageArtifact(applicationReleaseUuid,
constructApplicationArtifact(null, iconFile, bannerFile, attachments));
artifact);
return Response.status(Response.Status.OK)
.entity("Successfully uploaded artifacts for the application " + applicationReleaseUuid).build();
} catch (NotFoundException e) {
@ -454,18 +421,19 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Override
@PUT
@Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA})
@Consumes(MediaType.APPLICATION_JSON)
@Path("/ent-app-artifact/{deviceType}/{uuid}")
public Response updateApplicationArtifact(
@PathParam("deviceType") String deviceType,
@PathParam("uuid") String applicationReleaseUuid,
@Multipart("binaryFile") Attachment binaryFile) {
Base64File binaryFile) {
try {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.updateApplicationArtifact(deviceType, applicationReleaseUuid,
constructApplicationArtifact(binaryFile, null, null, null));
ApplicationManagementUtil.constructApplicationArtifact(null, null,
binaryFile, null));
return Response.status(Response.Status.OK)
.entity("Successfully uploaded artifacts for the application release. UUID is "
+ applicationReleaseUuid).build();
@ -522,19 +490,13 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Path("/ent-app-release/{uuid}")
public Response updateEntAppRelease(
@PathParam("uuid") String applicationUUID,
@Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper,
@Multipart(value = "binaryFile", required = false) Attachment binaryFile,
@Multipart(value = "icon", required = false) Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart(value = "screenshot1", required = false) Attachment screenshot1,
@Multipart(value = "screenshot2", required = false) Attachment screenshot2,
@Multipart(value = "screenshot3", required = false) Attachment screenshot3) {
EntAppReleaseWrapper entAppReleaseWrapper) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3);
try {
ApplicationArtifact artifact = ApplicationManagementUtil.constructApplicationArtifact(entAppReleaseWrapper.getIcon(),
entAppReleaseWrapper.getScreenshots(), entAppReleaseWrapper.getBinaryFile(), entAppReleaseWrapper.getBanner());
ApplicationRelease applicationRelease = applicationManager
.updateEntAppRelease(applicationUUID, entAppReleaseWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, screenshots));
.updateEntAppRelease(applicationUUID, entAppReleaseWrapper, artifact);
if (applicationRelease == null) {
String msg ="Ent app release updating is failed. Please contact the administrator. Application release "
+ "UUID: " + applicationUUID;
@ -569,18 +531,13 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Path("/public-app-release/{uuid}")
public Response updatePubAppRelease(
@PathParam("uuid") String applicationUUID,
@Multipart("applicationRelease") PublicAppReleaseWrapper publicAppReleaseWrapper,
@Multipart(value = "icon", required = false) Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart(value = "screenshot1", required = false) Attachment screenshot1,
@Multipart(value = "screenshot2", required = false) Attachment screenshot2,
@Multipart(value = "screenshot3", required = false) Attachment screenshot3) {
PublicAppReleaseWrapper publicAppReleaseWrapper) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3);
try {
ApplicationArtifact artifact = ApplicationManagementUtil.constructApplicationArtifact(publicAppReleaseWrapper.getIcon(),
publicAppReleaseWrapper.getScreenshots(), null, publicAppReleaseWrapper.getBanner());
ApplicationRelease applicationRelease = applicationManager
.updatePubAppRelease(applicationUUID, publicAppReleaseWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, screenshots));
.updatePubAppRelease(applicationUUID, publicAppReleaseWrapper, artifact);
if (applicationRelease == null) {
String msg ="Public app release updating is failed. Please contact the administrator. "
+ "Application release UUID: " + applicationUUID + ", Supported device type:";
@ -614,18 +571,13 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Path("/web-app-release/{uuid}")
public Response updateWebAppRelease(
@PathParam("uuid") String applicationUUID,
@Multipart("applicationRelease") WebAppReleaseWrapper webAppReleaseWrapper,
@Multipart(value = "icon", required = false) Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart(value = "screenshot1", required = false) Attachment screenshot1,
@Multipart(value = "screenshot2", required = false) Attachment screenshot2,
@Multipart(value = "screenshot3", required = false) Attachment screenshot3) {
WebAppReleaseWrapper webAppReleaseWrapper) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3);
try {
ApplicationArtifact artifact = ApplicationManagementUtil.constructApplicationArtifact(webAppReleaseWrapper.getIcon(),
webAppReleaseWrapper.getScreenshots(), null, webAppReleaseWrapper.getBanner());
ApplicationRelease applicationRelease = applicationManager
.updateWebAppRelease(applicationUUID, webAppReleaseWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, screenshots));
.updateWebAppRelease(applicationUUID, webAppReleaseWrapper, artifact);
if (applicationRelease == null) {
String msg ="web app release updating is failed. Please contact the administrator. Application "
+ "release UUID: " + applicationUUID;
@ -658,19 +610,13 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Path("/custom-app-release/{uuid}")
public Response updateCustomAppRelease(
@PathParam("uuid") String applicationUUID,
@Multipart("applicationRelease") CustomAppReleaseWrapper customAppReleaseWrapper,
@Multipart(value = "binaryFile", required = false) Attachment binaryFile,
@Multipart(value = "icon", required = false) Attachment iconFile,
@Multipart(value = "banner", required = false) Attachment bannerFile,
@Multipart(value = "screenshot1", required = false) Attachment screenshot1,
@Multipart(value = "screenshot2", required = false) Attachment screenshot2,
@Multipart(value = "screenshot3", required = false) Attachment screenshot3) {
CustomAppReleaseWrapper customAppReleaseWrapper) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Attachment> screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3);
try {
ApplicationArtifact artifact = ApplicationManagementUtil.constructApplicationArtifact(customAppReleaseWrapper.getIcon(),
customAppReleaseWrapper.getScreenshots(), customAppReleaseWrapper.getBinaryFile(), customAppReleaseWrapper.getBanner());
ApplicationRelease applicationRelease = applicationManager
.updateCustomAppRelease(applicationUUID, customAppReleaseWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, screenshots));
.updateCustomAppRelease(applicationUUID, customAppReleaseWrapper, artifact);
if (applicationRelease == null) {
String msg ="Custom app release updating is failed. Please contact the administrator. Application "
+ "release UUID: " + applicationUUID;
@ -919,134 +865,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
}
/***
* Construct the screenshot list by evaluating the availability of each screenshot.
*
* @param screenshot1 First Screenshot
* @param screenshot2 Second Screenshot
* @param screenshot3 Third Screenshot
* @return List of {@link Attachment}
*/
private List<Attachment> constructAttachmentList(Attachment screenshot1, Attachment screenshot2,
Attachment screenshot3) {
List<Attachment> attachments = new ArrayList<>();
if (screenshot1 != null) {
attachments.add(screenshot1);
}
if (screenshot2 != null) {
attachments.add(screenshot2);
}
if (screenshot3 != null) {
attachments.add(screenshot3);
}
return attachments;
}
/***
* This method can be used to construct {@link ApplicationArtifact}
*
* @param binaryFile binary file of the application release
* @param iconFile icon file of the application release
* @param bannerFile banner file of the application release
* @param attachmentList list of screenshot of the application release
* @return {@link ApplicationArtifact}
* @throws ApplicationManagementException if an error occurs when reading the attached data.
*/
private ApplicationArtifact constructApplicationArtifact(Attachment binaryFile, Attachment iconFile,
Attachment bannerFile, List<Attachment> attachmentList) throws ApplicationManagementException {
try {
ApplicationArtifact applicationArtifact = new ApplicationArtifact();
DataHandler dataHandler;
if (binaryFile != null) {
dataHandler = binaryFile.getDataHandler();
InputStream installerStream = dataHandler.getInputStream();
String installerFileName = dataHandler.getName();
if (installerStream == null) {
String msg = "Stream of the application release installer is null. Hence can't proceed. Please "
+ "verify the installer file.";
log.error(msg);
throw new BadRequestException(msg);
}
if (installerFileName == null) {
String msg = "Installer file name retrieving is failed.. Hence can't proceed. Please verify the "
+ "installer file.";
log.error(msg);
throw new BadRequestException(msg);
}
applicationArtifact.setInstallerName(installerFileName.replaceAll("\\s", ""));
applicationArtifact.setInstallerStream(installerStream);
}
if (iconFile != null) {
dataHandler = iconFile.getDataHandler();
String iconFileName = dataHandler.getName();
InputStream iconStream = dataHandler.getInputStream();
if (iconStream == null) {
String msg = "Stream of the application release icon is null. Hence can't proceed. Please "
+ "verify the uploaded icon file.";
log.error(msg);
throw new BadRequestException(msg);
}
if (iconFileName == null) {
String msg = "Icon file name retrieving is failed.. Hence can't proceed. Please verify the "
+ "icon file.";
log.error(msg);
throw new BadRequestException(msg);
}
applicationArtifact.setIconName(iconFileName);
applicationArtifact.setIconStream(iconStream);
}
if (bannerFile != null) {
dataHandler = bannerFile.getDataHandler();
String bannerFileName = dataHandler.getName();
InputStream bannerStream = dataHandler.getInputStream();
if (bannerStream == null) {
String msg = "Stream of the application release banner is null. Hence can't proceed. Please "
+ "verify the uploaded banner file.";
log.error(msg);
throw new BadRequestException(msg);
}
if (bannerFileName == null) {
String msg = "Banner file name retrieving is failed.. Hence can't proceed. Please verify the "
+ "banner file.";
log.error(msg);
throw new BadRequestException(msg);
}
applicationArtifact.setBannerName(bannerFileName);
applicationArtifact.setBannerStream(bannerStream);
}
if (attachmentList != null && !attachmentList.isEmpty()) {
Map<String, InputStream> screenshotData = new TreeMap<>();
for (Attachment sc : attachmentList) {
dataHandler = sc.getDataHandler();
String screenshotFileName = dataHandler.getName();
InputStream screenshotStream = dataHandler.getInputStream();
if (screenshotStream == null) {
String msg =
"Stream of one of the application release screenshot is null. Hence can't proceed. Please "
+ "verify the uploaded screenshots.";
log.error(msg);
throw new BadRequestException(msg);
}
if (screenshotFileName == null) {
String msg =
"Screenshot file name retrieving is failed for one screenshot. Hence can't proceed. "
+ "Please verify the screenshots.";
public <T> Response createApplication(T appWrapper, boolean isPublished) throws ApplicationManagementException, RequestValidatingException {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateAppCreatingRequest(appWrapper);
Application application = applicationManager.createApplication(appWrapper, isPublished);
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "Application creation is failed";
log.error(msg);
throw new BadRequestException(msg);
}
screenshotData.put(screenshotFileName, screenshotStream);
}
applicationArtifact.setScreenshots(screenshotData);
}
return applicationArtifact;
} catch (IOException e) {
String msg = "Error occurred when reading attachment data.";
log.error(msg, e);
throw new ApplicationManagementException(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}

@ -0,0 +1,363 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.application.mgt.publisher.api.services.impl;
import io.entgra.application.mgt.common.IdentityServerResponse;
import io.entgra.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.application.mgt.common.SPApplicationListResponse;
import io.entgra.application.mgt.common.dto.IdentityServiceProviderDTO;
import io.entgra.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException;
import io.entgra.application.mgt.common.response.Application;
import io.entgra.application.mgt.common.services.SPApplicationManager;
import io.entgra.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppWrapper;
import io.entgra.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.application.mgt.common.wrapper.WebAppWrapper;
import io.entgra.application.mgt.core.exception.BadRequestException;
import io.entgra.application.mgt.core.exception.NotFoundException;
import io.entgra.application.mgt.core.util.APIUtil;
import io.entgra.application.mgt.publisher.api.services.SPApplicationService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@Produces(MediaType.APPLICATION_JSON)
@Path("/identity-server-applications")
public class SPApplicationServiceImpl implements SPApplicationService {
private static final Log log = LogFactory.getLog(SPApplicationServiceImpl.class);
@Path("/identity-servers/identity-service-providers")
@GET
@Override
public Response getIdentityServiceProviders() {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
try {
List<IdentityServiceProviderDTO> identityServiceProviders = spAppManager.getIdentityServiceProviders();
return Response.status(Response.Status.OK).entity(identityServiceProviders).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while getting identity service providers";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@Path("/identity-servers")
@GET
@Override
public Response getIdentityServers() {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
List<IdentityServerResponse> identityServers = spAppManager.getIdentityServers();
return Response.status(Response.Status.OK).entity(identityServers).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/identity-servers/{id}")
@DELETE
@Override
public Response deleteIdentityServer(@PathParam("id") int id) {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
spAppManager.deleteIdentityServer(id);
return Response.status(Response.Status.OK).entity("Successfully deleted identity server").build();
} catch (NotFoundException e) {
String msg = "Identity server with the id " + id + " does not exist.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/identity-servers/{id}")
@GET
@Override
public Response getIdentityServer(@PathParam("id") int id) {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
IdentityServerResponse identityServer = spAppManager.getIdentityServerResponse(id);
return Response.status(Response.Status.OK).entity(identityServer).build();
} catch (NotFoundException e) {
String msg = "Identity server with the id " + id + " does not exist.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/identity-servers/{id}")
@PUT
@Override
public Response updateIdentityServer(IdentityServerDTO identityServerDTO, @PathParam("id") int id) {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
IdentityServerResponse identityServerResponse = spAppManager.updateIdentityServer(identityServerDTO, id);
return Response.status(Response.Status.OK).entity(identityServerResponse).build();
} catch (NotFoundException e) {
String msg = "Identity server with the id " + id + " does not exist.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (BadRequestException e) {
String errMsg = "Identity server request payload is invalid";
log.error(errMsg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/identity-servers")
@POST
@Override
public Response createIdentityServer(IdentityServerDTO identityServerDTO) {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
IdentityServerResponse identityServer = spAppManager.createIdentityServer(identityServerDTO);
return Response.status(Response.Status.CREATED).entity(identityServer).build();
} catch (BadRequestException e) {
String errMsg = "Identity server request payload is invalid";
log.error(errMsg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@GET
@Path("/identity-servers/identity-server-name")
@Override
public Response isIdentityServerNameExists(
@QueryParam("identityServerName") String identityServerName) {
try {
if (identityServerName == null) {
String msg = "Invalid identity server name, identityServerName query param cannot be empty/null.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).build();
}
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
if (spAppManager.isIdentityServerNameExist(identityServerName)) {
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
} catch (BadRequestException e) {
String errMsg = "Identity server request payload is invalid";
log.error(errMsg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@GET
@Path("/identity-servers/identity-server-url")
@Override
public Response isIdentityServerUrlExists(
@QueryParam("identityServerUrl") String identityServerUrl) {
try {
if (identityServerUrl == null) {
String msg = "Invalid identity server url, identityServerName query param cannot be empty/null.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).build();
}
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
if (spAppManager.isIdentityServerUrlExist(identityServerUrl)) {
return Response.status(Response.Status.CONFLICT).build();
}
return Response.status(Response.Status.OK).build();
} catch (BadRequestException e) {
String errMsg = "Identity server request payload is invalid";
log.error(errMsg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/{identity-server-id}/service-providers")
@GET
@Override
public Response getServiceProviders(@DefaultValue("30") @QueryParam("limit") Integer limit,@DefaultValue("0") @QueryParam("offset") Integer offset,
@PathParam("identity-server-id") int identityServerId) {
try {
SPApplicationManager spAppManager = APIUtil.getSPApplicationManager();
SPApplicationListResponse applications = spAppManager.retrieveSPApplicationFromIdentityServer(identityServerId, limit, offset);
return Response.status(Response.Status.OK).entity(applications).build();
} catch (NotFoundException e) {
String errMsg = "No Identity server exist with the id: " + identityServerId;
log.error(errMsg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build();
} catch (ApplicationManagementException e) {
String errMsg = "Error occurred while trying to merge identity server apps with existing apps";
log.error(errMsg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build();
}
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/attach")
@POST
@Override
public Response attachApps(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, List<Integer> appIds) {
SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager();
try {
spApplicationManager.validateAttachAppsRequest(identityServerId, serviceProviderId, appIds);
spApplicationManager.attachSPApplications(identityServerId, serviceProviderId, appIds);
} catch (NotFoundException e) {
String msg = "No identity server exist with the id " + identityServerId;
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (BadRequestException e) {
String msg = "Invalid appIds provided";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while attaching apps to service provider with the id" + serviceProviderId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).build();
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/detach")
@POST
@Override
public Response detachApps(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, List<Integer> appIds) {
SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager();
try {
spApplicationManager.validateDetachAppsRequest(identityServerId, serviceProviderId, appIds);
spApplicationManager.detachSPApplications(identityServerId, serviceProviderId, appIds);
} catch (NotFoundException e) {
String msg = "No identity server exist with the id " + identityServerId;
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (BadRequestException e) {
String msg = "Invalid appIds provided";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while attaching apps to service provider with the id" + serviceProviderId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).build();
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/ent-app")
@POST
@Override
public Response createEntApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, ApplicationWrapper app,
@QueryParam("isPublished") boolean isPublished) {
return createSPApplication(identityServerId, serviceProviderId, app, isPublished);
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/public-app")
@POST
@Override
public Response createPubApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, PublicAppWrapper app,
@QueryParam("isPublished") boolean isPublished) {
return createSPApplication(identityServerId, serviceProviderId, app, isPublished);
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/web-app")
@POST
@Override
public Response createWebApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, WebAppWrapper app,
@QueryParam("isPublished") boolean isPublished) {
return createSPApplication(identityServerId, serviceProviderId, app, isPublished);
}
@Path("/{identity-server-id}/service-provider/{service-provider-id}/create/custom-app")
@POST
@Override
public Response createCustomApp(@PathParam("identity-server-id") int identityServerId,
@PathParam("service-provider-id") String serviceProviderId, CustomAppWrapper app,
@QueryParam("isPublished") boolean isPublished) {
return createSPApplication(identityServerId, serviceProviderId, app, isPublished);
}
/**
* Validates and creates service provider application
*
* @param identityServerId id of the identity server
* @param spUID uid of the service provider
* @param appWrapper application wrapper
* @param <T> application wrapper class
* @return Response
*/
private <T> Response createSPApplication(int identityServerId, String spUID, T appWrapper, boolean isPublished) {
try {
SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager();
Application createdApp = spApplicationManager.createSPApplication(appWrapper, identityServerId, spUID, isPublished);
return Response.status(Response.Status.CREATED).entity(createdApp).build();
} catch (NotFoundException e) {
String msg = "No identity server exist with the id " + identityServerId;
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (BadRequestException e) {
String msg = "Found incompatible payload with create service provider app request.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (RequestValidatingException e) {
String msg = "Found invalid release payload with create service provider app request.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
catch (ApplicationManagementException e) {
String msg = "Error occurred while creating service provider app";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}

@ -25,6 +25,7 @@
<jaxrs:server id="applicationMgtService" address="/">
<jaxrs:serviceBeans>
<ref bean="identityServerApplicationMgtServiceBean"/>
<ref bean="applicationMgtServiceBean"/>
<ref bean="reviewMgtAdminServiceBean"/>
<ref bean="applicationMgtAdminServiceBean"/>
@ -54,6 +55,7 @@
<bean id="swaggerWriter" class="io.swagger.jaxrs.listing.SwaggerSerializers" />
<bean id="swaggerResource" class="io.swagger.jaxrs.listing.ApiListingResource" />
<bean id="identityServerApplicationMgtServiceBean" class="io.entgra.application.mgt.publisher.api.services.impl.SPApplicationServiceImpl"/>
<bean id="applicationMgtServiceBean" class="io.entgra.application.mgt.publisher.api.services.impl.ApplicationManagementPublisherAPIImpl"/>
<bean id="applicationMgtAdminServiceBean" class="io.entgra.application.mgt.publisher.api.services.impl.admin.ApplicationManagementPublisherAdminAPIImpl"/>
<bean id="reviewMgtAdminServiceBean" class="io.entgra.application.mgt.publisher.api.services.impl.admin.ReviewManagementPublisherAdminAPIImpl" />

@ -0,0 +1,27 @@
/* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.wso2.carbon.device.mgt.core.common;
public class Constants {
public static final String SCHEME_SEPARATOR = "://";
public static final String COLON = ":";
public static final String URI_QUERY_SEPARATOR = "?";
public static final String URI_SEPARATOR = "/";
public static final String BASIC_AUTH_HEADER_PREFIX = "Basic ";
public static final String BEARER = "Bearer ";
}

@ -0,0 +1,107 @@
/*
* Copyright (c) 2022, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. 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.wso2.carbon.device.mgt.core.common.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Base64;
public class FileUtil {
/**
* Useful to remove path separator string "," from base64 string
*
* @param base64String base64 string
* @return base64 string without path separator
*/
public static String removePathSeparatorFromBase64String(String base64String) {
String partSeparator = ",";
if (base64String.contains(partSeparator)) {
return base64String.split(partSeparator)[1];
}
return base64String;
}
/**
* Useful to convert base64 string to input stream
*
* @param base64 base64 string to be converted
* @return {@link InputStream} of the provided base64 string
*/
public static InputStream base64ToInputStream(String base64) {
base64 = FileUtil.removePathSeparatorFromBase64String(base64);
byte[] base64Bytes = Base64.getDecoder().decode(base64);
return new ByteArrayInputStream(base64Bytes);
}
/**
* This generates file name with a suffix depending on the duplicate name count, useful when saving
* files with the same name
*
* @param fileNameCount File count
* @return generated file name with suffix
*/
public static String generateDuplicateFileName(String fileName, int fileNameCount) {
String suffix = generateDuplicateFileNameSuffix(fileNameCount);
String fileNameWithoutExtension = extractFileNameWithoutExtension(fileName);
String fileNameWithSuffix = fileNameWithoutExtension + suffix;
fileNameWithSuffix = fileNameWithSuffix + '.' + extractFileExtension(fileName);
return fileNameWithSuffix;
}
/**
* This generates file name suffix for duplicate file names. For example,
* if it's the first file, the count is 1 in which case the name doesn't have any suffix
* else it adds suffix with (count - 1)
*
* @param fileNameCount File count
* @return generated file name suffix
*/
private static String generateDuplicateFileNameSuffix(int fileNameCount) {
String suffix = "";
if (fileNameCount < 1) {
throw new IllegalArgumentException("file name count must be above 0");
}
if (fileNameCount > 1) {
suffix = "(" + (fileNameCount - 1) + ")";
}
return suffix;
}
/**
* Use to extract file extension from file name
*
* @param fileName name of the file
* @return extension of the file
*/
private static String extractFileExtension(String fileName) {
return fileName.substring(fileName.lastIndexOf('.') + 1);
}
/**
* Use to extract the file name without the extension
* For example if you provide "main.java" as the fileName this will return main
*
* @param fileName name of the file
* @return file name without file extension
*/
private static String extractFileNameWithoutExtension(String fileName) {
return fileName.substring(0, fileName.lastIndexOf('.'));
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
* Copyright (c) 2022, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
@ -17,15 +17,13 @@
*/
package org.wso2.carbon.device.mgt.core.common.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.wso2.carbon.device.mgt.core.report.mgt.Constants;
import java.io.BufferedReader;
import org.wso2.carbon.device.mgt.core.common.Constants;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
@ -34,12 +32,47 @@ import java.util.Map;
public class HttpUtil {
/**
* Use to create {@link URI} from string
* This does encoding of the provided uri string before creating the URI
*
* @param uriString uri string to be used to create the URI
* @return created URI
*/
public static URI createURI(String uriString) {
uriString = uriString.replace(" ", "%20");
return URI.create(uriString);
}
public static String getRequestSubPathFromEnd(URI requestUri, int position) {
/**
* Use to create basic auth header string for provided credentials
*
* @param userName username credential
* @param password password credential
* @return Basic auth header
*/
public static String getBasicAuthBase64Header(String userName, String password) {
return Constants.BASIC_AUTH_HEADER_PREFIX + getBase64Encode(userName, password);
}
/**
* Use to get the base64 encoded string of key value pair.
* For example this can be useful when creating basic auth header
*
* @return base64 encoded string of provided key and value
*/
public static String getBase64Encode(String key, String value) {
return new String(Base64.encodeBase64((key + ":" + value).getBytes()));
}
/**
* Useful to get the sub path in a position from the given uri starting from end of the uri
*
* @param requestUri {@link URI}
* @param position of which the sub path is needed
* @return Sub path of the uri
*/
public static String extractRequestSubPathFromEnd(URI requestUri, int position) {
if (requestUri.getPath() != null) {
String[] pathList = requestUri.getPath().split("/");
if (pathList.length - 1 >= position) {
@ -49,8 +82,15 @@ public class HttpUtil {
return null;
}
public static String getRequestSubPath(String fullPath, int position) {
String[] pathList = fullPath.split("/");
/**
* Useful to get the sub path in a position from the given uri
*
* @param uri uri string from which the sub path should be extracted
* @param position of which the sub path is needed
* @return Sub path of the uri
*/
public static String extractRequestSubPath(String uri, int position) {
String[] pathList = uri.split("/");
if (pathList.length - 1 > position) {
String path = pathList[position + 1];
if(path.contains(Constants.URI_QUERY_SEPARATOR)) {
@ -61,14 +101,37 @@ public class HttpUtil {
return null;
}
/**
* This returns the response body as string
*
* @param response {@link HttpResponse}
* @return Response body string
* @throws IOException if errors while converting response body to string
*/
public static String getResponseString(HttpResponse response) throws IOException {
return EntityUtils.toString(response.getEntity());
}
public static boolean isQueryParamExist(String param, URI request) {
Map<String, List<String>> queryMap = getQueryMap(request);
/**
* Useful to check if a given query param exists in uri
*
* @param param query param to be checked
* @param uri in which query param should be checked
* @return if the provided query parameter exists in uri
*/
public static boolean isQueryParamExist(String param, URI uri) {
Map<String, List<String>> queryMap = getQueryMap(uri);
return queryMap.containsKey(param);
}
/**
* This is useful to get first query parameter value from a query map.
* For example a query parameter may have multiple values.
*
* @param param query parameter of which the value is needed
* @param queryMap query map which contains query paramters and it's values
* @return First value of provided query parameter
*/
public static String getFirstQueryValue(String param, Map<String, List<String>> queryMap) {
List<String> valueList = queryMap.get(param);
String firstValue = null;
@ -77,6 +140,20 @@ public class HttpUtil {
}
return firstValue;
}
/**
* This constructs a key/value Map from query string of the provided uri.
* In other words this will create a map with query parameters as keys and their
* values as values.
*
* For example if the uri contains "?bar=1&foo=2" this will return a map
* with bar and foo as keys and 1 and 2 as their values
*
* This is similar to getQueryMap(URI uri) method except that this accepts uri string
*
* @param uri of which the query map to be created
* @return Query map of the provided uri
*/
public static Map<String, List<String>> getQueryMap(String uri) {
String query = getQueryFromURIPath(uri);
Map<String, List<String>> map = new HashMap<>();
@ -97,8 +174,20 @@ public class HttpUtil {
}
return map;
}
public static Map<String, List<String>> getQueryMap(URI request) {
String query = request.getQuery();
/**
* This constructs a key/value Map from query string of the provided uri.
* In other words this will create a map with query parameters as keys and their
* values as values.
*
* For example if the uri contains "?bar=1&foo=2" this will return a map
* with bar and foo as keys and 1 and 2 as their values
*
* @param uri of which the query map to be created
* @return Query map of the provided uri
*/
public static Map<String, List<String>> getQueryMap(URI uri) {
String query = uri.getQuery();
Map<String, List<String>> map = new HashMap<>();
if (query != null) {
String[] params = query.split("&");
@ -117,6 +206,13 @@ public class HttpUtil {
}
return map;
}
/**
* Get query string from uri path. Return null if no query string exists
*
* @param uri of which query string should be taken
* @return Query string of the provided uri
*/
public static String getQueryFromURIPath(String uri) {
String query = null;
if (uri.length() > "?".length() && uri.contains("?")) {
@ -128,6 +224,12 @@ public class HttpUtil {
return query;
}
/**
* Get content type of http response
*
* @param response {@link HttpResponse}
* @return Content type
*/
public static String getContentType(HttpResponse response) {
ContentType contentType = ContentType.getOrDefault(response.getEntity());
return contentType.getMimeType();

@ -22,6 +22,9 @@
<DatasourceName>jdbc/APPM_DS</DatasourceName>
<Extensions>
<Extension name="SPApplicationManager">
<ClassName>io.entgra.application.mgt.core.impl.SPApplicationManagerImpl</ClassName>
</Extension>
<Extension name="ApplicationManager">
<ClassName>io.entgra.application.mgt.core.impl.ApplicationManagerImpl</ClassName>
</Extension>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
~
~ Entgra (Pvt) Ltd. 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.
-->
<IdentityServiceProviderConfiguration>
<IdentityServiceProviders>
<IdentityServiceProvider>
<ProviderName>WSO2 IAM</ProviderName>
<ProviderClassName>io.entgra.application.mgt.core.identityserver.serviceprovider.impl.WSO2IAMSPApplicationService</ProviderClassName>
<ServiceProvidersPageUri>/carbon/application/list-service-providers.jsp</ServiceProvidersPageUri>
<!-- <ServiceProvidersAPIContextPath>/t/carbon.super/api/server/v1/applications</ServiceProvidersAPIContextPath> -->
</IdentityServiceProvider>
</IdentityServiceProviders>
</IdentityServiceProviderConfiguration>

@ -22,6 +22,13 @@
<DatasourceName>jdbc/APPM_DS</DatasourceName>
<Extensions>
<Extension name="SPApplicationManager">
{% if application_mgt_conf.extension.isapplication_manager is defined %}
<ClassName>{{application_mgt_conf.extension.isapplication_manager}}</ClassName>
{% else %}
<ClassName>io.entgra.application.mgt.core.impl.SPApplicationManagerImpl</ClassName>
{% endif %}
</Extension>
<Extension name="ApplicationManager">
{% if application_mgt_conf.extension.application_manager is defined %}
<ClassName>{{application_mgt_conf.extension.application_manager}}</ClassName>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
~
~ Entgra (Pvt) Ltd. 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.
-->
<IdentityServiceProviderConfiguration>
<IdentityServiceProviders>
<IdentityServiceProvider>
<ProviderName>WSO2 IAM</ProviderName>
<ProviderClassName>io.entgra.application.mgt.core.identityserver.serviceprovider.impl.WSO2IAMSPApplicationService</ProviderClassName>
<ServiceProvidersPageUri>/carbon/application/list-service-providers.jsp</ServiceProvidersPageUri>
<!-- <ServiceProvidersAPIContextPath>/t/carbon.super/api/server/v1/applications</ServiceProvidersAPIContextPath> -->
</IdentityServiceProvider>
</IdentityServiceProviders>
</IdentityServiceProviderConfiguration>

@ -14,7 +14,6 @@ CREATE TABLE IF NOT EXISTS AP_APP(
DEVICE_TYPE_ID INTEGER NOT NULL,
PRIMARY KEY (ID)
);
-- -----------------------------------------------------
-- Table AP_APP_RELEASE
-- -----------------------------------------------------
@ -42,12 +41,9 @@ CREATE TABLE IF NOT EXISTS AP_APP_RELEASE(
RATED_USERS INTEGER NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_RELEASE_AP_APP1
FOREIGN KEY (AP_APP_ID)
REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_APP_RELEASE_AP_APP1 FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_RELEASE_AP_APP1_idx ON AP_APP_RELEASE (AP_APP_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_REVIEW
-- -----------------------------------------------------
@ -64,12 +60,9 @@ CREATE TABLE IF NOT EXISTS AP_APP_REVIEW(
ACTIVE_REVIEW BOOLEAN NOT NULL DEFAULT TRUE,
AP_APP_RELEASE_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_COMMENT_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_APP_COMMENT_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_COMMENT_AP_APP_RELEASE1_idx ON AP_APP_REVIEW (AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_LIFECYCLE_STATE
-- -----------------------------------------------------
@ -83,12 +76,9 @@ CREATE TABLE IF NOT EXISTS AP_APP_LIFECYCLE_STATE(
AP_APP_RELEASE_ID INTEGER NOT NULL,
REASON TEXT DEFAULT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_LIFECYCLE_STATE_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_APP_LIFECYCLE_STATE_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_LIFECYCLE_STATE_AP_APP_RELEASE1_idx ON AP_APP_LIFECYCLE_STATE( AP_APP_RELEASE_ID ASC);
CREATE INDEX fk_AP_APP_LIFECYCLE_STATE_AP_APP_RELEASE1_idx ON AP_APP_LIFECYCLE_STATE(AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_TAG
-- -----------------------------------------------------
@ -98,7 +88,6 @@ CREATE TABLE IF NOT EXISTS AP_APP_TAG(
TAG VARCHAR(100) NOT NULL,
PRIMARY KEY (ID)
);
-- -----------------------------------------------------
-- Table AP_DEVICE_SUBSCRIPTION
-- -----------------------------------------------------
@ -115,12 +104,9 @@ CREATE TABLE IF NOT EXISTS AP_DEVICE_SUBSCRIPTION(
DM_DEVICE_ID INTEGER NOT NULL,
AP_APP_RELEASE_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_DEVICE_SUBSCRIPTION_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_DEVICE_SUBSCRIPTION_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_DEVICE_SUBSCRIPTION_AP_APP_RELEASE1_idx ON AP_DEVICE_SUBSCRIPTION (AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_GROUP_SUBSCRIPTION
-- -----------------------------------------------------
@ -135,12 +121,9 @@ CREATE TABLE IF NOT EXISTS AP_GROUP_SUBSCRIPTION(
GROUP_NAME VARCHAR(100) NOT NULL,
AP_APP_RELEASE_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_GROUP_SUBSCRIPTION_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_GROUP_SUBSCRIPTION_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_GROUP_SUBSCRIPTION_AP_APP_RELEASE1_idx ON AP_GROUP_SUBSCRIPTION (AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_ROLE_SUBSCRIPTION
-- -----------------------------------------------------
@ -155,12 +138,9 @@ CREATE TABLE IF NOT EXISTS AP_ROLE_SUBSCRIPTION(
UNSUBSCRIBED_TIMESTAMP TIMESTAMP NULL DEFAULT NULL,
AP_APP_RELEASE_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_ROLE_SUBSCRIPTION_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_ROLE_SUBSCRIPTION_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_ROLE_SUBSCRIPTION_AP_APP_RELEASE1_idx ON AP_ROLE_SUBSCRIPTION (AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_UNRESTRICTED_ROLE
-- -----------------------------------------------------
@ -170,12 +150,9 @@ CREATE TABLE IF NOT EXISTS AP_UNRESTRICTED_ROLE(
ROLE VARCHAR(45) NOT NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_VISIBILITY_AP_APP1
FOREIGN KEY (AP_APP_ID)
REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_APP_VISIBILITY_AP_APP1 FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_VISIBILITY_AP_APP1_idx ON AP_UNRESTRICTED_ROLE (AP_APP_ID ASC);
-- -----------------------------------------------------
-- Table AP_USER_SUBSCRIPTION
-- -----------------------------------------------------
@ -190,12 +167,9 @@ CREATE TABLE IF NOT EXISTS AP_USER_SUBSCRIPTION(
UNSUBSCRIBED_TIMESTAMP TIMESTAMP NULL DEFAULT NULL,
AP_APP_RELEASE_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_USER_SUBSCRIPTION_AP_APP_RELEASE1
FOREIGN KEY (AP_APP_RELEASE_ID)
REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_USER_SUBSCRIPTION_AP_APP_RELEASE1 FOREIGN KEY (AP_APP_RELEASE_ID) REFERENCES AP_APP_RELEASE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_USER_SUBSCRIPTION_AP_APP_RELEASE1_idx ON AP_USER_SUBSCRIPTION (AP_APP_RELEASE_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_CATEGORY
-- -----------------------------------------------------
@ -206,45 +180,34 @@ CREATE TABLE IF NOT EXISTS AP_APP_CATEGORY(
CATEGORY_ICON VARCHAR(45) NULL,
PRIMARY KEY (ID)
);
-- -----------------------------------------------------
-- Table AP_APP_TAG_MAPPING
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS AP_APP_TAG_MAPPING(
ID INTEGER NOT NULL AUTO_INCREMENT,
TENANT_ID INTEGER NOT NULL,
AP_APP_TAG_ID INTEGER NOT NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_TAG_copy1_AP_APP_TAG1
FOREIGN KEY (AP_APP_TAG_ID)
REFERENCES AP_APP_TAG (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_AP_APP_TAG_copy1_AP_APP1
FOREIGN KEY (AP_APP_ID)
REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
ID INTEGER NOT NULL AUTO_INCREMENT,
TENANT_ID INTEGER NOT NULL,
AP_APP_TAG_ID INTEGER NOT NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_TAG_copy1_AP_APP_TAG1 FOREIGN KEY (AP_APP_TAG_ID) REFERENCES AP_APP_TAG (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_AP_APP_TAG_copy1_AP_APP1 FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_TAG_copy1_AP_APP_TAG1_idx ON AP_APP_TAG_MAPPING (AP_APP_TAG_ID ASC);
CREATE INDEX fk_AP_APP_TAG_copy1_AP_APP1_idx ON AP_APP_TAG_MAPPING (AP_APP_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_CATEGORY_MAPPING
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS AP_APP_CATEGORY_MAPPING(
ID INTEGER NOT NULL AUTO_INCREMENT,
TENANT_ID INTEGER NOT NULL,
AP_APP_CATEGORY_ID INTEGER NOT NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_CATEGORY_copy1_AP_APP_CATEGORY1
FOREIGN KEY (AP_APP_CATEGORY_ID)
REFERENCES AP_APP_CATEGORY (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_AP_APP_CATEGORY_copy1_AP_APP1
FOREIGN KEY (AP_APP_ID)
REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
ID INTEGER NOT NULL AUTO_INCREMENT,
TENANT_ID INTEGER NOT NULL,
AP_APP_CATEGORY_ID INTEGER NOT NULL,
AP_APP_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_CATEGORY_copy1_AP_APP_CATEGORY1 FOREIGN KEY (AP_APP_CATEGORY_ID) REFERENCES AP_APP_CATEGORY (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_AP_APP_CATEGORY_copy1_AP_APP1 FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_CATEGORY_copy1_AP_APP_CATEGORY1_idx ON AP_APP_CATEGORY_MAPPING (AP_APP_CATEGORY_ID ASC);
CREATE INDEX fk_AP_APP_CATEGORY_copy1_AP_APP1_idx ON AP_APP_CATEGORY_MAPPING (AP_APP_ID ASC);
-- -----------------------------------------------------
-- Table AP_APP_SUB_OP_MAPPING
-- -----------------------------------------------------
@ -254,12 +217,9 @@ CREATE TABLE IF NOT EXISTS AP_APP_SUB_OP_MAPPING (
OPERATION_ID INTEGER NOT NULL,
AP_DEVICE_SUBSCRIPTION_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1
FOREIGN KEY (AP_DEVICE_SUBSCRIPTION_ID)
REFERENCES AP_DEVICE_SUBSCRIPTION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1 FOREIGN KEY (AP_DEVICE_SUBSCRIPTION_ID) REFERENCES AP_DEVICE_SUBSCRIPTION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1_idx ON AP_APP_SUB_OP_MAPPING (AP_DEVICE_SUBSCRIPTION_ID ASC);
-- -----------------------------------------------------
-- Table AP_SCHEDULED_SUBSCRIPTION
-- -----------------------------------------------------
@ -275,8 +235,31 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
DELETED BOOLEAN,
PRIMARY KEY (ID)
);
-- -----------------------------------------------------
-- Table AP_IDENTITY_SERVER
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS AP_IDENTITY_SERVER (
ID INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NOT NULL,
URL VARCHAR(255) NOT NULL,
SP_APPS_URI VARCHAR(255) NOT NULL,
SP_APPS_API VARCHAR(255) NULL,
TENANT_ID INT NOT NULL,
USERNAME VARCHAR(255) NOT NULL,
PASSWORD VARCHAR(255) NOT NULL
) -- -----------------------------------------------------
-- Table AP_IS_SP_APP_MAPPING
-- -----------------------------------------------------;
CREATE TABLE IF NOT EXISTS AP_IS_SP_APP_MAPPING (
ID INT AUTO_INCREMENT PRIMARY KEY,
SP_UID VARCHAR(255) NOT NULL,
AP_APP_ID INT NOT NULL,
IS_ID INT NOT NULL,
TENANT_ID INT NOT NULL,
CONSTRAINT AP_IS_SP_APP_MAPPING_AP_APP_ID_fk FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID),
CONSTRAINT AP_IS_SP_APP_MAPPING_AP_IDENTITY_SERVER_ID_fk FOREIGN KEY (IS_ID) REFERENCES AP_IDENTITY_SERVER (ID)
);
-- Table AP_APP_FAVOURITES
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS AP_APP_FAVOURITES(
@ -285,7 +268,5 @@ CREATE TABLE IF NOT EXISTS AP_APP_FAVOURITES(
USER_NAME VARCHAR(100) NOT NULL,
TENANT_ID INTEGER NOT NULL,
PRIMARY KEY(ID),
CONSTRAINT AP_APP_FAVOURITES_AP_APP_ID_fk
FOREIGN KEY (AP_APP_ID)
REFERENCES AP_APP (ID)
CONSTRAINT AP_APP_FAVOURITES_AP_APP_ID_fk FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID)
);

@ -38,6 +38,10 @@
<Scope>perm:grafana:api:view</Scope>
<Scope>perm:app:review:view</Scope>
<Scope>perm:app:review:update</Scope>
<Scope>perm:app:publisher:service-provider:view</Scope>
<Scope>perm:app:publisher:service-provider:create</Scope>
<Scope>perm:app:publisher:service-provider:attach</Scope>
<Scope>perm:app:publisher:service-provider:detach</Scope>
<Scope>perm:app:publisher:view</Scope>
<Scope>perm:app:publisher:update</Scope>
<Scope>perm:app:store:view</Scope>

@ -57,6 +57,10 @@
<Scopes>
<Scope>perm:app:review:view</Scope>
<Scope>perm:app:review:update</Scope>
<Scope>perm:app:publisher:service-provider:view</Scope>
<Scope>perm:app:publisher:service-provider:create</Scope>
<Scope>perm:app:publisher:service-provider:attach</Scope>
<Scope>perm:app:publisher:service-provider:detach</Scope>
<Scope>perm:app:publisher:view</Scope>
<Scope>perm:app:publisher:update</Scope>
<Scope>perm:app:store:view</Scope>

Loading…
Cancel
Save