Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
prerna.auth.utils.SecurityEngineUtils Maven / Gradle / Ivy
package prerna.auth.utils;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.javatuples.Pair;
import com.google.gson.Gson;
import prerna.auth.AccessPermissionEnum;
import prerna.auth.AccessToken;
import prerna.auth.AuthProvider;
import prerna.auth.User;
import prerna.engine.api.IEngine;
import prerna.engine.api.IRawSelectWrapper;
import prerna.engine.impl.SmssUtilities;
import prerna.query.querystruct.SelectQueryStruct;
import prerna.query.querystruct.filters.AndQueryFilter;
import prerna.query.querystruct.filters.OrQueryFilter;
import prerna.query.querystruct.filters.SimpleQueryFilter;
import prerna.query.querystruct.joins.IRelation;
import prerna.query.querystruct.joins.SubqueryRelationship;
import prerna.query.querystruct.selectors.QueryColumnOrderBySelector;
import prerna.query.querystruct.selectors.QueryColumnSelector;
import prerna.query.querystruct.selectors.QueryFunctionHelper;
import prerna.query.querystruct.selectors.QueryFunctionSelector;
import prerna.query.querystruct.selectors.QueryIfSelector;
import prerna.rdf.engine.wrappers.WrapperManager;
import prerna.sablecc2.om.PixelDataType;
import prerna.util.ConnectionUtils;
import prerna.util.Constants;
import prerna.util.DIHelper;
import prerna.util.QueryExecutionUtility;
import prerna.util.Utility;
import prerna.util.sql.AbstractSqlQueryUtil;
public class SecurityEngineUtils extends AbstractSecurityUtils {
private static final Logger classLogger = LogManager.getLogger(SecurityEngineUtils.class);
/**
* Add an entire database into the security db
* @param engineId
*
* PLEASE DEFINE GLOBAL {@link #addEngine(String, boolean, User)}
*/
@Deprecated
public static void addEngine(String engineId, User user) {
if(ignoreDatabase(engineId)) {
// dont add local master or security db to security db
return;
}
// default engine is not global
addEngine(engineId, false, user);
}
/**
* Add an entire database into the security db
* @param engineId
*/
public static void addEngine(String engineId, boolean global, User user) {
if(ignoreDatabase(engineId)) {
// dont add local master or security db to security db
return;
}
String smssFile = DIHelper.getInstance().getEngineProperty(engineId + "_" + Constants.STORE) + "";
Properties prop = Utility.loadProperties(smssFile);
String engineName = prop.getProperty(Constants.ENGINE_ALIAS);
if(engineName == null) {
engineName = engineId;
}
boolean engineExists = containsEngineId(engineId);
if(engineExists) {
Object[] typeAndCost = getEngineTypeAndSubTypeAndCost(prop);
updateEngineTypeAndSubType(engineId, (IEngine.CATALOG_TYPE) typeAndCost[0], (String) typeAndCost[1]);
classLogger.info("Security database already contains engine of type "
+ typeAndCost[0] + " with unique id = " + Utility.cleanLogString(SmssUtilities.getUniqueName(prop)));
return;
} else {
Object[] typeAndCost = getEngineTypeAndSubTypeAndCost(prop);
addEngine(engineId, engineName, (IEngine.CATALOG_TYPE) typeAndCost[0], (String) typeAndCost[1], (String) typeAndCost[2], global, user);
}
// TODO: need to see when we should be updating the database metadata
// if(engineExists) {
// // update database properties anyway ... in case global was shifted for example
// updateDatabase(databaseId, databaseName, typeAndCost[0], typeAndCost[1], global);
// }
classLogger.info("Finished adding engine = " + Utility.cleanLogString(engineId));
}
/**
* Utility method to get the engine type, subtype, and cost
* This returns ENGINETYPE as the enum IEngine.CATALOG_TYPE and not the String format it is stored in
* @param prop
* @return
*/
public static Object[] getEngineTypeAndSubTypeAndCost(Properties smssProp) {
IEngine.CATALOG_TYPE engineType = null;
String engineSubType = null;
String engineCost = "$";
String rawType = smssProp.get(Constants.ENGINE_TYPE).toString();
try {
IEngine emptyClass = (IEngine) Class.forName(rawType).newInstance();
engineType = emptyClass.getCatalogType();
engineSubType = emptyClass.getCatalogSubType(smssProp);
} catch(Exception e) {
classLogger.warn("Unknown class name = " + rawType);
}
return new Object[]{engineType, engineSubType, engineCost};
}
/**
* This returns ENGINETYPE as the enum IEngine.CATALOG_TYPE and not the String format it is stored in
* @param engineId
* @return
*/
public static IEngine.CATALOG_TYPE getEngineType(String engineId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineId));
List results = QueryExecutionUtility.flushRsToListOfObjArray(securityDb, qs);
if(results == null || results.isEmpty()) {
throw new IllegalArgumentException("Could not find engine with id " + engineId);
}
Object[] result = results.get(0);
return IEngine.CATALOG_TYPE.valueOf(result[0]+"");
}
/**
* This returns ENGINETYPE as the enum IEngine.CATALOG_TYPE and not the String format it is stored in
* @param engineId
* @return
*/
public static Object[] getEngineTypeAndSubtype(String engineId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineId));
List results = QueryExecutionUtility.flushRsToListOfObjArray(securityDb, qs);
if(results == null || results.isEmpty()) {
throw new IllegalArgumentException("Could not find engine with id " + engineId);
}
Object[] result = results.get(0);
result[0] = IEngine.CATALOG_TYPE.valueOf(result[0]+"");
return results.get(0);
}
/**
*
* @param engineId
* @param engineName
* @param engineType
* @param engineSubType
* @param engineCost
* @param global
* @param user
*/
public static void addEngine(String engineId, String engineName, IEngine.CATALOG_TYPE engineType, String engineSubType, String engineCost, boolean global, User user) {
String query = "INSERT INTO ENGINE (ENGINEID, ENGINENAME, ENGINETYPE, ENGINESUBTYPE, COST, GLOBAL, DISCOVERABLE, CREATEDBY, CREATEDBYTYPE, DATECREATED) "
+ "VALUES (?,?,?,?,?,?,?,?,?,?)";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(query);
int parameterIndex = 1;
ps.setString(parameterIndex++, engineId);
if(engineName == null) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, engineName);
}
ps.setString(parameterIndex++, engineType.toString());
if(engineSubType == null) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, engineSubType);
}
if(engineCost == null) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, engineCost);
}
ps.setBoolean(parameterIndex++, global);
ps.setBoolean(parameterIndex++, false);
if(user != null) {
AuthProvider ap = user.getPrimaryLogin();
AccessToken token = user.getAccessToken(ap);
ps.setString(parameterIndex++, token.getId());
ps.setString(parameterIndex++, ap.toString());
} else {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
}
ps.setTimestamp(parameterIndex++, Utility.getCurrentSqlTimestampUTC());
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
public static void updateEngineTypeAndSubType(String engineId, IEngine.CATALOG_TYPE engineType, String engineSubType) {
String query = "UPDATE ENGINE SET ENGINETYPE=?, ENGINESUBTYPE=? WHERE ENGINEID=?";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(query);
int parameterIndex = 1;
ps.setString(parameterIndex++, engineType.toString());
ps.setString(parameterIndex++, engineSubType);
ps.setString(parameterIndex++, engineId);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
public static void addEngineOwner(String engineId, String userId) {
String query = "INSERT INTO ENGINEPERMISSION (USERID, PERMISSION, ENGINEID, VISIBILITY) VALUES (?,?,?,?)";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(query);
int parameterIndex = 1;
ps.setString(parameterIndex++, userId);
ps.setInt(parameterIndex++, AccessPermissionEnum.OWNER.getId());
ps.setString(parameterIndex++, engineId);
ps.setBoolean(parameterIndex++, true);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
* Get the database alias for a id
* @return
*/
public static String getEngineAliasForId(String id) {
// String query = "SELECT ENGINENAME FROM ENGINE WHERE ENGINEID='" + id + "'";
// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, query);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", id));
List results = QueryExecutionUtility.flushToListString(securityDb, qs);
if (results.isEmpty()) {
return null;
}
return results.get(0);
}
/**
* Get what permission the user has for a given engine
* @param userId
* @param engineId
* @return
*/
public static String getActualUserEnginePermission(User user, String engineId) {
return SecurityUserEngineUtils.getActualUserEnginePermission(user, engineId);
}
/**
*
* @return
*/
public static List getAllEngineIds() {
return getAllEngineIds(null);
}
/**
* Get a list of the database ids
* @return
*/
public static List getAllEngineIds(List engineTypes) {
// String query = "SELECT DISTINCT ENGINEID FROM ENGINE";
// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, query);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
if(engineTypes != null && !engineTypes.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypes));
}
return QueryExecutionUtility.flushToListString(securityDb, qs);
}
/**
* Get markdown for a given engine
* @param user
* @param engineId
* @return
*/
public static String getEngineMarkdown(User user, String engineId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAVALUE"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", Constants.MARKDOWN));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__ENGINEID", "==", engineId));
{
SelectQueryStruct qs1 = new SelectQueryStruct();
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
{
OrQueryFilter orFilter = new OrQueryFilter();
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", Arrays.asList(true, null), PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", getUserFiltersQs(user)));
qs1.addExplicitFilter(orFilter);
}
qs1.addRelation("ENGINE", "ENGINEPERMISSION", "join");
IRelation subQuery = new SubqueryRelationship(qs1, "ENGINE", "join", new String[] {"ENGINE__ENGINEID", "ENGINEMETA__ENGINEID", "="});
qs.addRelation(subQuery);
}
return QueryExecutionUtility.flushToString(securityDb, qs);
}
/**
* Get the engine permissions for a specific user
* @param singleUserId
* @param engineId
* @return
*/
public static Integer getUserEnginePermission(String singleUserId, String engineId) {
return SecurityUserEngineUtils.getUserEnginePermission(singleUserId, engineId);
}
/**
* Get the request pending database permission for a specific user
* @param singleUserId
* @param databaseId
* @return
*/
public static Integer getUserAccessRequestEnginePermission(String userId, String databaseId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEACCESSREQUEST__PERMISSION"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__REQUEST_USERID", "==", userId));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__ENGINEID", "==", databaseId));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__APPROVER_DECISION", "==", null));
return QueryExecutionUtility.flushToInteger(securityDb, qs);
}
/**
* Approving user access requests and giving user access in permissions
* @param userId
* @param userType
* @param engineId
* @param requests
*/
public static void approveEngineUserAccessRequests(User user, String engineId, List> requests, String endDate) throws IllegalAccessException{
// make sure user has right permission level to approve access requests
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// get user permissions of all requests
List permissions = new ArrayList();
for(Map i:requests){
permissions.add(i.get("permission"));
}
// if user is not an owner, check to make sure they cannot grant owner access
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalArgumentException("You cannot grant user access to others.");
} else {
if(!AccessPermissionEnum.isOwner(userPermissionLvl) && permissions.contains("OWNER")) {
throw new IllegalArgumentException("As a non-owner, you cannot grant owner access.");
}
}
Timestamp startDate = Utility.getCurrentSqlTimestampUTC();
Timestamp verifiedEndDate = null;
if (endDate != null) {
verifiedEndDate = AbstractSecurityUtils.calculateEndDate(endDate);
}
// bulk delete
String deleteQ = "DELETE FROM ENGINEPERMISSION WHERE USERID=? AND ENGINEID=?";
PreparedStatement deletePs = null;
try {
deletePs = securityDb.getPreparedStatement(deleteQ);
for(int i=0; i userDetails = User.getPrimaryUserIdAndTypePair(user);
try {
insertPs = securityDb.getPreparedStatement(insertQ);
for(int i=0; i> getDisplayDatabaseOwnersAndEditors(String databaseId) {
return SecurityUserEngineUtils.getDisplayEngineOwnersAndEditors(databaseId);
}
/**
* Retrieve the list of users for a given database
* @param user
* @param engineId
* @param searchParam
* @param permission
* @param limit
* @param offset
* @return
* @throws IllegalAccessException
*/
public static List> getEngineUsers(User user, String engineId, String searchParam, String permission, long limit, long offset) throws IllegalAccessException {
if(!userCanViewEngine(user, engineId)) {
throw new IllegalAccessException("The user does not have access to view this engine");
}
return SecurityUserEngineUtils.getEngineUsers(engineId, searchParam, permission, limit, offset);
}
/**
*
* @param user
* @param engineId
* @param userId
* @param permission
* @return
* @throws IllegalAccessException
*/
public static long getEngineUsersCount(User user, String engineId, String searchParam, String permission) throws IllegalAccessException {
if(!userCanViewEngine(user, engineId)) {
throw new IllegalAccessException("The user does not have access to view this engine");
}
boolean hasSearchParam = searchParam != null && !(searchParam=searchParam.trim()).isEmpty();
boolean hasPermission = permission != null && !(permission=permission.trim()).isEmpty();
SelectQueryStruct qs = new SelectQueryStruct();
QueryFunctionSelector fSelector = new QueryFunctionSelector();
fSelector.setAlias("count");
fSelector.setFunction(QueryFunctionHelper.COUNT);
fSelector.addInnerSelector(new QueryColumnSelector("SMSS_USER__ID"));
qs.addSelector(fSelector);
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", engineId));
if (hasSearchParam) {
OrQueryFilter or = new OrQueryFilter();
or.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "?like", searchParam));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__NAME", "?like", searchParam));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__USERNAME", "?like", searchParam));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__EMAIL", "?like", searchParam));
qs.addExplicitFilter(or);
}
if (hasPermission) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__PERMISSION", "==", AccessPermissionEnum.getIdByPermission(permission)));
}
qs.addRelation("SMSS_USER", "ENGINEPERMISSION", "inner.join");
qs.addRelation("ENGINEPERMISSION", "PERMISSION", "inner.join");
return QueryExecutionUtility.flushToLong(securityDb, qs);
}
/**
*
* @param user
* @param newUserId
* @param engineId
* @param permission
* @param endDate
* @param usageRestriction
* @param usageFrequency
* @param maxTokens
* @param maxResponseTime
* @throws IllegalAccessException
*/
public static void addEngineUser(User user, String newUserId, String engineId, String permission, String endDate,
String usageRestriction, String usageFrequency, int maxTokens, double maxResponseTime)
throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// make sure user doesn't already exist for this database
if(getUserEnginePermission(newUserId, engineId) != null) {
// that means there is already a value
throw new IllegalArgumentException("This user already has access to this engine. Please edit the existing permission level.");
}
// if i am not an owner
// then i need to check if i can edit this users permission
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
int newPermissionLvl = AccessPermissionEnum.getIdByPermission(permission);
// cannot give some owner permission if i am just an editor
if(AccessPermissionEnum.OWNER.getId() == newPermissionLvl) {
throw new IllegalAccessException("Cannot give owner level access to this engine since you are not currently an owner.");
}
}
Timestamp startDate = Utility.getCurrentSqlTimestampUTC();
Timestamp verifiedEndDate = null;
if (endDate != null) {
verifiedEndDate = AbstractSecurityUtils.calculateEndDate(endDate);
}
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement("INSERT INTO ENGINEPERMISSION (USERID, ENGINEID, VISIBILITY, PERMISSION, PERMISSIONGRANTEDBY, PERMISSIONGRANTEDBYTYPE, DATEADDED, ENDDATE, USAGERESTRICTION, USAGEFREQUENCY, MAXTOKENS, MAXRESPONSETIME) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)");
int parameterIndex = 1;
ps.setString(parameterIndex++, newUserId);
ps.setString(parameterIndex++, engineId);
ps.setBoolean(parameterIndex++, true);
ps.setInt(parameterIndex++, AccessPermissionEnum.getIdByPermission(permission));
ps.setString(parameterIndex++, userDetails.getValue0());
ps.setString(parameterIndex++, userDetails.getValue1());
ps.setTimestamp(parameterIndex++, startDate);
ps.setTimestamp(parameterIndex++, verifiedEndDate);
if(usageRestriction == null || (usageRestriction=usageRestriction.trim()).isEmpty()) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, usageRestriction);
}
if(usageFrequency == null || (usageFrequency=usageFrequency.trim()).isEmpty()) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, usageFrequency);
}
if(maxTokens == 0) {
ps.setNull(parameterIndex++, java.sql.Types.INTEGER);
} else {
ps.setInt(parameterIndex++, maxTokens);
}
if(maxResponseTime == 0.0) {
ps.setNull(parameterIndex++, java.sql.Types.DOUBLE);
} else {
ps.setDouble(parameterIndex++, maxResponseTime);
}
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred adding the user permissions for this engine. Detailed error message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
*
* @param user
* @param engineId
* @param permission
* @throws IllegalAccessException
*/
public static void addEngineUserPermissions(User user, String engineId, List> permission) throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// check to make sure these users do not already have permissions to database
// get list of userids from permission list map
List userIds = permission.stream().map(map -> (String) map.get("userid")).collect(Collectors.toList());
// this returns a list of existing permissions
Map existingUserPermission = SecurityUserEngineUtils.getUserEnginePermissions(userIds, engineId);
if (!existingUserPermission.isEmpty()) {
throw new IllegalArgumentException("The following users already have access to this engine. Please edit the existing permission level: "+String.join(",", existingUserPermission.keySet()));
}
// if user is not an owner, check to make sure they are not adding owner access
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
List permissionList = permission.stream().map(map -> (String) map.get("permission")).collect(Collectors.toList());
if(permissionList.contains("OWNER")) {
throw new IllegalArgumentException("As a non-owner, you cannot add owner user access.");
}
}
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
Timestamp startDate = Utility.getCurrentSqlTimestampUTC();
// insert new user permissions in bulk
String insertQ = "INSERT INTO ENGINEPERMISSION (USERID, ENGINEID, PERMISSION, VISIBILITY, PERMISSIONGRANTEDBY, PERMISSIONGRANTEDBYTYPE, DATEADDED, ENDDATE, USAGERESTRICTION, USAGEFREQUENCY, MAXTOKENS, MAXRESPONSETIME) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(insertQ);
for(int i=0; i thisPermissionMap = permission.get(i);
int parameterIndex = 1;
ps.setString(parameterIndex++, (String) thisPermissionMap.get("userid"));
ps.setString(parameterIndex++, engineId);
ps.setInt(parameterIndex++, AccessPermissionEnum.getIdByPermission((String) thisPermissionMap.get("permission")));
ps.setBoolean(parameterIndex++, true);
ps.setString(parameterIndex++, userDetails.getValue0());
ps.setString(parameterIndex++, userDetails.getValue1());
ps.setTimestamp(parameterIndex++, startDate);
// end date for this user
Timestamp verifiedEndDate = null;
if (thisPermissionMap.get("endDate") != null) {
verifiedEndDate = AbstractSecurityUtils.calculateEndDate((String) thisPermissionMap.get("endDate"));
ps.setTimestamp(parameterIndex++, verifiedEndDate);
} else {
ps.setNull(parameterIndex++, java.sql.Types.TIMESTAMP);
}
// engine usage restrictions
if(thisPermissionMap.get("usageRestriction") != null
&& !((String)thisPermissionMap.get("usageRestriction")).trim().isEmpty()) {
ps.setString(parameterIndex++, ((String)thisPermissionMap.get("usageRestriction")).trim());
} else {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
}
if(thisPermissionMap.get("usageFrequency") != null
&& !((String)thisPermissionMap.get("usageFrequency")).trim().isEmpty()) {
ps.setString(parameterIndex++, ((String)thisPermissionMap.get("usageFrequency")).trim());
} else {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
}
if(thisPermissionMap.get("maxTokens") != null) {
ps.setInt(parameterIndex++, ((Number)thisPermissionMap.get("maxTokens")).intValue());
} else {
ps.setNull(parameterIndex++, java.sql.Types.INTEGER);
}
if(thisPermissionMap.get("maxResponseTime") != null) {
ps.setDouble(parameterIndex++, ((Number)thisPermissionMap.get("maxResponseTime")).doubleValue());
} else {
ps.setNull(parameterIndex++, java.sql.Types.DOUBLE);
}
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred adding the user permissions for this engine. Detailed error message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
*
* @param user
* @param existingUserId
* @param engineId
* @param newPermission
* @param endDate
* @param usageRestriction
* @param usageFrequency
* @param maxTokens
* @param maxResponseTime
* @throws IllegalAccessException
*/
public static void editEngineUserPermission(User user, String existingUserId, String engineId, String newPermission, String endDate, String usageRestriction, String usageFrequency, int maxTokens, double maxResponseTime) throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// make sure we are trying to edit a permission that exists
Integer existingUserPermission = getUserEnginePermission(existingUserId, engineId);
if(existingUserPermission == null) {
throw new IllegalArgumentException("Attempting to modify engine permission for a user who does not currently have access to the engine");
}
int newPermissionLvl = AccessPermissionEnum.getIdByPermission(newPermission);
// if i am not an owner
// then i need to check if i can edit this users permission
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
// not an owner, check if trying to edit an owner or an editor/reader
// get the current permission
if(AccessPermissionEnum.OWNER.getId() == existingUserPermission) {
throw new IllegalAccessException("The user doesn't have the high enough permissions to modify this users engine permission.");
}
// also, cannot give some owner permission if i am just an editor
if(AccessPermissionEnum.OWNER.getId() == newPermissionLvl) {
throw new IllegalAccessException("Cannot give owner level access to this engine since you are not currently an owner.");
}
}
Timestamp startDate = Utility.getCurrentSqlTimestampUTC();
Timestamp verifiedEndDate = null;
if (endDate != null) {
verifiedEndDate = AbstractSecurityUtils.calculateEndDate(endDate);
}
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement("UPDATE ENGINEPERMISSION SET PERMISSION=?, PERMISSIONGRANTEDBY=?, PERMISSIONGRANTEDBYTYPE=?, DATEADDED=?, ENDDATE=?, USAGERESTRICTION=?, USAGEFREQUENCY=?, MAXTOKENS=?, MAXRESPONSETIME=? WHERE USERID=? AND ENGINEID=?");
int parameterIndex = 1;
//SET
ps.setInt(parameterIndex++, newPermissionLvl);
ps.setString(parameterIndex++, userDetails.getValue0());
ps.setString(parameterIndex++, userDetails.getValue1());
ps.setTimestamp(parameterIndex++, startDate);
ps.setTimestamp(parameterIndex++, verifiedEndDate);
if(usageRestriction == null || (usageRestriction=usageRestriction.trim()).isEmpty()) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, usageRestriction);
}
if(usageFrequency == null || (usageFrequency=usageFrequency.trim()).isEmpty()) {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
} else {
ps.setString(parameterIndex++, usageFrequency);
}
if(maxTokens == 0) {
ps.setNull(parameterIndex++, java.sql.Types.INTEGER);
} else {
ps.setInt(parameterIndex++, maxTokens);
}
if(maxResponseTime == 0.0) {
ps.setNull(parameterIndex++, java.sql.Types.DOUBLE);
} else {
ps.setDouble(parameterIndex++, maxResponseTime);
}
//WHERE
ps.setString(parameterIndex++, existingUserId);
ps.setString(parameterIndex++, engineId);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred updating the user permissions for this engine. Detailed error message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
*
* @param user
* @param engineId
* @param permission
* @throws IllegalAccessException
*/
public static void editEngineUserPermissions(User user, String engineId, List> permission) throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this database's permissions.");
}
// get userid of all requests
List existingUserIds = new ArrayList();
for(Map i:permission){
existingUserIds.add((String) i.get("userid"));
}
// get user permissions to edit
Map existingUserPermission = SecurityUserEngineUtils.getUserEnginePermissions(existingUserIds, engineId);
// make sure all users to edit currently has access to database
Set toRemoveUserIds = new HashSet(existingUserIds);
toRemoveUserIds.removeAll(existingUserPermission.keySet());
if (!toRemoveUserIds.isEmpty()) {
throw new IllegalArgumentException("Attempting to modify user permission for the following users who do not currently have access to the database: "+String.join(",", toRemoveUserIds));
}
// if user is not an owner, check to make sure they are not editting owner access
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
List permissionList = new ArrayList<>(existingUserPermission.values());
if(permissionList.contains(AccessPermissionEnum.OWNER.getId())) {
throw new IllegalArgumentException("As a non-owner, you cannot edit access of an owner.");
}
// also make sure, you are not adding an owner
for(Map req : permission) {
if(AccessPermissionEnum.OWNER.getId() == AccessPermissionEnum.getIdByPermission((String) req.get("permission"))) {
throw new IllegalArgumentException("As a non-owner, you cannot give a user access as an owner.");
}
}
}
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
Timestamp startDate = Utility.getCurrentSqlTimestampUTC();
// update user permissions in bulk
String updateQ = "UPDATE ENGINEPERMISSION SET PERMISSION = ?, PERMISSIONGRANTEDBY = ?, PERMISSIONGRANTEDBYTYPE = ?, DATEADDED = ?, ENDDATE = ?, USAGERESTRICTION = ?, USAGEFREQUENCY = ?, MAXTOKENS = ?, MAXRESPONSETIME = ? WHERE USERID = ? AND ENGINEID = ?";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(updateQ);
for(int i=0; i thisPermissionMap = permission.get(i);
int parameterIndex = 1;
//SET
ps.setInt(parameterIndex++, AccessPermissionEnum.getIdByPermission((String) thisPermissionMap.get("permission")));
ps.setString(parameterIndex++, userDetails.getValue0());
ps.setString(parameterIndex++, userDetails.getValue1());
ps.setTimestamp(parameterIndex++, startDate);
// end date for this user
Timestamp verifiedEndDate = null;
if (thisPermissionMap.get("endDate") != null) {
verifiedEndDate = AbstractSecurityUtils.calculateEndDate((String) thisPermissionMap.get("endDate"));
ps.setTimestamp(parameterIndex++, verifiedEndDate);
} else {
ps.setNull(parameterIndex++, java.sql.Types.TIMESTAMP);
}
// engine usage restrictions
if(thisPermissionMap.get("usageRestriction") != null
&& !((String)thisPermissionMap.get("usageRestriction")).trim().isEmpty()) {
ps.setString(parameterIndex++, ((String)thisPermissionMap.get("usageRestriction")).trim());
} else {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
}
if(thisPermissionMap.get("usageRestriction") != null
&& !((String)thisPermissionMap.get("usageFrequency")).trim().isEmpty()) {
ps.setString(parameterIndex++, ((String)thisPermissionMap.get("usageFrequency")).trim());
} else {
ps.setNull(parameterIndex++, java.sql.Types.VARCHAR);
}
if(thisPermissionMap.get("maxTokens") != null) {
ps.setInt(parameterIndex++, ((Number)thisPermissionMap.get("maxTokens")).intValue());
} else {
ps.setNull(parameterIndex++, java.sql.Types.INTEGER);
}
if(thisPermissionMap.get("maxResponseTime") != null) {
ps.setDouble(parameterIndex++, ((Number)thisPermissionMap.get("maxResponseTime")).doubleValue());
} else {
ps.setNull(parameterIndex++, java.sql.Types.DOUBLE);
}
//WHERE
ps.setString(parameterIndex++, (String) thisPermissionMap.get("userid"));
ps.setString(parameterIndex++, engineId);
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred updating the user permissions for this engine. Detailed error message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
* Delete all values
* @param engineId
*/
public static void deleteEngine(String engineId) {
List deletes = new ArrayList<>();
deletes.add("DELETE FROM ENGINE WHERE ENGINEID=?");
// deletes.add("DELETE FROM INSIGHT WHERE ENGINEID=?");
deletes.add("DELETE FROM ENGINEPERMISSION WHERE ENGINEID=?");
deletes.add("DELETE FROM ENGINEMETA WHERE ENGINEID=?");
// deletes.add("DELETE FROM WORKSPACEENGINE WHERE ENGINEID=?");
// deletes.add("DELETE FROM ASSETENGINE WHERE ENGINEID=?");
for(String deleteQuery : deletes) {
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(deleteQuery);
ps.setString(1, engineId);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
}
/**
*
* @param user
* @param editedUserId
* @param engineId
* @return
* @throws IllegalAccessException
*/
public static void removeEngineUser(User user, String existingUserId, String engineId) throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// make sure we are trying to edit a permission that exists
Integer existingUserPermission = getUserEnginePermission(existingUserId, engineId);
if(existingUserPermission == null) {
throw new IllegalArgumentException("Attempting to modify user permission for a user who does not currently have access to the engine");
}
// if i am not an owner
// then i need to check if i can remove this users permission
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
// not an owner, check if trying to edit an owner or an editor/reader
// get the current permission
if(AccessPermissionEnum.OWNER.getId() == existingUserPermission) {
throw new IllegalAccessException("The user doesn't have the high enough permissions to modify this users engine permission.");
}
}
String deleteQuery = "DELETE FROM ENGINEPERMISSION WHERE USERID=? AND ENGINEID=?";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(deleteQuery);
int parameterIndex = 1;
ps.setString(parameterIndex++, existingUserId);
ps.setString(parameterIndex++, engineId);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred removing the user permissions for this engine");
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
*
* @param user
* @param existingUserIds
* @param engineId
* @throws IllegalAccessException
*/
public static void removeEngineUsers(User user, List existingUserIds, String engineId) throws IllegalAccessException {
// make sure user can edit the database
int userPermissionLvl = getMaxUserEnginePermission(user, engineId);
if(!AccessPermissionEnum.isEditor(userPermissionLvl)) {
throw new IllegalAccessException("Insufficient privileges to modify this engine's permissions.");
}
// get user permissions to remove
Map existingUserPermission = SecurityUserEngineUtils.getUserEnginePermissions(existingUserIds, engineId);
// make sure all users to remove currently has access to database
Set toRemoveUserIds = new HashSet(existingUserIds);
toRemoveUserIds.removeAll(existingUserPermission.keySet());
if (!toRemoveUserIds.isEmpty()) {
throw new IllegalArgumentException("Attempting to modify user permission for the following users who do not currently have access to the engine: "+String.join(",", toRemoveUserIds));
}
// if user is not an owner, check to make sure they are not removing owner access
if(!AccessPermissionEnum.isOwner(userPermissionLvl)) {
List permissionList = new ArrayList(existingUserPermission.values());
if(permissionList.contains(AccessPermissionEnum.OWNER.getId())) {
throw new IllegalAccessException("As a non-owner, you cannot remove access of an owner.");
}
}
// first do a delete
String deleteQ = "DELETE FROM ENGINEPERMISSION WHERE USERID=? AND ENGINEID=?";
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(deleteQ);
for(int i=0; i userIdFilters = getUserFiltersQs(user);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", engineId));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIdFilters));
IRawSelectWrapper wrapper = null;
try {
wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
if(wrapper.hasNext()){
// need to update
PreparedStatement ps = securityDb.getPreparedStatement("UPDATE ENGINEPERMISSION SET VISIBILITY=? WHERE USERID=?");
if(ps == null) {
throw new IllegalArgumentException("Error generating prepared statement to set engine visibility");
}
try {
// we will set the permission to read only
for(AuthProvider loginType : user.getLogins()) {
String userId = user.getAccessToken(loginType).getId();
int parameterIndex = 1;
ps.setBoolean(parameterIndex++, visibility);
ps.setString(parameterIndex++, userId);
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw e;
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
} else {
// need to insert
PreparedStatement ps = securityDb.getPreparedStatement("INSERT INTO ENGINEPERMISSION "
+ "(USERID, ENGINEID, VISIBILITY, FAVORITE, PERMISSION) VALUES (?,?,?,?,?)");
if(ps == null) {
throw new IllegalArgumentException("Error generating prepared statement to set engine visibility");
}
try {
// we will set the permission to read only
for(AuthProvider loginType : user.getLogins()) {
String userId = user.getAccessToken(loginType).getId();
int parameterIndex = 1;
ps.setString(parameterIndex++, userId);
ps.setString(parameterIndex++, engineId);
ps.setBoolean(parameterIndex++, visibility);
// default favorite as false
ps.setBoolean(parameterIndex++, false);
ps.setInt(parameterIndex++, 3);
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw e;
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(wrapper != null) {
try {
wrapper.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
}
/**
* Change the user favorite (is favorite / not favorite) for an engine. Without removing its permissions.
* @param user
* @param engineId
* @param visibility
* @throws SQLException
* @throws IllegalAccessException
*/
public static void setEngineFavorite(User user, String engineId, boolean isFavorite) throws SQLException, IllegalAccessException {
if (!engineIsGlobal(engineId)
&& !userCanViewEngine(user, engineId)) {
throw new IllegalAccessException("The user doesn't have the permission to modify his visibility of this engine");
}
Collection userIdFilters = getUserFiltersQs(user);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", engineId));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIdFilters));
IRawSelectWrapper wrapper = null;
try {
wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
if(wrapper.hasNext()){
// need to update
PreparedStatement ps = securityDb.getPreparedStatement("UPDATE ENGINEPERMISSION SET FAVORITE=? WHERE USERID=?");
if(ps == null) {
throw new IllegalArgumentException("Error generating prepared statement to set engine favorites");
}
try {
// we will set the permission to read only
for(AuthProvider loginType : user.getLogins()) {
String userId = user.getAccessToken(loginType).getId();
int parameterIndex = 1;
ps.setBoolean(parameterIndex++, isFavorite);
ps.setString(parameterIndex++, userId);
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw e;
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
} else {
// need to insert
PreparedStatement ps = securityDb.getPreparedStatement("INSERT INTO ENGINEPERMISSION "
+ "(USERID, ENGINEID, VISIBILITY, FAVORITE, PERMISSION) VALUES (?,?,?,?,?)");
if(ps == null) {
throw new IllegalArgumentException("Error generating prepared statement to set engine favorites");
}
try {
// we will set the permission to read only
for(AuthProvider loginType : user.getLogins()) {
String userId = user.getAccessToken(loginType).getId();
int parameterIndex = 1;
ps.setString(parameterIndex++, userId);
ps.setString(parameterIndex++, engineId);
// default visibility as true
ps.setBoolean(parameterIndex++, true);
ps.setBoolean(parameterIndex++, isFavorite);
ps.setInt(parameterIndex++, 3);
ps.addBatch();
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw e;
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(wrapper != null) {
try {
wrapper.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
}
/**
* update the database name
* @param user
* @param engineId
* @param isPublic
* @return
* @throws IllegalAccessException
*/
public static boolean setEngineName(User user, String engineId, String newEngineName) throws IllegalAccessException {
if(!SecurityUserEngineUtils.userIsOwner(user, engineId)) {
throw new IllegalAccessException("The user doesn't have the permission to change the engine name. Only the owner or an admin can perform this action.");
}
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement("UPDATE ENGINE SET ENGINENAME=? WHERE ENGINEID=?");
int parameterIndex = 1;
// SET
ps.setString(parameterIndex++, newEngineName);
// WHERE
ps.setString(parameterIndex++, engineId);
ps.execute();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred updating the engine name");
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/*
* Database Metadata
*/
/**
*
* @return
*/
public static List getAllMetakeys() {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__METAKEY"));
List metakeys = QueryExecutionUtility.flushToListString(securityDb, qs);
return metakeys;
}
/**
* Update the engine metadata
* Will delete existing values and then perform a bulk insert
* @param engineId
* @param insightId
* @param tags
*/
public static void updateEngineMetadata(String engineId, Map metadata) {
// first do a delete
String deleteQ = "DELETE FROM ENGINEMETA WHERE METAKEY=? AND ENGINEID=?";
PreparedStatement deletePs = null;
try {
deletePs = securityDb.getPreparedStatement(deleteQ);
for(String field : metadata.keySet()) {
int parameterIndex = 1;
deletePs.setString(parameterIndex++, field);
deletePs.setString(parameterIndex++, engineId);
deletePs.addBatch();
}
deletePs.executeBatch();
if(!deletePs.getConnection().getAutoCommit()) {
deletePs.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, deletePs);
}
// now we do the new insert with the order of the tags
String query = securityDb.getQueryUtil().createInsertPreparedStatementString("ENGINEMETA", new String[]{"ENGINEID", "METAKEY", "METAVALUE", "METAORDER"});
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement(query);
for(String field : metadata.keySet()) {
Object val = metadata.get(field);
List values = new ArrayList<>();
if(val instanceof List) {
values = (List) val;
} else if(val instanceof Collection) {
values.addAll( (Collection) val);
} else {
values.add(val);
}
for(int i = 0; i < values.size(); i++) {
int parameterIndex = 1;
Object fieldVal = values.get(i);
ps.setString(parameterIndex++, engineId);
ps.setString(parameterIndex++, field);
ps.setString(parameterIndex++, fieldVal + "");
ps.setInt(parameterIndex++, i);
ps.addBatch();
}
}
ps.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
}
}
/**
* Get the wrapper for additional database metadata
* @param engineIds
* @param metaKeys
* @param ignoreMarkdown
* @return
* @throws Exception
*/
public static IRawSelectWrapper getEngineMetadataWrapper(Collection engineIds, List metaKeys, boolean ignoreMarkdown) throws Exception {
SelectQueryStruct qs = new SelectQueryStruct();
// selectors
qs.addSelector(new QueryColumnSelector("ENGINEMETA__ENGINEID"));
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAKEY"));
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAVALUE"));
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAORDER"));
// filters
if(engineIds != null && !engineIds.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__ENGINEID", "==", engineIds));
}
if(metaKeys != null && !metaKeys.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", metaKeys));
}
// exclude markdown metadata due to potential large data size
if(ignoreMarkdown) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "!=", Constants.MARKDOWN));
}
// order
qs.addOrderBy("ENGINEMETA__METAORDER");
IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
return wrapper;
}
/**
* Get the metadata for a specific database
* @param engineId
* @param metaKeys
* @param ignoreMarkdown
* @return
*/
public static Map getAggregateEngineMetadata(String engineId, List metaKeys, boolean ignoreMarkdown) {
Map retMap = new HashMap();
List engineIds = new ArrayList<>();
engineIds.add(engineId);
IRawSelectWrapper wrapper = null;
try {
wrapper = getEngineMetadataWrapper(engineIds, metaKeys, ignoreMarkdown);
while(wrapper.hasNext()) {
Object[] data = wrapper.next().getValues();
String metaKey = (String) data[1];
String metaValue = (String) data[2];
// always send as array
// if multi, send as array
if(retMap.containsKey(metaKey)) {
Object obj = retMap.get(metaKey);
if(obj instanceof List) {
((List) obj).add(metaValue);
} else {
List newList = new ArrayList<>();
newList.add(obj);
newList.add(metaValue);
retMap.put(metaKey, newList);
}
} else {
retMap.put(metaKey, metaValue);
}
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(wrapper != null) {
try {
wrapper.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
return retMap;
}
/**
* Check if the user has access to the engine
* @param engineId
* @param userId
* @return
* @throws Exception
*/
public static boolean checkUserHasAccessToDatabase(String engineId, String userId) throws Exception {
return SecurityUserEngineUtils.checkUserHasAccessToEngine(engineId, userId);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/*
* Copying permissions
*/
/**
* Copy the engine permissions from one engine to another
* @param sourceEngineId
* @param targetEngineId
* @param maxTokens
* @param maxResponseTime
* @param usageRestriction
* @param usageFrequency
* @throws Exception
*/
public static void copyEnginePermissions(String sourceEngineId, String targetEngineId) throws Exception {
String insertTargetEnginePermissionSql = "INSERT INTO ENGINEPERMISSION (ENGINEID, USERID, PERMISSION, VISIBILITY, USAGERESTRICTION, USAGEFREQUENCY, MAXTOKENS, MAXRESPONSETIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement insertTargetEnginePermissionStatement = securityDb.getPreparedStatement(insertTargetEnginePermissionSql);
// grab the permissions, filtered on the source database id
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USERID"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__PERMISSION"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__VISIBILITY"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USAGERESTRICTION"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USAGEFREQUENCY"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__MAXTOKENS"));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__MAXRESPONSETIME"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", sourceEngineId));
IRawSelectWrapper wrapper = null;
try {
wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
while(wrapper.hasNext()) {
Object[] row = wrapper.next().getValues();
// now loop through all the permissions
// but with the target engine id instead of the source engine id
insertTargetEnginePermissionStatement.setString(1, targetEngineId);
insertTargetEnginePermissionStatement.setString(2, (String) row[1]);
insertTargetEnginePermissionStatement.setInt(3, ((Number) row[2]).intValue() );
insertTargetEnginePermissionStatement.setBoolean(4, (Boolean) row[3]);
if(row[4] == null) {
insertTargetEnginePermissionStatement.setNull(5, java.sql.Types.VARCHAR);
} else {
insertTargetEnginePermissionStatement.setString(5, (String) row[4]);
}
if(row[5] == null) {
insertTargetEnginePermissionStatement.setNull(6, java.sql.Types.VARCHAR);
} else {
insertTargetEnginePermissionStatement.setString(6, (String) row[5]);
}
if(row[6] == null) {
insertTargetEnginePermissionStatement.setNull(7, java.sql.Types.INTEGER);
} else {
insertTargetEnginePermissionStatement.setInt(7, ((Number) row[6]).intValue() );
}
if(row[7] == null) {
insertTargetEnginePermissionStatement.setNull(8, java.sql.Types.DOUBLE);
} else {
insertTargetEnginePermissionStatement.setDouble(8, ((Number) row[7]).doubleValue() );
}
// add to batch
insertTargetEnginePermissionStatement.addBatch();
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw e;
} finally {
if(wrapper != null) {
try {
wrapper.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
// first delete the current project permissions
PreparedStatement ps = null;
try {
ps = securityDb.getPreparedStatement("DELETE FROM ENGINEPERMISSION WHERE ENGINEID=?");
int parameterIndex = 1;
ps.setString(parameterIndex++, targetEngineId);
// here we delete
ps.execute();
// now we insert
insertTargetEnginePermissionStatement.executeBatch();
if(!ps.getConnection().getAutoCommit()) {
ps.getConnection().commit();
}
if(!insertTargetEnginePermissionStatement.getConnection().getAutoCommit()) {
insertTargetEnginePermissionStatement.getConnection().commit();
}
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred transferring the engine permissions");
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, ps);
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, insertTargetEnginePermissionStatement);
}
}
/**
* Returns List of users that have no access credentials to a given engine
* @param engineId
* @return
*/
public static List> getEngineUsersNoCredentials(User user, String engineId, String searchTerm, long limit, long offset) throws IllegalAccessException {
/*
* Security check to make sure that the user can view the application provided.
*/
if (!userCanViewEngine(user, engineId)) {
throw new IllegalAccessException("The user does not have access to view this engine");
}
/*
* String Query =
* "SELECT SMSS_USER.ID, SMSS_USER.USERNAME, SMSS_USER.NAME, SMSS_USER.EMAIL FROM SMSS_USER WHERE ID NOT IN
* (SELECT e.USERID FROM ENGINEPERMISSION e WHERE e.ENGINEID = '"+ appID + "' e.PERMISSION IS NOT NULL);"
*/
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("SMSS_USER__ID", "id"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__TYPE", "type"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__USERNAME", "username"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__NAME", "name"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__EMAIL", "email"));
// filter for sub-query
{
SelectQueryStruct subQs = new SelectQueryStruct();
qs.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("SMSS_USER__ID", "!=", subQs));
//Sub-query itself
subQs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USERID"));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID","==",engineId));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__PERMISSION", "!=", null, PixelDataType.NULL_VALUE));
}
if (searchTerm != null && !(searchTerm = searchTerm.trim()).isEmpty()) {
OrQueryFilter or = new OrQueryFilter();
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__ID", "?like", searchTerm));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__NAME", "?like", searchTerm));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__USERNAME", "?like", searchTerm));
or.addFilter(SimpleQueryFilter.makeColToValFilter("SMSS_USER__EMAIL", "?like", searchTerm));
qs.addExplicitFilter(or);
}
qs.addOrderBy(new QueryColumnOrderBySelector("SMSS_USER__NAME"));
qs.addOrderBy(new QueryColumnOrderBySelector("SMSS_USER__EMAIL"));
qs.addOrderBy(new QueryColumnOrderBySelector("SMSS_USER__ID"));
if(limit > 0) {
qs.setLimit(limit);
}
if(offset > 0) {
qs.setOffSet(offset);
}
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Return the engines the user has explicit access to
* @param singleUserId
* @return
*/
public static Set getEngineUserHasExplicitAccess(User user) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
OrQueryFilter orFilter = new OrQueryFilter();
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", getUserFiltersQs(user)));
qs.addExplicitFilter(orFilter);
qs.addRelation("ENGINE", "ENGINEPERMISSION", "left.outer.join");
return QueryExecutionUtility.flushToSetString(securityDb, qs, false);
}
/**
* Return if user has explicit permissions to this engine
* @param user
* @param engineId
* @return
*/
public static boolean userHasExplicitAccess(User user, String engineId) {
return SecurityUserEngineUtils.getUserEnginePermission(user, engineId) != null;
}
/**
* Determine if a user can request a engine
* @param engineId
* @return
*/
public static boolean engineIsDiscoverable(String engineId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", true, PixelDataType.BOOLEAN));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineId));
IRawSelectWrapper wrapper = null;
try {
wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
if(wrapper.hasNext()) {
// if you are here, you can request
return true;
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(wrapper != null) {
try {
wrapper.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
return false;
}
/**
* set user access request
* @param userId
* @param userType
* @param engineId
* @param requestReasonComment
* @param permission
* @param user
*/
public static void setUserAccessRequest(String userId, String userType, String engineId, String requestReasonComment, int permission, User user) {
// first mark previously undecided requests as old
String updateQ = "UPDATE ENGINEACCESSREQUEST SET APPROVER_DECISION = 'OLD' WHERE REQUEST_USERID=? AND REQUEST_TYPE=? AND ENGINEID=? AND APPROVER_DECISION='NEW_REQUEST'";
PreparedStatement updatePs = null;
AbstractSqlQueryUtil securityQueryUtil = securityDb.getQueryUtil();
try {
int index = 1;
updatePs = securityDb.getPreparedStatement(updateQ);
updatePs.setString(index++, userId);
updatePs.setString(index++, userType);
updatePs.setString(index++, engineId);
updatePs.execute();
if(!updatePs.getConnection().getAutoCommit()) {
updatePs.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred while marking old user access request with detailed message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, updatePs);
}
// grab user info who is submitting request
Pair requesterDetails = User.getPrimaryUserIdAndTypePair(user);
// now we do the new insert
String insertQ = "INSERT INTO ENGINEACCESSREQUEST "
+ "(ID, REQUEST_USERID, REQUEST_TYPE, REQUEST_TIMESTAMP, REQUEST_REASON, ENGINEID, PERMISSION, SUBMITTED_BY_USERID, SUBMITTED_BY_TYPE, APPROVER_DECISION) "
+ "VALUES (?,?,?,?,?,?,?,?,?, 'NEW_REQUEST')";
PreparedStatement insertPs = null;
try {
java.sql.Timestamp timestamp = Utility.getCurrentSqlTimestampUTC();
int index = 1;
insertPs = securityDb.getPreparedStatement(insertQ);
insertPs.setString(index++, UUID.randomUUID().toString());
insertPs.setString(index++, userId);
insertPs.setString(index++, userType);
insertPs.setTimestamp(index++, timestamp);
securityQueryUtil.handleInsertionOfClob(insertPs.getConnection(), insertPs, requestReasonComment, index++, new Gson());
insertPs.setString(index++, engineId);
insertPs.setInt(index++, permission);
insertPs.setString(index++, requesterDetails.getValue0());
insertPs.setString(index++, requesterDetails.getValue1());
insertPs.execute();
if(!insertPs.getConnection().getAutoCommit()) {
insertPs.getConnection().commit();
}
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred while adding user access request detailed message = " + e.getMessage());
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, insertPs);
}
}
/**
*
* @param user
* @param engineId
* @return
*/
public static int getUserPendingAccessRequest(User user, String engineId) {
// grab user info who is submitting request
Pair requesterDetails = User.getPrimaryUserIdAndTypePair(user);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEACCESSREQUEST__APPROVER_DECISION"));
qs.addSelector(new QueryColumnSelector("ENGINEACCESSREQUEST__PERMISSION"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__REQUEST_USERID", "==", requesterDetails.getValue0()));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__REQUEST_TYPE", "==", requesterDetails.getValue1()));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEACCESSREQUEST__ENGINEID", "==", engineId));
qs.addOrderBy("ENGINEACCESSREQUEST__REQUEST_TIMESTAMP", "desc");
IRawSelectWrapper it = null;
try {
it = WrapperManager.getInstance().getRawWrapper(securityDb, qs);
while(it.hasNext()) {
Object[] values = it.next().getValues();
String mostRecentAction = (String) values[0];
if(!mostRecentAction.equals("APPROVED") && !mostRecentAction.equals("DENIED") && !mostRecentAction.equals("OLD")) {
return ((Number) values[1]).intValue();
}
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(it != null) {
try {
it.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
return -1;
}
/**
* Get the list of engines the user does not have access to but can request
* @param allUserEngines
* @throws Exception
*/
public static List> getUserRequestableEngines(Collection allUserEngines) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "!=", allUserEngines));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", true, PixelDataType.BOOLEAN));
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
public static List> getEngineInfo(Collection engineFilter) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineFilter));
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Retrieve the engine owner
* @param user
* @param engineId
* @param insightId
* @return
* @throws IllegalAccessException
*/
public static List getEngineOwners(String engineId) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("SMSS_USER__EMAIL", "email"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", engineId));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("PERMISSION__ID", "==", AccessPermissionEnum.OWNER.getId()));
qs.addRelation("SMSS_USER", "ENGINEPERMISSION", "inner.join");
qs.addRelation("ENGINEPERMISSION", "PERMISSION", "inner.join");
qs.addOrderBy(new QueryColumnOrderBySelector("SMSS_USER__ID"));
return QueryExecutionUtility.flushToListString(securityDb, qs);
}
/**
* Get global engines
* @return
*/
public static Set getGlobalEngineIds() {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
return QueryExecutionUtility.flushToSetString(securityDb, qs, false);
}
/**
* Get the list of the database information that the user has access to
*
* @param user
* @param engineTypes
* @param engineIdFilters
* @param favoritesOnly
* @param engineMetadataFilter
* @param permissionFilters
* @param searchTerm
* @param limit
* @param offset
* @return
*/
public static List> getUserEngineList(User user,
List engineTypes,
List engineIdFilters,
Boolean favoritesOnly,
Map engineMetadataFilter,
List permissionFilters,
String searchTerm,
String limit,
String offset) {
String enginePrefix = "ENGINE__";
String groupEnginePermission = "GROUPENGINEPERMISSION__";
Collection userIds = getUserFiltersQs(user);
boolean hasSearchTerm = searchTerm != null && !(searchTerm=searchTerm.trim()).isEmpty();
SelectQueryStruct qs1 = new SelectQueryStruct();
// selectors
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "app_id"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "app_name"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "app_type"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "app_subtype"));
qs1.addSelector(new QueryColumnSelector("ENGINE__COST", "app_cost"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
qs1.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
qs1.addSelector(new QueryColumnSelector("ENGINE__DISCOVERABLE", "database_discoverable"));
qs1.addSelector(new QueryColumnSelector("ENGINE__GLOBAL", "database_global"));
qs1.addSelector(new QueryColumnSelector("ENGINE__CREATEDBY", "database_created_by"));
qs1.addSelector(new QueryColumnSelector("ENGINE__CREATEDBYTYPE", "database_created_by_type"));
qs1.addSelector(new QueryColumnSelector("ENGINE__DATECREATED", "database_date_created"));
qs1.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.LOWER, "ENGINE__ENGINENAME", "low_database_name"));
qs1.addSelector(new QueryColumnSelector("USER_PERMISSIONS__PERMISSION", "user_permission"));
qs1.addSelector(new QueryColumnSelector("GROUP_PERMISSIONS__PERMISSION", "group_permission"));
qs1.addSelector(new QueryColumnSelector("USER_PERMISSIONS__FAVORITE", "database_favorite"));
qs1.addSelector(new QueryColumnSelector("USER_PERMISSIONS__FAVORITE", "app_favorite"));
// this block is for max permissions
// If both null - return null
// if either not null - return the permission value that is not null
// if both not null - return the max permissions (I.E lowest number)
{
AndQueryFilter and = new AndQueryFilter();
and.addFilter(SimpleQueryFilter.makeColToValFilter("GROUP_PERMISSIONS__PERMISSION", "==", null, PixelDataType.CONST_INT));
and.addFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__PERMISSION", "==", null, PixelDataType.CONST_INT));
AndQueryFilter and1 = new AndQueryFilter();
and1.addFilter(SimpleQueryFilter.makeColToValFilter("GROUP_PERMISSIONS__PERMISSION", "!=", null, PixelDataType.CONST_INT));
and1.addFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__PERMISSION", "==", null, PixelDataType.CONST_INT));
AndQueryFilter and2 = new AndQueryFilter();
and2.addFilter(SimpleQueryFilter.makeColToValFilter("GROUP_PERMISSIONS__PERMISSION", "==", null, PixelDataType.CONST_INT));
and2.addFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__PERMISSION", "!=", null, PixelDataType.CONST_INT));
SimpleQueryFilter maxPermFilter = SimpleQueryFilter.makeColToColFilter("USER_PERMISSIONS__PERMISSION", "<", "GROUP_PERMISSIONS__PERMISSION");
QueryIfSelector qis3 = QueryIfSelector.makeQueryIfSelector(maxPermFilter,
new QueryColumnSelector("USER_PERMISSIONS__PERMISSION"),
new QueryColumnSelector("GROUP_PERMISSIONS__PERMISSION"),
"permission"
);
QueryIfSelector qis2 = QueryIfSelector.makeQueryIfSelector(and2,
new QueryColumnSelector("USER_PERMISSIONS__PERMISSION"),
qis3,
"permission"
);
QueryIfSelector qis1 = QueryIfSelector.makeQueryIfSelector(and1,
new QueryColumnSelector("GROUP_PERMISSIONS__PERMISSION"),
qis2,
"permission"
);
QueryIfSelector qis = QueryIfSelector.makeQueryIfSelector(and,
new QueryColumnSelector("USER_PERMISSIONS__PERMISSION"),
qis1,
"permission"
);
qs1.addSelector(qis);
}
// add a join to get the user permission level, if favorite, and the visibility
{
SelectQueryStruct qs2 = new SelectQueryStruct();
qs2.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID", "ENGINEID"));
QueryFunctionSelector castFavorite = QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.CAST, "ENGINEPERMISSION__FAVORITE", "castFavorite");
castFavorite.setDataType(securityDb.getQueryUtil().getIntegerDataTypeName());
qs2.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.MAX, castFavorite, "FAVORITE"));
QueryFunctionSelector castVisibility = QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.CAST, "ENGINEPERMISSION__VISIBILITY", "castVisibility");
castVisibility.setDataType(securityDb.getQueryUtil().getIntegerDataTypeName());
qs2.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.MAX, castVisibility, "VISIBILITY"));
qs2.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.MIN, "ENGINEPERMISSION__PERMISSION", "PERMISSION"));
qs2.addGroupBy(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID", "ENGINEID"));
qs2.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
IRelation subQuery = new SubqueryRelationship(qs2, "USER_PERMISSIONS", "left.outer.join", new String[] {"USER_PERMISSIONS__ENGINEID", "ENGINE__ENGINEID", "="});
qs1.addRelation(subQuery);
}
// add a join to get the group permission level
{
SelectQueryStruct qs3 = new SelectQueryStruct();
qs3.addSelector(new QueryColumnSelector(groupEnginePermission + "ENGINEID", "ENGINEID"));
qs3.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.MIN, groupEnginePermission + "PERMISSION", "PERMISSION"));
qs3.addGroupBy(new QueryColumnSelector(groupEnginePermission + "ENGINEID", "ENGINEID"));
// filter on groups
OrQueryFilter groupEngineOrFilters = new OrQueryFilter();
List logins = user.getLogins();
for(AuthProvider login : logins) {
if(user.getAccessToken(login).getUserGroups().isEmpty()) {
continue;
}
AndQueryFilter andFilter = new AndQueryFilter();
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "TYPE", "==", user.getAccessToken(login).getUserGroupType()));
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "ID", "==", user.getAccessToken(login).getUserGroups()));
groupEngineOrFilters.addFilter(andFilter);
}
if (!groupEngineOrFilters.isEmpty()) {
qs3.addExplicitFilter(groupEngineOrFilters);
} else {
AndQueryFilter andFilter1 = new AndQueryFilter();
andFilter1.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "TYPE", "==", null));
andFilter1.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "ID", "==", null));
qs3.addExplicitFilter(andFilter1);
}
IRelation subQuery = new SubqueryRelationship(qs3, "GROUP_PERMISSIONS", "left.outer.join", new String[] {"GROUP_PERMISSIONS__ENGINEID", "ENGINE__ENGINEID", "="});
qs1.addRelation(subQuery);
}
// filters
if(engineIdFilters != null && !engineIdFilters.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineIdFilters));
}
if(engineTypes != null && !engineTypes.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypes));
}
// filter based on permission filters
if(permissionFilters != null && !permissionFilters.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__PERMISSION", "==", permissionFilters, PixelDataType.CONST_INT));
}
OrQueryFilter orFilter = new OrQueryFilter();
{
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__PERMISSION", "!=", null, PixelDataType.CONST_INT));
qs1.addExplicitFilter(orFilter);
}
// only show those that are visible
// remember, user permissions cast this to int
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__VISIBILITY", "==", Arrays.asList(new Object[] {1, null}), PixelDataType.CONST_INT));
// favorites only
// remember, user permissions cast this to int
if(favoritesOnly) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("USER_PERMISSIONS__FAVORITE", "==", 1, PixelDataType.CONST_INT));
}
// optional word filter on the engine name
if(hasSearchTerm) {
OrQueryFilter searchFilter = new OrQueryFilter();
searchFilter.addFilter(securityDb.getQueryUtil().getSearchRegexFilter("ENGINE__ENGINENAME", searchTerm));
searchFilter.addFilter(securityDb.getQueryUtil().getSearchRegexFilter("ENGINE__ENGINEID", searchTerm));
qs1.addExplicitFilter(searchFilter);
}
// filtering by enginemeta key-value pairs (i.e. :value): for each pair, add in-filter against engineids from subquery
if (engineMetadataFilter!=null && !engineMetadataFilter.isEmpty()) {
for (String k : engineMetadataFilter.keySet()) {
SelectQueryStruct subQs = new SelectQueryStruct();
subQs.addSelector(new QueryColumnSelector("ENGINEMETA__ENGINEID"));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", k));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAVALUE", "==", engineMetadataFilter.get(k)));
qs1.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "==", subQs));
}
}
// group permissions
{
// first lets make sure we have any groups
OrQueryFilter groupEngineOrFilters = new OrQueryFilter();
List logins = user.getLogins();
for(AuthProvider login : logins) {
if(user.getAccessToken(login).getUserGroups().isEmpty()) {
continue;
}
AndQueryFilter andFilter = new AndQueryFilter();
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "TYPE", "==", user.getAccessToken(login).getUserGroupType()));
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermission + "ID", "==", user.getAccessToken(login).getUserGroups()));
groupEngineOrFilters.addFilter(andFilter);
}
// 4.a does the group have explicit access
if(!groupEngineOrFilters.isEmpty()) {
SelectQueryStruct subQs = new SelectQueryStruct();
// store first and fill in sub query after
orFilter.addFilter(SimpleQueryFilter.makeColToSubQuery(enginePrefix + "ENGINEID", "==", subQs));
// we need to have the insight filters
subQs.addSelector(new QueryColumnSelector(groupEnginePermission + "ENGINEID"));
subQs.addExplicitFilter(groupEngineOrFilters);
}
}
// add the sort
qs1.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
Long long_limit = -1L;
Long long_offset = -1L;
if(limit != null && !limit.trim().isEmpty()) {
long_limit = ((Number) Double.parseDouble(limit)).longValue();
}
if(offset != null && !offset.trim().isEmpty()) {
long_offset = ((Number) Double.parseDouble(offset)).longValue();
}
qs1.setLimit(long_limit);
qs1.setOffSet(long_offset);
return QueryExecutionUtility.flushRsToMap(securityDb, qs1);
}
/**
* Get the list of the database ids that the user has access to
* @param user
* @param includeGlobal
* @param includeDiscoverable
* @param includeExistingAccess
* @return
*/
public static List getUserEngineIdList(User user, List engineTypes, boolean includeGlobal, boolean includeDiscoverable, boolean includeExistingAccess) {
String enginePrefix = "ENGINE__";
String enginePermissionPrefix = "ENGINEPERMISSION__";
String groupEnginePermissionPrefix = "GROUPENGINEPERMISSION__";
Collection userIds = getUserFiltersQs(user);
SelectQueryStruct qs1 = new SelectQueryStruct();
// selectors
qs1.addSelector(new QueryColumnSelector(enginePrefix + "ENGINEID", "database_id"));
// filters
OrQueryFilter orFilter = new OrQueryFilter();
if(includeGlobal) {
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter(enginePrefix + "GLOBAL", "==", true, PixelDataType.BOOLEAN));
}
if(includeDiscoverable) {
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter(enginePrefix + "DISCOVERABLE", "==", true, PixelDataType.BOOLEAN));
}
if(engineTypes != null && !engineTypes.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter(enginePrefix + "ENGINETYPE", "==", engineTypes));
}
String existingAccessComparator = "==";
if(!includeExistingAccess) {
existingAccessComparator = "!=";
}
if(!includeExistingAccess && !includeDiscoverable) {
throw new IllegalArgumentException("Fitler combinations can result in ids that the user does not have access to. Please adjust your parameters");
}
{
// user access
SelectQueryStruct qs2 = new SelectQueryStruct();
qs2.addSelector(new QueryColumnSelector(enginePermissionPrefix + "ENGINEID", "ENGINEID"));
qs2.addExplicitFilter(SimpleQueryFilter.makeColToValFilter(enginePermissionPrefix + "USERID", "==", userIds));
orFilter.addFilter(SimpleQueryFilter.makeColToSubQuery(enginePrefix + "ENGINEID", existingAccessComparator, qs2));
}
{
// filter on groups
OrQueryFilter groupEngineOrFilters = new OrQueryFilter();
List logins = user.getLogins();
for(AuthProvider login : logins) {
if(user.getAccessToken(login).getUserGroups().isEmpty()) {
continue;
}
AndQueryFilter andFilter = new AndQueryFilter();
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermissionPrefix + "TYPE", "==", user.getAccessToken(login).getUserGroupType()));
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter(groupEnginePermissionPrefix + "ID", "==", user.getAccessToken(login).getUserGroups()));
groupEngineOrFilters.addFilter(andFilter);
}
if (!groupEngineOrFilters.isEmpty()) {
SelectQueryStruct qs3 = new SelectQueryStruct();
qs3.addSelector(new QueryColumnSelector(groupEnginePermissionPrefix + "ENGINEID", "ENGINEID"));
qs3.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.MIN, groupEnginePermissionPrefix + "PERMISSION", "PERMISSION"));
qs3.addExplicitFilter(groupEngineOrFilters);
orFilter.addFilter(SimpleQueryFilter.makeColToSubQuery(enginePrefix + "ENGINEID", existingAccessComparator, qs3));
}
}
qs1.addExplicitFilter(orFilter);
return QueryExecutionUtility.flushToListString(securityDb, qs1);
}
/**
* Get all the available engine metadata and their counts for given keys
* @param engineFilters
* @param metaKey
* @return
*/
public static List> getAvailableMetaValues(List engineFilters, List metaKeys) {
SelectQueryStruct qs = new SelectQueryStruct();
// selectors
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAKEY"));
qs.addSelector(new QueryColumnSelector("ENGINEMETA__METAVALUE"));
QueryFunctionSelector fSelector = new QueryFunctionSelector();
fSelector.setAlias("count");
fSelector.setFunction(QueryFunctionHelper.COUNT);
fSelector.addInnerSelector(new QueryColumnSelector("ENGINEMETA__METAVALUE"));
qs.addSelector(fSelector);
// filters
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", metaKeys));
if(engineFilters != null && !engineFilters.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__ENGINEID", "==", engineFilters));
}
// group
qs.addGroupBy(new QueryColumnSelector("ENGINEMETA__METAKEY"));
qs.addGroupBy(new QueryColumnSelector("ENGINEMETA__METAVALUE"));
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Get all user database and database ids regardless of it being hidden or not
* @param userId
* @return
*/
public static List> getAllUserDatabaseList(User user) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "app_id"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "app_name"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "app_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "app_subtype"));
qs.addSelector(new QueryColumnSelector("ENGINE__COST", "app_cost"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
List> allGlobalEnginesMap = QueryExecutionUtility.flushRsToMap(securityDb, qs);
SelectQueryStruct qs2 = new SelectQueryStruct();
qs2.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "app_id"));
qs2.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "app_name"));
qs2.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "app_type"));
qs2.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "app_subtype"));
qs2.addSelector(new QueryColumnSelector("ENGINE__COST", "app_cost"));
qs2.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", getUserFiltersQs(user)));
qs2.addRelation("ENGINE", "ENGINEPERMISSION", "inner.join");
List> databaseMap = QueryExecutionUtility.flushRsToMap(securityDb, qs2);
databaseMap.addAll(allGlobalEnginesMap);
return databaseMap;
}
// /**
// * Get the database information
// * @param databaseFilter
// * @return
// */
// public static List> getAllDatabaseList(String databaseFilter) {
// List filters = null;
// if(databaseFilter != null && !databaseFilter.isEmpty()) {
// filters = new ArrayList<>();
// filters.add(databaseFilter);
// }
// return getAllDatabaseList(filters);
// }
// /**
// * Get the database information
// * @param databaseFilter
// * @return
// */
// public static List> getAllDatabaseList(List databaseFilters) {
// List engineTypes = new ArrayList<>();
// engineTypes.add(IEngine.CATALOG_TYPE.DATABASE.toString());
// return getAllEngineList(engineTypes, databaseFilters, null, null, null, null);
// }
// /**
// * Get database information
// * @param databaseFilters
// * @param engineMetadataFilter
// * @param searchTerm
// * @param limit
// * @param offset
// * @return
// */
// public static List> getAllEngineList(List engineType, List engineIdFilters, Map engineMetadataFilter,
// String searchTerm, String limit, String offset) {
//
// boolean hasSearchTerm = searchTerm != null && !(searchTerm=searchTerm.trim()).isEmpty();
//
// SelectQueryStruct qs = new SelectQueryStruct();
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "app_id"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "app_name"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "app_type"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "app_subtype"));
// qs.addSelector(new QueryColumnSelector("ENGINE__COST", "app_cost"));
//
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
// qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
// qs.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
// qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBY", "database_created_by"));
// qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBYTYPE", "database_created_by_type"));
// qs.addSelector(new QueryColumnSelector("ENGINE__DATECREATED", "database_date_created"));
// qs.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.LOWER, "ENGINE__ENGINENAME", "low_database_name"));
// if(engineType != null && !engineType.isEmpty()) {
// qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineType));
// }
// if(engineIdFilters != null && !engineIdFilters.isEmpty()) {
// qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineIdFilters));
// }
// // optional word filter on the engine name
// if(hasSearchTerm) {
// securityDb.getQueryUtil().appendSearchRegexFilter(qs, "ENGINE__ENGINENAME", searchTerm);
// }
// // filtering by enginemeta key-value pairs (i.e. :value): for each pair, add in-filter against engineids from subquery
// if (engineMetadataFilter!=null && !engineMetadataFilter.isEmpty()) {
// for (String k : engineMetadataFilter.keySet()) {
// SelectQueryStruct subQs = new SelectQueryStruct();
// subQs.addSelector(new QueryColumnSelector("ENGINEMETA__ENGINEID"));
// subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", k));
// subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAVALUE", "==", engineMetadataFilter.get(k)));
// qs.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "==", subQs));
// }
// }
// qs.addRelation("ENGINE", "ENGINEPERMISSION", "left.outer.join");
// // add the sort
// qs.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
//
// Long long_limit = -1L;
// Long long_offset = -1L;
// if(limit != null && !limit.trim().isEmpty()) {
// long_limit = ((Number) Double.parseDouble(limit)).longValue();
// }
// if(offset != null && !offset.trim().isEmpty()) {
// long_offset = ((Number) Double.parseDouble(offset)).longValue();
// }
// qs.setLimit(long_limit);
// qs.setOffSet(long_offset);
//
// return QueryExecutionUtility.flushRsToMap(securityDb, qs);
// }
/**
* Get the list of the engine information that the user has access to
* @param userId
* @return
*/
public static List> getUserEngineList(User user, String engineFilter, List engineTypeFilter) {
// String userFilters = getUserFilters(user);
// String filter = createFilter(engineFilter);
// String query = "SELECT DISTINCT "
// + "ENGINE.ENGINEID as \"app_id\", "
// + "ENGINE.ENGINENAME as \"app_name\", "
// + "ENGINE.TYPE as \"app_type\", "
// + "ENGINE.COST as \"app_cost\", "
// + "LOWER(ENGINE.ENGINENAME) as \"low_app_name\" "
// + "FROM ENGINE "
// + "LEFT JOIN ENGINEPERMISSION ON ENGINE.ENGINEID=ENGINEPERMISSION.ENGINEID "
// + "WHERE "
// + (!filter.isEmpty() ? ("ENGINE.ENGINEID " + filter + " AND ") : "")
// + "(ENGINEPERMISSION.USERID IN " + userFilters + " OR ENGINE.GLOBAL=TRUE) "
// + "ORDER BY LOWER(ENGINE.ENGINENAME)";
// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, query);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
qs.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
qs.addSelector(new QueryColumnSelector("ENGINE__DISCOVERABLE", "database_discoverable"));
qs.addSelector(new QueryColumnSelector("ENGINE__GLOBAL", "database_global"));
qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBY", "database_created_by"));
qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBYTYPE", "database_created_by_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__DATECREATED", "database_date_created"));
QueryFunctionSelector fun = new QueryFunctionSelector();
fun.setFunction(QueryFunctionHelper.LOWER);
fun.addInnerSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
fun.setAlias("low_database_name");
qs.addSelector(fun);
if(engineFilter != null && !engineFilter.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineFilter));
}
if(engineTypeFilter != null && !engineTypeFilter.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypeFilter));
}
{
OrQueryFilter orFilter = new OrQueryFilter();
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", Arrays.asList(true, null), PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", getUserFiltersQs(user)));
qs.addExplicitFilter(orFilter);
}
qs.addRelation("ENGINE", "ENGINEPERMISSION", "left.outer.join");
qs.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Get the list of the database information that the user has access to
* @param user
* @param engineTypeFilter
* @return
*/
public static List> getUserEngineList(User user, List engineTypeFilter, Integer limit, Integer offset) {
Collection userIds = getUserFiltersQs(user);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "app_id"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "app_name"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "app_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "app_subtype"));
qs.addSelector(new QueryColumnSelector("ENGINE__COST", "app_cost"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
qs.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
QueryFunctionSelector fun = new QueryFunctionSelector();
fun.setFunction(QueryFunctionHelper.LOWER);
fun.addInnerSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
fun.setAlias("low_database_name");
qs.addSelector(fun);
if(engineTypeFilter != null && !engineTypeFilter.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypeFilter));
}
{
OrQueryFilter orFilter = new OrQueryFilter();
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
qs.addExplicitFilter(orFilter);
}
{
SelectQueryStruct subQs = new SelectQueryStruct();
// store first and fill in sub query after
qs.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "!=", subQs));
// fill in the sub query with the necessary column output + filters
subQs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__VISIBILITY", "==", false, PixelDataType.BOOLEAN));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
}
// joins
qs.addRelation("ENGINE", "ENGINEPERMISSION", "left.outer.join");
qs.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
// add the limit and offset
if(limit != null && limit > 0) {
qs.setLimit(limit);
}
if(offset != null && offset > 0) {
qs.setOffSet(offset);
}
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Get the list of the engine information that the user has access to
* @param userId
* @return
*/
public static List> getDiscoverableEngineList(String engineFilter, List engineTypeFilter) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
qs.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBY", "database_created_by"));
qs.addSelector(new QueryColumnSelector("ENGINE__CREATEDBYTYPE", "database_created_by_type"));
qs.addSelector(new QueryColumnSelector("ENGINE__DATECREATED", "database_date_created"));
QueryFunctionSelector fun = new QueryFunctionSelector();
fun.setFunction(QueryFunctionHelper.LOWER);
fun.addInnerSelector(new QueryColumnSelector("ENGINE__ENGINENAME"));
fun.setAlias("low_database_name");
qs.addSelector(fun);
if(engineFilter != null && !engineFilter.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineFilter));
}
if(engineTypeFilter != null && !engineTypeFilter.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypeFilter));
}
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", true, PixelDataType.BOOLEAN));
qs.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Get the list of the database information that the user does not have access to, but is discoverable
*
* @param user
* @param engineTypes
* @param engineFilters
* @param engineMetadataFilter
* @param searchTerm
* @param limit
* @param offset
* @return
*/
public static List> getUserDiscoverableEngineList(User user,
List engineTypes,
List engineFilters,
Map engineMetadataFilter,
String searchTerm, String limit, String offset) {
Collection userIds = getUserFiltersQs(user);
boolean hasSearchTerm = searchTerm != null && !(searchTerm=searchTerm.trim()).isEmpty();
SelectQueryStruct qs1 = new SelectQueryStruct();
// selectors
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINEID", "database_id"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINENAME", "database_name"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINETYPE", "database_type"));
qs1.addSelector(new QueryColumnSelector("ENGINE__ENGINESUBTYPE", "database_subtype"));
qs1.addSelector(new QueryColumnSelector("ENGINE__COST", "database_cost"));
qs1.addSelector(new QueryColumnSelector("ENGINE__DISCOVERABLE", "database_discoverable"));
qs1.addSelector(new QueryColumnSelector("ENGINE__GLOBAL", "database_global"));
qs1.addSelector(new QueryColumnSelector("ENGINE__CREATEDBY", "database_created_by"));
qs1.addSelector(new QueryColumnSelector("ENGINE__CREATEDBYTYPE", "database_created_by_type"));
qs1.addSelector(new QueryColumnSelector("ENGINE__DATECREATED", "database_date_created"));
qs1.addSelector(QueryFunctionSelector.makeFunctionSelector(QueryFunctionHelper.LOWER, "ENGINE__ENGINENAME", "low_database_name"));
// only care about discoverable engines
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__DISCOVERABLE", "==", true, PixelDataType.BOOLEAN));
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", false, PixelDataType.BOOLEAN));
// remove user permission access
{
SelectQueryStruct subQsUser = new SelectQueryStruct();
subQsUser.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
subQsUser.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
qs1.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "!=", subQsUser));
}
{
// remove group permission access
SelectQueryStruct subQsGroup = new SelectQueryStruct();
subQsGroup.addSelector(new QueryColumnSelector("GROUPENGINEPERMISSION__ENGINEID"));
OrQueryFilter orFilter = new OrQueryFilter();
List logins = user.getLogins();
for(AuthProvider login : logins) {
if(user.getAccessToken(login).getUserGroups().isEmpty()) {
continue;
}
AndQueryFilter andFilter = new AndQueryFilter();
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter("GROUPENGINEPERMISSION__TYPE", "==", user.getAccessToken(login).getUserGroupType()));
andFilter.addFilter(SimpleQueryFilter.makeColToValFilter("GROUPENGINEPERMISSION__ID", "==", user.getAccessToken(login).getUserGroups()));
orFilter.addFilter(andFilter);
}
if (!orFilter.isEmpty()) {
subQsGroup.addExplicitFilter(orFilter);
qs1.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "!=", subQsGroup));
}
}
// filters
if(engineFilters != null && !engineFilters.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINEID", "==", engineFilters));
}
if(engineTypes != null && !engineTypes.isEmpty()) {
qs1.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__ENGINETYPE", "==", engineTypes));
}
// optional word filter on the engine name
if(hasSearchTerm) {
OrQueryFilter searchFilter = new OrQueryFilter();
searchFilter.addFilter(securityDb.getQueryUtil().getSearchRegexFilter("ENGINE__ENGINENAME", searchTerm));
searchFilter.addFilter(securityDb.getQueryUtil().getSearchRegexFilter("ENGINE__ENGINEID", searchTerm));
qs1.addExplicitFilter(searchFilter);
}
// filtering by enginemeta key-value pairs (i.e. :value): for each pair, add in-filter against engineids from subquery
if (engineMetadataFilter!=null && !engineMetadataFilter.isEmpty()) {
for (String k : engineMetadataFilter.keySet()) {
SelectQueryStruct subQs = new SelectQueryStruct();
subQs.addSelector(new QueryColumnSelector("ENGINEMETA__ENGINEID"));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAKEY", "==", k));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETA__METAVALUE", "==", engineMetadataFilter.get(k)));
qs1.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "==", subQs));
}
}
// add the sort
qs1.addOrderBy(new QueryColumnOrderBySelector("low_database_name"));
Long long_limit = -1L;
Long long_offset = -1L;
if(limit != null && !limit.trim().isEmpty()) {
long_limit = ((Number) Double.parseDouble(limit)).longValue();
}
if(offset != null && !offset.trim().isEmpty()) {
long_offset = ((Number) Double.parseDouble(offset)).longValue();
}
qs1.setLimit(long_limit);
qs1.setOffSet(long_offset);
return QueryExecutionUtility.flushRsToMap(securityDb, qs1);
}
/**
* Get user engines + global engines
* @param userId
* @return
*/
public static List getFullUserEngineIds(User user) {
// String userFilters = getUserFilters(user);
// String query = "SELECT DISTINCT ENGINEID FROM ENGINEPERMISSION WHERE USERID IN " + userFilters;
// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, query);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", getUserFiltersQs(user)));
List databaseList = QueryExecutionUtility.flushToListString(securityDb, qs);
databaseList.addAll(SecurityEngineUtils.getGlobalEngineIds());
return databaseList.stream().distinct().sorted().collect(Collectors.toList());
}
/**
* Get the visual user databases
* @param userId
* @return
*/
public static List getVisibleUserDatabaseIds(User user) {
Collection userIds = getUserFiltersQs(user);
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINE__ENGINEID"));
{
OrQueryFilter orFilter = new OrQueryFilter();
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINE__GLOBAL", "==", true, PixelDataType.BOOLEAN));
orFilter.addFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
qs.addExplicitFilter(orFilter);
}
{
SelectQueryStruct subQs = new SelectQueryStruct();
// store first and fill in sub query after
qs.addExplicitFilter(SimpleQueryFilter.makeColToSubQuery("ENGINE__ENGINEID", "!=", subQs));
// fill in the sub query with the necessary column output + filters
subQs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID"));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__VISIBILITY", "==", false, PixelDataType.BOOLEAN));
subQs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userIds));
}
// joins
qs.addRelation("ENGINE", "ENGINEPERMISSION", "left.outer.join");
return QueryExecutionUtility.flushToListString(securityDb, qs);
}
/**
*
* @param metakey
* @return
*/
public static List> getMetakeyOptions(String metakey) {
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__METAKEY", "metakey"));
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__SINGLEMULTI", "single_multi"));
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__DISPLAYORDER", "display_order"));
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__DISPLAYOPTIONS", "display_options"));
qs.addSelector(new QueryColumnSelector("ENGINEMETAKEYS__DEFAULTVALUES", "display_values"));
if (metakey != null && !metakey.isEmpty()) {
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEMETAKEYS__METAKEY", "==", metakey));
}
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
*
* @param metaoptions
* @return
*/
public static boolean updateMetakeyOptions(List> metaoptions) {
boolean valid = false;
PreparedStatement insertPs = null;
String tableName = "ENGINEMETAKEYS";
try {
// first truncate table clean
String truncateSql = "DELETE FROM " + tableName + " WHERE 1=1";
securityDb.removeData(truncateSql);
insertPs = securityDb.bulkInsertPreparedStatement(new Object[] {tableName, Constants.METAKEY, Constants.SINGLE_MULTI, Constants.DISPLAY_ORDER, Constants.DISPLAY_OPTIONS} );
// then insert latest options
for (int i = 0; i < metaoptions.size(); i++) {
insertPs.setString(1, (String) metaoptions.get(i).get("metakey"));
insertPs.setString(2, (String) metaoptions.get(i).get("singlemulti"));
insertPs.setInt(3, ((Number) metaoptions.get(i).get("order")).intValue());
insertPs.setString(4, (String) metaoptions.get(i).get("displayoptions"));
insertPs.addBatch();
}
insertPs.executeBatch();
if(!insertPs.getConnection().getAutoCommit()) {
insertPs.getConnection().commit();
}
valid = true;
} catch (SQLException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
ConnectionUtils.closeAllConnectionsIfPooling(securityDb, insertPs);
}
return valid;
}
/**
* Get the engine user permission restriction
* @param user
* @param engineId
* @return
*/
public static List> getEngineUsagePermissionMap(User user, String engineId) {
if (user == null || engineId == null || engineId.trim().isEmpty()) {
return null;
}
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("SMSS_USER__ID", "id"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__TYPE", "type"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__NAME", "name"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__EMAIL", "email"));
qs.addSelector(new QueryColumnSelector("SMSS_USER__MODELUSAGERESTRICTION", Constants.USER_USAGE_RESTRICTION_KEY));
qs.addSelector(new QueryColumnSelector("SMSS_USER__MODELUSAGEFREQUENCY", Constants.USER_MODEL_USAGE_FREQUENCY_KEY));
qs.addSelector(new QueryColumnSelector("SMSS_USER__MODELMAXTOKENS", Constants.USER_MODEL_MAX_TOKEN_KEY));
qs.addSelector(new QueryColumnSelector("SMSS_USER__MODELMAXRESPONSETIME", Constants.USER_MODEL_MAX_RESPONSE_TIME_KEY));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USAGERESTRICTION", Constants.ENGINE_USAGE_RESTRICTION_KEY));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__USAGEFREQUENCY", Constants.ENGINE_USAGE_FREQUENCY_KEY));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__MAXTOKENS", Constants.ENGINE_MAX_TOKEN_KEY));
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__MAXRESPONSETIME", Constants.ENGINE_MAX_RESPONSE_TIME_KEY));
// filter to the engine
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userDetails.getValue0()));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__ENGINEID", "==", engineId));
// relationship between SMSS_USER and ENGINEPERMISSION tables
qs.addRelation("SMSS_USER", "ENGINEPERMISSION", "left.outer.join");
return QueryExecutionUtility.flushRsToMap(securityDb, qs);
}
/**
* Get a list of engine IDs where USAGERESTRICTION is set (not empty or null)
*
* @param user
* @param engineId
* @return
*/
public static List getModelEngineIdsWithRestrictions(User user, String engineId) {
if (user == null || engineId == null || engineId.trim().isEmpty()) {
return null;
}
SelectQueryStruct qs = new SelectQueryStruct();
qs.addSelector(new QueryColumnSelector("ENGINEPERMISSION__ENGINEID", "engineId"));
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USERID", "==", userDetails.getValue0()));
qs.addExplicitFilter(SimpleQueryFilter.makeColToValFilter("ENGINEPERMISSION__USAGERESTRICTION","!=", Arrays.asList("", null) ));
qs.addRelation("SMSS_USER", "ENGINEPERMISSION", "left.outer.join");
return QueryExecutionUtility.flushToListString(securityDb, qs);
}
/**
* Updates the permissions for a user on specific engines by replacing existing
* permissions.
*
* @param user
* @param enginePermissions
* @throws Exception
*/
public static List> updateEngineUserPermissions(User user, List> enginePermissions) throws Exception {
List> newEngines = new ArrayList<>();
Pair userDetails = User.getPrimaryUserIdAndTypePair(user);
PreparedStatement deletePs = null;
PreparedStatement insertPs = null;
try {
// Step 1: Delete existing permissions for the engine
String deleteQuery = "DELETE FROM ENGINEPERMISSION WHERE USERID = ?";
deletePs = securityDb.getPreparedStatement(deleteQuery);
deletePs.setString(1, userDetails.getValue0());
deletePs.execute();
if (!deletePs.getConnection().getAutoCommit()) {
deletePs.getConnection().commit();
}
if(enginePermissions != null && !enginePermissions.isEmpty()) {
String insertQuery = "INSERT INTO ENGINEPERMISSION (USERID, PERMISSION, ENGINEID, DATEADDED) VALUES (?, ?, ?, ?)";
insertPs = securityDb.getPreparedStatement(insertQuery);
Timestamp currentTimestamp = Utility.getCurrentSqlTimestampUTC();
// loop through to add the new permissions
for (Map permissionMap : enginePermissions) {
String engineId = (String) permissionMap.get("engineId");
String engineName = (String) permissionMap.get("engineName");
IEngine.CATALOG_TYPE engineType = (IEngine.CATALOG_TYPE) permissionMap.get("engineType");
String engineSubType = (String) permissionMap.get("engineSubType");
String permission = (String) permissionMap.get("permission");
// Step 2: Validate EngineId exist in Engine table or not
boolean engineExists = engineExists(engineId);
if (!engineExists) {
newEngines.add(permissionMap);
addEngine(engineId, engineName, engineType, engineSubType, "", false, null);
}
// Step 3: Insert new permissions
insertPs.setString(1, userDetails.getValue0());
insertPs.setInt(2, AccessPermissionEnum.getIdByPermission(permission));
insertPs.setString(3, engineId);
insertPs.setTimestamp(4, currentTimestamp);
insertPs.addBatch();
}
insertPs.executeBatch();
if (!insertPs.getConnection().getAutoCommit()) {
insertPs.getConnection().commit();
}
}
return newEngines;
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("An error occurred while updating the user engine permissions in db ");
} finally {
ConnectionUtils.closeAllDbConnectionsIfPooling(securityDb, deletePs, insertPs);
}
}
}