Resolve conflicts

fixes https://roadmap.entgra.net/issues/9274
improvement/fix-task-deletion^2
osh 2 years ago
commit 21669f8dba

@ -17,7 +17,7 @@
package io.entgra.application.mgt.common.services; package io.entgra.application.mgt.common.services;
import io.entgra.application.mgt.common.ApplicationType; import io.entgra.application.mgt.common.ApplicationType;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.entgra.application.mgt.common.dto.ApplicationDTO; import io.entgra.application.mgt.common.dto.ApplicationDTO;
import io.entgra.application.mgt.common.exception.ResourceManagementException; import io.entgra.application.mgt.common.exception.ResourceManagementException;
import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.Attachment;

@ -22,6 +22,7 @@ import io.entgra.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.application.mgt.common.exception.ApplicationStorageManagementException; import io.entgra.application.mgt.common.exception.ApplicationStorageManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException; import io.entgra.application.mgt.common.exception.RequestValidatingException;
import io.entgra.application.mgt.common.exception.ResourceManagementException; import io.entgra.application.mgt.common.exception.ResourceManagementException;
import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
@ -121,4 +122,14 @@ public interface ApplicationStorageManager {
* @throws ApplicationStorageManagementException throws if an error occurs when accessing the file. * @throws ApplicationStorageManagementException throws if an error occurs when accessing the file.
*/ */
InputStream getFileStream(String deviceType, String tenantDomain) throws ApplicationStorageManagementException; InputStream getFileStream(String deviceType, String tenantDomain) throws ApplicationStorageManagementException;
/**
* Useful to generate MD5 string of {@link InputStream}
*
* @param inputStream {@link InputStream}
* @return md5 string of provided input stream
*
* @throws StorageManagementException if errors while generating md5 string
*/
String getMD5(InputStream inputStream) throws StorageManagementException;
} }

@ -16,7 +16,7 @@
*/ */
package io.entgra.application.mgt.common.wrapper; package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;

@ -16,7 +16,7 @@
*/ */
package io.entgra.application.mgt.common.wrapper; package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;

@ -16,7 +16,7 @@
*/ */
package io.entgra.application.mgt.common.wrapper; package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;

@ -16,7 +16,7 @@
*/ */
package io.entgra.application.mgt.common.wrapper; package io.entgra.application.mgt.common.wrapper;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;

@ -28,7 +28,7 @@ public class Artifacts {
private String imageLocation; private String imageLocation;
private String binaryLocation; private String binaryLocation;
@XmlElement(name = "ImageLocation", required = true) @XmlElement(name = "ImageLocationType", required = true)
public String getImageLocation() { public String getImageLocation() {
return imageLocation; return imageLocation;
} }

@ -17,7 +17,7 @@
package io.entgra.application.mgt.core.impl; package io.entgra.application.mgt.core.impl;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.entgra.application.mgt.core.dao.SPApplicationDAO; import io.entgra.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.application.mgt.core.util.ApplicationManagementUtil; import io.entgra.application.mgt.core.util.ApplicationManagementUtil;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
@ -86,7 +86,7 @@ import io.entgra.application.mgt.core.internal.DataHolder;
import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager; import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.application.mgt.core.util.ConnectionManagerUtil; import io.entgra.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.application.mgt.core.util.Constants; import io.entgra.application.mgt.core.util.Constants;
import io.entgra.application.mgt.core.util.StorageManagementUtil; import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
@ -600,16 +600,17 @@ public class ApplicationManagerImpl implements ApplicationManager {
*/ */
private String generateMD5OfApp(ApplicationArtifact applicationArtifact, byte[] content) throws ApplicationManagementException { private String generateMD5OfApp(ApplicationArtifact applicationArtifact, byte[] content) throws ApplicationManagementException {
try { try {
String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
String md5OfApp = applicationStorageManager.getMD5(new ByteArrayInputStream(content));
if (md5OfApp == null) { if (md5OfApp == null) {
String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName(); String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName();
log.error(msg); log.error(msg);
throw new ApplicationManagementException(msg); throw new ApplicationManagementException(msg);
} }
return md5OfApp; return md5OfApp;
} catch( ApplicationStorageManagementException e) { } catch(StorageManagementException e) {
String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName(); String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName();
log.error(msg); log.error(msg, e);
throw new ApplicationManagementException(msg, e); throw new ApplicationManagementException(msg, e);
} }
} }
@ -689,7 +690,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg); log.error(msg);
throw new ApplicationManagementException(msg); throw new ApplicationManagementException(msg);
} }
String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); String md5OfApp = applicationStorageManager.getMD5(new ByteArrayInputStream(content));
if (md5OfApp == null) { if (md5OfApp == null) {
String msg = "Error occurred while md5sum value retrieving process: application UUID " String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid(); + applicationReleaseDTO.getUuid();
@ -708,6 +709,11 @@ public class ApplicationManagerImpl implements ApplicationManager {
applicationStorageManager applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, tenantId); .uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, tenantId);
} }
} catch (StorageManagementException e) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying app release data."; String msg = "Error occurred when getting database connection for verifying app release data.";
log.error(msg, e); log.error(msg, e);
@ -752,7 +758,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) { try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = StorageManagementUtil.getMD5(binaryClone); String md5OfApp = applicationStorageManager.getMD5(binaryClone);
if (md5OfApp == null) { if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application " String msg = "Error occurred while retrieving md5sum value from the binary file for application "
@ -818,6 +824,11 @@ public class ApplicationManagerImpl implements ApplicationManager {
} }
} }
} }
} catch (StorageManagementException e) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application "
+ "release UUID " + applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (IOException e) { } catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
.getInstallerName(); .getInstallerName();
@ -3254,7 +3265,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
try { try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) { try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = StorageManagementUtil.getMD5(binaryClone); String md5OfApp = applicationStorageManager.getMD5(binaryClone);
if (md5OfApp == null) { if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for " String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid(); + "application release UUID " + applicationReleaseDTO.get().getUuid();
@ -3300,6 +3311,11 @@ public class ApplicationManagerImpl implements ApplicationManager {
} }
} }
} }
} catch (StorageManagementException e) {
String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (IOException e) { } catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " String msg = "Error occurred when getting byte array of binary file. Installer name: "
+ applicationArtifact.getInstallerName(); + applicationArtifact.getInstallerName();

@ -19,6 +19,7 @@ package io.entgra.application.mgt.core.impl;
import com.dd.plist.NSDictionary; import com.dd.plist.NSDictionary;
import net.dongliu.apk.parser.bean.ApkMeta; import net.dongliu.apk.parser.bean.ApkMeta;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -31,12 +32,13 @@ import io.entgra.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.application.mgt.core.exception.ParsingException; import io.entgra.application.mgt.core.exception.ParsingException;
import io.entgra.application.mgt.core.util.ArtifactsParser; import io.entgra.application.mgt.core.util.ArtifactsParser;
import io.entgra.application.mgt.core.util.Constants; import io.entgra.application.mgt.core.util.Constants;
import io.entgra.application.mgt.core.util.StorageManagementUtil; import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import org.wso2.carbon.device.mgt.core.common.util.StorageManagementUtil;
import java.io.*; import java.io.*;
import java.util.List; import java.util.List;
import static io.entgra.application.mgt.core.util.StorageManagementUtil.saveFile; import static org.wso2.carbon.device.mgt.core.common.util.StorageManagementUtil.saveFile;
/** /**
* This class contains the default concrete implementation of ApplicationStorage Management. * This class contains the default concrete implementation of ApplicationStorage Management.
@ -112,6 +114,11 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
+ applicationReleaseDTO.getUuid(); + applicationReleaseDTO.getUuid();
log.error(msg, e); log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e); throw new ApplicationStorageManagementException(msg, e);
} catch (StorageManagementException e) {
String msg = "Error occurred while uploading image artifacts"
+ applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ResourceManagementException(msg, e);
} }
} }
@ -159,6 +166,11 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
+ applicationReleaseDTO.getUuid(); + applicationReleaseDTO.getUuid();
log.error(msg, e); log.error(msg, e);
throw new ResourceManagementException( msg, e); throw new ResourceManagementException( msg, e);
} catch (StorageManagementException e) {
String msg = "Error occurred while uploading image artifacts"
+ applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ResourceManagementException(msg, e);
} }
} }
@ -286,4 +298,17 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
throw new ApplicationStorageManagementException(msg); throw new ApplicationStorageManagementException(msg);
} }
} }
@Override
public String getMD5(InputStream inputStream) throws StorageManagementException {
String md5;
try {
md5 = DigestUtils.md5Hex(inputStream);
} catch (IOException e) {
String msg = "IO Exception occurred while trying to get the md5sum value of application";
log.error(msg, e);
throw new StorageManagementException(msg, e);
}
return md5;
}
} }

@ -49,6 +49,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.routines.UrlValidator; import org.apache.commons.validator.routines.UrlValidator;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -327,9 +328,7 @@ public class SPApplicationManagerImpl implements SPApplicationManager {
* @throws BadRequestException if url is invalid * @throws BadRequestException if url is invalid
*/ */
private void validateIdentityServerUrl(String url) throws BadRequestException { private void validateIdentityServerUrl(String url) throws BadRequestException {
String[] schemes = {"http","https"}; if (!HttpUtil.isHttpUrlValid(url)) {
UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_LOCAL_URLS);
if (!urlValidator.isValid(url)) {
String msg = "Identity server url is not a valid url"; String msg = "Identity server url is not a valid url";
log.error(msg); log.error(msg);
throw new BadRequestException(msg); throw new BadRequestException(msg);

@ -18,13 +18,11 @@
package io.entgra.application.mgt.core.util; package io.entgra.application.mgt.core.util;
import io.entgra.application.mgt.common.ApplicationArtifact; import io.entgra.application.mgt.common.ApplicationArtifact;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.entgra.application.mgt.common.FileDataHolder; import io.entgra.application.mgt.common.FileDataHolder;
import io.entgra.application.mgt.common.dto.ApplicationDTO; 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.ApplicationManagementException;
import io.entgra.application.mgt.common.exception.RequestValidatingException; 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.services.SPApplicationManager;
import io.entgra.application.mgt.common.wrapper.ApplicationWrapper; import io.entgra.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper; import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper;

@ -23,7 +23,8 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import io.entgra.application.mgt.common.exception.ResourceManagementException; import io.entgra.application.mgt.common.exception.ResourceManagementException;
import io.entgra.application.mgt.core.util.StorageManagementUtil; import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import org.wso2.carbon.device.mgt.core.common.util.StorageManagementUtil;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -47,14 +48,14 @@ public class StorageManagementUtilTest {
public void testCreateArtifactDirectory() { public void testCreateArtifactDirectory() {
try { try {
StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER); StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER);
} catch (ResourceManagementException e) { } catch (StorageManagementException e) {
e.printStackTrace(); e.printStackTrace();
Assert.fail("Directory creation failed."); Assert.fail("Directory creation failed.");
} }
} }
@Test @Test
public void testSaveFile() throws IOException, ResourceManagementException { public void testSaveFile() throws IOException, ResourceManagementException, StorageManagementException {
StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER); StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER);
InputStream apk = new FileInputStream(APK_FILE); InputStream apk = new FileInputStream(APK_FILE);
StorageManagementUtil.saveFile(apk, TEMP_FOLDER + APK_FILE_NAME); StorageManagementUtil.saveFile(apk, TEMP_FOLDER + APK_FILE_NAME);
@ -65,7 +66,7 @@ public class StorageManagementUtilTest {
} }
@AfterMethod @AfterMethod
public void deleteFileTest() throws IOException, ResourceManagementException { public void deleteFileTest() throws IOException, StorageManagementException {
File file = new File(TEMP_FOLDER); File file = new File(TEMP_FOLDER);
StorageManagementUtil.delete(file); StorageManagementUtil.delete(file);
if (file.exists()) { if (file.exists()) {

@ -42,19 +42,16 @@ import io.entgra.application.mgt.core.impl.ApplicationManagerImpl;
import io.entgra.application.mgt.core.internal.DataHolder; import io.entgra.application.mgt.core.internal.DataHolder;
import io.entgra.application.mgt.core.util.ConnectionManagerUtil; import io.entgra.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.Base64File;
import org.wso2.carbon.device.mgt.core.common.util.FileUtil; import org.wso2.carbon.device.mgt.core.common.util.FileUtil;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class ApplicationManagementTest extends BaseTestCase { public class ApplicationManagementTest extends BaseTestCase {

@ -17,7 +17,7 @@
*/ */
package io.entgra.application.mgt.publisher.api.services; package io.entgra.application.mgt.publisher.api.services;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;

@ -18,7 +18,7 @@ package io.entgra.application.mgt.publisher.api.services.impl;
import io.entgra.application.mgt.common.ApplicationArtifact; import io.entgra.application.mgt.common.ApplicationArtifact;
import io.entgra.application.mgt.common.ApplicationList; import io.entgra.application.mgt.common.ApplicationList;
import io.entgra.application.mgt.common.Base64File; import org.wso2.carbon.device.mgt.common.Base64File;
import io.entgra.application.mgt.common.Filter; import io.entgra.application.mgt.common.Filter;
import io.entgra.application.mgt.common.LifecycleChanger; import io.entgra.application.mgt.common.LifecycleChanger;
import io.entgra.application.mgt.common.exception.ResourceManagementException; import io.entgra.application.mgt.common.exception.ResourceManagementException;

@ -33,6 +33,7 @@ import org.apache.axis2.transport.http.HTTPConstants;
import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList; import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.Constants;

@ -0,0 +1,277 @@
/*
* 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.jaxrs.service.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.apache.axis2.transport.http.HTTPConstants;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Metadata related REST-API implementation.
*/
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "Whitelabel Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "WhiteLabelManagement"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/whitelabel"),
})
}
),
tags = {
@Tag(name = "device_management")
}
)
@Scopes(
scopes = {
@Scope(
name = "View Whitelabel",
description = "View whitelabel details",
key = "perm:whitelabel:view",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/whitelabel/view"}
),
@Scope(
name = "Update Whitelabel",
description = "Updating whitelabel",
key = "perm:whitelabel:update",
roles = {"Internal/devicemgt-user"},
permissions = {"/device-mgt/whitelabel/update"}
),
}
)
@Api(value = "Whitelabel Management")
@Path("/whitelabel")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface WhiteLabelService {
@GET
@Path("/favicon")
@ApiOperation(
httpMethod = HTTPConstants.HEADER_GET,
value = "Get whitelabel favicon",
notes = "Get whitelabel favicon for the tenant of the logged in user",
tags = "Tenant Metadata Management"
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved white label favicon.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 500,
message = "Internal Server Error. " +
"\n Server error occurred while getting white label artifact.",
response = ErrorResponse.class)
})
Response getWhiteLabelFavicon();
@GET
@Path("/logo")
@ApiOperation(
httpMethod = HTTPConstants.HEADER_GET,
value = "Get whitelabel logo",
notes = "Get whitelabel logo for the tenant of the logged in user",
tags = "Tenant Metadata Management"
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved white label logo.",
response = Metadata.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 500,
message = "Internal Server Error. " +
"\n Server error occurred while getting white label artifact.",
response = ErrorResponse.class)
})
Response getWhiteLabelLogo();
@PUT
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Create whitelabel for tenant",
notes = "Create whitelabel for the tenant of the logged in user",
tags = "Tenant Metadata Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:whitelabel:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully created white label theme.",
response = Metadata.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 500,
message = "Internal Server Error. " +
"\n Server error occurred while creating white label theme.",
response = ErrorResponse.class)
})
Response updateWhiteLabelTheme(WhiteLabelThemeCreateRequest whiteLabelThemeCreateRequest);
@GET
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Get whitelabel for tenant",
notes = "Get whitelabel for the tenant of the logged in user",
tags = "Tenant Metadata Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:whitelabel:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched white label theme.",
response = Metadata.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 500,
message = "Internal Server Error. " +
"\n Server error occurred while fetching white label theme.",
response = ErrorResponse.class)
})
Response getWhiteLabelTheme();
@PUT
@Path("/reset")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Reset whitelabel for tenant",
notes = "Reset whitelabel to default for the tenant of the logged in user",
tags = "Tenant Metadata Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:whitelabel:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched white label theme.",
response = Metadata.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 500,
message = "Internal Server Error. " +
"\n Server error occurred while deleting white label theme.",
response = ErrorResponse.class)
})
Response resetWhiteLabel();
}

@ -18,20 +18,27 @@
package org.wso2.carbon.device.mgt.jaxrs.service.impl; package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyNotFoundException;
import org.wso2.carbon.device.mgt.common.exceptions.NotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService; import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelTheme;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList; import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList;
import org.wso2.carbon.device.mgt.jaxrs.service.api.MetadataService; import org.wso2.carbon.device.mgt.jaxrs.service.api.MetadataService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List; import java.util.List;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@ -147,4 +154,22 @@ public class MetadataServiceImpl implements MetadataService {
} }
} }
/**
* Useful to send files as application/octet-stream responses
*/
private Response sendFileStream(byte[] content) throws IOException {
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
Response.ResponseBuilder response = Response
.ok(binaryDuplicate, MediaType.APPLICATION_OCTET_STREAM);
response.status(Response.Status.OK);
// response.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.header("Content-Length", content.length);
return response.build();
} catch (IOException e) {
String msg = "Error occurred while creating input stream from buffer array. ";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
} }

@ -0,0 +1,151 @@
/*
* 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.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.FileResponse;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.NotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelTheme;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.jaxrs.service.api.WhiteLabelService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* This is the service class for metadata management.
*/
@Path("/whitelabel")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class WhiteLabelServiceImpl implements WhiteLabelService {
private static final Log log = LogFactory.getLog(WhiteLabelServiceImpl.class);
@GET
@Override
@Path("/favicon")
public Response getWhiteLabelFavicon() {
try {
FileResponse fileResponse = DeviceMgtAPIUtils.getWhiteLabelManagementService().getWhiteLabelFavicon();
return sendFileStream(fileResponse);
} catch (NotFoundException e) {
String msg = "Favicon white label image cannot be found in the system. Updating the whitelabel theme might" +
"help restore it";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (MetadataManagementException e) {
String msg = "Error occurred while getting favicon";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@GET
@Override
@Path("/logo")
public Response getWhiteLabelLogo() {
try {
FileResponse fileResponse = DeviceMgtAPIUtils.getWhiteLabelManagementService().getWhiteLabelLogo();
return sendFileStream(fileResponse);
} catch (NotFoundException e) {
String msg = "Logo white label image cannot be found in the system. Updating the whitelabel theme might" +
"help restore it";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (MetadataManagementException e) {
String msg = "Error occurred while getting logo";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@PUT
@Override
public Response updateWhiteLabelTheme(WhiteLabelThemeCreateRequest whiteLabelThemeCreateRequest) {
RequestValidationUtil.validateWhiteLabelTheme(whiteLabelThemeCreateRequest);
try {
WhiteLabelTheme createdWhiteLabelTheme = DeviceMgtAPIUtils.getWhiteLabelManagementService().updateWhiteLabelTheme(whiteLabelThemeCreateRequest);
return Response.status(Response.Status.CREATED).entity(createdWhiteLabelTheme).build();
} catch (MetadataManagementException e) {
String msg = "Error occurred while creating whitelabel for tenant";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@GET
@Override
public Response getWhiteLabelTheme() {
try {
WhiteLabelTheme whiteLabelTheme = DeviceMgtAPIUtils.getWhiteLabelManagementService().getWhiteLabelTheme();
return Response.status(Response.Status.CREATED).entity(whiteLabelTheme).build();
} catch (MetadataManagementException e) {
String msg = "Error occurred while deleting whitelabel for tenant";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (NotFoundException e) {
String msg = "Not white label theme configured for this tenant";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
}
@PUT
@Override
@Path("/reset")
public Response resetWhiteLabel() {
try {
DeviceMgtAPIUtils.getWhiteLabelManagementService().resetToDefaultWhiteLabelTheme();
return Response.status(Response.Status.CREATED).entity("White label theme deleted successfully.").build();
} catch (MetadataManagementException e) {
String msg = "Error occurred while resetting whitelabel for tenant";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
/**
* Useful to send file responses
*/
private Response sendFileStream(FileResponse fileResponse) {
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(fileResponse.getFileContent())) {
Response.ResponseBuilder response = Response
.ok(binaryDuplicate, fileResponse.getMimeType());
response.status(Response.Status.OK);
response.header("Content-Length", fileResponse.getFileContent().length);
return response.build();
} catch (IOException e) {
String msg = "Error occurred while creating input stream from buffer array. ";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}

@ -18,10 +18,13 @@
*/ */
package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; package org.wso2.carbon.device.mgt.jaxrs.service.impl.util;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.wso2.carbon.device.mgt.common.Base64File;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.Feature; import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager; import org.wso2.carbon.device.mgt.common.FeatureManager;
@ -31,8 +34,11 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelImageRequestPayload;
import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; import org.wso2.carbon.device.mgt.common.notification.mgt.Notification;
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -670,6 +676,114 @@ public class RequestValidationUtil {
} }
} }
/**
* Check if whitelabel theme create request contains valid payload and all required payload
*
* @param whiteLabelThemeCreateRequest {@link WhiteLabelThemeCreateRequest}
*/
public static void validateWhiteLabelTheme(WhiteLabelThemeCreateRequest whiteLabelThemeCreateRequest) {
if (whiteLabelThemeCreateRequest.getFavicon() == null) {
String msg = "Favicon is required to whitelabel";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
if (whiteLabelThemeCreateRequest.getLogo() == null) {
String msg = "Logo is required to whitelabel";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
if (whiteLabelThemeCreateRequest.getFooterText() == null) {
String msg = "Footer text is required to whitelabel";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
if (whiteLabelThemeCreateRequest.getAppTitle() == null) {
String msg = "App title is required to whitelabel";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
try {
validateWhiteLabelImage(whiteLabelThemeCreateRequest.getFavicon());
validateWhiteLabelImage(whiteLabelThemeCreateRequest.getLogo());
} catch (InputValidationException e) {
String msg = "Payload contains invalid base64 files";
log.error(msg, e);
throw e;
}
}
/**
* Validate if {@link WhiteLabelImageRequestPayload} contains mandatory fields.
*/
private static void validateWhiteLabelImage(WhiteLabelImageRequestPayload whiteLabelImage) {
if (whiteLabelImage.getImageType() == null) {
String msg = "Invalid payload found with the request. White label imageType cannot be null.";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
if (whiteLabelImage.getImageType() == WhiteLabelImageRequestPayload.ImageType.BASE64) {
try {
Base64File image = new Gson().fromJson(whiteLabelImage.getImage(), Base64File.class);
validateBase64File(image);
} catch (JsonSyntaxException e) {
String msg = "Invalid image payload found with the request. Image object does not represent a Base64 File. " +
"Hence verify the request payload object.";
log.error(msg, e);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
else if (whiteLabelImage.getImageType() == WhiteLabelImageRequestPayload.ImageType.URL) {
try {
String imageUrl = new Gson().fromJson(whiteLabelImage.getImage(), String.class);
if (!HttpUtil.isHttpUrlValid(imageUrl)) {
String msg = "Invalid image url provided for white label image.";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
} catch (JsonSyntaxException e) {
String msg = "Invalid payload found with the request. Hence verify the request payload object.";
log.error(msg, e);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
} else {
String msg = "Invalid payload found with the request. Unknown white label imageType " + whiteLabelImage.getImageType();
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
/**
* Validate if {@link Base64File} contains mandatory fields.
*/
private static void validateBase64File(Base64File base64File) {
if (base64File.getBase64String() == null || base64File.getName() == null) {
String msg = "Base64File doesn't contain required properties. name and base64String properties " +
"are required fields for base64file type";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
/** /**
* Validate if the metaData and metaKey values are non empty & in proper format. * Validate if the metaData and metaKey values are non empty & in proper format.
* *

@ -74,6 +74,7 @@ import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService; import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService;
@ -174,6 +175,7 @@ public class DeviceMgtAPIUtils {
// private static IntegrationClientService integrationClientService; // private static IntegrationClientService integrationClientService;
private static MetadataManagementService metadataManagementService; private static MetadataManagementService metadataManagementService;
private static WhiteLabelManagementService whiteLabelManagementService;
private static OTPManagementService otpManagementService; private static OTPManagementService otpManagementService;
private static volatile SubscriptionManager subscriptionManager; private static volatile SubscriptionManager subscriptionManager;
@ -511,6 +513,28 @@ public class DeviceMgtAPIUtils {
return notificationManagementService; return notificationManagementService;
} }
/**
* Initializing and accessing method for WhiteLabelManagementService.
*
* @return WhiteLabelManagementService instance
* @throws IllegalStateException if whiteLabelManagementService cannot be initialized
*/
public static WhiteLabelManagementService getWhiteLabelManagementService() {
if (whiteLabelManagementService == null) {
synchronized (DeviceMgtAPIUtils.class) {
if (whiteLabelManagementService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
whiteLabelManagementService = (WhiteLabelManagementService) ctx.getOSGiService(
WhiteLabelManagementService.class, null);
if (whiteLabelManagementService == null) {
throw new IllegalStateException("Whitelabel Management service not initialized.");
}
}
}
}
return whiteLabelManagementService;
}
/** /**
* Initializing and accessing method for MetadataManagementService. * Initializing and accessing method for MetadataManagementService.
* *

@ -49,6 +49,7 @@
<ref bean="swaggerResource"/> <ref bean="swaggerResource"/>
<ref bean="analyticsArtifactsManagementService"/> <ref bean="analyticsArtifactsManagementService"/>
<ref bean="metadataService"/> <ref bean="metadataService"/>
<ref bean="whitelabelService"/>
</jaxrs:serviceBeans> </jaxrs:serviceBeans>
<jaxrs:providers> <jaxrs:providers>
<ref bean="jsonProvider"/> <ref bean="jsonProvider"/>
@ -99,6 +100,7 @@
<bean id="jsonProvider" class="org.wso2.carbon.device.mgt.jaxrs.common.GsonMessageBodyHandler"/> <bean id="jsonProvider" class="org.wso2.carbon.device.mgt.jaxrs.common.GsonMessageBodyHandler"/>
<bean id="analyticsArtifactsManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.AnalyticsArtifactsManagementServiceImpl"/> <bean id="analyticsArtifactsManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.AnalyticsArtifactsManagementServiceImpl"/>
<bean id="metadataService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.MetadataServiceImpl"/> <bean id="metadataService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.MetadataServiceImpl"/>
<bean id="whitelabelService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.WhiteLabelServiceImpl"/>
<!--<bean id="errorHandler" class="org.wso2.carbon.device.mgt.jaxrs.common.ErrorHandler"/>--> <!--<bean id="errorHandler" class="org.wso2.carbon.device.mgt.jaxrs.common.ErrorHandler"/>-->
<cxf:bus> <cxf:bus>

@ -48,7 +48,9 @@
<context-param> <context-param>
<param-name>nonSecuredEndPoints</param-name> <param-name>nonSecuredEndPoints</param-name>
<param-value> <param-value>
/api/device-mgt/v1.0/users/validate /api/device-mgt/v1.0/users/validate,
/api/device-mgt/v1.0/whitelabel/favicon,
/api/device-mgt/v1.0/whitelabel/logo
</param-value> </param-value>
</context-param> </context-param>

@ -16,7 +16,7 @@
* under the License. * under the License.
*/ */
package io.entgra.application.mgt.common; package org.wso2.carbon.device.mgt.common;
public class Base64File { public class Base64File {

@ -0,0 +1,74 @@
/*
* 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.common;
public class FileResponse {
private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
private byte[] fileContent;
private String mimeType;
private String name;
public byte[] getFileContent() {
return fileContent;
}
public void setFileContent(byte[] fileContent) {
this.fileContent = fileContent;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public enum ImageExtension {
SVG() {
@Override
public String mimeType() {
return "image/svg+xml";
}
},
PNG,
JPG,
JPEG,
GIF;
public String mimeType() {
return DEFAULT_MIME_TYPE;
}
public static String mimeTypeOf(String extension) {
if (extension.isEmpty()) {
return DEFAULT_MIME_TYPE;
}
ImageExtension imageExtension = ImageExtension.valueOf(extension.toUpperCase());
return imageExtension.mimeType();
}
@Override
public String toString() {
return this.name().toLowerCase();
}
}
}

@ -0,0 +1,34 @@
/*
* 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.common.exceptions;
/**
* This exception will be thrown when the requested application or platform not found.
*/
public class NotFoundException extends Exception {
public NotFoundException(String message, Throwable throwable) {
super(message, throwable);
}
public NotFoundException(String message) {
super(message);
}
}

@ -23,7 +23,6 @@ import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyNotFoundException;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException; import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import java.util.List; import java.util.List;
/** /**

@ -0,0 +1,49 @@
/*
* 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.common.metadata.mgt;
public class WhiteLabelArtifactPath {
private String faviconPath;
private String logoPath;
public WhiteLabelArtifactPath() {
}
public WhiteLabelArtifactPath(String faviconPath, String logoPath) {
this.faviconPath = faviconPath;
this.logoPath = logoPath;
}
public String getFaviconPath() {
return faviconPath;
}
public void setFaviconPath(String faviconPath) {
this.faviconPath = faviconPath;
}
public String getLogoPath() {
return logoPath;
}
public void setLogoPath(String logoPath) {
this.logoPath = logoPath;
}
}

@ -0,0 +1,56 @@
/*
* 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.common.metadata.mgt;
public class WhiteLabelImage {
private ImageLocationType imageLocationType;
private String imageLocation;
public ImageLocationType getImageLocationType() {
return imageLocationType;
}
public void setImageLocationType(ImageLocationType imageLocationType) {
this.imageLocationType = imageLocationType;
}
public String getImageLocation() {
return imageLocation;
}
public void setImageLocation(String imageLocation) {
this.imageLocation = imageLocation;
}
public enum ImageName {
FAVICON,
LOGO;
@Override
public String toString() {
return name().toLowerCase();
}
}
public enum ImageLocationType {
URL,
CUSTOM_FILE,
DEFAULT_FILE
}
}

@ -0,0 +1,71 @@
/*
* 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.common.metadata.mgt;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import org.wso2.carbon.device.mgt.common.Base64File;
public class WhiteLabelImageRequestPayload {
private ImageType imageType;
private JsonElement image;
public ImageType getImageType() {
return imageType;
}
public void setImageType(ImageType imageType) {
this.imageType = imageType;
}
public JsonElement getImage() {
return image;
}
public Base64File getImageAsBase64File() {
if (imageType != ImageType.BASE64) {
throw new IllegalStateException("Cannot convert image with Image type of " + imageType + " to base64.");
}
return new Gson().fromJson(image, Base64File.class);
}
public String getImageAsUrl() {
if (imageType != ImageType.URL) {
throw new IllegalStateException("Cannot convert image with Image type of " + imageType + " to image url string.");
}
return new Gson().fromJson(image, String.class);
}
public void setImage(JsonElement image) {
this.image = image;
}
public enum ImageType {
URL,
BASE64;
public WhiteLabelImage.ImageLocationType getDTOImageLocationType() {
if (this == URL) {
return WhiteLabelImage.ImageLocationType.URL;
}
return WhiteLabelImage.ImageLocationType.CUSTOM_FILE;
}
}
}

@ -0,0 +1,73 @@
/*
* 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.common.metadata.mgt;
import org.wso2.carbon.device.mgt.common.FileResponse;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.NotFoundException;
/**
* Defines the contract of WhiteLabelManagementService.
*/
public interface WhiteLabelManagementService {
/**
* Use to get byte content of favicon whitelabel image
* @return byte content of favicon
* @throws MetadataManagementException if error occurred while retrieving favicon
* @throws NotFoundException if favicon is not found
*/
FileResponse getWhiteLabelFavicon() throws
MetadataManagementException, NotFoundException;
/**
* Use to get byte content of logo whitelabel image
* @return byte content of logo
* @throws MetadataManagementException if error occurred while retrieving logo
* @throws NotFoundException if logo is not found
*/
FileResponse getWhiteLabelLogo() throws
MetadataManagementException, NotFoundException;
/**
* This method is useful to create & persist default white label theme for provided tenant if
* it doesn't exist already
* @throws MetadataManagementException if error while adding default white label theme
*/
void addDefaultWhiteLabelThemeIfNotExist(int tenantId) throws MetadataManagementException;
/**
* This method is useful to reset existing white label to default whitelabel
* @throws MetadataManagementException if error while resetting default white label theme
*/
void resetToDefaultWhiteLabelTheme() throws MetadataManagementException;
/**
* This method is useful to update existing white label theme
* @throws MetadataManagementException if error while updating existing white label theme
*/
WhiteLabelTheme updateWhiteLabelTheme(WhiteLabelThemeCreateRequest createWhiteLabelTheme)
throws MetadataManagementException;
/**
* This method is useful to get existing white label theme
* @throws MetadataManagementException if error while getting existing white label theme
*/
WhiteLabelTheme getWhiteLabelTheme() throws MetadataManagementException, NotFoundException;
}

@ -0,0 +1,58 @@
/*
* 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.common.metadata.mgt;
public class WhiteLabelTheme {
private WhiteLabelImage faviconImage;
private WhiteLabelImage logoImage;
private String footerText;
private String appTitle;
public String getFooterText() {
return footerText;
}
public void setFooterText(String footerText) {
this.footerText = footerText;
}
public WhiteLabelImage getFaviconImage() {
return faviconImage;
}
public void setFaviconImage(WhiteLabelImage faviconImage) {
this.faviconImage = faviconImage;
}
public WhiteLabelImage getLogoImage() {
return logoImage;
}
public void setLogoImage(WhiteLabelImage logoImage) {
this.logoImage = logoImage;
}
public String getAppTitle() {
return appTitle;
}
public void setAppTitle(String appTitle) {
this.appTitle = appTitle;
}
}

@ -0,0 +1,58 @@
/*
* 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.common.metadata.mgt;
public class WhiteLabelThemeCreateRequest {
private WhiteLabelImageRequestPayload favicon;
private WhiteLabelImageRequestPayload logo;
private String footerText;
private String appTitle;
public WhiteLabelImageRequestPayload getFavicon() {
return favicon;
}
public void setFavicon(WhiteLabelImageRequestPayload favicon) {
this.favicon = favicon;
}
public WhiteLabelImageRequestPayload getLogo() {
return logo;
}
public void setLogo(WhiteLabelImageRequestPayload logo) {
this.logo = logo;
}
public String getFooterText() {
return footerText;
}
public void setFooterText(String footerText) {
this.footerText = footerText;
}
public String getAppTitle() {
return appTitle;
}
public void setAppTitle(String appTitle) {
this.appTitle = appTitle;
}
}

@ -0,0 +1,32 @@
/* Copyright (c) 2019, 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.exception;
/**
* Represents the exception thrown during storing and retrieving the artifacts.
*/
public class StorageManagementException extends Exception {
public StorageManagementException(String message, Throwable ex) {
super(message, ex);
}
public StorageManagementException(String message) {
super(message);
}
}

@ -19,6 +19,8 @@
package org.wso2.carbon.device.mgt.core.common.util; package org.wso2.carbon.device.mgt.core.common.util;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.wso2.carbon.device.mgt.common.Base64File;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -54,7 +56,7 @@ public class FileUtil {
} }
/** /**
* Useful to convert input stream to base64 string * Useful to convert file to base64 string
* *
* @param file stream to be converted * @param file stream to be converted
* @return base64 string of the provided input stream * @return base64 string of the provided input stream
@ -64,6 +66,17 @@ public class FileUtil {
return Base64.getEncoder().encodeToString(fileContent); return Base64.getEncoder().encodeToString(fileContent);
} }
/**
* Useful to convert {@link File} to {@link Base64File}
*
* @param file to be converted
* @return {@link Base64File} of the provided input stream
*/
public static Base64File fileToBase64File(File file) throws IOException {
String base64String = fileToBase64String(file);
return new Base64File(file.getName(), base64String);
}
/** /**
* This generates file name with a suffix depending on the duplicate name count, useful when saving * This generates file name with a suffix depending on the duplicate name count, useful when saving
* files with the same name * files with the same name
@ -75,7 +88,7 @@ public class FileUtil {
String suffix = generateDuplicateFileNameSuffix(fileNameCount); String suffix = generateDuplicateFileNameSuffix(fileNameCount);
String fileNameWithoutExtension = extractFileNameWithoutExtension(fileName); String fileNameWithoutExtension = extractFileNameWithoutExtension(fileName);
String fileNameWithSuffix = fileNameWithoutExtension + suffix; String fileNameWithSuffix = fileNameWithoutExtension + suffix;
fileNameWithSuffix = fileNameWithSuffix + '.' + extractFileExtension(fileName); fileNameWithSuffix = fileNameWithSuffix + '.' + extractFileExtensionFileName(fileName);
return fileNameWithSuffix; return fileNameWithSuffix;
} }
@ -98,13 +111,27 @@ public class FileUtil {
return suffix; return suffix;
} }
/**
* Use to extract file extension from file path
*
* @param filePath path of the file
* @return extension of the file
*/
public static String extractFileExtensionFromFilePath(String filePath) {
File file = new File(filePath);
return extractFileExtensionFileName(file.getName());
}
/** /**
* Use to extract file extension from file name * Use to extract file extension from file name
* *
* @param fileName name of the file * @param fileName name of the file
* @return extension of the file * @return extension of the file
*/ */
private static String extractFileExtension(String fileName) { public static String extractFileExtensionFileName(String fileName) {
if (!fileName.contains(".")) {
return "";
}
return fileName.substring(fileName.lastIndexOf('.') + 1); return fileName.substring(fileName.lastIndexOf('.') + 1);
} }

@ -19,6 +19,7 @@ package org.wso2.carbon.device.mgt.core.common.util;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
@ -234,4 +235,16 @@ public class HttpUtil {
ContentType contentType = ContentType.getOrDefault(response.getEntity()); ContentType contentType = ContentType.getOrDefault(response.getEntity());
return contentType.getMimeType(); return contentType.getMimeType();
} }
/**
* Validate http url (For example make sure it uses http/https protocol)
*
* @param url url to be checked if valid
* @return if provided http url is valid
*/
public static boolean isHttpUrlValid(String url) {
String[] schemes = {"http","https"};
UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_LOCAL_URLS);
return urlValidator.isValid(url);
}
} }

@ -16,16 +16,12 @@
* under the License. * under the License.
*/ */
package io.entgra.application.mgt.core.util; package org.wso2.carbon.device.mgt.core.common.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import io.entgra.application.mgt.common.ImageArtifact; import org.wso2.carbon.device.mgt.common.Base64File;
import io.entgra.application.mgt.common.exception.ApplicationStorageManagementException; import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import io.entgra.application.mgt.common.exception.ResourceManagementException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -47,14 +43,13 @@ public class StorageManagementUtil {
* This method is responsible for creating artifact parent directories in the given path. * This method is responsible for creating artifact parent directories in the given path.
* *
* @param artifactDirectoryPath Path for the artifact directory. * @param artifactDirectoryPath Path for the artifact directory.
* @throws ResourceManagementException Resource Management Exception.
*/ */
public static void createArtifactDirectory(String artifactDirectoryPath) throws ResourceManagementException { public static void createArtifactDirectory(String artifactDirectoryPath) throws StorageManagementException {
File artifactDirectory = new File(artifactDirectoryPath); File artifactDirectory = new File(artifactDirectoryPath);
if (!artifactDirectory.exists() && !artifactDirectory.mkdirs()) { if (!artifactDirectory.exists() && !artifactDirectory.mkdirs()) {
throw new ResourceManagementException( throw new StorageManagementException(
"Cannot create directories in the path to save the application related artifacts"); "Cannot create directories in the path: " + artifactDirectoryPath);
} }
} }
@ -103,20 +98,13 @@ public class StorageManagementUtil {
} }
/** /**
* To create {@link ImageArtifact}. * To save a bas64 string of a file in a given location.
* *
* @param imageFile Image File. * @param base64File {@link Base64File} of the file.
* @param imageArtifactPath Path of the image artifact file.
* @return Image Artifact.
* @throws IOException IO Exception.
*/ */
public static ImageArtifact createImageArtifact(File imageFile, String imageArtifactPath) throws IOException { public static void saveFile(Base64File base64File, String path) throws IOException {
ImageArtifact imageArtifact = new ImageArtifact(); InputStream inputStream = FileUtil.base64ToInputStream(base64File.getBase64String());
imageArtifact.setName(imageFile.getName()); saveFile(inputStream, path);
imageArtifact.setType(Files.probeContentType(imageFile.toPath()));
byte[] imageBytes = IOUtils.toByteArray(new FileInputStream(imageArtifactPath));
imageArtifact.setEncodedImage(Base64.encodeBase64URLSafeString(imageBytes));
return imageArtifact;
} }
/*** /***
@ -138,16 +126,4 @@ public class StorageManagementUtil {
throw new IOException(msg, e); throw new IOException(msg, e);
} }
} }
public static String getMD5(InputStream binaryFile) throws ApplicationStorageManagementException {
String md5;
try {
md5 = DigestUtils.md5Hex(binaryFile);
} catch (IOException e) {
String msg = "IO Exception occurred while trying to get the md5sum value of application";
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
}
return md5;
}
} }

@ -26,6 +26,7 @@ import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguratio
import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.GeoFenceCacheConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.GeoFenceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.operation.timeout.OperationTimeoutConfiguration; import org.wso2.carbon.device.mgt.core.config.operation.timeout.OperationTimeoutConfiguration;
import org.wso2.carbon.device.mgt.core.config.metadata.mgt.MetaDataConfiguration;
import org.wso2.carbon.device.mgt.core.event.config.EventOperationTaskConfiguration; import org.wso2.carbon.device.mgt.core.event.config.EventOperationTaskConfiguration;
import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration; import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations; import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
@ -70,6 +71,7 @@ public final class DeviceManagementConfig {
private EnrollmentNotificationConfiguration enrollmentNotificationConfiguration; private EnrollmentNotificationConfiguration enrollmentNotificationConfiguration;
private DefaultRoles defaultRoles; private DefaultRoles defaultRoles;
private OperationTimeoutConfiguration operationTimeoutConfiguration; private OperationTimeoutConfiguration operationTimeoutConfiguration;
private MetaDataConfiguration metaDataConfiguration;
@XmlElement(name = "ManagementRepository", required = true) @XmlElement(name = "ManagementRepository", required = true)
public DeviceManagementConfigRepository getDeviceManagementConfigRepository() { public DeviceManagementConfigRepository getDeviceManagementConfigRepository() {
@ -265,5 +267,14 @@ public final class DeviceManagementConfig {
public void setOperationTimeoutConfiguration(OperationTimeoutConfiguration operationTimeoutConfiguration) { public void setOperationTimeoutConfiguration(OperationTimeoutConfiguration operationTimeoutConfiguration) {
this.operationTimeoutConfiguration = operationTimeoutConfiguration; this.operationTimeoutConfiguration = operationTimeoutConfiguration;
} }
@XmlElement(name = "MetaDataConfiguration", required = true)
public MetaDataConfiguration getMetaDataConfiguration() {
return metaDataConfiguration;
}
public void setMetaDataConfiguration(MetaDataConfiguration metaDataConfiguration) {
this.metaDataConfiguration = metaDataConfiguration;
}
} }

@ -0,0 +1,38 @@
/*
* 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.config.metadata.mgt;
import org.wso2.carbon.device.mgt.core.config.metadata.mgt.whitelabel.WhiteLabelConfiguration;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "MetaDataConfiguration")
public class MetaDataConfiguration {
private WhiteLabelConfiguration whiteLabelConfiguration;
@XmlElement(name = "WhiteLabelConfiguration", required = true)
public WhiteLabelConfiguration getWhiteLabelConfiguration() {
return whiteLabelConfiguration;
}
public void setWhiteLabelConfiguration(WhiteLabelConfiguration whiteLabelConfiguration) {
this.whiteLabelConfiguration = whiteLabelConfiguration;
}
}

@ -0,0 +1,56 @@
/*
* 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.config.metadata.mgt.whitelabel;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "WhiteLabelConfiguration")
public class WhiteLabelConfiguration {
private String footerText;
private String appTitle;
private WhiteLabelImages whiteLabelImages;
@XmlElement(name = "FooterText", required = true)
public String getFooterText() {
return footerText;
}
public void setFooterText(String footerText) {
this.footerText = footerText;
}
@XmlElement(name = "WhiteLabelImages", required = true)
public WhiteLabelImages getWhiteLabelImages() {
return whiteLabelImages;
}
public void setWhiteLabelImages(WhiteLabelImages whiteLabelImages) {
this.whiteLabelImages = whiteLabelImages;
}
@XmlElement(name = "AppTitle", required = true)
public String getAppTitle() {
return appTitle;
}
public void setAppTitle(String appTitle) {
this.appTitle = appTitle;
}
}

@ -0,0 +1,67 @@
/*
* 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.config.metadata.mgt.whitelabel;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "WhiteLabelImages")
public class WhiteLabelImages {
private String storagePath;
private String defaultImagesLocation;
private String defaultFaviconName;
private String defaultLogoName;
@XmlElement(name = "StoragePath", required = true)
public String getStoragePath() {
return storagePath;
}
public void setStoragePath(String storagePath) {
this.storagePath = storagePath;
}
@XmlElement(name = "DefaultFaviconName", required = true)
public String getDefaultFaviconName() {
return defaultFaviconName;
}
public void setDefaultFaviconName(String defaultFaviconName) {
this.defaultFaviconName = defaultFaviconName;
}
@XmlElement(name = "DefaultLogoName", required = true)
public String getDefaultLogoName() {
return defaultLogoName;
}
public void setDefaultLogoName(String defaultLogoName) {
this.defaultLogoName = defaultLogoName;
}
@XmlElement(name = "DefaultImagesLocation", required = true)
public String getDefaultImagesLocation() {
return defaultImagesLocation;
}
public void setDefaultImagesLocation(String defaultImagesLocation) {
this.defaultImagesLocation = defaultImagesLocation;
}
}

@ -26,6 +26,8 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization
import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationProviderService; import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationProviderService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig; import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig;
@ -34,6 +36,7 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManag
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager; import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.metadata.mgt.MetadataManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.operation.timeout.task.OperationTimeoutTaskManagerService; import org.wso2.carbon.device.mgt.core.operation.timeout.task.OperationTimeoutTaskManagerService;
import org.wso2.carbon.device.mgt.core.privacy.PrivacyComplianceProvider; import org.wso2.carbon.device.mgt.core.privacy.PrivacyComplianceProvider;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository; import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository;
@ -85,6 +88,8 @@ public class DeviceManagementDataHolder {
private ExecutorService eventConfigExecutors; private ExecutorService eventConfigExecutors;
private OperationTimeoutTaskManagerService operationTimeoutTaskManagerService; private OperationTimeoutTaskManagerService operationTimeoutTaskManagerService;
private DeviceAPIClientService deviceAPIClientService; private DeviceAPIClientService deviceAPIClientService;
private MetadataManagementService metadataManagementService;
private WhiteLabelManagementService whiteLabelManagementService;
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap( private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<>()); new HashMap<>());
@ -95,7 +100,8 @@ public class DeviceManagementDataHolder {
return this.map; return this.map;
} }
private DeviceManagementDataHolder() {} private DeviceManagementDataHolder() {
}
public static DeviceManagementDataHolder getInstance() { public static DeviceManagementDataHolder getInstance() {
return thisInstance; return thisInstance;
@ -359,4 +365,20 @@ public class DeviceManagementDataHolder {
public void setDeviceAPIClientService(DeviceAPIClientService deviceAPIClientService) { public void setDeviceAPIClientService(DeviceAPIClientService deviceAPIClientService) {
this.deviceAPIClientService = deviceAPIClientService; this.deviceAPIClientService = deviceAPIClientService;
} }
public MetadataManagementService getMetadataManagementService() {
return metadataManagementService;
}
public void setMetadataManagementService(MetadataManagementService metadataManagementService) {
this.metadataManagementService = metadataManagementService;
}
public WhiteLabelManagementService getWhiteLabelManagementService() {
return whiteLabelManagementService;
}
public void setWhiteLabelManagementService(WhiteLabelManagementService whiteLabelManagementService) {
this.whiteLabelManagementService = whiteLabelManagementService;
}
} }

@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
@ -31,6 +32,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService; import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
@ -59,6 +61,7 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.impl.DeviceInformation
import org.wso2.carbon.device.mgt.core.event.config.EventConfigurationProviderServiceImpl; import org.wso2.carbon.device.mgt.core.event.config.EventConfigurationProviderServiceImpl;
import org.wso2.carbon.device.mgt.core.geo.service.GeoLocationProviderServiceImpl; import org.wso2.carbon.device.mgt.core.geo.service.GeoLocationProviderServiceImpl;
import org.wso2.carbon.device.mgt.core.metadata.mgt.MetadataManagementServiceImpl; import org.wso2.carbon.device.mgt.core.metadata.mgt.MetadataManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.metadata.mgt.WhiteLabelManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory; import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.notification.mgt.NotificationManagementServiceImpl; import org.wso2.carbon.device.mgt.core.notification.mgt.NotificationManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory; import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory;
@ -293,6 +296,8 @@ public class DeviceManagementServiceComponent {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Registering OSGi service DeviceManagementProviderServiceImpl"); log.debug("Registering OSGi service DeviceManagementProviderServiceImpl");
} }
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
/* Registering Tenants Observer */ /* Registering Tenants Observer */
BundleContext bundleContext = componentContext.getBundleContext(); BundleContext bundleContext = componentContext.getBundleContext();
TenantCreateObserver listener = new TenantCreateObserver(); TenantCreateObserver listener = new TenantCreateObserver();
@ -358,8 +363,20 @@ public class DeviceManagementServiceComponent {
/* Registering Metadata Service */ /* Registering Metadata Service */
MetadataManagementService metadataManagementService = new MetadataManagementServiceImpl(); MetadataManagementService metadataManagementService = new MetadataManagementServiceImpl();
DeviceManagementDataHolder.getInstance().setMetadataManagementService(metadataManagementService);
bundleContext.registerService(MetadataManagementService.class.getName(), metadataManagementService, null); bundleContext.registerService(MetadataManagementService.class.getName(), metadataManagementService, null);
/* Registering Whitelabel Service */
WhiteLabelManagementService whiteLabelManagementService = new WhiteLabelManagementServiceImpl();
DeviceManagementDataHolder.getInstance().setWhiteLabelManagementService(whiteLabelManagementService);
try {
whiteLabelManagementService.addDefaultWhiteLabelThemeIfNotExist(tenantId);
} catch (Throwable e) {
log.error("Error occurred while adding default tenant white label theme", e);
}
bundleContext.registerService(WhiteLabelManagementService.class.getName(), whiteLabelManagementService, null);
/* Registering Event Configuration Service */ /* Registering Event Configuration Service */
EventConfigurationProviderService eventConfigurationService = new EventConfigurationProviderServiceImpl(); EventConfigurationProviderService eventConfigurationService = new EventConfigurationProviderServiceImpl();
DeviceManagementDataHolder.getInstance().setEventConfigurationProviderService(eventConfigurationService); DeviceManagementDataHolder.getInstance().setEventConfigurationProviderService(eventConfigurationService);

@ -33,7 +33,6 @@ import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataDAO;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOException; import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOException;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory; import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
@ -44,7 +43,7 @@ public class MetadataManagementServiceImpl implements MetadataManagementService
private static final Log log = LogFactory.getLog(MetadataManagementServiceImpl.class); private static final Log log = LogFactory.getLog(MetadataManagementServiceImpl.class);
private MetadataDAO metadataDAO; private final MetadataDAO metadataDAO;
public MetadataManagementServiceImpl() { public MetadataManagementServiceImpl() {
this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO(); this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO();

@ -0,0 +1,396 @@
/*
* 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.metadata.mgt;
import com.google.gson.Gson;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Base64File;
import org.wso2.carbon.device.mgt.common.FileResponse;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.NotFoundException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelImage;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelImageRequestPayload;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelTheme;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelThemeCreateRequest;
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.metadata.mgt.MetaDataConfiguration;
import org.wso2.carbon.device.mgt.core.config.metadata.mgt.whitelabel.WhiteLabelConfiguration;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataDAO;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOException;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.metadata.mgt.dao.util.MetadataConstants;
import org.wso2.carbon.device.mgt.core.metadata.mgt.util.WhiteLabelStorageUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
/**
* This class implements the MetadataManagementService.
*/
public class WhiteLabelManagementServiceImpl implements WhiteLabelManagementService {
private static final Log log = LogFactory.getLog(WhiteLabelManagementServiceImpl.class);
private final MetadataDAO metadataDAO;
public WhiteLabelManagementServiceImpl() {
this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO();
}
@Override
public FileResponse getWhiteLabelFavicon() throws MetadataManagementException, NotFoundException {
try {
WhiteLabelTheme whiteLabelTheme = getWhiteLabelTheme();
return getImageFileResponse(whiteLabelTheme.getFaviconImage(), WhiteLabelImage.ImageName.FAVICON);
} catch (IOException e) {
String msg = "Error occurred while getting byte content of favicon";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
@Override
public FileResponse getWhiteLabelLogo() throws MetadataManagementException, NotFoundException {
try {
WhiteLabelTheme whiteLabelTheme = getWhiteLabelTheme();
return getImageFileResponse(whiteLabelTheme.getLogoImage(), WhiteLabelImage.ImageName.LOGO);
} catch (IOException e) {
String msg = "Error occurred while getting byte content of logo";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
/**
* Useful to get white label image file response for provided {@link WhiteLabelImage.ImageName}
*/
private FileResponse getImageFileResponse(WhiteLabelImage image, WhiteLabelImage.ImageName imageName) throws
IOException, MetadataManagementException, NotFoundException {
if (image.getImageLocationType() == WhiteLabelImage.ImageLocationType.URL) {
return getImageFileResponseFromUrl(image.getImageLocation());
}
return WhiteLabelStorageUtil.getWhiteLabelImageStream(image, imageName);
}
/**
* Useful to get white label image file response from provided url
*/
private FileResponse getImageFileResponseFromUrl(String url) throws IOException, NotFoundException {
FileResponse fileResponse = new FileResponse();
try(CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet imageGetRequest = new HttpGet(url);
HttpResponse response = client.execute(imageGetRequest);
InputStream imageStream = response.getEntity().getContent();
if (imageStream == null) {
String msg = "Failed to retrieve the image from url: " + url;
log.error(msg);
throw new NotFoundException(msg);
}
byte[] fileContent = IOUtils.toByteArray(imageStream);
fileResponse.setFileContent(fileContent);
String mimeType = HttpUtil.getContentType(response);
fileResponse.setMimeType(mimeType);
return fileResponse;
}
}
@Override
public void addDefaultWhiteLabelThemeIfNotExist(int tenantId) throws MetadataManagementException {
try {
MetadataManagementDAOFactory.beginTransaction();
if (!metadataDAO.isExist(tenantId, MetadataConstants.WHITELABEL_META_KEY)) {
WhiteLabelTheme whiteLabelTheme = getDefaultWhiteLabelTheme();
Metadata metadata = constructWhiteLabelThemeMetadata(whiteLabelTheme);
metadataDAO.addMetadata(tenantId, metadata);
if (log.isDebugEnabled()) {
log.debug("White label metadata entry has inserted successfully");
}
}
MetadataManagementDAOFactory.commitTransaction();
} catch (MetadataManagementDAOException e) {
MetadataManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while inserting default whitelabel metadata entry.";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while opening a connection to the data source";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} finally {
MetadataManagementDAOFactory.closeConnection();
}
}
@Override
public void resetToDefaultWhiteLabelTheme() throws MetadataManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
WhiteLabelTheme whiteLabelTheme = getDefaultWhiteLabelTheme();
Metadata metadata = constructWhiteLabelThemeMetadata(whiteLabelTheme);
DeviceManagementDataHolder.getInstance().getMetadataManagementService().updateMetadata(metadata);
WhiteLabelStorageUtil.deleteWhiteLabelImageForTenantIfExists(tenantId);
}
/**
* Construct and return default whitelabel detail bean {@link WhiteLabelImage}
*/
private WhiteLabelTheme getDefaultWhiteLabelTheme() {
String footerText = getDefaultFooterText();
String appTitle = getDefaultAppTitle();
WhiteLabelImage favicon = constructDefaultFaviconImage();
WhiteLabelImage logo = constructDefaultLogoImage();
WhiteLabelTheme defaultTheme = new WhiteLabelTheme();
defaultTheme.setFooterText(footerText);
defaultTheme.setAppTitle(appTitle);
defaultTheme.setLogoImage(logo);
defaultTheme.setFaviconImage(favicon);
return defaultTheme;
}
/**
* Get default whitelabel label page title from config
*/
private String getDefaultAppTitle() {
MetaDataConfiguration metaDataConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getMetaDataConfiguration();
WhiteLabelConfiguration whiteLabelConfiguration = metaDataConfiguration.getWhiteLabelConfiguration();
return whiteLabelConfiguration.getAppTitle();
}
/**
* Get default whitelabel label footer from config
*/
private String getDefaultFooterText() {
MetaDataConfiguration metaDataConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getMetaDataConfiguration();
WhiteLabelConfiguration whiteLabelConfiguration = metaDataConfiguration.getWhiteLabelConfiguration();
return whiteLabelConfiguration.getFooterText();
}
/**
* This is useful to construct and get the default favicon whitelabel image
*
* @return {@link WhiteLabelImage}
*/
private WhiteLabelImage constructDefaultFaviconImage() {
MetaDataConfiguration metaDataConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getMetaDataConfiguration();
WhiteLabelConfiguration whiteLabelConfiguration = metaDataConfiguration.getWhiteLabelConfiguration();
WhiteLabelImage favicon = new WhiteLabelImage();
favicon.setImageLocation(whiteLabelConfiguration.getWhiteLabelImages().getDefaultFaviconName());
setDefaultWhiteLabelImageCommonProperties(favicon);
return favicon;
}
/**
* This is useful to construct and get the default logo whitelabel image
*
* @return {@link WhiteLabelImage}
*/
private WhiteLabelImage constructDefaultLogoImage() {
MetaDataConfiguration metaDataConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getMetaDataConfiguration();
WhiteLabelConfiguration whiteLabelConfiguration = metaDataConfiguration.getWhiteLabelConfiguration();
WhiteLabelImage logo = new WhiteLabelImage();
logo.setImageLocation(whiteLabelConfiguration.getWhiteLabelImages().getDefaultLogoName());
setDefaultWhiteLabelImageCommonProperties(logo);
return logo;
}
/**
* This is useful to set common properties such as DEFAULT_FILE type for {@link WhiteLabelImage.ImageLocationType}
* for default white label image bean{@link WhiteLabelImage}
*/
private void setDefaultWhiteLabelImageCommonProperties(WhiteLabelImage image) {
image.setImageLocationType(WhiteLabelImage.ImageLocationType.DEFAULT_FILE);
}
@Override
public WhiteLabelTheme updateWhiteLabelTheme(WhiteLabelThemeCreateRequest createWhiteLabelTheme)
throws MetadataManagementException {
if (log.isDebugEnabled()) {
log.debug("Creating Metadata : [" + createWhiteLabelTheme.toString() + "]");
}
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
File existingFaviconImage = null;
File existingLogoImage = null;
try {
WhiteLabelTheme theme = getWhiteLabelTheme();
if (theme.getFaviconImage().getImageLocationType() == WhiteLabelImage.ImageLocationType.CUSTOM_FILE) {
existingFaviconImage = WhiteLabelStorageUtil.getWhiteLabelImageFile(theme.getFaviconImage(), WhiteLabelImage.ImageName.FAVICON);
}
if (theme.getLogoImage().getImageLocationType() == WhiteLabelImage.ImageLocationType.CUSTOM_FILE) {
existingLogoImage = WhiteLabelStorageUtil.getWhiteLabelImageFile(theme.getLogoImage(), WhiteLabelImage.ImageName.LOGO);
}
storeWhiteLabelImageIfRequired(createWhiteLabelTheme.getFavicon(), WhiteLabelImage.ImageName.FAVICON, tenantId);
storeWhiteLabelImageIfRequired(createWhiteLabelTheme.getLogo(), WhiteLabelImage.ImageName.LOGO, tenantId);
WhiteLabelTheme whiteLabelTheme = constructWhiteLabelTheme(createWhiteLabelTheme);
Metadata metadataWhiteLabelTheme = constructWhiteLabelThemeMetadata(whiteLabelTheme);
try {
MetadataManagementDAOFactory.beginTransaction();
metadataDAO.updateMetadata(tenantId, metadataWhiteLabelTheme);
MetadataManagementDAOFactory.commitTransaction();
if (log.isDebugEnabled()) {
log.debug("Metadata entry created successfully. " + createWhiteLabelTheme);
}
return whiteLabelTheme;
} catch (MetadataManagementDAOException e) {
MetadataManagementDAOFactory.rollbackTransaction();
restoreWhiteLabelImages(existingFaviconImage, existingLogoImage, tenantId);
String msg = "Error occurred while creating the metadata entry. " + createWhiteLabelTheme;
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} catch (TransactionManagementException e) {
restoreWhiteLabelImages(existingFaviconImage, existingLogoImage, tenantId);
String msg = "Error occurred while opening a connection to the data source";
log.error(msg, e);
throw new MetadataManagementException("Error occurred while creating metadata record", e);
} finally {
MetadataManagementDAOFactory.closeConnection();
}
} catch (NotFoundException e) {
String msg = "Error occurred while retrieving existing white label theme";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
/**
* This is method is useful to restore provided existing white label images (i.e: favicon/logo).
* For example if any exception occurred white updating/deleting white label, this method can be used to
* restore the existing images in any case. Note that the existing images should be first loaded so that
* those can be passed to this method in order to restore.
*
* @param existingFavicon existing favicon image file
* @param existingLogo existing logo image file
*/
private void restoreWhiteLabelImages(File existingFavicon, File existingLogo, int tenantId)
throws MetadataManagementException {
WhiteLabelStorageUtil.deleteWhiteLabelImageForTenantIfExists(tenantId);
if (existingFavicon != null) {
WhiteLabelStorageUtil.storeWhiteLabelImage(existingFavicon, WhiteLabelImage.ImageName.FAVICON, tenantId);
}
if (existingLogo != null) {
WhiteLabelStorageUtil.storeWhiteLabelImage(existingLogo, WhiteLabelImage.ImageName.LOGO, tenantId);
}
}
/**
* This handles storing provided white label image if required.
* For example if the provided white label image is of URL type it doesn't need to be stored
*
* @param whiteLabelImage image to be stored
* @param imageName (i.e: FAVICON)
*/
private void storeWhiteLabelImageIfRequired(WhiteLabelImageRequestPayload whiteLabelImage,
WhiteLabelImage.ImageName imageName, int tenantId)
throws MetadataManagementException {
if (whiteLabelImage.getImageType() == WhiteLabelImageRequestPayload.ImageType.BASE64) {
Base64File imageBase64 = new Gson().fromJson(whiteLabelImage.getImage(), Base64File.class);
WhiteLabelStorageUtil.updateWhiteLabelImage(imageBase64, imageName, tenantId);
}
}
/**
* Generate {@link WhiteLabelTheme} from provided {@link WhiteLabelThemeCreateRequest}
*/
private WhiteLabelTheme constructWhiteLabelTheme(WhiteLabelThemeCreateRequest whiteLabelThemeCreateRequest) {
WhiteLabelTheme whiteLabelTheme = new WhiteLabelTheme();
WhiteLabelImageRequestPayload faviconPayload = whiteLabelThemeCreateRequest.getFavicon();
WhiteLabelImageRequestPayload logoPayload = whiteLabelThemeCreateRequest.getLogo();
WhiteLabelImage faviconImage = constructWhiteLabelImageDTO(faviconPayload);
WhiteLabelImage logoImage = constructWhiteLabelImageDTO(logoPayload);
whiteLabelTheme.setFaviconImage(faviconImage);
whiteLabelTheme.setLogoImage(logoImage);
whiteLabelTheme.setFooterText(whiteLabelThemeCreateRequest.getFooterText());
whiteLabelTheme.setAppTitle(whiteLabelThemeCreateRequest.getAppTitle());
return whiteLabelTheme;
}
/**
* Generate {@link WhiteLabelImage} from provided {@link WhiteLabelImageRequestPayload}
*/
private WhiteLabelImage constructWhiteLabelImageDTO(WhiteLabelImageRequestPayload image) {
WhiteLabelImage imageResponse = new WhiteLabelImage();
WhiteLabelImage.ImageLocationType imageLocationType = image.getImageType().getDTOImageLocationType();
imageResponse.setImageLocationType(imageLocationType);
String imageLocation;
if (image.getImageType() == WhiteLabelImageRequestPayload.ImageType.BASE64) {
Base64File imageBase64 = image.getImageAsBase64File();
imageLocation = imageBase64.getName();
} else {
imageLocation = image.getImageAsUrl();
}
imageResponse.setImageLocation(imageLocation);
return imageResponse;
}
/**
* Generate {@link Metadata} from provided {@link WhiteLabelImage}
*/
private Metadata constructWhiteLabelThemeMetadata(WhiteLabelTheme whiteLabelTheme) {
String whiteLabelThemeJsonString = new Gson().toJson(whiteLabelTheme);
Metadata metadata = new Metadata();
metadata.setMetaKey(MetadataConstants.WHITELABEL_META_KEY);
metadata.setMetaValue(whiteLabelThemeJsonString);
return metadata;
}
@Override
public WhiteLabelTheme getWhiteLabelTheme() throws MetadataManagementException, NotFoundException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (log.isDebugEnabled()) {
log.debug("Retrieving whitelabel theme for tenant: " + tenantId);
}
try {
MetadataManagementDAOFactory.openConnection();
Metadata metadata = metadataDAO.getMetadata(tenantId, MetadataConstants.WHITELABEL_META_KEY);
if (metadata == null) {
String msg = "Whitelabel theme not found for tenant: " + tenantId;
log.debug(msg);
throw new NotFoundException(msg);
}
return new Gson().fromJson(metadata.getMetaValue(), WhiteLabelTheme.class);
} catch (MetadataManagementDAOException e) {
String msg = "Error occurred while retrieving white label theme for tenant:" + tenantId;
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while opening a connection to the data source";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} finally {
MetadataManagementDAOFactory.closeConnection();
}
}
}

@ -0,0 +1,22 @@
/* 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.metadata.mgt.dao.util;
public class MetadataConstants {
public static final String WHITELABEL_META_KEY = "whitelabel";
}

@ -0,0 +1,212 @@
/* 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.metadata.mgt.util;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Base64File;
import org.wso2.carbon.device.mgt.common.FileResponse;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.NotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelImage;
import org.wso2.carbon.device.mgt.core.common.exception.StorageManagementException;
import org.wso2.carbon.device.mgt.core.common.util.FileUtil;
import org.wso2.carbon.device.mgt.core.common.util.StorageManagementUtil;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.metadata.mgt.MetaDataConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* This class contains the default concrete implementation of ApplicationStorage Management.
*/
public class WhiteLabelStorageUtil {
private static final Log log = LogFactory.getLog(WhiteLabelStorageUtil.class);
private static final MetaDataConfiguration metadataConfig;
private static final String STORAGE_PATH;
static {
metadataConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getMetaDataConfiguration();
if (metadataConfig == null) {
throw new RuntimeException("Meta configuration is not found in cdm-config.xml");
}
STORAGE_PATH = metadataConfig.getWhiteLabelConfiguration().getWhiteLabelImages().getStoragePath();
}
/**
* Store provided white label {@link Base64File} image
*
* @param image base64 image file
* @param imageName {@link WhiteLabelImage.ImageName} (i.e FAVICON)
*/
public static void storeWhiteLabelImage(Base64File image, WhiteLabelImage.ImageName imageName, int tenantId)
throws MetadataManagementException {
String storedLocation;
try {
String imageStoringBaseDirPath = STORAGE_PATH + File.separator + tenantId;
StorageManagementUtil.createArtifactDirectory(imageStoringBaseDirPath);
String storingDir = imageStoringBaseDirPath + File.separator + imageName;
StorageManagementUtil.createArtifactDirectory(storingDir);
storedLocation = storingDir + File.separator + image.getName();
StorageManagementUtil.saveFile(image, storedLocation);
} catch (IOException e) {
String msg = "IO Exception occurred while saving whitelabel artifacts for the tenant " + tenantId;
log.error(msg, e);
throw new MetadataManagementException(msg, e);
} catch (StorageManagementException e) {
String msg = "Error occurred while uploading white label image artifacts";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
/**
* Store provided white label {@link File} image
*
* @param image white label file
* @param imageName {@link WhiteLabelImage.ImageName} (i.e FAVICON)
*/
public static void storeWhiteLabelImage(File image, WhiteLabelImage.ImageName imageName, int tenantId) throws
MetadataManagementException {
try {
storeWhiteLabelImage(FileUtil.fileToBase64File(image), imageName, tenantId);
} catch (IOException e) {
String msg = "Error occurred when converting provided File object to Base64File class";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
/**
* Update white label image for provided tenant
*
* @param image {@link Base64File} white label file
* @param imageName (i.e: FAVICON)
*/
public static void updateWhiteLabelImage(Base64File image, WhiteLabelImage.ImageName imageName, int tenantId)
throws MetadataManagementException {
deleteWhiteLabelImageIfExists(imageName, tenantId);
storeWhiteLabelImage(image, imageName, tenantId);
}
/**
* Use to get a given {@link WhiteLabelImage.ImageName (i.e: LOGO)} white label image File
*
* @param image detail bean
* @param imageName (i.e: LOGO)
* @return white label image file {@link File}
*/
public static File getWhiteLabelImageFile(WhiteLabelImage image, WhiteLabelImage.ImageName imageName)
throws MetadataManagementException {
String fullPathToImage = getPathToImage(image, imageName);
return new File(fullPathToImage);
}
/**
* Useful to get the given {@link WhiteLabelImage.ImageName (i.e: LOGO)} white label image InputStream
*
* @param image - white label image detail bean
* @param imageName (i.e: LOGO)
* @return white label image input stream
*/
public static FileResponse getWhiteLabelImageStream(WhiteLabelImage image, WhiteLabelImage.ImageName imageName)
throws MetadataManagementException, NotFoundException {
FileResponse fileResponse = new FileResponse();
String fullPathToFile = getPathToImage(image, imageName);
try {
InputStream imageStream = StorageManagementUtil.getInputStream(fullPathToFile);
if (imageStream == null) {
String msg = "Failed to get the " + imageName + " image with the file name: " + fullPathToFile;
log.error(msg);
throw new NotFoundException(msg);
}
byte[] fileContent = IOUtils.toByteArray(imageStream);
String fileExtension = FileUtil.extractFileExtensionFromFilePath(image.getImageLocation());
String mimeType = FileResponse.ImageExtension.mimeTypeOf(fileExtension);
fileResponse.setMimeType(mimeType);
fileResponse.setFileContent(fileContent);
return fileResponse;
} catch (IOException e) {
String msg = "Error occurred when accessing the file in file path: " + fullPathToFile;
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
/**
* Construct the path to white label image in the file system and return
*
* @param image - white label image detail bean
* @param imageName (i.e: LOGO)
* @return Full path to white label image in the system
*/
private static String getPathToImage(WhiteLabelImage image, WhiteLabelImage.ImageName imageName)
throws MetadataManagementException {
WhiteLabelImage.ImageLocationType imageLocationType = image.getImageLocationType();
if (imageLocationType == WhiteLabelImage.ImageLocationType.URL) {
String msg = "White label images of URL type is not stored, hence it doesn't have a path in file system.";
log.error(msg);
throw new MetadataManagementException(msg);
}
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String fileName = image.getImageLocation();
String filePath = String.valueOf(tenantId);
if (imageLocationType == WhiteLabelImage.ImageLocationType.DEFAULT_FILE) {
filePath = metadataConfig.getWhiteLabelConfiguration().getWhiteLabelImages().getDefaultImagesLocation();
}
return STORAGE_PATH + File.separator + filePath + File.separator + imageName + File.separator + fileName;
}
/***
* This method is responsible to delete provided white label image file which if exist
*/
public static void deleteWhiteLabelImageIfExists(WhiteLabelImage.ImageName imageName, int tenantId) throws MetadataManagementException {
String artifactPath = STORAGE_PATH + File.separator + tenantId + File.separator + imageName;
File artifact = new File(artifactPath);
if (artifact.exists()) {
try {
StorageManagementUtil.delete(artifact);
} catch (IOException e) {
String msg = "Error occurred while deleting whitelabel artifacts";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
}
/***
* This method is responsible to delete all white label images for provided tenant
*/
public static void deleteWhiteLabelImageForTenantIfExists(int tenantId) throws MetadataManagementException {
String artifactPath = STORAGE_PATH + File.separator + tenantId;
File artifact = new File(artifactPath);
if (artifact.exists()) {
try {
StorageManagementUtil.delete(artifact);
} catch (IOException e) {
String msg = "Error occurred while deleting whitelabel artifacts";
log.error(msg, e);
throw new MetadataManagementException(msg, e);
}
}
}
}

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException;
import org.wso2.carbon.device.mgt.common.roles.config.Role; import org.wso2.carbon.device.mgt.common.roles.config.Role;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
@ -68,6 +69,12 @@ public class DeviceMgtTenantMgtListener implements TenantMgtListener {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
} }
try {
DeviceManagementDataHolder.getInstance().getWhiteLabelManagementService().
addDefaultWhiteLabelThemeIfNotExist(tenantInfoBean.getTenantId());
} catch (MetadataManagementException e) {
log.error("Error occurred while adding default white label theme to created tenant.", e);
}
} }
@Override @Override

@ -183,6 +183,25 @@
</Role> </Role>
</Roles> </Roles>
</DefaultRoles> </DefaultRoles>
<MetaDataConfiguration>
<WhiteLabelConfiguration>
<FooterText>
&lt;a href='https://entgra.io' target='_blank'&gt;
Entgra
&lt;/a&gt;
IoT Server 5.0.0 | &#169; 2023
, All Rights Reserved.
</FooterText>
<AppTitle>Entgra</AppTitle>
<WhiteLabelImages>
<StoragePath>repository/resources/whitelabel</StoragePath>
<DefaultFaviconName>favicon.png</DefaultFaviconName>
<DefaultLogoName>logo.png</DefaultLogoName>
<DefaultImagesLocation>default</DefaultImagesLocation>
</WhiteLabelImages>
</WhiteLabelConfiguration>
</MetaDataConfiguration>
<OperationTimeoutConfigurations> <OperationTimeoutConfigurations>
<OperationTimeouts> <OperationTimeouts>
</OperationTimeouts> </OperationTimeouts>

@ -195,6 +195,8 @@
<Scope>perm:android:upgrade-firmware</Scope> <Scope>perm:android:upgrade-firmware</Scope>
<Scope>perm:android:send-notification</Scope> <Scope>perm:android:send-notification</Scope>
<Scope>perm:geo-service:geo-fence</Scope> <Scope>perm:geo-service:geo-fence</Scope>
<Scope>perm:whitelabel:view</Scope>
<Scope>perm:whitelabel:update</Scope>
<Scope>perm:metadata:view</Scope> <Scope>perm:metadata:view</Scope>
<Scope>perm:metadata:create</Scope> <Scope>perm:metadata:create</Scope>
<Scope>perm:metadata:update</Scope> <Scope>perm:metadata:update</Scope>

@ -322,6 +322,24 @@
</Role> </Role>
</Roles> </Roles>
</DefaultRoles> </DefaultRoles>
<MetaDataConfiguration>
<WhiteLabelConfiguration>
<FooterText>
&lt;a href='https://entgra.io' target='_blank'&gt;
Entgra
&lt;/a&gt;
IoT Server 5.0.0 | &#169; 2023
, All Rights Reserved.
</FooterText>
<AppTitle>Entgra</AppTitle>
<WhiteLabelImages>
<StoragePath>repository/resources/whitelabel</StoragePath>
<DefaultFaviconName>favicon.png</DefaultFaviconName>
<DefaultLogoName>logo.png</DefaultLogoName>
<DefaultImagesLocation>default</DefaultImagesLocation>
</WhiteLabelImages>
</WhiteLabelConfiguration>
</MetaDataConfiguration>
<OperationTimeoutConfigurations> <OperationTimeoutConfigurations>
<OperationTimeouts> <OperationTimeouts>
<!--<OperationTimeout>--> <!--<OperationTimeout>-->

Loading…
Cancel
Save