/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.security.permission;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.GroupConstants;
import com.liferay.portal.kernel.model.ResourceConstants;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.RoleConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionCheckerFactoryUtil;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
import com.liferay.portal.kernel.service.ResourcePermissionLocalServiceUtil;
import com.liferay.portal.kernel.service.RoleLocalServiceUtil;
import com.liferay.portal.kernel.service.UserGroupRoleLocalServiceUtil;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.test.rule.AggregateTestRule;
import com.liferay.portal.kernel.test.rule.DeleteAfterTestRun;
import com.liferay.portal.kernel.test.rule.Sync;
import com.liferay.portal.kernel.test.rule.SynchronousDestinationTestRule;
import com.liferay.portal.kernel.test.util.CompanyTestUtil;
import com.liferay.portal.kernel.test.util.GroupTestUtil;
import com.liferay.portal.kernel.test.util.RoleTestUtil;
import com.liferay.portal.kernel.test.util.TestPropsValues;
import com.liferay.portal.kernel.test.util.UserTestUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.test.rule.LiferayIntegrationTestRule;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
/**
* @author Christopher Kian
* @author Preston Crary
*/
@Sync
public class InlineSQLHelperImplTest {
@ClassRule
@Rule
public static final AggregateTestRule aggregateTestRule =
new AggregateTestRule(
new LiferayIntegrationTestRule(),
SynchronousDestinationTestRule.INSTANCE);
@Before
public void setUp() throws Exception {
_groupOne = GroupTestUtil.addGroup();
_groupTwo = GroupTestUtil.addGroup();
_groupIds = new long[] {_groupOne.getGroupId(), _groupTwo.getGroupId()};
_user = UserTestUtil.addUser();
_originalPermissionChecker =
PermissionThreadLocal.getPermissionChecker();
}
@After
public void tearDown() {
PermissionThreadLocal.setPermissionChecker(_originalPermissionChecker);
}
@Test
public void testClauseOrdering() throws Exception {
_addGroupRole(_groupOne, RoleConstants.SITE_MEMBER);
_addGroupRole(_groupTwo, RoleConstants.SITE_MEMBER);
_setPermissionChecker();
_assertClauseOrdering(_SQL_PLAIN + _SQL_WHERE, _WHERE_CLAUSE);
_assertClauseOrdering(_SQL_PLAIN + _SQL_GROUP_BY, _GROUP_BY_CLAUSE);
_assertClauseOrdering(_SQL_PLAIN + _SQL_ORDER_BY, _ORDER_BY_CLAUSE);
_assertClauseOrdering(
_SQL_PLAIN + _SQL_WHERE + _SQL_GROUP_BY, _GROUP_BY_CLAUSE);
_assertClauseOrdering(
_SQL_PLAIN + _SQL_WHERE + _SQL_ORDER_BY, _ORDER_BY_CLAUSE);
_assertClauseOrdering(
_SQL_PLAIN + _SQL_GROUP_BY + _SQL_ORDER_BY, _ORDER_BY_CLAUSE);
_assertClauseOrdering(
_SQL_PLAIN + _SQL_WHERE + _SQL_GROUP_BY + _SQL_ORDER_BY,
_ORDER_BY_CLAUSE);
}
@Test
public void testCompanyScope() throws Exception {
_role = RoleTestUtil.addRole(
"scopeCompanyRole", RoleConstants.TYPE_REGULAR);
RoleLocalServiceUtil.addUserRole(_user.getUserId(), _role);
ResourcePermissionLocalServiceUtil.addResourcePermission(
CompanyThreadLocal.getCompanyId(), _CLASS_NAME,
ResourceConstants.SCOPE_COMPANY,
String.valueOf(_role.getCompanyId()), _role.getRoleId(),
ActionKeys.VIEW);
_setPermissionChecker();
String sql = _inlineSQLHelperImpl.replacePermissionCheckJoin(
_SQL_PLAIN, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD,
_GROUP_ID_FIELD, new long[] {_groupOne.getGroupId()}, null);
Assert.assertSame(_SQL_PLAIN, sql);
Assert.assertTrue(
_inlineSQLHelperImpl.isEnabled(_groupOne.getGroupId()));
}
@Test
public void testGetRoles() throws Exception {
_groupThree = GroupTestUtil.addGroup();
_role = RoleTestUtil.addRole("testRole", RoleConstants.TYPE_SITE);
_addGroupRole(_groupThree, "testRole");
_setPermissionChecker();
Role guestRole = RoleLocalServiceUtil.getRole(
_groupThree.getCompanyId(), RoleConstants.GUEST);
Role siteMemberRole = RoleLocalServiceUtil.getRole(
_groupThree.getCompanyId(), RoleConstants.SITE_MEMBER);
Role userRole = RoleLocalServiceUtil.getRole(
_groupThree.getCompanyId(), RoleConstants.USER);
long[] roleIds = _inlineSQLHelperImpl.getRoleIds(
_groupThree.getGroupId());
String msg = StringUtil.merge(roleIds);
Assert.assertTrue(msg, ArrayUtil.contains(roleIds, _role.getRoleId()));
Assert.assertTrue(
msg, ArrayUtil.contains(roleIds, guestRole.getRoleId()));
Assert.assertTrue(
msg, ArrayUtil.contains(roleIds, siteMemberRole.getRoleId()));
Assert.assertTrue(
msg, ArrayUtil.contains(roleIds, userRole.getRoleId()));
}
@Test
public void testGroupAdminResourcePermission() throws Exception {
_addGroupRole(_groupOne, RoleConstants.SITE_ADMINISTRATOR);
_addGroupRole(_groupTwo, RoleConstants.SITE_MEMBER);
_setPermissionChecker();
String sql = _replacePermissionCheckJoin(_SQL_PLAIN);
Role ownerRole = RoleLocalServiceUtil.getRole(
TestPropsValues.getCompanyId(), RoleConstants.OWNER);
StringBundler sb = new StringBundler(3);
sb.append(" OR ((ResourcePermission.primKeyId = 0) AND ");
sb.append("(ResourcePermission.roleId = ");
sb.append(ownerRole.getRoleId());
Assert.assertTrue(sql, sql.contains(sb.toString()));
}
@Test
public void testGroupScope() throws Exception {
_role = RoleTestUtil.addRole("scopeGroupRole", RoleConstants.TYPE_SITE);
_addGroupRole(_groupOne, "scopeGroupRole");
ResourcePermissionLocalServiceUtil.addResourcePermission(
CompanyThreadLocal.getCompanyId(), _CLASS_NAME,
ResourceConstants.SCOPE_GROUP,
String.valueOf(_groupOne.getGroupId()), _role.getRoleId(),
ActionKeys.VIEW);
_setPermissionChecker();
String sql = _inlineSQLHelperImpl.replacePermissionCheck(
_SQL_PLAIN, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD,
_GROUP_ID_FIELD, new long[] {_groupOne.getGroupId()}, null);
Assert.assertSame(_SQL_PLAIN, sql);
Assert.assertTrue(
_inlineSQLHelperImpl.isEnabled(_groupOne.getGroupId()));
}
@Test
public void testGroupTemplateScope() throws Exception {
_role = RoleTestUtil.addRole(
"scopeGroupTemplateRole", RoleConstants.TYPE_SITE);
_addGroupRole(_groupOne, "scopeGroupTemplateRole");
ResourcePermissionLocalServiceUtil.addResourcePermission(
CompanyThreadLocal.getCompanyId(), _CLASS_NAME,
ResourceConstants.SCOPE_GROUP_TEMPLATE,
String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
_role.getRoleId(), ActionKeys.VIEW);
_setPermissionChecker();
String sql = _inlineSQLHelperImpl.replacePermissionCheckJoin(
_SQL_PLAIN, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD,
_GROUP_ID_FIELD, new long[] {_groupOne.getGroupId()}, null);
Assert.assertSame(_SQL_PLAIN, sql);
Assert.assertTrue(
_inlineSQLHelperImpl.isEnabled(_groupOne.getGroupId()));
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidCompany() throws Exception {
_company = CompanyTestUtil.addCompany();
_groupThree = GroupTestUtil.addGroup();
_groupThree.setCompanyId(_company.getCompanyId());
GroupLocalServiceUtil.updateGroup(_groupThree);
_addGroupRole(_groupThree, RoleConstants.SITE_MEMBER);
_addGroupRole(_groupOne, RoleConstants.SITE_MEMBER);
_setPermissionChecker();
_inlineSQLHelperImpl.replacePermissionCheck(
_SQL_PLAIN, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD,
_GROUP_ID_FIELD,
new long[] {_groupOne.getGroupId(), _groupThree.getGroupId()},
null);
}
@Test
public void testIsNotEnabledForOmniAdmin() throws Exception {
Role role = RoleLocalServiceUtil.getRole(
_user.getCompanyId(), RoleConstants.ADMINISTRATOR);
UserLocalServiceUtil.addRoleUser(role.getRoleId(), _user);
_setPermissionChecker();
Assert.assertFalse(_inlineSQLHelperImpl.isEnabled(_groupIds));
}
@Test
public void testIsNotEnabledSiteAdmin() throws Exception {
_addGroupRole(_groupOne, RoleConstants.SITE_ADMINISTRATOR);
_setPermissionChecker();
Assert.assertFalse(
_inlineSQLHelperImpl.isEnabled(_groupOne.getGroupId()));
Assert.assertTrue(
_inlineSQLHelperImpl.isEnabled(_groupTwo.getGroupId()));
}
@Test
public void testSQLComposition() throws Exception {
_addGroupRole(_groupOne, RoleConstants.SITE_MEMBER);
_addGroupRole(_groupTwo, RoleConstants.SITE_MEMBER);
_setPermissionChecker();
String sql = _replacePermissionCheckJoin(_SQL_PLAIN);
_assertWhereClause(sql, _CLASS_PK_FIELD);
StringBundler sb = new StringBundler(4);
sb.append(_RESOURCE_PERMISSION);
sb.append(".name = '");
sb.append(_CLASS_NAME);
sb.append("'");
Assert.assertTrue(sql, sql.contains(sb.toString()));
sb = new StringBundler(3);
sb.append(_RESOURCE_PERMISSION);
sb.append(".companyId = ");
sb.append(CompanyThreadLocal.getCompanyId());
Assert.assertTrue(sql, sql.contains(sb.toString()));
sb = new StringBundler(3);
sb.append(_USER_ID_FIELD);
sb.append(" = ");
sb.append(_user.getUserId());
Assert.assertTrue(sql, sql.contains(sb.toString()));
_assertValidSql(sql);
sql = _replacePermissionCheckJoin(_SQL_PLAIN + _SQL_WHERE);
_assertWhereClause(sql, _CLASS_PK_FIELD);
Assert.assertTrue(
sql,
sql.endsWith(
" AND " + _SQL_WHERE.substring(_WHERE_CLAUSE.length())));
_assertValidSql(sql);
}
private void _addGroupRole(Group group, String roleName) throws Exception {
Role role = RoleLocalServiceUtil.getRole(
TestPropsValues.getCompanyId(), roleName);
UserGroupRoleLocalServiceUtil.addUserGroupRoles(
new long[] {_user.getUserId()}, group.getGroupId(),
role.getRoleId());
}
private void _assertClauseOrdering(String sql, String endingClause) {
String actualSql = _inlineSQLHelperImpl.replacePermissionCheckJoin(
sql, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD, _GROUP_ID_FIELD,
_groupIds, null);
int wherePos = actualSql.lastIndexOf(_WHERE_CLAUSE);
int groupByPos = actualSql.indexOf(_GROUP_BY_CLAUSE);
int orderByPos = actualSql.indexOf(_ORDER_BY_CLAUSE);
Assert.assertNotEquals(actualSql, -1, wherePos);
if (endingClause.equals(_WHERE_CLAUSE)) {
Assert.assertEquals(actualSql, -1, groupByPos);
Assert.assertEquals(actualSql, -1, orderByPos);
}
else if (endingClause.equals(_GROUP_BY_CLAUSE)) {
Assert.assertTrue(actualSql, wherePos < groupByPos);
Assert.assertEquals(actualSql, -1, orderByPos);
}
else {
Assert.assertTrue(actualSql, wherePos < orderByPos);
}
}
private void _assertValidSql(String sql) throws Exception {
try (Connection connection = DataAccess.getConnection();
PreparedStatement ps = connection.prepareStatement(sql)) {
ps.execute();
}
}
private void _assertWhereClause(String sql, String classPK) {
StringBundler sb = new StringBundler(4);
sb.append(_WHERE_CLAUSE);
sb.append("(");
sb.append(classPK);
sb.append(" IN (");
Assert.assertTrue(sql, sql.contains(sb.toString()));
}
private String _replacePermissionCheckJoin(String sql) throws Exception {
return _inlineSQLHelperImpl.replacePermissionCheckJoin(
sql, _CLASS_NAME, _CLASS_PK_FIELD, _USER_ID_FIELD, _GROUP_ID_FIELD,
_groupIds, null);
}
private void _setPermissionChecker() throws Exception {
PermissionChecker permissionChecker =
PermissionCheckerFactoryUtil.create(_user);
PermissionThreadLocal.setPermissionChecker(permissionChecker);
}
private static final String _CLASS_NAME =
"com.liferay.journal.model.JournalArticle";
private static final String _CLASS_PK_FIELD =
"JournalArticle.resourcePrimKey";
private static final String _GROUP_BY_CLAUSE = " GROUP BY ";
private static final String _GROUP_ID_FIELD = "groupIdField";
private static final String _ORDER_BY_CLAUSE = " ORDER BY ";
private static final String _RESOURCE_PERMISSION = "ResourcePermission";
private static final String _SQL_GROUP_BY = " GROUP BY " + _CLASS_PK_FIELD;
private static final String _SQL_ORDER_BY = " ORDER BY " + _CLASS_PK_FIELD;
private static final String _SQL_PLAIN =
"SELECT COUNT(*) FROM JournalArticle";
private static final String _SQL_WHERE =
" WHERE " + _CLASS_PK_FIELD + " != 0";
private static final String _USER_ID_FIELD =
_RESOURCE_PERMISSION + ".ownerId";
private static final String _WHERE_CLAUSE = " WHERE ";
@DeleteAfterTestRun
private Company _company;
private long[] _groupIds;
@DeleteAfterTestRun
private Group _groupOne;
@DeleteAfterTestRun
private Group _groupThree;
@DeleteAfterTestRun
private Group _groupTwo;
private final InlineSQLHelperImpl _inlineSQLHelperImpl =
new InlineSQLHelperImpl();
private PermissionChecker _originalPermissionChecker;
@DeleteAfterTestRun
private Role _role;
@DeleteAfterTestRun
private User _user;
}