Compare commits

Invalid templates have been ignored

1 invalid template(s) found pull_request_template.md: frontmatter must start with a separator line

...

29 Commits

Author SHA1 Message Date
Lasantha Dharmakeerthi 7d91cfff3c Fix error response formatting issue and NullPointerException when getting a fileName with a query param
1 week ago
Nipuni Kavindya ba3e4623df Fix NullPointerException in getFileMetaEntry method for URLs with chunked transfer encoding.
1 week ago
Nipuni Kavindya 5853e529c7 Fix throwing NullPointerException when getting a fileName with a query param.
1 week ago
Nipuni Kavindya 16b7c4f3e7 Fix error response formatting issue.
1 week ago
Lasantha Dharmakeerthi 860470832f Fix test case failure when extracting cert from signature
2 weeks ago
Lasantha Dharmakeerthi a10bdd1d05 Scopes related to tagging feature
2 weeks ago
Uddhika Ishara 3094743045 Merge remote-tracking branch 'origin/uddhika-device-mgt' into uddhika-device-mgt
2 weeks ago
Uddhika Ishara 85d7ed641a removed new line
2 weeks ago
Uddhika Ishara 663df92b42 Merge branch 'master' into uddhika-device-mgt
2 weeks ago
Uddhika Ishara bd8ecb8718 further added scope lines
2 weeks ago
Uddhika Ishara 4792f4af72 fixes scope lines
2 weeks ago
Uddhika Ishara ae4978cee8 scopes related to tagging feature
2 weeks ago
Navod Zoysa 1aa32528b0 Fix test case failure when extracting cert from signature
2 weeks ago
Lasantha Dharmakeerthi 66c9c4f4e6 Fix Device statuses intermittently not saving issue
3 weeks ago
Arshana b2b4c5c676 Add scpeific instructions in java doc comment
3 weeks ago
Lasantha Dharmakeerthi 7f06804823 Fix client cert verification issue in sub tenants
3 weeks ago
Navod Zoysa 00633e34f5 Fix client cert verification issue in sub tenants
4 weeks ago
Lasantha Dharmakeerthi a2d9da923b Improved SQL query with DESC sorting
4 weeks ago
Lasantha Dharmakeerthi 09b9dd3ded Fix login issues in sub tenants
4 weeks ago
Navod Zoysa 3d872e3b72 Merge pull request 'Remove unused windows os updates scopes' (#535) from subodhinie/device-mgt-core:os_updates into master
1 month ago
Navod Zoysa 66f6982098 Merge pull request 'Fix missing commit by moving transaction commit after metadata update.' (#532) from nipuni/device-mgt-core:11963 into master
1 month ago
Subodhinie 0e82c9c304 Remove unused windows os updates scopes
1 month ago
Pramila Niroshan 20df0c879f Improved SQL query with DESC sorting
1 month ago
Rajitha Kumara 8f47c448bd Fix login issues in sub tenants
1 month ago
Nipuni Kavindya b7e0580112 Fix missing commit by moving transaction commit after metadata update.
1 month ago
Lasantha Dharmakeerthi a45820e845 Remove code quality check from PRs
1 month ago
Lasantha Dharmakeerthi 337f26446b Fix the validation issue when the APK file and screenshot names contain spaces
1 month ago
Nipuni Kavindya cba9f7ce08 Fix the validation issue when the APK file and screenshot names contain spaces
1 month ago
prathabanKavin 0ac795903f Remove code quality check from PRs
PullRequestValidation/community/device-mgt-core/pipeline/pr-master This commit looks good Details
1 month ago

35
Jenkinsfile vendored

@ -5,7 +5,6 @@ pipeline {
environment {
def isPendingUpstreamDependenciesExists = false
def triggeredViaPush = false
SCANNER_HOME = tool 'sonar-scanner'
JAVA_HOME = '/usr/lib/jvm/java-11-openjdk'
PATH = "${JAVA_HOME}/bin:${env.PATH}"
}
@ -48,22 +47,6 @@ pipeline {
}
}
}
stage('Check SonarQube Installation') {
steps {
script {
echo "Initial JAVA_HOME: ${env.JAVA_HOME}"
echo "Initial PATH: ${env.PATH}"
withEnv(["JAVA_HOME=${env.JAVA_HOME}", "PATH=${env.JAVA_HOME}/bin:${env.PATH}"]) {
sh """
java -version
${SCANNER_HOME}/bin/sonar-scanner --version
"""
}
}
}
}
stage('Fetch Pending Upstream Dependencies') {
steps {
@ -111,24 +94,6 @@ pipeline {
}
}
}
stage('Code Quality Check') {
steps {
script {
def projectName = "device-mgt-core-${env.CHANGE_ID}"
def projectKey = "device-mgt-core-${env.CHANGE_ID}"
withSonarQubeEnv('sonar') {
sh """
$SCANNER_HOME/bin/sonar-scanner \
-Dsonar.projectName=${projectName} \
-Dsonar.projectKey=${projectKey} \
-Dsonar.java.binaries=target
"""
}
}
}
}
stage('Report Job Status') {
steps {

@ -122,7 +122,10 @@ public class FileDownloaderServiceProvider {
}
FileMetaEntry fileMetaEntry = new FileMetaEntry();
fileMetaEntry.setSize(Long.parseLong(Objects.requireNonNull(response.header("Content-Length"))));
String contentLength = response.header("Content-Length");
if (contentLength != null) {
fileMetaEntry.setSize(Long.parseLong(contentLength));
}
fileMetaEntry.setFileName(fileNameSegments[0]);
fileMetaEntry.setExtension(fileNameSegments[1]);
return fileMetaEntry;
@ -132,9 +135,21 @@ public class FileDownloaderServiceProvider {
}
/**
* Extracting file name segments by parsing the URL
* @param url Remote URL to extract file name segments
* @return Array containing file name segments or null when failed to extract
* Extracts file name segments (name and extension) by parsing the given URL.
* This method handles two types of URL formats:
* - If the URL includes a query parameter in the format `?fileName=`, the file name
* is extracted from this query parameter (ex: when referencing an existing
* screenshot or icon from the main release)
* - If the URL does not have the `fileName` query parameter, the method attempts to
* extract the file name from the URL path. (ex: this applies to cases where new files are
* uploaded, and only a path-based URL is provided)
* After locating the file name (from either the query parameter or path), the method
* splits the name into segments based on the last dot (`.`), returning the base name and
* extension as a two-element array. If file name cannot be extracted, `null` is returned.
*
* @param url Remote URL to extract file name segments from, which may contain a file name
* as either a query parameter (`fileName=...`) or in the path.
* @return An array containing the file name and extension segments, or null if extraction fails.
*/
public static String[] extractFileNameSegmentsFromUrl(URL url) {
if (url == null) {
@ -143,24 +158,35 @@ public class FileDownloaderServiceProvider {
}
return null;
}
String []urlSegments = url.toString().split("/");
if (urlSegments.length < 1) {
if (log.isDebugEnabled()) {
log.debug("Cannot determine the file name for the remote file");
String fullQualifiedName = null;
String query = url.getQuery();
if (query != null && query.startsWith("fileName=")) {
String[] queryParts = query.split("=", 2);
if (queryParts.length > 1 && !queryParts[1].isEmpty()) {
fullQualifiedName = queryParts[1];
}
return null;
}
String fullQualifiedName = urlSegments[urlSegments.length - 1];
String []fileNameSegments = fullQualifiedName.split("\\.(?=[^.]+$)");
if (fileNameSegments.length != 2) {
if (fullQualifiedName == null) {
String[] urlSegments = url.getPath().split("/");
if (urlSegments.length > 0) {
fullQualifiedName = urlSegments[urlSegments.length - 1];
}
}
if (fullQualifiedName != null) {
String[] fileNameSegments = fullQualifiedName.split("\\.(?=[^.]+$)");
if (fileNameSegments.length == 2) {
return fileNameSegments;
} else {
if (log.isDebugEnabled()) {
log.debug("Error encountered when constructing file name");
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("Error encountered when constructing file name");
}
return null;
}
return fileNameSegments;
return null;
}
/**

@ -48,6 +48,8 @@ import org.apache.commons.validator.routines.UrlValidator;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import javax.ws.rs.core.Response;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ -503,31 +505,29 @@ public class APIUtil {
applicationRelease.setSupportedOsVersions(applicationReleaseDTO.getSupportedOsVersions());
applicationRelease.setRating(applicationReleaseDTO.getRating());
applicationRelease.setIconPath(
basePath + Constants.ICON_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName());
if (!StringUtils.isEmpty(applicationReleaseDTO.getBannerName())){
basePath + Constants.ICON_ARTIFACT + Constants.FILE_NAME_PARAM +
URLEncoder.encode(applicationReleaseDTO.getIconName(), StandardCharsets.UTF_8));
if (!StringUtils.isEmpty(applicationReleaseDTO.getBannerName())) {
applicationRelease.setBannerPath(
basePath + Constants.BANNER_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO
.getBannerName());
basePath + Constants.BANNER_ARTIFACT + Constants.FILE_NAME_PARAM +
URLEncoder.encode(applicationReleaseDTO.getBannerName(), StandardCharsets.UTF_8));
}
applicationRelease.setInstallerPath(constructInstallerPath(applicationReleaseDTO.getInstallerName(),
applicationReleaseDTO.getAppHashValue()));
applicationRelease.setInstallerPath(
constructInstallerPath(applicationReleaseDTO.getInstallerName(), applicationReleaseDTO.getAppHashValue()));
if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName1())) {
screenshotPaths
.add(basePath + Constants.SCREENSHOT_ARTIFACT + 1 + Constants.FORWARD_SLASH + applicationReleaseDTO
.getScreenshotName1());
screenshotPaths.add(
basePath + Constants.SCREENSHOT_ARTIFACT + 1 + Constants.FILE_NAME_PARAM +
URLEncoder.encode(applicationReleaseDTO.getScreenshotName1(), StandardCharsets.UTF_8));
}
if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName2())) {
screenshotPaths
.add(basePath + Constants.SCREENSHOT_ARTIFACT + 2 + Constants.FORWARD_SLASH + applicationReleaseDTO
.getScreenshotName2());
screenshotPaths.add(
basePath + Constants.SCREENSHOT_ARTIFACT + 2 + Constants.FILE_NAME_PARAM +
URLEncoder.encode(applicationReleaseDTO.getScreenshotName2(), StandardCharsets.UTF_8));
}
if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName3())) {
screenshotPaths
.add(basePath + Constants.SCREENSHOT_ARTIFACT + 3 + Constants.FORWARD_SLASH + applicationReleaseDTO
.getScreenshotName3());
screenshotPaths.add(
basePath + Constants.SCREENSHOT_ARTIFACT + 3 + Constants.FILE_NAME_PARAM +
URLEncoder.encode(applicationReleaseDTO.getScreenshotName3(), StandardCharsets.UTF_8));
}
applicationRelease.setScreenshots(screenshotPaths);
return applicationRelease;
@ -543,9 +543,12 @@ public class APIUtil {
public static String constructInstallerPath(String installerName, String appHash) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
UrlValidator urlValidator = new UrlValidator();
String basePath = getArtifactDownloadBaseURL() + tenantId + Constants.FORWARD_SLASH + appHash + Constants.FORWARD_SLASH;
return urlValidator.isValid(installerName) ? installerName
: basePath + Constants.APP_ARTIFACT + Constants.FORWARD_SLASH + installerName;
String basePath = getArtifactDownloadBaseURL() + tenantId + Constants.FORWARD_SLASH +
appHash + Constants.FORWARD_SLASH;
return urlValidator.isValid(installerName)
? installerName
: basePath + Constants.APP_ARTIFACT + Constants.FILE_NAME_PARAM +
URLEncoder.encode(installerName, StandardCharsets.UTF_8);
}
public static String getArtifactDownloadBaseURL() throws ApplicationManagementException {

@ -140,6 +140,11 @@ public class Constants {
public static final String DB_TYPE_POSTGRESQL = "PostgreSQL";
}
/**
* Query parameter for specifying the filename in the App artifact URL.
*/
public static final String FILE_NAME_PARAM = "?fileName=";
/**
* Directory name of the icon artifact that are saved in the file system.
*/

@ -183,6 +183,15 @@ public class FileTransferServiceHelperUtil {
return fileDescriptorResolvedFromRelease;
}
String file = urlPathSegments[urlPathSegments.length - 1];
String query = downloadUrl.getQuery();
if (query != null && query.startsWith("fileName=")) {
String[] queryParts = query.split("=", 2);
if (queryParts.length > 1 && !queryParts[1].isEmpty()) {
file = queryParts[1];
}
}
if (urlPathSegments.length < 2) {
if (log.isDebugEnabled()) {
log.debug("URL patch segments contain less than 2 segments");
@ -190,7 +199,6 @@ public class FileTransferServiceHelperUtil {
return null;
}
String file = urlPathSegments[urlPathSegments.length - 1];
String artifactHolder = urlPathSegments[urlPathSegments.length - 2];
try {
FileDescriptor fileDescriptor = new FileDescriptor();

@ -139,7 +139,7 @@ public class GenericCertificateDAOImpl extends AbstractCertificateDAOImpl {
isCertificateUsernameProvided = true;
}
query += "ORDER BY ID LIMIT ?,?";
query += "ORDER BY ID DESC LIMIT ?,?";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
int paramIdx = 1;

@ -78,7 +78,7 @@ public class OracleCertificateDAOImpl extends AbstractCertificateDAOImpl {
isCertificateUsernameProvided = true;
}
query += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
query += "ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
int paramIdx = 1;

@ -78,7 +78,7 @@ public class PostgreSQLCertificateDAOImpl extends AbstractCertificateDAOImpl {
isCertificateUsernameProvided = true;
}
query += "ORDER BY ID LIMIT ? OFFSET ?";
query += "ORDER BY ID DESC LIMIT ? OFFSET ?";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
int paramIdx = 1;

@ -78,7 +78,7 @@ public class SQLServerCertificateDAOImpl extends AbstractCertificateDAOImpl {
isCertificateUsernameProvided = true;
}
query += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
query += "ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
int paramIdx = 1;

@ -429,19 +429,34 @@ public class CertificateGenerator {
generateCertificate(byteArrayInputStream);
if (reqCert != null && reqCert.getSerialNumber() != null) {
log.debug("looking up certificate for serial: " + reqCert.getSerialNumber().toString());
CertificateResponse lookUpCertificate = keyStoreReader.getCertificateBySerial(
reqCert.getSerialNumber().toString());
if (log.isDebugEnabled()) {
log.debug("looking up certificate for serial: " + reqCert.getSerialNumber().toString());
}
String orgUnit = CommonUtil.getSubjectDnAttribute(reqCert,
CertificateManagementConstants.ORG_UNIT_ATTRIBUTE);
CertificateResponse lookUpCertificate;
if (CommonUtil.isScepOrgUnit(orgUnit)) {
int tenantId = Integer.parseInt(orgUnit.split(("_"))[1]);
lookUpCertificate = keyStoreReader.getCertificateBySerial(reqCert.getSerialNumber().toString(),
tenantId);
} else {
lookUpCertificate = keyStoreReader.getCertificateBySerial(
reqCert.getSerialNumber().toString());
}
if (lookUpCertificate != null && lookUpCertificate.getCertificate() != null) {
log.debug("certificate found for serial: " + reqCert.getSerialNumber()
.toString());
if (log.isDebugEnabled()) {
log.debug("certificate found for serial: " + reqCert.getSerialNumber()
.toString());
}
Certificate certificate = (Certificate) Serializer.deserialize(lookUpCertificate.getCertificate());
if (certificate instanceof X509Certificate) {
return (X509Certificate) certificate;
}
} else {
log.debug("certificate not found for serial: " + reqCert.getSerialNumber()
.toString());
if (log.isDebugEnabled()) {
log.debug("certificate not found for serial: " + reqCert.getSerialNumber()
.toString());
}
}
}
@ -464,7 +479,6 @@ public class CertificateGenerator {
log.error(errorMsg);
throw new KeystoreException(errorMsg, e);
}
return null;
}

@ -35,6 +35,8 @@ public final class CertificateManagementConstants {
public static final String DES_EDE = "DESede";
public static final String CONF_LOCATION = "conf.location";
public static final String DEFAULT_PRINCIPAL = "O=WSO2, OU=Mobile, C=LK";
public static final String ORG_UNIT_ATTRIBUTE = "OU=";
public static final String ORG_UNIT_TENANT_PREFIX = "tenant_";
public static final String RSA_PRIVATE_KEY_BEGIN_TEXT = "-----BEGIN RSA PRIVATE KEY-----\n";
public static final String RSA_PRIVATE_KEY_END_TEXT = "-----END RSA PRIVATE KEY-----";
public static final String EMPTY_TEXT = "";

@ -17,7 +17,11 @@
*/
package io.entgra.device.mgt.core.certificate.mgt.core.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
@ -42,4 +46,47 @@ public class CommonUtil {
public static synchronized BigInteger generateSerialNumber() {
return BigInteger.valueOf(System.currentTimeMillis());
}
/**
* Returns the value of the given attribute from the subject distinguished name. eg: "entgra.net"
* from "CN=entgra.net"
* @param requestCertificate {@link X509Certificate} that needs to extract an attribute from
* @param attribute the attribute name that needs to be extracted from the cert. eg: "CN="
* @return the value of the attribute
*/
public static String getSubjectDnAttribute(X509Certificate requestCertificate, String attribute) {
String distinguishedName = requestCertificate.getSubjectDN().getName();
if (StringUtils.isNotEmpty(distinguishedName)) {
String[] dnSplits = distinguishedName.split(",");
for (String dnSplit : dnSplits) {
if (dnSplit.contains(attribute)) {
String[] cnSplits = dnSplit.split("=");
if (StringUtils.isNotEmpty(cnSplits[1])) {
return cnSplits[1];
}
}
}
}
return null;
}
/**
* Checks if the organizational unit (OU) attribute has a valid tenant id in order to verify that it is
* a SCEP certificate. eg: OU=tenant_1
* <br/><br/>
* Refer to engineering mail SCEP implementation for Android
* @param orgUnit organizational unit (OU) of the certificate
* @return true if it is a valid SCEP org unit else false
*/
public static boolean isScepOrgUnit(String orgUnit) {
if (StringUtils.isNotEmpty(orgUnit)) {
if (orgUnit.contains(CertificateManagementConstants.ORG_UNIT_TENANT_PREFIX)) {
String[] orgUnitArray = orgUnit.split(("_"));
if (orgUnitArray.length > 1) {
return NumberUtils.isNumber(orgUnitArray[1]);
}
}
}
return false;
}
}

@ -151,9 +151,9 @@ public class DeviceStatusManagementServiceImpl implements DeviceStatusManagement
if (metadataDAO.isExist(tenantId, MetadataConstants.IS_DEVICE_STATUS_CHECK_META_KEY)) {
// Add default device status check metadata entries
metadataDAO.updateMetadata(tenantId, constructDeviceStatusCheckMetadata(isChecked));
MetadataManagementDAOFactory.commitTransaction();
return true;
}
MetadataManagementDAOFactory.commitTransaction();
} catch (MetadataManagementDAOException e) {
MetadataManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while updating device status check metadata entry.";

@ -546,14 +546,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
int updatedRows = enrollmentDAO.updateEnrollment(device.getEnrolmentInfo(), tenantId);
boolean isEnableDeviceStatusCheck = deviceStatusManagementService.getDeviceStatusCheck(tenantId);
boolean isValidState = deviceStatusManagementService.isDeviceStatusValid(device.getType(),
device.getEnrolmentInfo().getStatus().name(),tenantId);
if (updatedRows == 1 && !deviceStatusManagementService.getDeviceStatusCheck(tenantId)){
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
} else if (updatedRows ==1 && isEnableDeviceStatusCheck && isValidState ) {
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
}
addDeviceStatus(deviceStatusManagementService, tenantId, updatedRows, device.getEnrolmentInfo(),
device.getType());
DeviceManagementDAOFactory.commitTransaction();
log.info("Device enrollment modified successfully",
@ -672,13 +666,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
DeviceStatusManagementService deviceStatusManagementService = DeviceManagementDataHolder
.getInstance().getDeviceStatusManagementService();
int updatedRows = enrollmentDAO.updateEnrollment(device.getEnrolmentInfo(), tenantId);
boolean isEnableDeviceStatusCheck = deviceStatusManagementService.getDeviceStatusCheck(tenantId);
boolean isValidState = deviceStatusManagementService.isDeviceStatusValid(device.getType(),device.getEnrolmentInfo().getStatus().name(),tenantId);
if (updatedRows == 1 && !deviceStatusManagementService.getDeviceStatusCheck(tenantId)){
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
} else if (updatedRows ==1 && isEnableDeviceStatusCheck && isValidState ) {
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
}
addDeviceStatus(deviceStatusManagementService, tenantId, updatedRows, device.getEnrolmentInfo(), device.getType());
DeviceManagementDAOFactory.commitTransaction();
this.removeDeviceFromCache(deviceId);
@ -3475,17 +3463,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
String type = deviceIdentifier.getType();
DeviceStatusManagementService deviceStatusManagementService = DeviceManagementDataHolder
.getInstance().getDeviceStatusManagementService();
DeviceManagementDAOFactory.commitTransaction();
if (updatedRows > 0) {
isUpdatedEnrollment = true;
}
boolean isEnableDeviceStatusCheck = deviceStatusManagementService.getDeviceStatusCheck(tenantId);
boolean isValidState = deviceStatusManagementService.isDeviceStatusValid(type, enrolmentInfo.getStatus().name(), tenantId);
if (updatedRows == 1 && !deviceStatusManagementService.getDeviceStatusCheck(tenantId)) {
enrollmentDAO.addDeviceStatus(enrolmentInfo.getId(), enrolmentInfo.getStatus());
} else if (updatedRows == 1 && isEnableDeviceStatusCheck && isValidState) {
enrollmentDAO.addDeviceStatus(enrolmentInfo.getId(), enrolmentInfo.getStatus());
}
addDeviceStatus(deviceStatusManagementService, tenantId, updatedRows, enrolmentInfo, type);
DeviceManagementDAOFactory.commitTransaction();
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
@ -3503,6 +3485,24 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return isUpdatedEnrollment;
}
/**
* Save the status according to status check(allowed device status)
* Before invoking this method the calling function should have started a transaction
* @param deviceStatusManagementService instance of deviceStatusManagementService
* @param tenantId ID of the tenant
* @param updatedRows number of updated rows
* @param enrolmentInfo enrollment info of the device
* @param type type of the device
*/
private void addDeviceStatus(DeviceStatusManagementService deviceStatusManagementService, int tenantId,
int updatedRows,EnrolmentInfo enrolmentInfo,String type)
throws MetadataManagementException, DeviceManagementDAOException {
boolean isEnableDeviceStatusCheck = deviceStatusManagementService.getDeviceStatusCheck(tenantId);
boolean isValidState = deviceStatusManagementService.isDeviceStatusValid(type, enrolmentInfo.getStatus().name(), tenantId);
if (updatedRows == 1 && (!isEnableDeviceStatusCheck || isValidState)) {
enrollmentDAO.addDeviceStatus(enrolmentInfo.getId(), enrolmentInfo.getStatus());
}
}
private int getTenantId() {
return CarbonContext.getThreadLocalCarbonContext().getTenantId();
@ -4523,13 +4523,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
DeviceStatusManagementService deviceStatusManagementService = DeviceManagementDataHolder
.getInstance().getDeviceStatusManagementService();
int updatedRows = enrollmentDAO.updateEnrollment(device.getEnrolmentInfo(), tenantId);
boolean isEnableDeviceStatusCheck = deviceStatusManagementService.getDeviceStatusCheck(tenantId);
boolean isValidState = deviceStatusManagementService.isDeviceStatusValid(type, String.valueOf(EnrolmentInfo.Status.REMOVED),tenantId);
if (updatedRows == 1 && !deviceStatusManagementService.getDeviceStatusCheck(tenantId)){
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
} else if (updatedRows ==1 && isEnableDeviceStatusCheck && isValidState ) {
enrollmentDAO.addDeviceStatus(device.getEnrolmentInfo().getId(), device.getEnrolmentInfo().getStatus());
}
addDeviceStatus(deviceStatusManagementService, tenantId, updatedRows, device.getEnrolmentInfo(),
type);
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while dis-enrolling device: " +

@ -37,6 +37,8 @@ import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
@ -44,6 +46,10 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
@ -61,6 +67,8 @@ public class LoginHandler extends HttpServlet {
private static String uiConfigUrl;
private static String iotCoreUrl;
private static String kmManagerUrl;
private static String adminUsername;
private static String adminPassword;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
@ -87,14 +95,14 @@ public class LoginHandler extends HttpServlet {
LoginCache loginCache = HandlerUtil.getLoginCache(httpSession);
OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, username);
OAuthApp oAuthApp = loginCache.getOAuthAppCache(oAuthAppCacheKey);
if (oAuthApp == null) {
initializeAdminCredentials();
ArrayList<String> supportedGrantTypes = new ArrayList<>();
supportedGrantTypes.add(HandlerConstants.PASSWORD_GRANT_TYPE);
supportedGrantTypes.add(HandlerConstants.REFRESH_TOKEN_GRANT_TYPE);
ClassicHttpRequest apiRegEndpoint = ClassicRequestBuilder.post(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT)
.setEntity(HandlerUtil.constructAppRegPayload(tags, applicationName,
username, password, null, supportedGrantTypes))
adminUsername, adminPassword, null, supportedGrantTypes))
.setHeader(org.apache.hc.core5.http.HttpHeaders.CONTENT_TYPE,
org.apache.hc.core5.http.ContentType.APPLICATION_JSON.toString())
.setHeader(org.apache.hc.core5.http.HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder().encodeToString((username + HandlerConstants.COLON + password).getBytes()))
@ -143,6 +151,10 @@ public class LoginHandler extends HttpServlet {
log.error("Error occurred while sending the response into the socket. ", e);
} catch (JsonSyntaxException e) {
log.error("Error occurred while parsing the response. ", e);
} catch (ParserConfigurationException e) {
log.error("Error while creating the document builder. ");
} catch (SAXException e) {
log.error("Error while parsing xml file. ", e);
} catch (LoginException e) {
log.error("Error occurred while getting token data. ", e);
}
@ -251,4 +263,21 @@ public class LoginHandler extends HttpServlet {
.build();
return HandlerUtil.execute(tokenEndpoint);
}
/**
* Initialize the admin credential variables
*
* @throws ParserConfigurationException - Throws when error occur during initializing the document builder
* @throws IOException - Throws when error occur during document parsing
* @throws SAXException - Throws when error occur during document parsing
*/
private void initializeAdminCredentials() throws ParserConfigurationException, IOException, SAXException {
File userMgtConf = new File("repository/conf/user-mgt.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(userMgtConf);
adminUsername = doc.getElementsByTagName("UserName").item(0).getTextContent();
adminPassword = doc.getElementsByTagName("Password").item(0).getTextContent();
}
}

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.ui.request.interceptor.beans;
public class ErrorResponse {
private int code;
private String data;
private int status;
public ErrorResponse(int code, String data, int status) {
this.code = code;
this.data = data;
this.status = status;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}

@ -20,17 +20,16 @@ package io.entgra.device.mgt.core.ui.request.interceptor.util;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.entgra.device.mgt.core.ui.request.interceptor.beans.AuthData;
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ErrorResponse;
import io.entgra.device.mgt.core.ui.request.interceptor.cache.LoginCache;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
@ -227,16 +226,37 @@ public class HandlerUtil {
proxyResponse.setExecutorResponse(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil
.getStatusKey(HandlerConstants.INTERNAL_ERROR_CODE));
}
JsonNode dataNode = proxyResponse.getData();
String responseData = extractDataAsString(dataNode);
resp.setStatus(proxyResponse.getCode());
resp.setContentType(ContentType.APPLICATION_JSON.getMimeType());
resp.setCharacterEncoding(Consts.UTF_8.name());
proxyResponse.setExecutorResponse(null);
proxyResponse.setData(null);
ErrorResponse errorResponse = new ErrorResponse(
proxyResponse.getCode(),
responseData,
proxyResponse.getStatus()
);
try (PrintWriter writer = resp.getWriter()) {
writer.write(gson.toJson(proxyResponse));
writer.write(gson.toJson(errorResponse));
}
}
/**
* Extracts a string representation from the given JsonNode.
*
* @param dataNode the JsonNode from which to extract the string representation (can be null).
* @return the string representation of the JsonNode, or null if the dataNode is null.
*/
private static String extractDataAsString(JsonNode dataNode) {
if (dataNode == null) {
return null;
}
return dataNode.isTextual() ? dataNode.asText() : dataNode.toString();
}
/**
* Handle error requests with custom error codes.
*
@ -772,9 +792,7 @@ public class HandlerUtil {
try {
finalNode = objectMapper.readTree(content);
} catch (JsonProcessingException e) {
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("message", content);
finalNode = objectMapper.valueToTree(objectNode);
finalNode = new TextNode(content);
}
}
return finalNode;

@ -392,7 +392,6 @@
<Scope>win:ops:os-updates-info</Scope>
<Scope>win:microsoft-store:search</Scope>
<Scope>win:updates:read</Scope>
<Scope>win:update:modify</Scope>
<Scope>admin:tenant:view</Scope>
<Scope>dm:admin:devices:usage:view</Scope>
<Scope>and:ops:clear-app</Scope>
@ -428,6 +427,12 @@
<Scope>dm:admin:cea:sync</Scope>
<Scope>am:pub:app:upload</Scope>
<Scope>dm:devices:ops:status:update</Scope>
<Scope>tm:tags:view</Scope>
<Scope>tm:tags:create</Scope>
<Scope>tm:tags:update</Scope>
<Scope>tm:tags:delete</Scope>
<Scope>tm:tags:mapping:create</Scope>
<Scope>tm:tags:mapping:delete</Scope>
</Scopes>
<SSOConfiguration>
<Issuer>device-mgt</Issuer>

Loading…
Cancel
Save