Security constraints added

This commit is contained in:
Konstantin Krivopustov 2008-12-26 13:47:32 +00:00
parent a095a26d73
commit e751b3c60e
22 changed files with 657 additions and 37 deletions

View File

@ -155,6 +155,25 @@ alter table SEC_PERMISSION add constraint SEC_PERMISSION_UNIQUE unique (ROLE_ID,
------------------------------------------------------------------------------------------------------------
create table SEC_CONSTRAINT (
ID varchar(36),
CREATE_TS timestamp,
CREATED_BY varchar(20),
VERSION integer,
UPDATE_TS timestamp,
UPDATED_BY varchar(20),
DELETE_TS timestamp,
DELETED_BY varchar(20),
ENTITY_NAME varchar(50),
WHERE_CLAUSE varchar(500),
GROUP_ID varchar(36),
primary key (ID)
);
alter table SEC_CONSTRAINT add constraint SEC_CONSTRAINT_GROUP foreign key (GROUP_ID) references SEC_GROUP;
------------------------------------------------------------------------------------------------------------
insert into SEC_USER (ID, CREATE_TS, VERSION, LOGIN, PASSWORD, NAME)
values ('60885987-1b61-4247-94c7-dff348347f93', current_timestamp, 0, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator');

View File

@ -14,6 +14,7 @@
<class>com.haulmont.cuba.security.entity.Profile</class>
<class>com.haulmont.cuba.security.entity.ProfileRole</class>
<class>com.haulmont.cuba.security.entity.Permission</class>
<class>com.haulmont.cuba.security.entity.Constraint</class>
<properties>
<property name="openjpa.Log" value="log4j"/>

View File

@ -22,8 +22,12 @@ public interface EntityManager
<T extends BaseEntity> T find(Class<T> clazz, Object key);
Query createQuery();
Query createQuery(String qlStr);
Query createNativeQuery();
Query createNativeQuery(String sql);
void setView(View view);

View File

@ -18,6 +18,10 @@ import java.util.Date;
public interface Query
{
String getQueryString();
void setQueryString(String queryString);
List getResultList();
Object getSingleResult();

View File

@ -11,8 +11,11 @@
package com.haulmont.cuba.core;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.core.global.QueryTransformer;
import com.haulmont.cuba.core.global.QueryTransformerFactory;
import java.util.Arrays;
import java.util.List;
public abstract class SecurityProvider
{
@ -54,5 +57,35 @@ public abstract class SecurityProvider
return (Arrays.binarySearch(session.getRoles(), role) >= 0);
}
public static void applyConstraints(Query query, String entityName) {
getInstance().__applyConstraints(query, entityName);
}
protected abstract UserSession __currentUserSession();
protected void __applyConstraints(Query query, String entityName) {
List<String> constraints = __currentUserSession().getConstraints(entityName);
if (constraints.isEmpty())
return;
QueryTransformer transformer = QueryTransformerFactory.createTransformer(
query.getQueryString(), entityName);
for (String constraint : constraints) {
transformer.addWhere(constraint);
}
query.setQueryString(transformer.getResult());
for (String paramName : transformer.getAddedParams()) {
setQueryParam(query, paramName);
}
}
protected void setQueryParam(Query query, String paramName) {
if ("currentUserLogin".equals(paramName)) {
query.setParameter("currentUserLogin", __currentUserSession().getLogin());
}
else if ("currentUserId".equals(paramName)) {
query.setParameter("currentUserId", __currentUserSession().getUserId());
}
}
}

View File

@ -15,9 +15,11 @@ import com.haulmont.cuba.core.global.BasicInvocationContext;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.PersistenceProvider;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.SecurityProvider;
import javax.ejb.Stateless;
import java.util.List;
import java.util.Map;
@Stateless(name = BasicWorker.JNDI_NAME)
public class BasicWorkerBean implements BasicWorker
@ -65,11 +67,18 @@ public class BasicWorkerBean implements BasicWorker
public <T extends BaseEntity> List<T> loadList(BasicInvocationContext ctx) {
EntityManager em = PersistenceProvider.getEntityManager();
Query query = em.createQuery(ctx.getQueryString());
SecurityProvider.applyConstraints(query, ctx.getMetaClass().getName());
for (Map.Entry<String, Object> entry : ctx.getQueryParams().entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
if (ctx.getView() != null) {
query.setView(ctx.getView());
}
List resultList = query.getResultList();
return resultList;
}
}

View File

@ -11,17 +11,20 @@
package com.haulmont.cuba.core.global;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.chile.core.model.MetaClass;
import java.io.Serializable;
import java.util.Map;
import java.util.HashMap;
public class BasicInvocationContext implements Serializable
{
private static final long serialVersionUID = -6533204272933592530L;
private Class<? extends BaseEntity> entityClass;
private Object id;
private String queryString;
private Map<String, Object> queryParams = new HashMap<String, Object>();
private View view;
public Class<? extends BaseEntity> getEntityClass() {
@ -33,6 +36,10 @@ public class BasicInvocationContext implements Serializable
return this;
}
public MetaClass getMetaClass() {
return MetadataProvider.getSession().getClass(entityClass);
}
public Object getId() {
return id;
}
@ -51,6 +58,15 @@ public class BasicInvocationContext implements Serializable
return this;
}
public Map<String, Object> getQueryParams() {
return queryParams;
}
public BasicInvocationContext addQueryParam(String name, Object value) {
queryParams.put(name, value);
return this;
}
public View getView() {
return view;
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 26.12.2008 10:17:29
*
* $Id$
*/
package com.haulmont.cuba.core.global;
import java.util.Set;
public interface QueryTransformer
{
void addWhere(String where);
void mergeWhere(String query);
void reset();
String getResult();
Set<String> getAddedParams();
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 26.12.2008 10:10:03
*
* $Id$
*/
package com.haulmont.cuba.core.global;
public class QueryTransformerFactory
{
public static QueryTransformer createTransformer(String query, String targetEntity) {
return new QueryTransformerRegex(query, targetEntity);
}
}

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 26.12.2008 9:53:52
*
* $Id$
*/
package com.haulmont.cuba.core.global;
import org.apache.commons.lang.StringUtils;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class QueryTransformerRegex implements QueryTransformer
{
public static final String ENTITY_PATTERN_REGEX = "(\\b[_A-Za-z]+\\$[A-Z][_A-Za-z]*)(\\s+as\\b)?\\s+([a-z]+[a-z0-9]*)*\\b";
public static final Pattern ENTITY_PATTERN = Pattern.compile(ENTITY_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final String WHERE_PATTERN_REGEX = "\\bWHERE\\b";
public static final Pattern WHERE_PATTERN = Pattern.compile(WHERE_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final String LAST_CLAUSE_PATTERN_REGEX = "(\\bGROUP\\s+BY\\b)|(\\bORDER\\s+BY\\b)|(\\bHAVING\\b)";
public static final Pattern LAST_CLAUSE_PATTERN = Pattern.compile(LAST_CLAUSE_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final String ALIAS_PATTERN_REGEX = "(^|\\s|\\()(\\w+)\\.";
public static final Pattern ALIAS_PATTERN = Pattern.compile(ALIAS_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
public static final String PARAM_PATTERN_REGEX = ":([a-zA-Z_0-9]+)";
public static final Pattern PARAM_PATTERN = Pattern.compile(PARAM_PATTERN_REGEX, Pattern.CASE_INSENSITIVE);
private String source;
private String targetEntity;
private StringBuffer buffer;
private Set<String> addedParams;
QueryTransformerRegex(String source, String targetEntity) {
this.source = source;
this.targetEntity = targetEntity;
buffer = new StringBuffer(source);
addedParams = new HashSet<String>();
}
public void addWhere(String where) {
String alias = null;
Matcher entityMatcher = ENTITY_PATTERN.matcher(buffer);
while (entityMatcher.find()) {
if (targetEntity.equals(entityMatcher.group(1))) {
alias = entityMatcher.group(3);
break;
}
}
if (StringUtils.isBlank(alias))
error("No alias for target entity " + targetEntity + " found");
int insertPos = source.length();
Matcher lastClauseMatcher = LAST_CLAUSE_PATTERN.matcher(buffer);
if (lastClauseMatcher.find(entityMatcher.end()))
insertPos = lastClauseMatcher.start() - 1;
StringBuilder sb = new StringBuilder();
Matcher whereMatcher = WHERE_PATTERN.matcher(buffer);
if (whereMatcher.find(entityMatcher.end()))
sb.append(" and ");
else
sb.append(" where ");
addReplacingAlias(sb, where, alias);
buffer.insert(insertPos, sb);
Matcher paramMatcher = PARAM_PATTERN.matcher(where);
while (paramMatcher.find()) {
addedParams.add(paramMatcher.group(1));
}
}
public void mergeWhere(String query) {
int startPos = 0;
Matcher whereMatcher = WHERE_PATTERN.matcher(query);
if (whereMatcher.find())
startPos = whereMatcher.end() + 1;
int endPos = query.length();
Matcher lastClauseMatcher = LAST_CLAUSE_PATTERN.matcher(query);
if (lastClauseMatcher.find())
endPos = lastClauseMatcher.start();
addWhere(query.substring(startPos, endPos));
}
private void addReplacingAlias(StringBuilder sb, String where, String alias) {
Matcher matcher = ALIAS_PATTERN.matcher(where);
int pos = 0;
while (matcher.find()) {
sb.append(where.substring(pos, matcher.start(2)));
pos = matcher.end(2);
sb.append(alias);
}
sb.append(where.substring(pos));
}
public void reset() {
buffer = new StringBuffer(source);
addedParams.clear();
}
public String getResult() {
return buffer.toString();
}
public Set<String> getAddedParams() {
return Collections.unmodifiableSet(addedParams);
}
private void error(String message) {
throw new RuntimeException(message + " [" + buffer.toString() + "]");
}
}

View File

@ -34,8 +34,6 @@ public class EntityManagerImpl implements EntityManager
void onClose();
}
private Log log = LogFactory.getLog(EntityManagerImpl.class);
private OpenJPAEntityManager jpaEm;
private boolean closed;
@ -88,14 +86,24 @@ public class EntityManagerImpl implements EntityManager
return jpaEm.find(clazz, key);
}
public Query createQuery() {
return new QueryImpl(jpaEm, false);
}
public Query createQuery(String qlStr) {
log.trace("Creating JPQL query: " + qlStr);
return new QueryImpl(jpaEm.createQuery(qlStr));
QueryImpl query = new QueryImpl(jpaEm, false);
query.setQueryString(qlStr);
return query;
}
public Query createNativeQuery() {
return new QueryImpl(jpaEm, true);
}
public Query createNativeQuery(String sql) {
log.trace("Creating SQL query: " + sql);
return new QueryImpl(jpaEm.createNativeQuery(sql));
QueryImpl query = new QueryImpl(jpaEm, true);
query.setQueryString(sql);
return query;
}
public void setView(View view) {

View File

@ -12,7 +12,6 @@ package com.haulmont.cuba.core.sys;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.global.ViewProperty;
import javax.persistence.TemporalType;
import javax.persistence.FlushModeType;
@ -20,61 +19,94 @@ import java.util.List;
import java.util.Date;
import org.apache.openjpa.persistence.OpenJPAQuery;
import org.apache.openjpa.persistence.FetchPlan;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class QueryImpl implements Query
{
private OpenJPAQuery query;
private Log log = LogFactory.getLog(QueryImpl.class);
public QueryImpl(OpenJPAQuery query) {
this.query = query;
this.query.setFlushMode(FlushModeType.COMMIT);
private OpenJPAEntityManager em;
private OpenJPAQuery query;
private boolean isNative;
private String queryString;
public QueryImpl(OpenJPAEntityManager entityManager, boolean isNative) {
this.em = entityManager;
this.isNative = isNative;
}
private OpenJPAQuery getQuery() {
if (query == null) {
if (isNative) {
log.trace("Creating SQL query: " + queryString);
query = em.createNativeQuery(queryString);
query.setFlushMode(FlushModeType.COMMIT);
}
else {
log.trace("Creating JPQL query: " + queryString);
query = em.createQuery(queryString);
query.setFlushMode(FlushModeType.COMMIT);
}
}
return query;
}
public List getResultList() {
return query.getResultList();
return getQuery().getResultList();
}
public Object getSingleResult() {
return query.getSingleResult();
return getQuery().getSingleResult();
}
public int executeUpdate() {
return query.executeUpdate();
return getQuery().executeUpdate();
}
public Query setMaxResults(int maxResult) {
query.setMaxResults(maxResult);
getQuery().setMaxResults(maxResult);
return this;
}
public Query setFirstResult(int startPosition) {
query.setFirstResult(startPosition);
getQuery().setFirstResult(startPosition);
return this;
}
public Query setParameter(String name, Object value) {
query.setParameter(name, value);
getQuery().setParameter(name, value);
return this;
}
public Query setParameter(String name, Date value, TemporalType temporalType) {
query.setParameter(name, value, temporalType);
getQuery().setParameter(name, value, temporalType);
return this;
}
public Query setParameter(int position, Object value) {
query.setParameter(position, value);
getQuery().setParameter(position, value);
return this;
}
public Query setParameter(int position, Date value, TemporalType temporalType) {
query.setParameter(position, value, temporalType);
getQuery().setParameter(position, value, temporalType);
return this;
}
public Query setView(View view) {
ViewHelper.setView(query.getFetchPlan(), view);
ViewHelper.setView(getQuery().getFetchPlan(), view);
return this;
}
public String getQueryString() {
return queryString;
}
public void setQueryString(String queryString) {
if (query != null)
throw new IllegalStateException("Unable to set query string: query is already created");
this.queryString = queryString;
}
}

View File

@ -13,11 +13,10 @@ package com.haulmont.cuba.core.sys;
import com.haulmont.cuba.core.SecurityProvider;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.sys.UserSessionManager;
import org.jboss.security.SecurityAssociation;
import java.util.UUID;
import org.jboss.security.SecurityAssociation;
public class SecurityProviderImpl extends SecurityProvider
{
protected UserSession __currentUserSession() {

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 25.12.2008 16:25:02
*
* $Id$
*/
package com.haulmont.cuba.security.entity;
import com.haulmont.cuba.core.entity.StandardEntity;
import javax.persistence.*;
@Entity(name = "sec$Constraint")
@Table(name = "SEC_CONSTRAINT")
public class Constraint extends StandardEntity
{
private static final long serialVersionUID = -8598548105315052474L;
@Column(name = "ENTITY_NAME", length = 50)
private String entityName;
@Column(name = "WHERE_CLAUSE", length = 500)
private String whereClause;
@ManyToOne
@JoinColumn(name = "GROUP_ID")
private Group group;
public String getEntityName() {
return entityName;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public String getWhereClause() {
return whereClause;
}
public void setWhereClause(String whereClause) {
this.whereClause = whereClause;
}
}

View File

@ -15,6 +15,7 @@ import com.haulmont.cuba.core.entity.annotation.Listeners;
import javax.persistence.*;
import java.util.List;
import java.util.Set;
@Entity(name = "sec$Group")
@Table(name = "SEC_GROUP")
@ -34,6 +35,9 @@ public class Group extends StandardEntity
@OrderBy("level")
private List<GroupHierarchy> hierarchyList;
@OneToMany(mappedBy = "group")
private Set<Constraint> constraints;
public String getName() {
return name;
}
@ -58,6 +62,14 @@ public class Group extends StandardEntity
this.hierarchyList = hierarchyList;
}
public Set<Constraint> getConstraints() {
return constraints;
}
public void setConstraints(Set<Constraint> constraints) {
this.constraints = constraints;
}
public String toString() {
return "Group{" +
"name='" + name + '\'' +

View File

@ -20,11 +20,7 @@ public class Permission extends StandardEntity
{
private static final long serialVersionUID = 4188184934170706381L;
public static int TYPE_ACTION = 10;
public static int TYPE_ENTITY_OP = 20;
public static int TYPE_ENTITY_ATTR = 30;
public static int TYPE_SPECIFIC = 40;
/** @see com.haulmont.cuba.security.entity.PermissionType PermissionType.getId() */
@Column(name = "TYPE")
private Integer type;

View File

@ -10,6 +10,10 @@
*/
package com.haulmont.cuba.security.entity;
/**
* Type of permission<br>
* id - corresponding database value
*/
public enum PermissionType
{
ACTION(10),
@ -23,10 +27,12 @@ public enum PermissionType
this.id = id;
}
/** Returns corresponding database value */
public int getId() {
return id;
}
/** Constructs type from corresponding database value */
public static PermissionType fromId(int id) {
for (PermissionType type : PermissionType.values()) {
if (type.getId() == id) {

View File

@ -28,6 +28,7 @@ public class UserSession implements Serializable
private final Locale locale;
private final Map<String, Integer>[] permissions;
private final Map<String, List<String>> constraints;
public UserSession(User user, String[] roles, Locale locale) {
id = UuidProvider.createUuid();
@ -44,6 +45,8 @@ public class UserSession implements Serializable
for (int i = 0; i < permissions.length; i++) {
permissions[i] = new HashMap<String, Integer>();
}
constraints = new HashMap<String, List<String>>();
}
public UUID getId() {
@ -87,6 +90,20 @@ public class UserSession implements Serializable
return p == null || p >= value;
}
public void addConstraint(String entityName, String constraint) {
List<String> list = constraints.get(entityName);
if (list == null) {
list = new ArrayList<String>();
constraints.put(entityName, list);
}
list.add(constraint);
}
public List<String> getConstraints(String entityName) {
List<String> list = constraints.get(entityName);
return list != null ? list : Collections.<String>emptyList();
}
public String toString() {
return "UserSession{" +
"id=" + id +

View File

@ -13,6 +13,9 @@ package com.haulmont.cuba.security.sys;
import com.haulmont.cuba.security.entity.*;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.global.NoUserSessionException;
import com.haulmont.cuba.core.PersistenceProvider;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Query;
import java.util.*;
@ -42,6 +45,7 @@ public class UserSessionManager
}
UserSession session = new UserSession(user, roleNames.toArray(new String[roleNames.size()]), locale);
compilePermissions(session, roles);
compileConstraints(session, profile.getGroup());
sessions.add(session);
return session;
}
@ -64,6 +68,19 @@ public class UserSessionManager
}
}
private void compileConstraints(UserSession session, Group group) {
EntityManager em = PersistenceProvider.getEntityManager();
Query q = em.createQuery("select c from sec$GroupHierarchy h join h.parent.constraints c " +
"where h.group = ?1");
q.setParameter(1, group);
List<Constraint> constraints = q.getResultList();
List<Constraint> list = new ArrayList<Constraint>(constraints);
list.addAll(group.getConstraints());
for (Constraint constraint : list) {
session.addConstraint(constraint.getEntityName(), constraint.getWhereClause());
}
}
public void removeSession(UserSession session) {
sessions.remove(session);
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 26.12.2008 12:53:07
*
* $Id$
*/
package com.haulmont.cuba.core.global;
import junit.framework.TestCase;
import java.util.Set;
public class QueryTransformerRegexTest extends TestCase
{
public void test() {
QueryTransformerRegex transformer = new QueryTransformerRegex(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = :par",
"sec$GroupHierarchy");
transformer.addWhere("a.createdBy = :par1");
String res = transformer.getResult();
assertEquals(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = :par and h.createdBy = :par1",
res);
transformer = new QueryTransformerRegex(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level order by c.level having c.level > 0",
"sec$GroupHierarchy");
transformer.addWhere("a.createdBy = :par1");
res = transformer.getResult();
assertEquals(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"and h.createdBy = :par1 group by c.level order by c.level having c.level > 0",
res);
Set<String> set = transformer.getAddedParams();
assertEquals(1, set.size());
assertEquals("par1", set.iterator().next());
transformer.addWhere("(a.updatedBy = :par2 and a.groupId = :par3)");
res = transformer.getResult();
assertEquals(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"and h.createdBy = :par1 and (h.updatedBy = :par2 and h.groupId = :par3) group by c.level order by c.level having c.level > 0",
res);
set = transformer.getAddedParams();
assertEquals(3, set.size());
transformer.reset();
transformer.mergeWhere("select gh from sec$GroupHierarchy gh where gh.version between 1 and 2");
res = transformer.getResult();
assertEquals(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"and h.version between 1 and 2 group by c.level order by c.level having c.level > 0",
res);
}
public void testInvalidEntity() {
QueryTransformerRegex transformer = new QueryTransformerRegex(
"select c from sec$GroupHierarchy h join h.parent.constraints c where h.group = ?1 " +
"group by c.level order by c.level having c.level > 0",
"sec$Group");
try {
transformer.addWhere("a.createdBy = :par1");
fail();
} catch (Exception e) {
assertTrue(e instanceof RuntimeException);
}
}
}

View File

@ -11,14 +11,13 @@
package com.haulmont.cuba.core.sys;
import com.haulmont.cuba.core.SecurityProvider;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.entity.User;
import java.util.UUID;
import java.util.Locale;
import com.haulmont.cuba.security.global.UserSession;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.Locale;
import java.util.UUID;
public class TestSecurityProvider extends SecurityProvider
{
protected UserSession __currentUserSession() {
@ -29,6 +28,8 @@ public class TestSecurityProvider extends SecurityProvider
user.setPassword(DigestUtils.md5Hex("test_admin"));
UserSession session = new UserSession(user, new String[]{"Administrators"}, Locale.getDefault());
session.addConstraint("sec$Group", "a.createdBy = :currentUserLogin");
return session;
}
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 25.12.2008 17:39:53
*
* $Id$
*/
package com.haulmont.cuba.security;
import com.haulmont.cuba.core.*;
import com.haulmont.cuba.core.global.BasicInvocationContext;
import com.haulmont.cuba.core.app.BasicService;
import com.haulmont.cuba.security.entity.Group;
import com.haulmont.cuba.security.entity.Profile;
import com.haulmont.cuba.security.entity.User;
import com.haulmont.cuba.security.entity.Constraint;
import com.haulmont.cuba.security.app.LoginWorker;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.global.LoginException;
import java.util.UUID;
import java.util.Locale;
import java.util.List;
import java.util.Date;
import org.apache.commons.codec.digest.DigestUtils;
public class ConstraintTest extends CubaTestCase
{
private static final String ADMIN_NAME = "admin";
private static final String ADMIN_PASSW = DigestUtils.md5Hex("admin");
private static final String PROFILE_NAME = "testProfile";
private UUID constraintId, parentConstraintId, groupId, parentGroupId, profileId;
protected void setUp() throws Exception {
super.setUp();
Transaction tx = Locator.createTransaction();
try {
EntityManager em = PersistenceProvider.getEntityManager();
User user = em.find(User.class, UUID.fromString("60885987-1b61-4247-94c7-dff348347f93"));
Group parentGroup = new Group();
parentGroupId = parentGroup.getId();
parentGroup.setName("testParentGroup");
em.persist(parentGroup);
tx.commitRetaining();
em = PersistenceProvider.getEntityManager();
Constraint parentConstraint = new Constraint();
parentConstraintId = parentConstraint.getId();
parentConstraint.setEntityName("core$Server");
parentConstraint.setWhereClause("address = '127.0.0.1'");
parentConstraint.setGroup(parentGroup);
em.persist(parentConstraint);
Group group = new Group();
groupId = group.getId();
group.setName("testGroup");
group.setParent(parentGroup);
em.persist(group);
Constraint constraint = new Constraint();
constraintId = constraint.getId();
constraint.setEntityName("core$Server");
constraint.setWhereClause("name = 'localhost'");
constraint.setGroup(group);
em.persist(constraint);
Profile profile = new Profile();
profileId = profile.getId();
profile.setName(PROFILE_NAME);
profile.setUser(user);
profile.setGroup(group);
em.persist(profile);
tx.commit();
} finally {
tx.end();
}
}
protected void tearDown() throws Exception {
Transaction tx = Locator.createTransaction();
try {
EntityManager em = PersistenceProvider.getEntityManager();
Query q = em.createNativeQuery("delete from SEC_PROFILE where ID = ?");
q.setParameter(1, profileId.toString());
q.executeUpdate();
q = em.createNativeQuery("delete from SEC_CONSTRAINT where ID = ? or ID = ?");
q.setParameter(1, parentConstraintId.toString());
q.setParameter(2, constraintId.toString());
q.executeUpdate();
q = em.createNativeQuery("delete from SEC_GROUP_HIERARCHY where GROUP_ID = ?");
q.setParameter(1, groupId.toString());
q.executeUpdate();
q = em.createNativeQuery("delete from SEC_GROUP where ID = ?");
q.setParameter(1, groupId.toString());
q.executeUpdate();
q = em.createNativeQuery("delete from SEC_GROUP_HIERARCHY where GROUP_ID = ?");
q.setParameter(1, groupId.toString());
q.executeUpdate();
q = em.createNativeQuery("delete from SEC_GROUP where ID = ?");
q.setParameter(1, parentGroupId.toString());
q.executeUpdate();
tx.commit();
} finally {
tx.end();
}
super.tearDown();
}
public void test() throws LoginException {
LoginWorker lw = Locator.lookupLocal(LoginWorker.JNDI_NAME);
UserSession userSession = lw.login(ADMIN_NAME, ADMIN_PASSW, PROFILE_NAME, Locale.getDefault());
assertNotNull(userSession);
List<String> constraints = userSession.getConstraints("core$Server");
assertEquals(2, constraints.size());
BasicService bs = Locator.lookupLocal(BasicService.JNDI_NAME);
BasicInvocationContext ctx = new BasicInvocationContext()
.setEntityClass(Group.class)
.setQueryString("select g from sec$Group g where g.createTs <= :createTs")
.addQueryParam("createTs", new Date());
List<Group> list = bs.loadList(ctx);
assertTrue(list.size() > 0);
}
}