Merge branch 'support-4.1.15' into 'support-4.1.15'

Fix error in unmanaged app uninstall

See merge request entgra-support/support-carbon-device-mgt!46
4.x.x
Pahansith Gunathilake 4 years ago
commit ae92a985fa

@ -24,6 +24,7 @@ import org.wso2.carbon.device.application.mgt.common.AppLifecycleState;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
import org.wso2.carbon.device.application.mgt.common.dto.CategoryDTO;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO;
import org.wso2.carbon.device.application.mgt.common.dto.TagDTO;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO;
@ -491,6 +492,9 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
+ " from the database");
}
try {
if (packageNames.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",
@ -826,9 +830,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
log.debug("Request received in DAO Layer to get category ids for given category names");
}
try {
List<Integer> tagIds = new ArrayList<>();
if (categoryNames.isEmpty()) {
return tagIds;
}
Connection conn = this.getDBConnection();
int index = 1;
List<Integer> tagIds = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT AP_APP_CATEGORY.ID AS ID FROM AP_APP_CATEGORY WHERE AP_APP_CATEGORY.CATEGORY IN (",
") AND TENANT_ID = ?");
@ -1117,9 +1124,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
log.debug("Request received in DAO Layer to get tag ids for given tag names");
}
try {
List<Integer> tagIds = new ArrayList<>();
if (tagNames.isEmpty()) {
return tagIds;
}
Connection conn = this.getDBConnection();
int index = 1;
List<Integer> tagIds = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT AP_APP_TAG.ID AS ID FROM AP_APP_TAG WHERE AP_APP_TAG.TAG IN (",
") AND TENANT_ID = ?");

@ -564,6 +564,11 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements
public List<ApplicationReleaseDTO> getReleaseByPackages(List<String> packages, int tenantId) throws
ApplicationManagementDAOException {
List<ApplicationReleaseDTO> releaseDTOs = new ArrayList<>();
if (packages.isEmpty()) {
return releaseDTOs;
}
String sql = "SELECT "
+ "AR.ID AS RELEASE_ID, "
+ "AR.DESCRIPTION AS RELEASE_DESCRIPTION, "
@ -600,7 +605,6 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements
}
statement.setInt(index, tenantId);
try (ResultSet resultSet = statement.executeQuery()) {
List<ApplicationReleaseDTO> releaseDTOs = new ArrayList<>();
while (resultSet.next()) {
releaseDTOs.add(DAOUtil.constructAppReleaseDTO(resultSet));
}

@ -110,6 +110,9 @@ public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
+ "application. Commenting user: " + username + " and tenant-id: " + tenantId);
}
try {
if (appReleaseIds.isEmpty()) {
return false;
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT rv.ID FROM AP_APP_REVIEW rv WHERE rv.AP_APP_RELEASE_ID IN (",
@ -283,6 +286,9 @@ public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
log.debug("DAO request is received to Get all active application reviews.");
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT " + "AP_APP_REVIEW.ID AS ID, "
@ -336,6 +342,9 @@ public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
log.debug("DAO request is received to Get all active application reviews of user " + username);
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
@ -473,6 +482,10 @@ public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
log.debug("DAO request is received to Get all application rating values of an application.");
}
try {
List<Integer> reviews = new ArrayList<>();
if (uuids.isEmpty()) {
return reviews;
}
int index = 1;
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
@ -487,7 +500,6 @@ public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
}
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
List<Integer> reviews = new ArrayList<>();
while (rs.next()) {
reviews.add(rs.getInt("RATING"));
}

@ -97,6 +97,9 @@ public class OracleReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all active application reviews.");
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT " + "AP_APP_REVIEW.ID AS ID, "
@ -150,6 +153,9 @@ public class OracleReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all active application reviews of user " + username);
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
@ -203,6 +209,10 @@ public class OracleReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all application rating values of an application.");
}
try {
List<Integer> reviews = new ArrayList<>();
if (uuids.isEmpty()) {
return reviews;
}
int index = 1;
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
@ -217,7 +227,6 @@ public class OracleReviewDAOImpl extends GenericReviewDAOImpl {
}
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
List<Integer> reviews = new ArrayList<>();
while (rs.next()) {
reviews.add(rs.getInt("RATING"));
}

@ -97,6 +97,9 @@ public class SQLServerReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all active application reviews.");
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT " + "AP_APP_REVIEW.ID AS ID, "
@ -150,6 +153,9 @@ public class SQLServerReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all active application reviews of user " + username);
}
try {
if (releaseIds.isEmpty()) {
return new ArrayList<>();
}
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
@ -203,6 +209,10 @@ public class SQLServerReviewDAOImpl extends GenericReviewDAOImpl {
log.debug("DAO request is received to Get all application rating values of an application.");
}
try {
List<Integer> reviews = new ArrayList<>();
if (uuids.isEmpty()) {
return reviews;
}
int index = 1;
Connection conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
@ -217,7 +227,6 @@ public class SQLServerReviewDAOImpl extends GenericReviewDAOImpl {
}
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
List<Integer> reviews = new ArrayList<>();
while (rs.next()) {
reviews.add(rs.getInt("RATING"));
}

@ -383,9 +383,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
log.debug("Request received in DAO Layer to get device subscriptions for given device ids.");
}
try {
Map<Integer, DeviceSubscriptionDTO> deviceSubscriptionDTOHashMap = new HashMap<>();
if (deviceIds.isEmpty()) {
return deviceSubscriptionDTOHashMap;
}
Connection conn = this.getDBConnection();
int index = 1;
Map<Integer, DeviceSubscriptionDTO> deviceSubscriptionDTOHashMap = new HashMap<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
+ "DS.ID AS ID, "
@ -439,9 +442,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
log.debug("Request received in DAO Layer to get already subscribed users for given list of user names.");
}
try {
List<String> subscribedUsers = new ArrayList<>();
if (users.isEmpty()) {
return subscribedUsers;
}
Connection conn = this.getDBConnection();
int index = 1;
List<String> subscribedUsers = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT US.USER_NAME AS USER_NAME "
+ "FROM AP_USER_SUBSCRIPTION US "
@ -479,9 +485,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
log.debug("Request received in DAO Layer to get already subscribed role names for given list of roles.");
}
try {
List<String> subscribedRoles = new ArrayList<>();
if (roles.isEmpty()) {
return subscribedRoles;
}
Connection conn = this.getDBConnection();
int index = 1;
List<String> subscribedUsers = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT RS.ROLE_NAME AS ROLE "
+ "FROM AP_ROLE_SUBSCRIPTION RS "
@ -496,11 +505,11 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
subscribedUsers.add(rs.getString("ROLE"));
subscribedRoles.add(rs.getString("ROLE"));
}
}
}
return subscribedUsers;
return subscribedRoles;
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to getg subscribed roles for given role "
+ "names.";
@ -520,9 +529,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
log.debug("Request received in DAO Layer to get already subscribed groups for given list of groups.");
}
try {
List<String> subscribedGroups = new ArrayList<>();
if (groups.isEmpty()) {
return subscribedGroups;
}
Connection conn = this.getDBConnection();
int index = 1;
List<String> subscribedUsers = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT GS.GROUP_NAME AS GROUP_NAME "
+ "FROM AP_GROUP_SUBSCRIPTION GS "
@ -537,11 +549,11 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
subscribedUsers.add(rs.getString("GROUP_NAME"));
subscribedGroups.add(rs.getString("GROUP_NAME"));
}
}
}
return subscribedUsers;
return subscribedGroups;
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already subscribed groups for given "
+ "group names.";
@ -562,9 +574,12 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
log.debug("Request received to DAO Layer to get already subscribed dvice Ids for given list of device Ids.");
}
try {
List<Integer> subscribedDevices = new ArrayList<>();
if (deviceIds.isEmpty()) {
return subscribedDevices;
}
Connection conn = this.getDBConnection();
int index = 1;
List<Integer> subscribedDevices = new ArrayList<>();
StringJoiner joiner = new StringJoiner(",",
"SELECT DS.ID AS DEVICE_SUBSCRIPTION_ID "
+ "FROM AP_DEVICE_SUBSCRIPTION DS "
@ -695,6 +710,9 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
public boolean updateDeviceSubStatus(int deviceId, List<Integer> deviceSubIds, String status, int tenantId)
throws ApplicationManagementDAOException {
try {
if (deviceSubIds.isEmpty()) {
return false;
}
Connection conn = this.getDBConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",

@ -380,6 +380,9 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Device> devices = new ArrayList<>();
if (deviceProps.isEmpty()) {
return devices;
}
try {
List<List<String>> outputLists = new ArrayList<>();
List<String> deviceList = null;
@ -935,6 +938,9 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
throws DeviceManagementDAOException {
List<Device> devices = new ArrayList<>();
try {
if (deviceStatuses.isEmpty()) {
return devices;
}
Connection conn = this.getConnection();
StringJoiner joiner = new StringJoiner(",","SELECT "
+ "e1.OWNER, "
@ -1222,6 +1228,9 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
Connection conn;
PreparedStatement stmt = null;
try {
if (devices.isEmpty()) {
return false;
}
conn = this.getConnection();
StringBuilder sql = new StringBuilder("UPDATE DM_ENROLMENT SET STATUS = ? WHERE DEVICE_ID IN " +
"(SELECT d.ID FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.DEVICE_IDENTIFICATION IN (");
@ -1913,6 +1922,10 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
int counter = 0;
List<Device> devices = new ArrayList<>();
if (deviceIdentifiers.isEmpty()) {
return devices;
}
StringJoiner joiner = new StringJoiner(",",
"SELECT "
+ "d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, "
@ -1961,6 +1974,10 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
int counter = 0;
List<Device> devices = new ArrayList<>();
if (deviceIdentifiers.isEmpty() || statuses.isEmpty()) {
return devices;
}
StringJoiner statusJoiner = new StringJoiner(",", "e.STATUS IN (", ") ");
while (counter < statuses.size()) {
statusJoiner.add("?");

@ -68,6 +68,9 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
public List<EventConfig> getEventsOfGroups(List<Integer> groupIds, int tenantId) throws EventManagementDAOException {
try {
List<EventConfig> eventList = new ArrayList<>();
if (groupIds.isEmpty()) {
return eventList;
}
Connection conn = this.getConnection();
String sql = "SELECT " +
"E.ID AS EVENT_ID, " +
@ -145,6 +148,9 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
@Override
public void deleteEventGroupMappingRecordsByEventIds(List<Integer> eventsIdsToDelete) throws EventManagementDAOException {
try {
if (eventsIdsToDelete.isEmpty()) {
return;
}
Connection conn = this.getConnection();
String sql = "DELETE FROM DM_DEVICE_EVENT_GROUP_MAPPING WHERE EVENT_ID IN (%s)";
String inClause = String.join(", ", Collections.nCopies(eventsIdsToDelete.size(), "?"));
@ -166,6 +172,9 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
@Override
public void deleteEventGroupMappingRecordsByGroupIds(List<Integer> groupIdsToDelete) throws EventManagementDAOException {
try {
if (groupIdsToDelete.isEmpty()) {
return;
}
Connection conn = this.getConnection();
String sql = "DELETE FROM DM_DEVICE_EVENT_GROUP_MAPPING WHERE GROUP_ID IN (%s)";
String inClause = String.join(", ", Collections.nCopies(groupIdsToDelete.size(), "?"));
@ -230,6 +239,9 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
public List<EventConfig> getEventsById(List<Integer> eventIdList) throws EventManagementDAOException {
try {
List<EventConfig> eventList = new ArrayList<>();
if (eventIdList.isEmpty()) {
return eventList;
}
Connection conn = this.getConnection();
String sql = "SELECT " +
"ID AS EVENT_ID, " +
@ -269,6 +281,9 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
public List<Integer> getGroupsOfEvents(List<Integer> eventIdList) throws EventManagementDAOException {
try {
List<Integer> groupIdList = new ArrayList<>();
if (eventIdList.isEmpty()) {
return groupIdList;
}
Connection conn = this.getConnection();
String sql = "SELECT " +
"GROUP_ID " +

@ -772,6 +772,9 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
throws GroupManagementDAOException {
List<Device> devices = new ArrayList<>();
try {
if (deviceStatuses.isEmpty()) {
return devices;
}
Connection conn = GroupManagementDAOFactory.getConnection();
StringJoiner joiner = new StringJoiner(",","SELECT "
+ "d1.DEVICE_ID, "

@ -421,6 +421,9 @@ public class GeofenceDAOImpl implements GeofenceDAO {
public Map<Integer, List<EventConfig>> getEventsOfGeoFences(List<Integer> geofenceIds) throws DeviceManagementDAOException {
try {
Map<Integer, List<EventConfig>> geoFenceEventMap = new HashMap<>();
if (geofenceIds.isEmpty()) {
return geoFenceEventMap;
}
Connection conn = this.getConnection();
String sql = "SELECT " +
"E.ID AS EVENT_ID, " +
@ -490,6 +493,9 @@ public class GeofenceDAOImpl implements GeofenceDAO {
public Set<GeoFenceGroupMap> getGroupIdsOfGeoFences(List<Integer> fenceIds) throws DeviceManagementDAOException {
try {
Set<GeoFenceGroupMap> geoFenceGroupSet = new HashSet<>();
if (fenceIds.isEmpty()) {
return geoFenceGroupSet;
}
Connection conn = this.getConnection();
String sql = "SELECT " +
"FENCE_ID, " +

@ -883,6 +883,10 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
Connection conn;
try {
List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) {
return devices;
}
conn = this.getConnection();
int index = 1;
@ -937,7 +941,6 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setInt(index, limitValue);
try (ResultSet rs = ps.executeQuery()) {
List<Device> devices = new ArrayList<>();
while (rs.next()) {
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
}
@ -956,6 +959,9 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException {
try {
if (deviceIds.isEmpty()) {
return 0;
}
Connection conn = this.getConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",

@ -853,6 +853,10 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
Connection conn;
try {
List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) {
return devices;
}
conn = this.getConnection();
int index = 1;
@ -907,7 +911,6 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setInt(index, limitValue);
try (ResultSet rs = ps.executeQuery()) {
List<Device> devices = new ArrayList<>();
while (rs.next()) {
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
}
@ -926,6 +929,9 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException {
try {
if (deviceIds.isEmpty()) {
return 0;
}
Connection conn = this.getConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",

@ -833,6 +833,10 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
Connection conn;
try {
List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) {
return devices;
}
conn = this.getConnection();
int index = 1;
@ -887,7 +891,6 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setInt(index, limitValue);
try (ResultSet rs = ps.executeQuery()) {
List<Device> devices = new ArrayList<>();
while (rs.next()) {
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
}
@ -906,6 +909,9 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException {
try {
if (deviceIds.isEmpty()) {
return 0;
}
Connection conn = this.getConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",

@ -699,6 +699,10 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
Connection conn;
try {
List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) {
return devices;
}
conn = this.getConnection();
int index = 1;
@ -753,7 +757,6 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setInt(index, limitValue);
try (ResultSet rs = ps.executeQuery()) {
List<Device> devices = new ArrayList<>();
while (rs.next()) {
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
}
@ -1039,6 +1042,9 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException {
try {
if (deviceIds.isEmpty()) {
return 0;
}
Connection conn = this.getConnection();
int index = 1;
StringJoiner joiner = new StringJoiner(",",

@ -24,6 +24,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import io.entgra.ui.request.interceptor.beans.AuthData;
import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.exceptions.LoginException;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
import io.entgra.ui.request.interceptor.util.HandlerUtil;
@ -74,6 +77,13 @@ public class LoginHandler extends HttpServlet {
JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray();
JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray();
// Check if OAuth app cache exists. If not create a new application.
LoginCacheManager loginCacheManager = new LoginCacheManager();
loginCacheManager.initializeCacheManager();
OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
OAuthApp oAuthApp = loginCacheManager.getOAuthAppCache(oAuthAppCacheKey);
if (oAuthApp == null) {
HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT);
apiRegEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder()
.encodeToString((username + HandlerConstants.COLON + password).getBytes()));
@ -86,14 +96,42 @@ public class LoginHandler extends HttpServlet {
HandlerUtil.handleError(resp, clientAppResponse);
return;
}
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED && getTokenAndPersistInSession(req, resp,
clientAppResponse.getData(), scopes)) {
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) {
JsonParser jsonParser = new JsonParser();
JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData());
String clientId = null;
String clientSecret = null;
String encodedClientApp = null;
if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
encodedClientApp = Base64.getEncoder()
.encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes());
oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
oAuthApp = new OAuthApp(
HandlerConstants.PUBLISHER_APPLICATION_NAME,
username,
clientId,
clientSecret,
encodedClientApp
);
loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
}
if (getTokenAndPersistInSession(req, resp, clientId, clientSecret, encodedClientApp, scopes)) {
ProxyResponse proxyResponse = new ProxyResponse();
proxyResponse.setCode(HttpStatus.SC_OK);
HandlerUtil.handleSuccess(resp, proxyResponse);
return;
}
}
HandlerUtil.handleError(resp, null);
} else {
getTokenAndPersistInSession(req, resp, oAuthApp.getClientId(), oAuthApp.getClientSecret(), oAuthApp.getEncodedClientApp(), scopes);
}
} catch (IOException e) {
log.error("Error occurred while sending the response into the socket. ", e);
} catch (JsonSyntaxException e) {
@ -103,25 +141,23 @@ public class LoginHandler extends HttpServlet {
}
}
/***
/**
* Generates token from token endpoint and persists them inside the session
*
* @param req - {@link HttpServletRequest}
* @param clientAppResult - clientAppResult
* @param scopes - scopes defied in the application-mgt.xml
* @throws LoginException - login exception throws when getting token result
* @param resp - {@link HttpServletResponse}
* @param clientId - clientId of the OAuth app
* @param clientSecret - clientSecret of the OAuth app
* @param encodedClientApp - Base64 encoded clientId:clientSecret.
* @param scopes - User scopes JSON Array
* @return boolean response
* @throws LoginException - Throws if any error occurs while getting login response
*/
private boolean getTokenAndPersistInSession(HttpServletRequest req, HttpServletResponse resp,
String clientAppResult, JsonArray scopes) throws LoginException {
String clientId, String clientSecret, String encodedClientApp,
JsonArray scopes) throws LoginException {
JsonParser jsonParser = new JsonParser();
try {
JsonElement jClientAppResult = jsonParser.parse(clientAppResult);
if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
String encodedClientApp = Base64.getEncoder()
.encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes());
ProxyResponse tokenResultResponse = getTokenResult(encodedClientApp, scopes);
@ -154,7 +190,6 @@ public class LoginHandler extends HttpServlet {
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
return true;
}
}
return false;
} catch (IOException e) {
throw new LoginException("Error occurred while sending the response into the socket", e);

@ -23,6 +23,9 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
import io.entgra.ui.request.interceptor.util.HandlerUtil;
import org.apache.commons.lang.text.StrSubstitutor;
@ -72,24 +75,62 @@ public class SsoLoginHandler extends HttpServlet {
private static String encodedAdminCredentials;
private static String encodedClientApp;
private static String applicationId;
private static String applicationName;
private static String baseContextPath;
private JsonObject uiConfigJsonObject;
private HttpSession httpSession;
private LoginCacheManager loginCacheManager;
private OAuthApp oAuthApp;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
try {
httpSession = req.getSession(false);
if (httpSession != null) {
httpSession.invalidate();
}
httpSession = req.getSession(true);
initializeAdminCredentials();
baseContextPath = req.getContextPath();
applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler"));
// Check if oauth app cache is available
loginCacheManager = new LoginCacheManager();
loginCacheManager.initializeCacheManager();
oAuthApp = loginCacheManager.getOAuthAppCache(
new OAuthAppCacheKey(applicationName, adminUsername)
);
if (oAuthApp == null) {
dynamicClientRegistration(req, resp);
String clientId = httpSession.getAttribute("clientId").toString();
}
String clientId = oAuthApp.getClientId();
JsonArray scopesSsoJson = uiConfigJsonObject.get("scopes").getAsJsonArray();
String scopesSsoString = HandlerUtil.getScopeString(scopesSsoJson);
String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK;
persistAuthSessionData(req, oAuthApp.getClientId(), oAuthApp.getClientSecret(),
oAuthApp.getEncodedClientApp(), scopesSsoString);
resp.sendRedirect(iotsCoreUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
"?response_type=code" +
"&client_id=" + clientId +
"&state=" +
"&scope=openid " + scopesSsoString +
"&redirect_uri=" + loginCallbackUrl);
} catch (IOException e) {
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);
}
}
/***
@ -101,17 +142,6 @@ public class SsoLoginHandler extends HttpServlet {
*/
private void dynamicClientRegistration(HttpServletRequest req, HttpServletResponse resp) {
try {
File userMgtConf = new File("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();
baseContextPath = req.getContextPath();
String applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler"));
String iotsCorePort = System.getProperty("iot.core.https.port");
if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
@ -124,14 +154,7 @@ public class SsoLoginHandler extends HttpServlet {
+ HandlerConstants.COLON + iotsCorePort;
String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
httpSession = req.getSession(false);
if (httpSession != null) {
httpSession.invalidate();
}
httpSession = req.getSession(true);
uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray();
JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray();
@ -153,19 +176,22 @@ public class SsoLoginHandler extends HttpServlet {
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) {
JsonParser jsonParser = new JsonParser();
JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData());
String clientId = null;
String clientSecret = null;
if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
encodedClientApp = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());
String redirectUrl = req.getParameter("redirect");
httpSession = req.getSession(false);
httpSession.setAttribute("clientId", clientId);
httpSession.setAttribute("clientSecret", clientSecret);
httpSession.setAttribute("encodedClientApp", encodedClientApp);
httpSession.setAttribute("scope", HandlerUtil.getScopeString(scopes));
httpSession.setAttribute("redirectUrl", redirectUrl);
String scopesString = HandlerUtil.getScopeString(scopes);
persistAuthSessionData(req, clientId, clientSecret, encodedClientApp, scopesString);
}
// cache the oauth app credentials
OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, adminUsername);
oAuthApp = new OAuthApp(applicationName, adminUsername, clientId, clientSecret, encodedClientApp);
loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
}
// Get the details of the registered application
@ -221,7 +247,6 @@ public class SsoLoginHandler extends HttpServlet {
if (updateApplicationGrantTypesEndpointResponse.getCode() == HttpStatus.SC_OK) {
return;
}
HandlerUtil.handleError(resp, null);
} catch (IOException e) {
log.error("Error occurred while sending the response into the socket. ", e);
@ -234,6 +259,43 @@ public class SsoLoginHandler extends HttpServlet {
}
}
/**
* 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("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();
}
/**
* Persist the Auth data inside the session
*
* @param req - Http Servlet request
* @param clientId - Client ID of the SP
* @param clientSecret - Client secret of the SP
* @param encodedClientApp - Base64 encoded clientId:clientSecret.
* @param scopes - User scopes
*/
private void persistAuthSessionData(HttpServletRequest req, String clientId, String clientSecret,
String encodedClientApp, String scopes) {
httpSession = req.getSession(false);
httpSession.setAttribute("clientId", clientId);
httpSession.setAttribute("clientSecret", clientSecret);
httpSession.setAttribute("encodedClientApp", encodedClientApp);
httpSession.setAttribute("scope", scopes);
httpSession.setAttribute("redirectUrl", req.getParameter("redirect"));
}
/***
* Generates payload for application grant_type update payload
*
@ -311,7 +373,7 @@ public class SsoLoginHandler extends HttpServlet {
*/
private void updateSaasApp(String appName) throws ParserConfigurationException, IOException, SAXException {
File getAppRequestXmlFile = new File(HandlerConstants.PAYLOADS_DIR + "/get-app-request.xml");
String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT;;
String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT;
HttpPost getApplicationEndpoint = new HttpPost(identityAppMgtUrl);
getApplicationEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC +

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
/**
* Contains necessary functions to manage oAuth app cache during login handling
*/
public class LoginCacheManager {
private CacheManager cacheManager = null;
private Cache<OAuthAppCacheKey, OAuthApp> cache = null;
/**
* Initialize the cache manager if it is not already initialized
*/
public void initializeCacheManager() {
cacheManager = Caching.getCacheManagerFactory().getCacheManager(HandlerConstants.LOGIN_CACHE);
}
/**
* Persists OAuth app cache if it is not already persisted
*
* @param oAuthAppCacheKey - The identifier key of the cache
* @param oAuthApp - The value of the cache which contains OAuth app data
*/
public void addOAuthAppToCache(OAuthAppCacheKey oAuthAppCacheKey, OAuthApp oAuthApp) {
cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
cache.put(oAuthAppCacheKey, oAuthApp);
}
/**
* Retrieves the OAuth app cache
*
* @param oAuthAppCacheKey - The key to identify the cache
* @return - Returns OAuthApp object
*/
public OAuthApp getOAuthAppCache(OAuthAppCacheKey oAuthAppCacheKey) {
cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
return cache.get(oAuthAppCacheKey);
}
}

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
/**
* The data object used for Login Cache
*/
public class OAuthApp {
private String appName;
private String appOwner;
private String clientId;
private String clientSecret;
private String encodedClientApp;
public OAuthApp(String appName, String appOwner, String clientId, String clientSecret, String encodedClientApp) {
this.appName = appName;
this.appOwner = appOwner;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.encodedClientApp = encodedClientApp;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppOwner() {
return appOwner;
}
public void setAppOwner(String appOwner) {
this.appOwner = appOwner;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getEncodedClientApp() {
return encodedClientApp;
}
public void setEncodedClientApp(String encodedClientApp) {
this.encodedClientApp = encodedClientApp;
}
}

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
import java.util.Objects;
/**
* The key object used for Login Cache
*/
public class OAuthAppCacheKey {
private String appName;
private String appOwner;
private volatile int hashCode;
public OAuthAppCacheKey(String appName, String appOwner) {
this.appName = appName;
this.appOwner = appOwner;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppOwner() {
return appOwner;
}
public void setAppOwner(String appOwner) {
this.appOwner = appOwner;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj instanceof OAuthAppCacheKey) {
final OAuthAppCacheKey other = (OAuthAppCacheKey) obj;
String thisId = this.appName + "-" + this.appOwner;
String otherId = other.appName + "-" + other.appOwner;
return thisId.equals(otherId);
}
return false;
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(appName, appOwner);
}
return hashCode;
}
}

@ -55,6 +55,7 @@ public class HandlerConstants {
public static final String PASSWORD_GRANT_TYPE = "password";
public static final String JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
public static final String PRODUCTION_KEY = "PRODUCTION";
public static final String LOGIN_CACHE = "LOGIN_CACHE";
public static final String SCHEME_SEPARATOR = "://";
public static final String COLON = ":";

Loading…
Cancel
Save