123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- /**
- * Licensed Materials - Property of IBM
- *
- * IBM Cognos Products: CAMAAA
- *
- * (C) Copyright IBM Corp. 2005, 2016
- *
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.ResultSetMetaData;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Locale;
- import com.cognos.CAM_AAA.authentication.IAccount;
- import com.cognos.CAM_AAA.authentication.INamespace;
- import com.cognos.CAM_AAA.authentication.IQueryOption;
- import com.cognos.CAM_AAA.authentication.ISearchFilter;
- import com.cognos.CAM_AAA.authentication.ISearchFilterConditionalExpression;
- import com.cognos.CAM_AAA.authentication.ISearchFilterFunctionCall;
- import com.cognos.CAM_AAA.authentication.ISearchFilterRelationExpression;
- import com.cognos.CAM_AAA.authentication.ISortProperty;
- import com.cognos.CAM_AAA.authentication.QueryResult;
- import com.cognos.CAM_AAA.authentication.UnrecoverableException;
- public class QueryUtil
- {
- private static void addSQLConditionFragment(final StringBuffer sqlCondition, final String columnName, final String likePattern)
- {
- sqlCondition.append(" " + columnName + " LIKE '" + likePattern + "' ESCAPE '!'");
- }
- public static Account createAccount(final ConnectionManager connectionManager, final String userName, final String password)
- throws UnrecoverableException
- {
- final Object[][] data =
- QueryUtil.query(connectionManager.getConnection(),
- "SELECT USERID FROM USERS WHERE USERNAME = ? AND PASSWORD = ?", userName, password);
- final String userID = QueryUtil.getSingleStringResult(data);
- if (null != userID)
- {
- final String userSearchPath = "u:" + userID;
- return connectionManager.getAccountCache().findAccount(userSearchPath);
- }
- throw new UnrecoverableException("Invalid Credentials", "Could not authenticate with the provide credentials");
- }
- public static String escapeSpecialChars(final String str)
- {
- final StringBuffer escapedString = new StringBuffer(str);
- final String bangApostrophe = "!'";
- final String bangPercent = "!%";
-
- for (int i = 0; i < escapedString.length();)
- {
- final char c = escapedString.charAt(i);
- switch (c)
- {
- case '\'':
- escapedString.insert(i, bangApostrophe);
- i += bangApostrophe.length() + 1;
- break;
- case '%':
- escapedString.insert(i, bangPercent);
- i += bangPercent.length() + 1;
- break;
- default:
- i++;
- break;
- }
- }
- return escapedString.toString();
- }
- private static Object[] getDataRow(final ResultSet resultSet) throws SQLException
- {
- final ResultSetMetaData rsMetaData = resultSet.getMetaData();
- final Object[] row = new Object[rsMetaData.getColumnCount()];
- for (int i = 0; i < row.length; ++i)
- row[i] = resultSet.getObject(i + 1);
- return row;
- }
- public static Locale getLocale(final String localeID)
- {
- if (2 > localeID.length())
- return Locale.ENGLISH;
- final String language = localeID.substring(0, 2);
- final int fullLocaleLength = 5;
- if (fullLocaleLength == localeID.length())
- {
- final String country = localeID.substring(3, 5);
- return new Locale(language, country);
- }
- return new Locale(language);
- }
- private static Object[] getMetaDataRow(final ResultSet resultSet) throws SQLException
- {
- final ResultSetMetaData rsMetaData = resultSet.getMetaData();
- final Object[] metaDataRow = new Object[rsMetaData.getColumnCount()];
- for (int i = 0; i < metaDataRow.length; ++i)
- metaDataRow[i] = rsMetaData.getColumnName(i);
- return metaDataRow;
- }
- private static Object[] getSingleRowResult(final Object[][] data)
- {
- if (1 == data.length)
- return data[0];
- return null;
- }
- private static String getSingleStringResult(final Object[][] data)
- {
- final Object[] row = QueryUtil.getSingleRowResult(data);
- if (null != row && 1 == row.length)
- return String.valueOf(row[0]);
- return null;
- }
- public static String getSqlCondition(final ISearchFilter theSearchFilter)
- {
- final String falseCondition = " 1 = 0 ";
- final String trueCondition = "1 = 1 ";
- final StringBuffer sqlCondition = new StringBuffer();
- if (theSearchFilter != null)
- switch (theSearchFilter.getSearchFilterType())
- {
- case ISearchFilter.ConditionalExpression:
- final ISearchFilterConditionalExpression item = (ISearchFilterConditionalExpression) theSearchFilter;
- final String operator = item.getOperator();
- final ISearchFilter[] filters = item.getFilters();
- if (filters.length > 0)
- {
- sqlCondition.append("( ");
- sqlCondition.append(QueryUtil.getSqlCondition(filters[0]));
- for (int i = 1; i < filters.length; i++)
- {
- sqlCondition.append(' ');
- sqlCondition.append(operator);
- sqlCondition.append(' ');
- sqlCondition.append(QueryUtil.getSqlCondition(filters[i]));
- }
- sqlCondition.append(" )");
- }
-
- break;
- case ISearchFilter.FunctionCall:
- final ISearchFilterFunctionCall functionItem = (ISearchFilterFunctionCall) theSearchFilter;
- final String functionName = functionItem.getFunctionName();
- if (functionName.equals(ISearchFilterFunctionCall.Contains))
- {
- final String[] parameter = functionItem.getParameters();
- final String propertyName = parameter[0];
- final String value = parameter[1];
- final String likePattern = "%" + QueryUtil.escapeSpecialChars(value) + "%";
- if (propertyName.equals("@objectClass"))
- {
- if (-1 != "account".indexOf(value))
- sqlCondition.append(" ISUSER = 1 ");
- else if (-1 != "group".indexOf(value))
- sqlCondition.append(" ISGROUP = 1 ");
- else
- sqlCondition.append(falseCondition);
- }
- else if (propertyName.equals("@defaultName") || propertyName.equals("@name"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "NAME", likePattern);
- else if (propertyName.equals("@userName"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "USERNAME", likePattern);
- else
- sqlCondition.append(trueCondition);
- }
- else if (functionName.equals(ISearchFilterFunctionCall.StartsWith))
- {
- final String[] parameter = functionItem.getParameters();
- final String propertyName = parameter[0];
- final String value = parameter[1];
- final String likePattern = QueryUtil.escapeSpecialChars(value) + "%";
- if (propertyName.equals("@objectClass"))
- {
- if ("account".startsWith(value))
- sqlCondition.append(" ISUSER = 1 ");
- else if ("group".startsWith(value))
- sqlCondition.append(" ( ISGROUP = 1 ) ");
- else
- //
- // Make sure this is a false statement
- //
- sqlCondition.append(falseCondition);
- }
- else if (propertyName.equals("@defaultName") || propertyName.equals("@name"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "NAME", likePattern);
- else if (propertyName.equals("@userName"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "USERNAME", likePattern);
- else
- //
- // We ignore the properties that are not
- // supported.
- //
- sqlCondition.append(trueCondition);
- }
- else if (functionName.equals(ISearchFilterFunctionCall.EndsWith))
- {
- final String[] parameter = functionItem.getParameters();
- final String propertyName = parameter[0];
- final String value = parameter[1];
- if (propertyName.equals("@objectClass"))
- {
- if ("account".endsWith(value))
- sqlCondition.append(" ISUSER = 1 ");
- else if ("group".endsWith(value))
- sqlCondition.append(" ( ISGROUP = 1 ) ");
- else
- sqlCondition.append(falseCondition);
- }
- else if (propertyName.equals("@defaultName") || propertyName.equals("@name"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "NAME", "%" + QueryUtil.escapeSpecialChars(value));
- else if (propertyName.equals("@userName"))
- QueryUtil.addSQLConditionFragment(sqlCondition, "USERNAME", "%" + QueryUtil.escapeSpecialChars(value));
- else
- sqlCondition.append(trueCondition);
- }
- else
- sqlCondition.append(trueCondition);
-
- break;
- case ISearchFilter.RelationalExpression:
- final ISearchFilterRelationExpression relationalItem = (ISearchFilterRelationExpression) theSearchFilter;
- final String propertyName = relationalItem.getPropertyName();
- final String constraint = relationalItem.getConstraint();
- final String relationalOperator = relationalItem.getOperator();
- if (propertyName.equals("@objectClass"))
- {
- if (constraint.equals("account"))
- {
- if (relationalOperator.equals(ISearchFilterRelationExpression.EqualTo))
- sqlCondition.append(" ISUSER = 1 ");
- else if (relationalOperator.equals(ISearchFilterRelationExpression.NotEqual))
- sqlCondition.append(" ISUSER = 0 ");
- else
- //
- // Make sure this is a false statement
- //
- sqlCondition.append(falseCondition);
- }
- else if (constraint.equals("group"))
- {
- if (relationalOperator.equals(ISearchFilterRelationExpression.EqualTo))
- sqlCondition.append(" ( ISGROUP = 1 ) ");
- else if (relationalOperator.equals(ISearchFilterRelationExpression.NotEqual))
- sqlCondition.append(" ( ISGROUP = 0 ) ");
- else
- sqlCondition.append(falseCondition);
- }
- else
- sqlCondition.append(falseCondition);
- }
- else if (propertyName.equals("@defaultName") || propertyName.equals("@name"))
- sqlCondition.append(" NAME " + relationalOperator + " '" + constraint + "'");
- else if (propertyName.equals("@userName"))
- sqlCondition.append(" USERNAME " + relationalOperator + " '" + constraint + "'");
- else
- sqlCondition.append(trueCondition);
-
- break;
- }
- return sqlCondition.toString();
- }
- public static Object[][] query(final Connection connection, final String sql, final Object... parameters)
- throws UnrecoverableException
- {
- return QueryUtil.queryImpl(connection, sql, false, parameters);
- }
- private static Object[][] queryImpl(final Connection connection, final String sql, final boolean includeMetadata,
- final Object... parameters) throws UnrecoverableException
- {
- final List< Object[] > data = new ArrayList< Object[] >();
- try (final PreparedStatement statement = connection.prepareStatement(sql))
- {
- for (int i = 0; i < parameters.length; ++i)
- statement.setObject(i + 1, parameters[i]);
- try (final ResultSet resultSet = statement.executeQuery())
- {
- if (includeMetadata)
- data.add(QueryUtil.getMetaDataRow(resultSet));
- while (resultSet.next())
- data.add(QueryUtil.getDataRow(resultSet));
- }
- }
- catch (final SQLException ex)
- {
- throw new UnrecoverableException("SQL Exception", "An exception was caught while querying the authentication database.");
- }
- return data.toArray(new Object[0][]);
- }
- public static Object[][] queryWithMetaData(final Connection connection, final String sql, final Object... parameters)
- throws UnrecoverableException
- {
- return QueryUtil.queryImpl(connection, sql, true, parameters);
- }
- public static void searchQuery(final ConnectionManager connectionManager, final String theSqlCondition,
- final IQueryOption theQueryOption, final String[] theProperties, final ISortProperty[] theSortProperties,
- final QueryResult theResult, final INamespace theNamespace) throws SQLException, UnrecoverableException
- {
- final StringBuffer sqlStatement = new StringBuffer();
- sqlStatement.append("SELECT ID, USERNAME, NAME, ISUSER, ISGROUP FROM OBJECTVIEW");
- if (theSqlCondition.length() > 0)
- sqlStatement.append(" WHERE ").append(theSqlCondition);
- final long maxCount = theQueryOption.getMaxCount();
- final long skipCount = theQueryOption.getSkipCount();
- String theSortClause = new String();
- if (theSortProperties != null)
- {
- for (int i = 0; i < theSortProperties.length; i++)
- {
- final ISortProperty property = theSortProperties[i];
- if (property.getPropertyName().equals("name"))
- {
- if (theSortClause.length() > 0)
- theSortClause += ", ";
- theSortClause += "NAME";
- if (property.getSortOrder() == ISortProperty.SortOrderAscending)
- theSortClause += " ASC";
- else
- theSortClause += " DESC";
- }
- }
- if (theSortClause.length() > 0)
- sqlStatement.append(" ORDER BY ").append(theSortClause);
- }
- final Object[][] data = QueryUtil.query(connectionManager.getConnection(), sqlStatement.toString());
- if (0 < data.length)
- {
- long curSkip = 0, curMax = 0;
- final int isUserCol = 3;
- final int isGroupCol = 4;
- for (int i = 0; i < data.length; i++)
- {
- final Object[] row = data[i];
- final boolean bIsUser = ((Integer) row[isUserCol]).intValue() == 1;
- final boolean bIsGroup = ((Integer) row[isGroupCol]).intValue() == 1;
- // We need to handle paging information
- if (bIsUser || bIsGroup)
- {
- if (curSkip++ < skipCount) // We need to skip skipCount
- // first objects
- continue;
- else if (curMax >= maxCount && maxCount > 0) // If we
- // already
- // have
- // maxCount
- // objects,
- // we can
- // stop
- // looking
- break;
- else
- // curMax < maxCount - we need to keep retrieving
- // entries
- curMax++;
- }
- else
- // If the entry is neither a user nor a role, we'll skip it
- continue;
- final String objectID = String.valueOf(row[0]);
- final String userName = (String) row[1];
- final String objectName = (String) row[2];
- if (bIsUser)
- {
- final String searchPath = "u:" + objectID;
- final Account account = connectionManager.getAccountCache().findAccount(searchPath);
- account.addName(Locale.getDefault(), objectName);
- account.setUserName(userName);
- // The following two custom properties used for testing
- // purposes
- account.addCustomProperty("newProp1", "value1");
- account.addCustomProperty("newProp2", "value2");
- theResult.addObject(account);
- }
- else if (bIsGroup)
- {
- final String searchPath = "g:" + objectID;
- final Group group = connectionManager.getGroupCache().findGroup(searchPath);
- group.addName(Locale.getDefault(), objectName);
- theResult.addObject(group);
- }
- }
- }
- }
- public static void updateMembership(final ConnectionManager connectionManager, final Visa theVisa) throws SQLException,
- UnrecoverableException
- {
- final IAccount account = theVisa.getAccount();
- final String userID = account.getObjectID().substring(2);
- final String tenantID = getTenantId(account);
- final Object[][] data =
- QueryUtil
- .query(connectionManager.getConnection(), "SELECT GROUPID, GROUPNAME FROM GROUPS WHERE USERID = ? AND (TENANT = ? OR TENANT='')", userID, tenantID);
- for (int i = 0; i < data.length; ++i)
- {
- final Object[] row = data[i];
- final String groupID = String.valueOf(row[0]);
- final String groupName = (String) row[1];
- final Group group = connectionManager.getGroupCache().findGroup("g:" + groupID);
- group.addName(account.getContentLocale(), groupName);
- theVisa.addGroup(group);
- }
- }
-
- public static String getTenantId(IAccount account) {
- String value[] = account.getCustomPropertyValue(AccountCache.TENANTID_ACCOUNT_PROPERTY);
- return value != null ? value[0] : null;
- }
- }
|