- Cleanup ccm-core:org.libreccm.core: Removed unused classes (those replaced by 
  org.libreccm.security)
- Modified org.libreccm.security.PermissionChecker: 
    - #checkPermission(String, CcmObject) does not longer return the object, 
      when the current user is permitted to access the object.
    - new method #checkPermission(String, CcmObject, Class) checks for 
      permission to access the object and returns the object or a virtual 
      "Access denied" object (like SecuredCollection).
- "Access denied" string is provided as a constant by org.libreccm.core.CoreConstants


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3767 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2015-12-11 13:05:46 +00:00
parent e1ad4b4347
commit 576d28a8ce
47 changed files with 223 additions and 7476 deletions

View File

@ -180,6 +180,9 @@ public class ConfigRegistry {
}
InputStream is = m_loader.getResourceAsStream(key + ".config");
if (is == null) {
throw new UncheckedWrapperException(String.format("No .config for key '%s' found", key));
}
if (is != null) {
try {
XML.parse(is, new ConfigRegistryParser());

View File

@ -46,19 +46,6 @@ import javax.servlet.annotation.WebListener;
* expecially setting the runtime context (file locations) and (in the future)
* the database connection.
*
* The methods of this classes are by definition only invoked by the Servlet
* container / web application server, not by any Servlet or java class of the
* application itself! Invocation is managed by the deployment descriptor.
*
* Note! Don't forget to configure it in web.xml deployment descriptor!
* <listener>
* <listener-class>
* com.arsdigita.runtime.CCMApplicationContextListener
* </listener-class>
* </listener>
* According to the 2.3 specification these tags must be placed after the filter
* tags and before the Servlet tags!
*
* @author pboy
* @author Jens Pelzetter <a href="mailto:jens.pelzetter@googlemail.com">Jens
* Pelzetter</a>
@ -66,7 +53,7 @@ import javax.servlet.annotation.WebListener;
@WebListener
public class CCMApplicationContextListener implements ServletContextListener {
public static final Logger logger = LogManager.getLogger(
public static final Logger LOGGER = LogManager.getLogger(
CCMApplicationContextListener.class);
@Override
@ -75,7 +62,7 @@ public class CCMApplicationContextListener implements ServletContextListener {
final String appBase = context.getRealPath("/");
logger.info(String.format("Setting base directory to %s", appBase));
LOGGER.info(String.format("Setting base directory to %s", appBase));
CCMResourceManager.setBaseDirectory(appBase);
}

View File

@ -18,7 +18,6 @@
*/
package org.libreccm.core;
import com.arsdigita.runtime.ConfigRegistry;
import com.arsdigita.ui.admin.AdminApplicationCreator;
import com.arsdigita.ui.admin.AdminServlet;
import com.arsdigita.ui.login.LoginApplicationCreator;
@ -100,11 +99,9 @@ public class CcmCore implements CcmModule {
final EntityManager entityManager = event.getEntityManager();
final SystemUsersSetup systemUsersSetup = new SystemUsersSetup(
entityManager);
entityManager);
systemUsersSetup.setupSystemUsers();
final ConfigRegistry configRegistry = new ConfigRegistry();
configRegistry.initialize("ccm-core");
}

View File

@ -40,6 +40,7 @@ import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Pattern;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

View File

@ -19,6 +19,10 @@
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import javax.enterprise.context.RequestScoped;
/**
@ -39,6 +43,12 @@ public class CcmObjectRepository extends AbstractEntityRepository<Long, CcmObjec
if (entity == null) {
throw new IllegalArgumentException("Can't save null.");
}
if (ACCESS_DENIED.equals(entity.getDisplayName())) {
throw new IllegalArgumentException(
"Can't save the Access Denied object.");
}
return entity.getObjectId() == 0;
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
/**
* This bean stores several data about the current session, for example the
* current party.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@SessionScoped
public class CcmSessionContext implements Serializable {
private static final long serialVersionUID = 6110177865273823685L;
private Subject currentSubject;
private Subject effectiveSubject;
public Subject getCurrentSubject() {
return currentSubject;
}
public void setCurrentSubject(final Subject currentSubject) {
this.currentSubject = currentSubject;
this.effectiveSubject = currentSubject;
}
public Subject getEffectiveSubject() {
return effectiveSubject;
}
protected void setEffectiveSubject(final Subject effectiveSubject) {
this.effectiveSubject = effectiveSubject;
}
public boolean isLoggedIn() {
return currentSubject != null;
}
/**
* Execute code under different privileges. Useful if no current user is
* available, for example in the startup phase.
*
* The there is a current user the method will check if the current user
* has the permission to use the {@code sudo} method.
*
* @param subject The party with which permissions the code is executed.
* @param runnable The code to execute.
*/
public void sudo(final Subject subject, final Runnable runnable) {
//ToDo: Check if current user is permitted to use sudo.
effectiveSubject = subject;
runnable.run();
effectiveSubject = currentSubject;
}
}

View File

@ -25,10 +25,24 @@ package org.libreccm.core;
*/
public final class CoreConstants {
/**
* XML namespace used for XML created by and from classes in the ccm-core
* module.
*/
public static final String CORE_XML_NS = "http://core.libreccm.org";
/**
* Name of the database schema (namespace) for the tables storing the
* entities from the ccm-core module.
*/
public static final String DB_SCHEMA = "CCM_CORE";
/**
* String used as display name for the virtual <i>Access denied</i> objects
* in the security API.
*/
public static final String ACCESS_DENIED = "Access denied";
private CoreConstants() {
//Nothing
}

View File

@ -1,181 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.validator.constraints.NotBlank;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/**
* A {@code Group} is collection of {@link User}s.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CCM_GROUPS", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Group.findGroupByName",
query = "SELECT g FROM Group g WHERE g.name = :groupName"),
@NamedQuery(name = "Group.searchGroupByName",
query = "SELECT g FROM Group g "
+ "WHERE LOWER(g.name) LIKE '%:groupName%'")
})
@XmlRootElement(name = "user-group", namespace = CORE_XML_NS)
public class Group extends Subject implements Serializable {
private static final long serialVersionUID = -5555063356689597270L;
/**
* The name of the {@code Group}. Must be unique.
*/
@Column(name = "NAME", length = 512, unique = true, nullable = false)
@NotBlank
@XmlElement(name = "name", namespace = CORE_XML_NS)
private String name;
/**
* The {@link Role}s assigned to the {@code Group}.
*/
@OneToMany(mappedBy = "sourceGroup")
@XmlElementWrapper(name = "roles", namespace = CORE_XML_NS)
@XmlElement(name = "role", namespace = CORE_XML_NS)
private List<Role> roles;
/**
* The members of the group. For adding or removing members the methods
* provided by the {@link GroupManager} should be used.
*/
@OneToMany(mappedBy = "group")
@XmlElementWrapper(name = "group-memberships", namespace = CORE_XML_NS)
@XmlElement(name = "group-membership", namespace = CORE_XML_NS)
private List<GroupMembership> members;
public Group() {
super();
roles = new ArrayList<>();
members = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public List<Role> getRoles() {
if (roles == null) {
return null;
} else {
return Collections.unmodifiableList(roles);
}
}
protected void setRoles(final List<Role> roles) {
this.roles = roles;
}
protected void addRole(final Role role) {
roles.add(role);
}
protected void removeRole(final Role role) {
roles.remove(role);
}
public List<GroupMembership> getMembers() {
if (members == null) {
return null;
} else {
return Collections.unmodifiableList(members);
}
}
protected void setMembers(final List<GroupMembership> members) {
this.members = members;
}
protected void addMember(final GroupMembership member) {
members.add(member);
}
protected void removeMember(final GroupMembership member) {
members.remove(member);
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 83 * hash + Objects.hashCode(this.name);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Group)) {
return false;
}
final Group other = (Group) obj;
if (!other.canEqual(this)) {
return false;
}
return Objects.equals(this.name, other.getName());
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof Group;
}
@Override
public String toString(final String data) {
return super.toString(String.format(", name = \"%s\"%s",
name,
data));
}
}

View File

@ -1,147 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
/**
* Provides methods for managing the members of a {@link Group}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class GroupManager {
@Inject
private transient EntityManager entityManager;
@Inject
private transient GroupRepository groupRepository;
@Inject
private transient UserRepository userRepository;
/**
* Add a user to a group. If the user is already a member of the group, this
* method will do nothing.
*
* @param user The user to add to the group. If the value is {@code null}
* an {@link IllegalArgumentException} will be thrown.
* @param group The group to add the user to. If the value is {@code null}
* an {@link IllegalArgumentException} will be thrown.
*/
public void addUserToGroup(final User user, final Group group) {
if (user == null) {
throw new IllegalArgumentException(
"Can't add null as user to a group.");
}
if (group == null) {
throw new IllegalArgumentException("Can't add a user to group null");
}
if (isMemberOfGroup(user, group)) {
return;
}
final GroupMembership membership = new GroupMembership();
membership.setGroup(group);
membership.setUser(user);
group.addMember(membership);
user.addGroupMembership(membership);
entityManager.persist(membership);
groupRepository.save(group);
userRepository.save(user);
}
/**
* Remove a user from a group. If the user is not member of the group this
* method will do nothing.
*
* @param user The user to remove from the group. If the value is
* {@code null} an {@link IllegalArgumentException} will be
* thrown.
* @param group The group to remove the user from. If the value is
* {@code null} an {@link IllegalArgumentException} will be
* thrown.
*/
public void removeUserFromGroup(final User user, final Group group) {
if (user == null) {
throw new IllegalArgumentException(
"Can't remove user null from a group.");
}
if (group == null) {
throw new IllegalArgumentException(
"Can't remove a user from group null");
}
GroupMembership delete = null;
for(final GroupMembership membership : group.getMembers()) {
if (membership.getUser().equals(user)) {
delete = membership;
break;
}
}
if (delete != null) {
group.removeMember(delete);
user.removeGroupMembership(delete);
entityManager.remove(delete);
}
}
/**
* Determines if a user is member of a group.
*
* @param user The user to check. If the value is {@code null} an
* {@link IllegalArgumentException} will be thrown.
* @param group The group to check. If the value is {@code null} an
* {@link IllegalArgumentException} will be thrown.
*
* @return {@code true} if the provided user is a member of the provided
* group, {@code false} otherwise.
*/
public boolean isMemberOfGroup(final User user, final Group group) {
if (user == null) {
throw new IllegalArgumentException("Can't check null user");
}
if (group == null) {
throw new IllegalArgumentException("Can't check null group");
}
boolean result = false;
for (final GroupMembership membership : user.getGroupMemberships()) {
if (group.equals(membership.getGroup())) {
result = true;
break;
}
}
return result;
}
}

View File

@ -1,136 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
* An association class for the association between a group and it members.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "GROUP_MEMBERSHIPS", schema = DB_SCHEMA)
@XmlRootElement(name = "group-membership", namespace = CORE_XML_NS)
public class GroupMembership implements Serializable {
private static final long serialVersionUID = 1897274442468035089L;
@Id
@Column(name = "MEMBERSHIP_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement(name = "membership-id", namespace = CORE_XML_NS)
private long membershipId;
@ManyToOne
@XmlTransient
private Group group;
@ManyToOne
@XmlTransient
private User user;
public long getMembershipId() {
return membershipId;
}
protected void setMembershipId(final long membershipId) {
this.membershipId = membershipId;
}
public Group getGroup() {
return group;
}
protected void setGroup(final Group group) {
this.group = group;
}
public User getUser() {
return user;
}
protected void setUser(final User user) {
this.user = user;
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash
+ (int) (this.membershipId ^ (this.membershipId >>> 32));
hash = 37 * hash + Objects.hashCode(this.group);
hash = 37 * hash + Objects.hashCode(this.user);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof GroupMembership)) {
return false;
}
final GroupMembership other = (GroupMembership) obj;
if (!other.canEqual(this)) {
return false;
}
if (this.membershipId != other.getMembershipId()) {
return false;
}
if (!Objects.equals(this.group, other.getGroup())) {
return false;
}
return Objects.equals(this.user, other.getUser());
}
public boolean canEqual(final Object obj) {
return obj instanceof GroupMembership;
}
@Override
public String toString() {
return String.format("%s{ "
+ "membershipId = %d, "
+ "user = %s, "
+ "group = %s, "
+ " },",
super.toString(),
membershipId,
Objects.toString(user),
Objects.toString(group));
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;
/**
* A repository class for retrieving, storing and deleting {@link Group}s.
*
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class GroupRepository extends AbstractEntityRepository<Long, Group> {
@Inject
private transient EntityManager entityManager;
@Override
public Class<Group> getEntityClass() {
return Group.class;
}
@Override
public boolean isNew(final Group entity) {
if (entity == null) {
throw new IllegalArgumentException("Can't save null.");
}
return entity.getSubjectId() == 0;
}
public Group findByGroupName(final String groupName) {
final TypedQuery<Group> query = entityManager.createNamedQuery(
"Group.findGroupByName", Group.class);
query.setParameter("groupName", groupName);
final List<Group> result = query.getResultList();
//Check if result list is empty and if not return the first element.
//If their is a result than there can only be one because the
//name column of group has a unique constraint.
if (result.isEmpty()) {
return null;
} else {
return result.get(0);
}
}
public List<Group> searchGroupByName(final String groupName) {
final TypedQuery<Group> query = entityManager.createNamedQuery(
"Group.searchGroupByName", Group.class);
query.setParameter("groupName", groupName);
return query.getResultList();
}
}

View File

@ -1,302 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Represents a {@link Privilege} granted to a {@link Subject} on an
* {@link CcmObject} or all {@link CcmObject}s.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "PERMISSIONS", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Permission.findPermissionsForSubject",
query = "SELECT p FROM Permission p WHERE p.grantee = :subject"),
@NamedQuery(name = "Permission.findPermissionsForUser",
query = "SELECT p FROM Permission p "
+ "WHERE p.grantee = :user "
+ " OR p.grantee IN (SELECT g "
+ " FROM Group g JOIN g.members m"
+ " WHERE m.user = :user)"),
@NamedQuery(name = "Permission.findPermissionsForCcmObject",
query = "SELECT p FROM Permission p WHERE p.object = :object"),
@NamedQuery(name = "Permission.findPermissionsForUserPrivilegeAndObject",
query = "SELECT p FROM Permission p "
+ "WHERE (p.grantee = :user"
+ " OR p.grantee IN (SELECT g "
+ " FROM Group g JOIN g.members m"
+ " WHERE m.user = :user))"
+ " AND p.grantedPrivilege = :privilege"
+ " AND p.object = :object"),
@NamedQuery(name = "Permission.findWildcardPermissionsForUserPrivilegeAndObject",
query = "SELECT p FROM Permission p "
+ "WHERE (p.grantee = :user"
+ " OR p.grantee IN (SELECT g "
+ " FROM Group g JOIN g.members m"
+ " WHERE m.user = :user))"
+ " AND p.grantedPrivilege = :privilege"
+ " AND p.object IS NULL"),
@NamedQuery(name = "Permission.findPermissionsForSubjectPrivilegeAndObject",
query = "SELECT p FROM Permission p "
+ "WHERE p.grantee = :subject"
+ " AND p.grantedPrivilege = :privilege"
+ " AND p.object = :object"),
@NamedQuery(name = "Permission.findWildcardPermissionsForSubjectPrivilegeAndObject",
query = "SELECT p FROM Permission p "
+ "WHERE p.grantee = :subject"
+ " AND p.grantedPrivilege = :privilege"
+ " AND p.object IS NULL")
})
//Can't reduce complexity yet
@SuppressWarnings({"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity"})
@XmlRootElement(name = "permission", namespace = CORE_XML_NS)
public class Permission implements Serializable {
private static final long serialVersionUID = -2368935232499907547L;
/**
* The database id of the permission.
*/
@Id
@Column(name = "PERMISSION_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement(name = "permission-id", namespace = CORE_XML_NS)
private long permissionId;
/**
* The {@link Subject} (a {@link User} or a {@link Group}) to which the
* permission is granted. If the permission is granted to a {@link Group} all
* {@link User}s in that have the permission.
*/
@ManyToOne
@JoinColumn(name = "GRANTEE_ID")
private Subject grantee;
/**
* The {@link Privilege} granted by this {@code Permission}.
*/
@OneToOne
@JoinColumn(name = "GRANTED_PRIVILEGE_ID")
@XmlElement(name = "privilege", namespace = CORE_XML_NS)
private Privilege grantedPrivilege;
/**
* The {@link CcmObject} on which the permission is granted. If the the
* {@code object} is {@code null} the permission is granted for
* <strong>all</strong> objects.
*/
@ManyToOne
@JoinColumn(name = "OBJECT_ID")
private CcmObject object;
/**
* The {@link User} which created this {@code Permission}. The property can
* be {@code null} if this {@code Permission} was created by a system
* process.
*/
@ManyToOne
@JoinColumn(name = "CREATION_USER_ID")
@XmlElement(name = "creation-user", namespace = CORE_XML_NS)
private User creationUser;
/**
* The date and time on which this {@code Permission} was created. This
* property can be {@code null} if this {@code Permission} was created by a
* system process.
*/
@Column(name = "CREATION_DATE")
@Temporal(TemporalType.TIMESTAMP)
@XmlElement(name = "creation-date", namespace = CORE_XML_NS)
private Date creationDate;
/**
* The IP of the system from which this {@code Permission} was created. This
* property can be {@code null} if this {@code Permission} was created by a
* system process.
*/
@Column(name = "CREATION_IP")
@XmlElement(name = "creation-ip", namespace = CORE_XML_NS)
private String creationIp;
public long getPermissionId() {
return permissionId;
}
public void setPermissionId(final long permissionId) {
this.permissionId = permissionId;
}
public Subject getGrantee() {
return grantee;
}
protected void setGrantee(final Subject grantee) {
this.grantee = grantee;
}
public Privilege getGrantedPrivilege() {
return grantedPrivilege;
}
protected void setGrantedPrivilege(final Privilege grantedPrivilege) {
this.grantedPrivilege = grantedPrivilege;
}
public CcmObject getObject() {
return object;
}
protected void setObject(final CcmObject object) {
this.object = object;
}
public User getCreationUser() {
return creationUser;
}
public void setCreationUser(final User creationUser) {
this.creationUser = creationUser;
}
public Date getCreationDate() {
if (creationDate == null) {
return null;
} else {
return new Date(creationDate.getTime());
}
}
public void setCreationDate(final Date creationDate) {
this.creationDate = new Date(creationDate.getTime());
}
public String getCreationIp() {
return creationIp;
}
public void setCreationIp(final String creationIp) {
this.creationIp = creationIp;
}
@Override
public int hashCode() {
int hash = 3;
hash
= 31 * hash + (int) (permissionId ^ (permissionId >>> 32));
hash = 31 * hash + Objects.hashCode(grantee);
hash = 31 * hash + Objects.hashCode(grantedPrivilege);
hash = 31 * hash + Objects.hashCode(object);
hash = 31 * hash + Objects.hashCode(creationUser);
hash = 31 * hash + Objects.hashCode(creationDate);
hash = 31 * hash + Objects.hashCode(creationIp);
return hash;
}
@Override
//Can't reduce complexity yet
@SuppressWarnings({"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity",
"PMD.NPathComplexity"})
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Permission)) {
return false;
}
final Permission other = (Permission) obj;
if (!other.canEqual(this)) {
return false;
}
if (permissionId != other.getPermissionId()) {
return false;
}
if (!Objects.equals(grantee, other.getGrantee())) {
return false;
}
if (!Objects.equals(grantedPrivilege, other.getGrantedPrivilege())) {
return false;
}
if (!Objects.equals(object, other.getObject())) {
return false;
}
if (!Objects.equals(creationUser, other.getCreationUser())) {
return false;
}
if (!Objects.equals(creationDate, other.getCreationDate())) {
return false;
}
return Objects.equals(creationIp, other.getCreationIp());
}
public boolean canEqual(final Object obj) {
return obj instanceof Permission;
}
@Override
public String toString() {
return String.format("%s{ "
+ "permissionId = %d, "
+ "grantee = %s, "
+ "grantedPrivilege = %s, "
+ "object = %s, "
+ "creationUser = %s,"
+ "creationDate = %tF %<tT, "
+ "creationIp = %s"
+ " }",
super.toString(),
permissionId,
Objects.toString(grantee),
Objects.toString(grantedPrivilege),
Objects.toString(object),
Objects.toString(creationUser),
creationDate,
creationIp);
}
}

View File

@ -1,363 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import java.util.List;
/**
* This class provides methods for managing {@link Permission}s.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PermissionManager {
@Inject
@SuppressWarnings("PMD.LongVariable") //Nothing wrong with this name
private transient PermissionRepository permissionRepository;
@Inject
@SuppressWarnings("PMD.LongVariable") //Nothing wrong with this name
private transient PrivilegeRepository privilegeRepository;
@Inject
@SuppressWarnings("PMD.LongVariable") //Nothing wrong with this name
private transient CcmObjectRepository ccmObjectRepository;
@Inject
private transient SubjectRepository subjectRepository;
@Inject
private transient UserRepository userRepository;
/**
* Creates a new permission granting the provided {@code privilege} on the
* provided {@code object} to the provided {@code subject}. If the
* permission is already granted to the provided {@code subject} this method
* does nothing.
*
* @param privilege The privilege to grant. Can't be {@code null}.
* @param object The object on which the privilege is granted. Can be
* {@code null}.
* @param subject The subject to grant the privilege to. Can't be
* {@code null}.
*/
public void grantPermission(final Privilege privilege,
final CcmObject object,
final Subject subject) {
if (privilege == null) {
throw new IllegalArgumentException(
"Illegal argument 'null' provided for parameter privilege.");
}
if (subject == null) {
throw new IllegalArgumentException(
"Illegal argument 'null' provided for parameter subject");
}
if (!isPermitted(privilege, object, subject)) {
final Permission permission = new Permission();
permission.setGrantedPrivilege(privilege);
permission.setObject(object);
permission.setGrantee(subject);
subject.addGrantedPermission(permission);
subjectRepository.save(subject);
if (object != null) {
object.addPermission(permission);
ccmObjectRepository.save(object);
}
permissionRepository.save(permission);
}
}
/**
* Removes the permission granting the provided {@code privilege} on the
* provided {@code object} to the provided {@code subject}. If there is not
* permission granting the provided privilege on the provided {@code object}
* to the provided {@code subject} this method does nothing.
*
* @param privilege The privilege to revoke. Can't be {@code null}.
* @param object The object on which the privilege is revoked. Can be
* {@code null}.
* @param subject The subject to revoke the privilege from. Can't be
* {@code null}.
*/
public void revokePermission(final Privilege privilege,
final CcmObject object,
final Subject subject) {
final List<Permission> permissions = permissionRepository
.findPermissionsForSubjectPrivilegeAndObject(subject,
privilege,
object);
for (final Permission permission : permissions) {
if (object != null) {
object.removePermission(permission);
ccmObjectRepository.save(object);
}
subject.removeGrantedPermission(permission);
subjectRepository.save(subject);
permissionRepository.delete(permission);
}
}
/**
* Checks if the the provided {@code subject} has a permission granting the
* provided {@code privilege} on the provided {@code object}.
*
* The method will also check if the subject has a permission granting the
* {@code admin} privilege on the provided object or on all objects. The
* {@code admin} privilege implies that the user is granted all other
* privileges on the object.
*
* If the provided subject is {@code null} the method will try to retrieve
* the public user from the database. If there is no public user the method
* will return {@code false}.
*
* @param privilege The privilege to check. Can't be {@code null}.
* @param object The object on which the privilege is granted. Can't be
* {@code null}.
* @param subject The subject to which the privilege is granted. Can't be
* {@code null}.
*
* @return {@code true} of the subject has a permission granting
* {@code privilege} on {@code object}, either explicit or implicit.
*
* @see UserRepository#retrievePublicUser()
*/
public boolean isPermitted(final Privilege privilege,
final CcmObject object,
final Subject subject) {
if (privilege == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter privilege");
}
//Check if the current subject is null. If yes try to retrieve the
//public user
Subject subjectObj = null;
if (subject == null) {
final User publicUser = userRepository.retrievePublicUser();
if (publicUser == null) {
//If the public user is not available an null value for the
//subject parameter is an illegal argument.
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter privilege");
} else {
subjectObj = publicUser;
}
} else {
//Subject is not null. Use provided subject
subjectObj = subject;
}
//Depending if the subject is a user or a group delegate to the correct
//method. For users we have to check the permissions of the groups the
//user is member of also, for group we don't have.
if (subjectObj instanceof User) {
return isPermitted(privilege, object, (User) subjectObj);
} else if (subjectObj instanceof Group) {
return isPermitted(privilege, object, (Group) subjectObj);
} else {
//For unknown subclasses of subject return false.
return false;
}
}
/**
* Checks if a user has a permission granting a privilege on an object. If
* the provided {@code object} is {@code null} the method will only check
* for wildcard permission (permissions for all objects).
*
* @param privilege The privilege. Can't be {@code null}.
* @param object The object. Can be {@code null}.
* @param user The user. Can be {@code null}.
*
* @return {@code true} if the provided {@code user} has a permission
* granting the provided privilege for the provided object,
* {@code false} if not.
*/
@SuppressWarnings("PMD.CyclomaticComplexity")
private boolean isPermitted(final Privilege privilege,
final CcmObject object,
final User user) {
boolean result = false;
final Privilege admin = privilegeRepository.retrievePrivilege(
Privilege.ADMIN);
//Check if the there is direct permission granting the provided
//privilege on the provided object. If the object is null or the
//privilege is the admin privilege this check is not performed.
if (object != null && !privilege.equals(admin)) {
final List<Permission> permissions = permissionRepository
.findPermissionsForUserPrivilegeAndObject(user, privilege,
object);
result = !permissions.isEmpty();
}
//Check for an wildcard permission (a permission for all objects) for
//the provided privilege. This check is only performed when result is
//still false the provided privilege is not the admin privilege.
if (!result && !privilege.equals(admin)) {
final List<Permission> permissions = permissionRepository
.findPermissionsForUserPrivilegeAndObject(user, privilege, null);
result = !permissions.isEmpty();
}
//Check for a permission granting the admin privilege on the provided
//object. This check is only performed if result is still false,
//the admin variable is not null (null means that there is no admin
//privilege) and the provided object is not null.
if (!result && admin != null && object != null) {
final List<Permission> permissions = permissionRepository
.findPermissionsForUserPrivilegeAndObject(user,
admin,
object);
result = !permissions.isEmpty();
}
//Check for a permission granting the admin privilege systemwide. This
//check in only performed if result is still false and admin is not null.
if (!result && admin != null) {
final List<Permission> permissions = permissionRepository
.findPermissionsForUserPrivilegeAndObject(user,
admin,
null);
result = !permissions.isEmpty();
}
return result;
}
/**
* Checks if a {@link Group} is granted a {@link Privilege} on a
* {@link CcmObject} or on all {@link CcmObject}s.
*
* As for
* {@link #isPermitted(org.libreccm.core.Privilege, org.libreccm.core.CcmObject, org.libreccm.core.User)},
* this method also checks if the {@code admin} privilege was granted to the
* group for the provided {@code object} or for all objects.
*
* @param privilege The privilege. Can't be {@code null}.
* @param object The object. Can be {@code null}.
* @param group The group. Can't be {@code null}.
*
* @return {@code true} if the group has a permission granting the provided
* {@code privilege} on the the provided {@code object} (or on all
* objects), {@code false} of not.
*
* @see #isPermitted(org.libreccm.core.Privilege,
* org.libreccm.core.CcmObject, org.libreccm.core.Subject)
* @see #isPermitted(org.libreccm.core.Privilege,
* org.libreccm.core.CcmObject, org.libreccm.core.User)
*/
public boolean isPermitted(final Privilege privilege,
final CcmObject object,
final Group group) {
boolean result;
final List<Permission> directPermissions = permissionRepository
.findPermissionsForSubjectPrivilegeAndObject(group,
privilege,
object);
result = !directPermissions.isEmpty();
if (!result) {
final List<Permission> permissions = permissionRepository
.findPermissionsForSubjectPrivilegeAndObject(group,
privilege,
null);
result = !permissions.isEmpty();
}
if (!result) {
final Privilege admin = privilegeRepository.retrievePrivilege(
"admin");
if (admin != null) {
final List<Permission> permissions = permissionRepository
.findPermissionsForSubjectPrivilegeAndObject(group,
admin,
object);
result = !permissions.isEmpty();
}
}
if (!result) {
final Privilege admin = privilegeRepository.retrievePrivilege(
"admin");
if (admin != null) {
final List<Permission> permissions = permissionRepository
.findPermissionsForSubjectPrivilegeAndObject(group,
admin,
null);
result = !permissions.isEmpty();
}
}
return result;
}
/**
* Checks if the the provided {@code subject} has a permission granting the
* provided {@code privilege} on the provided {@code object}.
*
* If the provided subject is {@code null} the method will try to retrieve
* the public user from the database. If there is no public user the method
* will return {@code false}.
*
* Internally this methods calls
* {@link #isPermitted(org.libreccm.core.Privilege, org.libreccm.core.CcmObject, org.libreccm.core.Subject)}
* and throws an {@link UnauthorizedAcccessException} if the return value is
* {@code null}.
*
* @param privilege The privilege to check. Can't be {@code null}.
* @param object The object on which the privilege is granted. Can't be
* {@code null}.
* @param subject The subject to which the privilege is granted. Can't be
* {@code null}.
*
* @throws UnauthorizedAcccessException If there is no permission granting
* {@code privilege} on {@code object}
* to {@code subject}
*
* @see #isPermitted(org.libreccm.core.Privilege,
* org.libreccm.core.CcmObject, org.libreccm.core.Subject)
*/
public void checkPermission(final Privilege privilege,
final CcmObject object,
final Subject subject)
throws UnauthorizedAcccessException {
if (!isPermitted(privilege, object, subject)) {
throw new UnauthorizedAcccessException(String.format(
"Privilege \"%s\" has not been granted to subject \"%s\" "
+ "on object \"%s\".",
privilege.getLabel(),
subject.toString(),
object.toString()));
}
}
}

View File

@ -1,202 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;
/**
* Repository class for retrieving, storing and deleting permissions.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PermissionRepository
extends AbstractEntityRepository<Long, Permission> {
@Inject
private transient EntityManager entityManager;
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
@Override
public Class<Permission> getEntityClass() {
return Permission.class;
}
/**
* {@inheritDoc }
*
* @param entity {@inheritDoc }
*
* @return {@inheritDoc }
*/
@Override
public boolean isNew(final Permission entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity to save can't be null.");
}
return entity.getPermissionId() == 0;
}
/**
* Finds all permissions granted to a specific subject (either a user or
* group).
*
* Please note that this method does <strong>not</strong> find permissions
* granted to a user by the groups a user is member of. To get these
* permissions also use the
* {@link #findPermissionsForUser(org.libreccm.core.User)} method instead.
*
* @param subject The subject.
*
* @return All permissions granted to the provided subject.
*/
public List<Permission> findPermissionsForSubject(final Subject subject) {
if (subject == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter subject.");
}
final TypedQuery<Permission> query = entityManager.createNamedQuery(
"Permission.findPermissionsForSubject", Permission.class);
query.setParameter("subject", subject);
return query.getResultList();
}
/**
* Finds a permissions granted to a user and to the groups the user is
* member of.
*
* If you only need the permissions assigned to the user itself use the
* {@link #findPermissionsForSubject(org.libreccm.core.Subject)} method.
*
* @param user The user.
*
* @return All permissions granted to the user or the groups the user is
* member of.
*/
public List<Permission> findPermissionsForUser(final User user) {
if (user == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter user");
}
final TypedQuery<Permission> query = entityManager.createNamedQuery(
"Permission.findPermissionsForUser", Permission.class);
query.setParameter("user", user);
return query.getResultList();
}
/**
* Finds all permissions granted on a object.
*
* @param object The object.
*
* @return All permissions granted on the object.
*/
public List<Permission> findPermissionsForCcmObject(final CcmObject object) {
if (object == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter object.");
}
final TypedQuery<Permission> query = entityManager.createNamedQuery(
"Permission.findPermissionsForCcmObject", Permission.class);
query.setParameter("object", object);
return query.getResultList();
}
public List<Permission> findPermissionsForUserPrivilegeAndObject(
final User user,
final Privilege privilege,
final CcmObject object) {
if (user == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter user");
}
if (privilege == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter privilege");
}
final TypedQuery<Permission> query;
if (object == null) {
query = entityManager.createNamedQuery(
"Permission.findWildcardPermissionsForUserPrivilegeAndObject",
Permission.class);
} else {
query = entityManager.createNamedQuery(
"Permission.findPermissionsForUserPrivilegeAndObject", Permission.class);
query.setParameter("object", object);
}
query.setParameter("user", user);
query.setParameter("privilege", privilege);
return query.getResultList();
}
public List<Permission> findPermissionsForSubjectPrivilegeAndObject(
final Subject subject,
final Privilege privilege,
final CcmObject object) {
if (subject == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter subject");
}
if (privilege == null) {
throw new IllegalArgumentException(
"Illegal value 'null' provided for parameter privilege");
}
final TypedQuery<Permission> query;
if (object == null) {
query = entityManager.createNamedQuery(
"Permission.findWildcardPermissionsForSubjectPrivilegeAndObject",
Permission.class);
} else {
query = entityManager.createNamedQuery(
"Permission.findPermissionsForSubjectPrivilegeAndObject", Permission.class);
query.setParameter("object", object);
}
query.setParameter("subject", subject);
query.setParameter("privilege", privilege);
return query.getResultList();
}
}

View File

@ -1,158 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import org.hibernate.validator.constraints.NotBlank;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* An embeddable entity representing a person's name.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Embeddable
@XmlRootElement(name = "person-name", namespace = CORE_XML_NS)
public class PersonName implements Serializable {
private static final long serialVersionUID = -5805626320605809172L;
@Column(name = "TITLE_PRE", length = 512)
@XmlElement(name = "title-pre", namespace = CORE_XML_NS)
private String titlePre;
@Column(name = "GIVEN_NAME", length = 512)
@NotBlank
@XmlElement(name = "given-name", namespace = CORE_XML_NS)
private String givenName;
@Column(name = "MIDDLE_NAME", length = 512)
@XmlElement(name = "middle-name", namespace = CORE_XML_NS)
private String middleName;
@Column(name = "FAMILY_NAME", length = 512)
@NotBlank
@XmlElement(name = "family-name", namespace = CORE_XML_NS)
private String familyName;
@Column(name = "TITLE_POST", length = 512)
@XmlElement(name = "title-post", namespace = CORE_XML_NS)
private String titlePost;
public String getTitlePre() {
return titlePre;
}
public void setTitlePre(final String titlePre) {
this.titlePre = titlePre;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(final String givenName) {
this.givenName = givenName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(final String middleName) {
this.middleName = middleName;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(final String familyName) {
this.familyName = familyName;
}
public String getTitlePost() {
return titlePost;
}
public void setTitlePost(final String titlePost) {
this.titlePost = titlePost;
}
@Override
public int hashCode() {
int hash = 5;
hash = 37 * hash + Objects.hashCode(this.titlePre);
hash = 37 * hash + Objects.hashCode(this.givenName);
hash = 37 * hash + Objects.hashCode(this.middleName);
hash = 37 * hash + Objects.hashCode(this.familyName);
hash = 37 * hash + Objects.hashCode(this.titlePost);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof PersonName)) {
return false;
}
final PersonName other = (PersonName) obj;
if (!Objects.equals(this.titlePre, other.getTitlePre())) {
return false;
}
if (!Objects.equals(this.givenName, other.getGivenName())) {
return false;
}
if (!Objects.equals(this.middleName, other.getMiddleName())) {
return false;
}
if (!Objects.equals(this.familyName, other.getFamilyName())) {
return false;
}
return Objects.equals(this.titlePost, other.getTitlePost());
}
@Override
public String toString() {
return String.format("%s{ "
+ "titlePre = \"%s\", "
+ "givenName = \"%s\", "
+ "middleName = \"%s\", "
+ "familyName = \"%s\", "
+ "titlePost = \"%s\""
+ " }",
super.toString(),
titlePre,
givenName,
middleName,
familyName,
titlePost);
}
}

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Privileges are used the create {@link Permission}s for specific operations.
* Modules can create {@code Privilege}s by using the
* {@link PrivilegeRepository}.
*
* This class is an JPA implementation of the PDL object type
* {@code com.arsdigita.kernel.permissions.Privilege} which has been implemented
* as an JPA entity. In future releases this class will may refactored to an
* {@code enum}. After the class has been refactored to an {@code enum} it is
* not longer necessary to store the available privileges in the database.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CCM_PRIVILEGES", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Privilege.findPrivilegeByName",
query = "SELECT p FROM Privilege p "
+ "WHERE p.label = :label"),
@NamedQuery(name = "Privilege.isPrivilegeInUse",
query = "SELECT COUNT(p) FROM Permission p "
+ " JOIN p.grantedPrivilege g "
+ " WHERE g.label = :label")
})
@XmlRootElement(name = "PRIVILEGE", namespace = CORE_XML_NS)
public class Privilege implements Serializable {
private static final long serialVersionUID = -3986038536996049440L;
/**
* Constant for the {@code admin} privilege because this privilege is used
* very often.
*/
public static final String ADMIN = "admin";
/**
* ID for the privilege.
*/
@Id
@Column(name = "PRIVILEGE_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement(name = "privilege-id", namespace = CORE_XML_NS)
private long privilegeId;
/**
* The label of the {@code Privilege}.
*/
@Column(name = "LABEL", length = 255, nullable = false, unique = true)
@XmlElement(name = "label", namespace = CORE_XML_NS)
private String label;
public long getPrivilegeId() {
return privilegeId;
}
public void setPrivilegeId(final long privilegeId) {
this.privilegeId = privilegeId;
}
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
@Override
public int hashCode() {
int hash = 7;
hash = 43 * hash + (int) (privilegeId ^ (privilegeId >>> 32));
hash = 43 * hash + Objects.hashCode(label);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Privilege)) {
return false;
}
final Privilege other = (Privilege) obj;
if (!other.canEqual(this)) {
return false;
}
if (privilegeId != other.getPrivilegeId()) {
return false;
}
return Objects.equals(label, other.getLabel());
}
public boolean canEqual(final Object obj) {
return obj instanceof Privilege;
}
@Override
public String toString() {
return String.format("%s{ "
+ "privilegeId = %d, "
+ "privilege = \"%s\""
+ " }",
super.toString(),
privilegeId,
label);
}
}

View File

@ -1,122 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
/**
* Repository class for retrieving and creating new {@link Privilege}s.
*
* When the {@link Privilege} class is refactored to an enum this class will be
* removed.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PrivilegeRepository {
@Inject
private transient EntityManager entityManager;
/**
* Finds the {@link Privilege} identified by {@code name}.
*
* @param label The name of the privilege to return.
*
* @return The requested privilege.
*
* @throws UnknownPrivilegeException if there is no privilege identified by
* the provided {@code name}.
*/
public Privilege retrievePrivilege(final String label) {
final TypedQuery<Privilege> query = entityManager.createNamedQuery(
"Privilege.findPrivilegeByName", Privilege.class);
query.setParameter("label", label);
try {
return query.getSingleResult();
} catch (NoResultException ex) {
throw new UnknownPrivilegeException(String.format(
"There is no privilege \"%s\".", label), ex);
}
}
/**
* Creates a new {@link Privilege}.
*
* This method can only be invoked by the system user.
*
* ToDo: Check if current user is system user.
*
* @param label The privilege to create.
*
* @return The new privilege.
*/
public Privilege createPrivilege(final String label) {
final Privilege privilege = new Privilege();
privilege.setLabel(label);
entityManager.persist(privilege);
return privilege;
}
/**
* Deletes a {@link Privilege}.
*
* ToDo: Check if current user is system user.
*
* @param privilegeName The privilege to delete.
*
* @throws UnknownPrivilegeException if there is no privilege identified by
* the provided {@code name}.
*/
public void deletePrivilege(final String privilegeName) {
if (isPrivilegeInUse(privilegeName)) {
throw new IllegalArgumentException(
"Provided privilage can't be removed because its still in use");
}
final Privilege privilege = retrievePrivilege(privilegeName);
entityManager.remove(privilege);
}
/**
* Checks a {@link Privilege} is in use.
*
* @param label The name of the privilege to check.
*
* @return {@code true} if the privilege is in use (there is a least one
* permission using it), {@code false} otherwise.
*/
public boolean isPrivilegeInUse(final String label) {
final TypedQuery<Long> query = entityManager.createNamedQuery(
"Privilege.isPrivilegeInUse", Long.class);
query.setParameter("label", label);
final Long result = query.getSingleResult();
return result > 0;
}
}

View File

@ -1,194 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.validator.constraints.NotBlank;
import static org.libreccm.core.CoreConstants.*;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
/**
* A role can be assigned to a group. This class was migrated from the old CCM
* code (com.arsdigita.kernel.Role}. Obviously it does not more than to provide
* an named association between to groups.
*
* @todo Check if this class can be removed or refactored to make the whole
* system of users, groups and permissions simpler.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CCM_ROLES", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Role.findRolesForName",
query = "SELECT r FROM Role r "
+ "WHERE r.name = :roleName "
+ "ORDER BY r.name"),
@NamedQuery(name = "Role.findRolesForSourceGroup",
query = "SELECT r FROM Role r "
+ "WHERE r.sourceGroup = :sourceGroup "
+ "ORDER BY r.name"),
@NamedQuery(name = "Role.findRolesForImplicitGroup",
query = "SELECT r FROM Role r "
+ "WHERE r.implicitGroup = :implicitGroup "
+ "ORDER BY r.name")
})
@SuppressWarnings("PMD.ShortClassName") //Role is perfectly fine name.
public class Role implements Serializable {
private static final long serialVersionUID = 3314358449751376350L;
@Id
@Column(name = "ROLE_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long roleId;
@Column(name = "NAME", length = 512)
@NotBlank
private String name;
@ManyToOne
@JoinColumn(name = "SOURCE_GROUP_ID")
private Group sourceGroup;
@OneToOne
@JoinColumn(name = "IMPLICIT_GROUP_ID")
private Group implicitGroup;
@Column(name = "DESCRIPTION")
private String description;
public Role() {
//Nothing
}
public long getRoleId() {
return roleId;
}
public void setRoleId(final long roleId) {
this.roleId = roleId;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public Group getSourceGroup() {
return sourceGroup;
}
protected void setSourceGroup(final Group sourceGroup) {
this.sourceGroup = sourceGroup;
}
public Group getImplicitGroup() {
return implicitGroup;
}
protected void setImplicitGroup(final Group implicitGroup) {
this.implicitGroup = implicitGroup;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (int) (this.roleId ^ (this.roleId >>> 32));
hash = 59 * hash + Objects.hashCode(this.name);
hash = 59 * hash + Objects.hashCode(this.sourceGroup);
hash = 59 * hash + Objects.hashCode(this.implicitGroup);
hash = 59 * hash + Objects.hashCode(this.description);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Role)) {
return false;
}
final Role other = (Role) obj;
if (!other.canEqual(this)) {
return false;
}
if (this.roleId != other.getRoleId()) {
return false;
}
if (!Objects.equals(this.name, other.getName())) {
return false;
}
if (!Objects.equals(this.sourceGroup, other.getSourceGroup())) {
return false;
}
if (!Objects.equals(this.implicitGroup, other.getImplicitGroup())) {
return false;
}
return Objects.equals(this.description, other.getDescription());
}
public boolean canEqual(final Object obj) {
return obj instanceof Role;
}
@Override
public String toString() {
return String.format("%s{ "
+ "roleId = %d, "
+ "name = \"%s\", "
+ "sourceGroup = %s, "
+ "implicitGroup = %s, "
+ " }",
super.toString(),
roleId,
name,
Objects.toString(sourceGroup),
Objects.toString(implicitGroup));
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class RoleRepository extends AbstractEntityRepository<Long, Role> {
@Inject
private transient EntityManager entityManager;
@Override
public Class<Role> getEntityClass() {
return Role.class;
}
@Override
public boolean isNew(final Role entity) {
if (entity == null) {
throw new IllegalArgumentException("Role to save can't be null.");
}
return entity.getRoleId() == 0;
}
/**
* Find role(s) by name. There can be several roles with the same name.
*
* @param roleName
* @return A list of roles identified by name.
*/
public List<Role> findRolesForName(final String roleName) {
final TypedQuery<Role> query = entityManager.createNamedQuery(
"Role.findRolesForName", Role.class);
query.setParameter("roleName", roleName);
return query.getResultList();
}
public List<Role> findRolesForSourceGroup(final Group group) {
final TypedQuery<Role> query = entityManager.createNamedQuery(
"Role.findRolesForSourceGroup", Role.class);
query.setParameter("sourceGroup", group);
return query.getResultList();
}
public List<Role> findRolesForImplicitGroup(final Group group) {
final TypedQuery<Role> query = entityManager.createNamedQuery(
"Role.findRolesForImplicitGroup", Role.class);
query.setParameter("implicitGroup", group);
return query.getResultList();
}
}

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import java.io.Serializable;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Internal basic class for {@link User} and {@link Group}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "SUBJECTS", schema = DB_SCHEMA)
@Inheritance(strategy = InheritanceType.JOINED)
@XmlRootElement(name = "subject", namespace = CORE_XML_NS)
public class Subject implements Serializable {
private static final long serialVersionUID = 6303836654273293979L;
@Id
@Column(name = "SUBJECT_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long subjectId;
@OneToMany(mappedBy = "grantee")
//Can't shorten this variable name without reducing descriptiveness
@SuppressWarnings("PMD.LongVariable")
@XmlElementWrapper(name = "granted-permissions", namespace = CORE_XML_NS)
@XmlElement(name = "granted-permission", namespace = CORE_XML_NS)
private List<Permission> grantedPermissions;
public Subject() {
super();
grantedPermissions = new ArrayList<>();
}
public long getSubjectId() {
return subjectId;
}
protected void setSubjectId(final long subjectId) {
this.subjectId = subjectId;
}
public List<Permission> getGrantedPermissions() {
return Collections.unmodifiableList(grantedPermissions);
}
//Can't shorten this variable name without reducing descriptiveness
@SuppressWarnings("PMD.LongVariable")
protected void setGrantedPermissions(
final List<Permission> grantedPermissions) {
this.grantedPermissions = grantedPermissions;
}
protected void addGrantedPermission(final Permission permission) {
grantedPermissions.add(permission);
}
protected void removeGrantedPermission(final Permission permission) {
grantedPermissions.remove(permission);
}
@Override
public int hashCode() {
int hash = 7;
hash = 53 * hash + (int) (subjectId ^ (subjectId >>> 32));
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Subject)) {
return false;
}
final Subject other = (Subject) obj;
if (!other.canEqual(this)) {
return false;
}
if (subjectId != other.getSubjectId()) {
return false;
}
return subjectId == other.getSubjectId();
}
public boolean canEqual(final Object obj) {
return obj instanceof Subject;
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format("%s{ "
+ "subjectId = %d, "
+ "%s"
+ " }",
super.toString(),
subjectId,
data);
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class SubjectRepository extends AbstractEntityRepository<Long, Subject> {
@Override
public Class<Subject> getEntityClass() {
return Subject.class;
}
@Override
public boolean isNew(final Subject entity) {
return entity.getSubjectId() == 0;
}
}

View File

@ -1,449 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import org.hibernate.validator.constraints.NotBlank;
import org.libreccm.docrepo.Repository;
import org.libreccm.docrepo.Resource;
import javax.persistence.AssociationOverride;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static org.libreccm.core.CoreConstants.CORE_XML_NS;
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
/**
* The {@code User} entity stores the name and the password of a user along with
* some other informations.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CCM_USERS", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "User.findUserByScreenName",
query = "SELECT u FROM User u WHERE u.screenName = :screenname"),
@NamedQuery(name = "User.findUserByEmailAddress",
query = "SELECT u FROM User u JOIN u.emailAddresses e "
+ "WHERE e.address = :emailAddress")})
@XmlRootElement(name = "user", namespace = CORE_XML_NS)
//Supressing a few warnings from PMD because they misleading here.
//User is perfectly fine class name, and the complexity is not to high...
@SuppressWarnings({"PMD.ShortClassName",
"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity",
"PMD.GodClass"})
public class User extends Subject implements Serializable {
private static final long serialVersionUID = 892038270064849732L;
/**
* The real name of the user. We are using an {@code Embeddable} here.
*/
@Embedded
@AssociationOverride(
name = "USER_NAMES",
joinTable = @JoinTable(name = "USER_NAMES",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "USER_ID")}))
@XmlElement(name = "person-name", namespace = CORE_XML_NS)
private PersonName name;
/**
* A user name of the user. Usually an abbreviation of the users real name.
* For example a the <em>John Doe</em> might have the scree name
* <code>jdoe</code>. The screen name is used as user name for logins (if
* the system if configured so, otherwise the email address of the user is
* used).
*/
@Column(name = "SCREEN_NAME", length = 255, nullable = false, unique = true)
@NotBlank
@XmlElement(name = "screen-name", namespace = CORE_XML_NS)
private String screenName;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "USER_EMAIL_ADDRESSES",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "USER_ID")})
@Size(min = 1)
@XmlElementWrapper(name = "email-addresses", namespace = CORE_XML_NS)
@XmlElement(name = "email-address", namespace = CORE_XML_NS)
private List<EmailAddress> emailAddresses;
/**
* A user can be banned which means that he or she can't login into the
* system anymore.
*/
@Column(name = "BANNED")
@XmlElement(name = "banned", namespace = CORE_XML_NS)
private boolean banned;
/**
* An alias for the user used in an another system for SSO, for example
* LDAP.
*/
@Column(name = "SSO_LOGIN", length = 512)
@XmlElement(name = "sso-login", namespace = CORE_XML_NS)
private String ssoLogin;
/**
* The hashed password of the user.
*/
@Column(name = "PASSWORD", length = 2048)
@XmlTransient
private String password;
/**
* The salt used to hash the password.
*/
@Column(name = "SALT", length = 2048)
@XmlTransient
private String salt;
/**
* The hash algorithm used to hash the password. This allows us the change
* to another, stronger hash algorithm without invalidating existing
* accounts. The algorithm to use for new passwords can be configured by the
* administrator.
*
*/
@Column(name = "HASH_ALGORITHM", length = 64)
@XmlTransient
private String hashAlgorithm;
/**
* Indicates that the user should be forced to change his or her password on
* the next login.
*/
@Column(name = "PASSWORD_RESET_REQUIRED")
//Can't shorten the name without making the name cryptic.
@SuppressWarnings("PMD.LongVariable")
private boolean passwordResetRequired;
/**
* Question the recover a forgotten password.
*/
@Column(name = "PASSWORD_QUESTION", length = 2048)
@XmlElement(name = "password-question", namespace = CORE_XML_NS)
private String passwordQuestion;
/**
* Answer the the {@link #passwordQuestion}.
*/
@Column(name = "PASSWORD_ANSWER", length = 2048)
@XmlElement(name = "password-answer", namespace = CORE_XML_NS)
private String passwordAnswer;
/**
* The groups of which the user is a member.
*/
@OneToMany(mappedBy = "user")
@XmlElementWrapper(name = "group-memberships")
@XmlElement(name = "group-membership", namespace = CORE_XML_NS)
private List<GroupMembership> groupMemberships;
/**
* The {@link Resource}s created by this {@code User}.
*/
@OneToMany(mappedBy = "creationUser")
private List<Resource> createdResources;
/**
* The {@link Resource}s modified by this {@code User}.
*/
@OneToMany(mappedBy = "lastModifiedUser")
private List<Resource> modifiedResources;
/**
* The {@link Repository}s owned by this {@code User}.
*/
@OneToMany(mappedBy = "owner")
private List<Repository> repositories;
public User() {
super();
name = new PersonName();
emailAddresses = new ArrayList<>();
this.groupMemberships = new ArrayList<>();
}
public PersonName getName() {
return name;
}
public void setName(final PersonName name) {
this.name = name;
}
public String getScreenName() {
return screenName;
}
public void setScreenName(final String screenName) {
this.screenName = screenName;
}
public List<EmailAddress> getEmailAddresses() {
if (emailAddresses == null) {
return null;
} else {
return Collections.unmodifiableList(emailAddresses);
}
}
protected void setEmailAddresses(final List<EmailAddress> eMailAddresses) {
this.emailAddresses = eMailAddresses;
}
public void addEmailAddress(final EmailAddress emailAddress) {
emailAddresses.add(emailAddress);
}
public void removeEmailAddress(final EmailAddress emailAddress) {
emailAddresses.remove(emailAddress);
}
public boolean isBanned() {
return banned;
}
public void setBanned(final boolean banned) {
this.banned = banned;
}
public String getSsoLogin() {
return ssoLogin;
}
public void setSsoLogin(final String ssoLogin) {
this.ssoLogin = ssoLogin;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(final String salt) {
this.salt = salt;
}
public String getHashAlgorithm() {
return hashAlgorithm;
}
public void setHashAlgorithm(final String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
public boolean isPasswordResetRequired() {
return passwordResetRequired;
}
@SuppressWarnings("PMD.LongVariable")
public void setPasswordResetRequired(final boolean passwordResetRequired) {
this.passwordResetRequired = passwordResetRequired;
}
public String getPasswordQuestion() {
return passwordQuestion;
}
public void setPasswordQuestion(final String passwordQuestion) {
this.passwordQuestion = passwordQuestion;
}
public String getPasswordAnswer() {
return passwordAnswer;
}
public void setPasswordAnswer(final String passwordAnswer) {
this.passwordAnswer = passwordAnswer;
}
public List<GroupMembership> getGroupMemberships() {
return Collections.unmodifiableList(groupMemberships);
}
protected void setGroupMemberships(
final List<GroupMembership> groupMemberships) {
this.groupMemberships = groupMemberships;
}
protected void addGroupMembership(final GroupMembership groupMembership) {
groupMemberships.add(groupMembership);
}
protected void removeGroupMembership(
final GroupMembership groupMembership) {
groupMemberships.remove(groupMembership);
}
public List<Resource> getCreatedResources() {
return createdResources;
}
public void setCreatedResources(List<Resource> createdResources) {
this.createdResources = createdResources;
}
public List<Resource> getModifiedResources() {
return modifiedResources;
}
public void setModifiedResources(List<Resource> modifiedResources) {
this.modifiedResources = modifiedResources;
}
public List<Repository> getRepositories() {
return repositories;
}
public void setRepositories(List<Repository> repositories) {
this.repositories = repositories;
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 59 * hash + Objects.hashCode(name);
hash = 59 * hash + Objects.hashCode(screenName);
hash = 59 * hash + (banned ? 1 : 0);
hash = 59 * hash + Objects.hashCode(ssoLogin);
hash = 59 * hash + Objects.hashCode(password);
hash = 59 * hash + Objects.hashCode(salt);
hash = 59 * hash + Objects.hashCode(hashAlgorithm);
hash = 59 * hash + (passwordResetRequired ? 1 : 0);
hash = 59 * hash + Objects.hashCode(passwordQuestion);
hash = 59 * hash + Objects.hashCode(passwordAnswer);
return hash;
}
@Override
//Can't reduce complexity yet
@SuppressWarnings({"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity",
"PMD.NPathComplexity"})
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
if (!(obj instanceof User)) {
return false;
}
final User other = (User) obj;
if (!other.canEqual(this)) {
return false;
}
if (!Objects.equals(name, other.getName())) {
return false;
}
if (!Objects.equals(screenName, other.getScreenName())) {
return false;
}
if (banned != other.isBanned()) {
return false;
}
if (!Objects.equals(ssoLogin, other.getSsoLogin())) {
return false;
}
if (!Objects.equals(password, other.getPassword())) {
return false;
}
if (!Objects.equals(salt, other.getSalt())) {
return false;
}
if (!Objects.equals(hashAlgorithm, other.getHashAlgorithm())) {
return false;
}
if (passwordResetRequired != other.isPasswordResetRequired()) {
return false;
}
if (!Objects.equals(passwordQuestion, other.getPasswordQuestion())) {
return false;
}
return Objects.equals(passwordAnswer, other.getPasswordAnswer());
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof User;
}
@Override
public String toString(final String data) {
return super.toString(String.format(", name = %s, "
+ "screenName = \"%s\", "
+ "emailAddress = { %s }"
+ "banned = %b, "
+ "ssoLogin = \"%s\" "
+ "hashAlgorithm = \"%s\" "
+ "passwordResetRequired = %b%s",
Objects.toString(name),
screenName,
Objects.toString(emailAddresses),
banned,
ssoLogin,
hashAlgorithm,
passwordResetRequired,
data));
}
}

View File

@ -1,172 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
* This class provides complex operations on {@link User} objects like updating
* the password. To use this class add an injection point to your class.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class UserManager {
/**
* {@link UserRepository} for interacting with the database. The method
* takes care of hashing the password with random salt.
*
*/
@Inject
private transient UserRepository userRepository;
/**
* Helper method for generating an password hash.
*
* @param password The password to hash.
* @param salt The salt to append.
*
* @return The password hash.
*/
private byte[] generateHash(final byte[] password, final byte[] salt) {
final byte[] saltedPassword = new byte[password.length + salt.length];
System.arraycopy(password, 0, saltedPassword, 0, password.length);
System.arraycopy(salt, 0, saltedPassword, password.length, salt.length);
try {
final MessageDigest digest = MessageDigest.getInstance(
getHashAlgorithm());
final byte[] hashedPassword = digest.digest(saltedPassword);
return hashedPassword;
} catch (NoSuchAlgorithmException ex) {
throw new PasswordHashingFailedException(
"Failed to generate hash for password", ex);
}
}
/**
* Update the password of an user.
*
* @param user The user whose password is to be updated.
* @param password The new password.
*/
public void updatePassword(final User user, final String password) {
final Random random = new Random(System.currentTimeMillis());
final byte[] passwordBytes = password.getBytes(
StandardCharsets.UTF_8);
final byte[] salt = new byte[getSaltLength()];
random.nextBytes(salt);
final byte[] hashedBytes = generateHash(passwordBytes, salt);
final Base64 base64 = new Base64();
final String hashedPassword = base64.encodeToString(hashedBytes);
final String saltStr = base64.encodeToString(salt);
user.setPassword(hashedPassword);
user.setSalt(saltStr);
userRepository.save(user);
}
/**
* Verify a password for the a specific user.
*
* @param user The user whose password is to be checked.
* @param password The password to verify.
*
* @return {@code true} if the provided password matches the password
* stored, {@code false} if not.
*/
public boolean verifyPasswordForUser(final User user,
final String password) {
final Base64 base64 = new Base64();
final byte[] hashed = generateHash(
password.getBytes(StandardCharsets.UTF_8),
base64.decode(user.getSalt()));
final String hashedPassword = base64.encodeAsString(hashed);
return hashedPassword.equals(user.getPassword());
}
public boolean verifyPasswordForScreenname(final String screenname,
final String password)
throws UserNotFoundException {
final User user = userRepository.findByScreenName(screenname);
if (user == null) {
throw new UserNotFoundException(String.format(
"No user identified by screenname '%s' found.", screenname));
} else {
return verifyPasswordForUser(user, password);
}
}
public boolean verifyPasswordForEmail(final String emailAddress,
final String password)
throws UserNotFoundException {
final User user = userRepository.findByEmailAddress(emailAddress);
if (user == null) {
throw new UserNotFoundException(String.format(
"No user identified by email address '%s' found.", emailAddress));
} else {
return verifyPasswordForUser(user, password);
}
}
/**
* Gets the hash algorithm to use.
*
* ToDo: Make configurable.
*
* @return At the moment SHA-512, will be made configurable.
*/
public String getHashAlgorithm() {
return "SHA-512";
}
/**
* Returns the length for the salt (number of bytes).
*
* ToDo: Make configurable.
*
* @return At the moment 256. Will be made configurable.
*/
public int getSaltLength() {
return 256;
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
/**
* Thrown by several methods of the {@link UserManager} if a {@link User} can't
* be found.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class UserNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of <code>UserNotFoundException</code> without detail message.
*/
public UserNotFoundException() {
super();
}
/**
* Constructs an instance of <code>UserNotFoundException</code> with the specified detail message.
*
* @param msg The detail message.
*/
public UserNotFoundException(final String msg) {
super(msg);
}
/**
* Constructs an instance of <code>UserNotFoundException</code> which wraps the
* specified exception.
*
* @param exception The exception to wrap.
*/
public UserNotFoundException(final Exception exception) {
super(exception);
}
/**
* Constructs an instance of <code>UserNotFoundException</code> with the specified message which also wraps the
* specified exception.
*
* @param msg The detail message.
* @param exception The exception to wrap.
*/
public UserNotFoundException(final String msg, final Exception exception) {
super(msg, exception);
}
}

View File

@ -1,151 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.TypedQuery;
/**
* Provides methods for retrieving, storing and deleting {@link User} objects.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class UserRepository extends AbstractEntityRepository<Long, User> {
@Inject
private transient PrivilegeRepository privilegeRepository;
@Override
public Class<User> getEntityClass() {
return User.class;
}
@Override
public boolean isNew(final User entity) {
if (entity == null) {
throw new IllegalArgumentException("Can't save null.");
}
return entity.getSubjectId() == 0;
}
/**
* Retrieves the internal system user which is permitted to execute almost
* every operation.
*
* @return The internal system user.
*/
public User retrieveSystemUser() {
final User systemUser = new User();
systemUser.setScreenName("system");
final Privilege adminPrivilege = privilegeRepository.retrievePrivilege(
"admin");
final Permission systemPermission = new Permission();
systemPermission.setGrantee(systemUser);
systemPermission.setGrantedPrivilege(adminPrivilege);
systemUser.addGrantedPermission(systemPermission);
return systemUser;
}
/**
* Retrieves the public user. The public user is used to represent the
* privileges of a user which is not logged in. The public user is a
* ordinary user account in the database with the screen name
* {@code public-user}.
*
* @return The public user or {@code null} if there is no account for the
* public user.
*/
public User retrievePublicUser() {
return findByScreenName("public-user");
}
/**
* Retrieve a user by its screen name.
*
* @param screenname The {@code screename} of the user.
*
* @return The user identified by the provided {@code screenname} if there
* is such a user, {@code null} if not.
*/
public User findByScreenName(final String screenname) {
final TypedQuery<User> query = getEntityManager().createNamedQuery(
"User.findUserByScreenName", User.class);
query.setParameter("screenname", screenname);
final List<User> result = query.getResultList();
//Check if result list is empty and if not return the first element.
//If their ist a result than there can only be one because the
//screen_name column has a unique constraint.
if (result.isEmpty()) {
return null;
} else {
return result.get(0);
}
}
/**
* Finds a user by one of the email addresses assigned to the user.
*
* @param emailAddress The email address of the user.
*
* @return The user identified by the provided email address if there is
* such a user, {@code null} otherwise.
*
* @throws MultipleMatchingUserException Because the email addresses are
* represented by an embedded entity
* (see {@link User} and
* {@link EmailAddress}) it is not
* possible to enforce uniqueness on
* the database level. Therefore this
* method deals with the case that
* there is more than on matching user
* and throws an (unchecked) exception
* if this is the case. However if
* this the case something very
* strange has happened and the
* database should be checked
* carefully.
*/
public User findByEmailAddress(final String emailAddress) {
final TypedQuery<User> query = getEntityManager().createNamedQuery(
"User.findUserByEmailAddress", User.class);
query.setParameter("emailAddress", emailAddress);
final List<User> result = query.getResultList();
if (result.isEmpty()) {
return null;
} else if (result.size() == 1) {
return result.get(0);
} else {
throw new MultipleMatchingUserException(String.format(
"Found multipe users identified by email address '%s'. "
+ "Check your database.",
emailAddress));
}
}
}

View File

@ -1,215 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
/**
* This {@code LoginModule} provides common methods for {@code LoginModule}s
* using a username/password combination to authenticate users. If provides
* common methods. It tries to fetch username and password from shared data
* provided by the calling {@link LoginContext} if possible. Otherwise is
* queries the user using {@link Callback}s. Username and password are stored in
* the shared data for use by other {@code LoginModule}s.
*
* This class in a reworked version of
* {@code org.arsdigita.kernel.security.AbstractPasswordLoginModule} developed
* by Sameer Ajmani (according to the JavaDoc). The main differences is that the
* new version uses generics and multi-catch for exceptions. Also the code,
* especially if clauses have been reworked to match the conventions enforced by
* PMD and other style checkers. Also the methods {@code getPassword} and
* {@code getUsername} have been renamed to {@code retrievePassword} and
* {@code retrieveUsername} because this class is not a Java Bean and the values
* are not Java Bean Properties.
*
* This class is abstract. The methods
* {@link #checkPassword(java.lang.String, char[])}, {@link #commit()}, {@link #abort()}
* and {@link #logout()} are left to implement by sub classes.
*
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class AbstractPasswordLoginModule implements LoginModule {
private static final Logger LOGGER = LogManager.getLogger(
AbstractPasswordLoginModule.class);
/**
* Key for username in shared data map.
*/
private static final String NAME_KEY = "javax.security.auth.login.name";
/**
* Key for password in shared data map.
*/
private static final String PASSWORD_KEY
= "javax.security.auth.login.password";
/**
* Fields set by the {@link #initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
* method.
* We only set the fields we use in this class.
*/
private transient CallbackHandler callbackHandler;
private transient Map<String, ?> sharedState;
/**
* {@inheritDoc }
*
* @param subject {@inheritDoc }
* @param callbackHandler {@inheritDoc }
* @param sharedState {@inheritDoc }
* @param options {@inheritDoc }
*/
@Override
public void initialize(final Subject subject,
final CallbackHandler callbackHandler,
final Map<String, ?> sharedState,
final Map<String, ?> options) {
LOGGER.debug("Initalizing...");
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
LOGGER.debug("Initalized...");
}
/**
* Implementation of the {@link LoginModule#login()} method. Retrieves the
* username and the password using the {@link #retrieveUsername()} and
* {@link #retrievePassword()} methods and call the
* {@link #checkPassword(java.lang.String, char[])} method.
*
* @return The return value of the
* {@link #checkPassword(java.lang.String, char[])} method.
*
* @throws LoginException If something goes wrong.
*/
@Override
public boolean login() throws LoginException {
LOGGER.debug("Trying to authenticate user...");
return checkPassword(retrieveUsername(), retrievePassword());
}
/**
* {@inheritDoc }
*
* @return {@inheritDoc }
*
* @throws LoginException {@inheritDoc }
*/
@Override
public abstract boolean commit() throws LoginException;
/**
* {@inheritDoc }
*
* @return {@inheritDoc }
*
* @throws LoginException {@inheritDoc }
*/
@Override
public abstract boolean abort() throws LoginException;
/**
* {@inheritDoc }
*
* @return {@inheritDoc }
*
* @throws LoginException {@inheritDoc }
*/
@Override
public abstract boolean logout() throws LoginException;
/**
* Attempts to read username from shared data map; otherwise retreives it
* using a NameCallback.
*
* @return the username.
*
* @throws LoginException if an error occurs.
*/
@SuppressWarnings("PMD.PreserveStackTrace")
private String retrieveUsername() throws LoginException {
String username = (String) sharedState.get(NAME_KEY);
if (username == null) {
try {
final NameCallback callback = new NameCallback("Username: ");
callbackHandler.handle(new Callback[]{callback});
username = callback.getName();
} catch (IOException | UnsupportedCallbackException ex) {
throw new LoginException("Could not get Username");
}
}
return username;
}
/**
* Attempts to read password from shared data map; otherwise retreives it
* using a PasswordCallback.
*
* @return the password.
*
* @throws LoginException if an error occurs.
*/
@SuppressWarnings("PMD.StackTraceLost")
private String retrievePassword() throws LoginException {
String password = (String) sharedState.get(PASSWORD_KEY);
if (password == null) {
try {
final PasswordCallback callback = new PasswordCallback(
"Password: ",
false);
callbackHandler.handle(new Callback[]{callback});
password = new String(callback.getPassword());
} catch (UnsupportedCallbackException | IOException ex) {
throw new LoginException("Could not get password");
}
}
return password;
}
/**
* Checks whether the given username/password combination is valid.
*
* @param username the username to check.
* @param password the password to check.
*
* @return {@code true} if the username/password combination is valid,
* {@code false} to otherwise.
*
* @throws LoginException If an error occurs.
*/
protected abstract boolean checkPassword(String username, String password)
throws LoginException;
}

View File

@ -1,161 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.User;
import org.libreccm.core.UserManager;
import org.libreccm.core.UserRepository;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.LoginException;
/**
* Checks a username and a password in the database.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LocalLoginModule extends AbstractPasswordLoginModule {
private transient Subject subject;
@Override
public void initialize(final Subject subject,
final CallbackHandler callbackHandler,
final Map<String, ?> sharedState,
final Map<String, ?> options) {
super.initialize(subject, callbackHandler, sharedState, options);
this.subject = subject;
}
@Override
public boolean commit() throws LoginException {
return true;
}
@Override
public boolean abort() throws LoginException {
return true;
}
@Override
public boolean logout() throws LoginException {
return true;
}
/**
* Checks the provided password against the (hashed) password in the
* database.
*
* @param username The username identifying the user account the verify.
* @param password The password to verify.
*
* @return {@code true} if the password matches the password in the
* database, {@code false} if not or if there is no user account
* identified by the provided user name.
*
* @throws LoginException If an error occurs in the process.
*/
@Override
@SuppressWarnings("PMD.StackTraceLost")
protected boolean checkPassword(final String username,
final String password)
throws LoginException {
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new LoginException(
String.format(
"Failed to obtain reference for UserRepository: %s",
ex.getMessage()));
}
final UserManager userManager;
try {
userManager = cdiUtil.findBean(UserManager.class);
} catch (CdiLookupException ex) {
throw new LoginException(String.format(
"Failed to obtain reference for UserManager: %s",
ex.getMessage()));
}
//Depending on the configured user identifier retrieve the user account
//using the screen name or the email address.
final User user;
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
user = userRepository.findByEmailAddress(username);
} else {
user = userRepository.findByScreenName(username);
}
//If no matching user is found report this by throwing an exception.
if (user == null) {
throw new AccountNotFoundException(String.format(
"No user account identified by '%s' found.", username));
}
final boolean result = userManager.verifyPasswordForUser(user, password);
if (result) {
final UserPrincipal userPrincipal = new UserPrincipal(user);
subject.getPrincipals().add(userPrincipal);
return true;
} else {
return false;
}
// Verify the password. The algorithm used for hashing is stored in the
// database so we need to retrieve the correct MessageDigest instance
// first.
// try {
// final MessageDigest digest = MessageDigest.getInstance(user
// .getHashAlgorithm());
// final String saltedPassword = String.format("%s%s",
// password,
// user.getSalt());
// final String passwordHash = new String(digest.digest(
// saltedPassword.getBytes()));
//
// if (passwordHash.equals(user.getPassword())) {
// subject.getPrincipals().add(new UserPrincipal(user));
// return true;
// } else {
// return false;
// }
// } catch (NoSuchAlgorithmException ex) {
// throw new LoginException(String.format(
// "Failed to validate password because the password stored for "
// + "user '%s' in the database is hashed with algorithm '%s' "
// + "which is not avialable.",
// username, user.getHashAlgorithm()));
// }
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import com.arsdigita.kernel.security.SecurityConfig;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.spi.LoginModule;
/**
* Configuration for JAAS containing all active {@link LoginModule}
* implementations.
*
* The active modules are stored in the {@link SecurityConfig} as an array
* of strings. The original {@code com.arsdigita.kernel.security.LoginConfig}
* class parsed this string array in its constructor. For LibreCCM 7 the code
* has been split up. The logic for parsing the configuration is now provided
* by the {@link LoginConfigBuilder} class. This allowed us the greatly
* simplify this class. Also now we don't have a constructor which throws
* Exceptions.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LoginConfig extends Configuration {
/**
* The configuration entries.
*/
private final transient Map<String, AppConfigurationEntry[]> appConfigs;
private LoginConfig() {
this.appConfigs = new HashMap<>();
}
LoginConfig(final Map<String, AppConfigurationEntry[]> appConfigs) {
this.appConfigs = appConfigs;
}
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
return appConfigs.get(name);
}
@Override
public void refresh() {
// Nothing
}
}

View File

@ -1,311 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.runtime.ConfigError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.spi.LoginModule;
/**
* Creates a {@link LoginConfig} instance from an array or an list of strings.
*
* The process of creating a {@link LoginConfig} instance from the string values
* like those stored in the {@link SecurityConfig} is a complex process.
* Originally the constructor of the
* {@code com.arsdigita.kernel.security.LoginConfig} class has done all this
* work. Some parts were outsourced to private methods.
*
* The problem with this approach is that several of this method may throw an
* exception/error. But throwing exceptions from a constructor is considered a
* bad practise. Also the private support methods made the original
* {@code LoginConfig} class quite big and complex. Therefore the code has been
* split up. The construction process is now done by this class which creates
* {@code LoginConfig} from a provided list or array of strings. The strings
* must be in the correct format:
*
* <pre>
* context:moduleName:controlFlag[:option1[:option2[:...]]]
* </pre>
*
* <dl>
* <dt>{@code context}</dt>
* <dd>String</dd>
*
* <dt>{@code moduleName}</dt>
* <dd>Fully qualified class name of a {@link LoginModule}.</dd>
*
* <dt>{@code controlFlag}</dt>
* <dd>
* One of the following flags:
* <ul>
* <li>{@code required}</li>
* <li>{@code requisite}</li>
* <li>{@code sufficient}</li>
* <li>{@code optional}</li>
* </ul>
* </dd>
*
* <dt>option</dt>
* <dd>Options for the module in the following format: {@code key=value}</dd>
* </dl>
*
* Examples:
*
* <pre>
* Request:com.arsdigita.kernel.security.CredentialLoginModule:requisite:debug=true
* Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
* Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite
* Register:com.arsdigita.kernel.security.CredentialLoginModule:optional
* </pre>
*
* The build a {@link LoginConfig} first construct an instance of this class and
* pass the string array containing the configuration. For example:
*
* <pre>
* final LoginConfigBuilder loginConfigBuilder =
* new LoginConfigBuilder(SecurityConfig.getInstance().getLoginConfig());
* </pre>
*
* Then call the {@link #build()} method which does all the work:
*
* <pre>
* final LoginConfig loginConfig = loginConfigBuilder.build();
* </pre>
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LoginConfigBuilder {
private final transient String[] config;
/**
* Creates a new {@code LoginConfigBuilder} for the provided configuration.
*
* @param config The configuration for which an {@link LoginConfig} should
* be created, as array of strings as provided by
* {@link SecurityConfig#getLoginConfig()}.
*/
@SuppressWarnings("PMD.UseVarargs") //Can't use varargs here
public LoginConfigBuilder(final String[] config) {
this.config = new String[config.length];
System.arraycopy(config, 0, this.config, 0, config.length);
}
/**
* Creates a {@link LoginConfig} from {@link #config}.
*
* If one entry of the {@link #config} is malformed a {@link ConfigError}
* will be thrown.
*
* @return A {@link LoginConfig} object.
*/
public LoginConfig build() {
//Temporary storage for the data extracted from the config string array.
final Map<String, List<String>> contextConfigs = new HashMap<>();
//Parse the tuples in the config string array.
for (final String tuple : config) {
//Find the index of the first ':'.
final int index = tuple.indexOf(':');
//Extract context and module config parts from the tuple.
final String context = tuple.substring(0, index);
final String moduleConfig = tuple.substring(index + 1);
//Put them in the list for the context.
final List<String> contextConfig = retrieveContextConfig(
context, contextConfigs);
contextConfig.add(moduleConfig);
}
//Create the map of AppConfigurationEntry objects.
final Map<String, AppConfigurationEntry[]> appConfigs = new HashMap<>();
for (final Map.Entry<String, List<String>> entry : contextConfigs
.entrySet()) {
//Add the config entry. The helper method called creates the
//AppConfigurationEntry object from the string value.
addAppConfig(appConfigs, entry.getKey(), entry.getValue());
}
//Create the LoginConfig object with the Map of AppConfigurationEntries.
return new LoginConfig(appConfigs);
}
/**
* Helper method for retrieving a list for specific context from the context
* maps. Used by {@link #build()}. If the map has no entry with the provided
* name a new list is created a put into the list.
*
* @param context The name of the context, used as key in the
* provided map.
* @param contextConfigs The map of context configs.
*
* @return The context configs list for the provided context.
*/
private List<String> retrieveContextConfig(
final String context, final Map<String, List<String>> contextConfigs) {
List<String> contextConfig = contextConfigs.get(context);
if (contextConfig == null) {
contextConfig = new ArrayList<>();
contextConfigs.put(context, contextConfig);
}
return contextConfig;
}
/**
* Helper method for creating an {@link AppConfigurationEntry} object from a
* string.
*
* @param appConfigs The map of {@link AppConfigurationEntry} objects in
* which the created entry will be stored.
* @param name The name of the context for which the
* {@link AppConfigurationEntry} is created.
* @param entries The list of configuration entries to parse.
*/
private void addAppConfig(
final Map<String, AppConfigurationEntry[]> appConfigs,
final String name,
final List<String> entries) {
//Map containing the parsed entries
final AppConfigurationEntry[] configEntries
= new AppConfigurationEntry[entries
.size()];
//Parse all entries. We use a "traditional" for loop here because we
//need the position in the array.
for (int i = 0; i < entries.size(); i++) {
//Load the current configuration entry.
configEntries[i] = loadAppConfigEntry(entries.get(i));
}
//Put the parsed entires into the map
appConfigs.put(name, configEntries);
}
/**
* Helper method for parsing a single configuration entry. The
*
* tokens entry
*
* @return
*/
private AppConfigurationEntry loadAppConfigEntry(final String entry) {
//Split the string tokens. The tokens are limited by the ':' character.
final String[] tokens = entry.split(":");
//If there less then two tokens the entry is malformed and we throw an
//ConfigError.
if (tokens.length < 2) {
final StringBuilder builder = new StringBuilder();
for (final String str : tokens) {
builder.append(str);
}
throw new ConfigError(String.format(
"Malformed SecurityConfig entry: %s", builder.toString()));
}
//Extract the name of the configured module (the first token)
final String name = tokens[0];
//Extract the flat (second token)
final AppConfigurationEntry.LoginModuleControlFlag flag = parseFlag(
tokens[1]);
//Extract the provided options if any
final Map<String, String> options = new HashMap<>();
if (tokens.length > 2) {
for (int i = 2; i < tokens.length; i++) {
//The the option to the map of options.
addOption(tokens[i], options);
}
}
//Create an AppConfguration using the extracted data.
return new AppConfigurationEntry(name, flag, options);
}
/**
* Helper method to convert a string to a
* {@link AppConfigurationEntry.LoginModuleControlFlag}. If the provided
* string is not a valid flag a {@link ConfigError} is thrown.
*
* @param flag The string to convert.
*
* @return {@link AppConfigurationEntry.LoginModuleControlFlag} instance.
*/
private AppConfigurationEntry.LoginModuleControlFlag parseFlag(
final String flag) {
switch (flag.toUpperCase(Locale.ROOT)) {
case "REQUISITE":
return AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
case "REQUIRED":
return AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
case "SUFFICIENT":
return AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
case "OPTIONAL":
return AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
default:
throw new ConfigError(String.format(
"Unknown flag \"%s\". Valid flags are: REQUISITE, "
+ "REQUIRED, SUFFICIENT, OPTIONAL",
flag));
}
}
/**
* Helper method for extracting the key and value parts from an module
* option string. If the option string is malformed an {@link ConfigError}
* is thrown.
*
* @param option The option string to parse.
* @param options The map of options to which the parsed option we be added.
*/
private void addOption(final String option,
final Map<String, String> options) {
//Find the index of the '=' character.
final int index = option.indexOf('=');
//If there is no '=' in the string the option string is invalid
if (index == -1) {
throw new ConfigError(String.format(
"The option string \"%s\" is malformed.", option));
}
//Extract key and value an put them into the options map.
final String key = option.substring(0, index);
final String value = option.substring(index + 1);
options.put(key, value);
}
}

View File

@ -1,121 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/**
* Provides methods for authenticating a user and for logging out a user.
*
* Under the hood JAAS is used for authentication.
*
* If a user is authenticated successfully the user object is stored in the
* session scoped bean {@link CcmSessionContext}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class LoginManager {
/**
* Name of the register login context.
*/
private static final String LOGIN_CONTEXT = "Register";
@Inject
private transient CcmSessionContext sessionContext;
// @Inject
// private transient UserRepository userRepository;
public void login(final String username, final String password)
throws LoginException {
final CallbackHandler callbackHandler = new LoginCallbackHandler(
username, password);
final LoginContext loginContext = new LoginContext(
LOGIN_CONTEXT,
callbackHandler);
loginContext.login();
final Subject subject = loginContext.getSubject();
final Set<UserPrincipal> principals = subject.getPrincipals(
UserPrincipal.class);
if (principals.isEmpty()) {
throw new LoginException("No principal set");
} else {
final Iterator<UserPrincipal> iterator = principals.iterator();
final UserPrincipal principal = iterator.next();
final User user = principal.getUser();
sessionContext.setCurrentSubject(user);
}
}
public void logout() {
sessionContext.setCurrentSubject(null);
}
private static class LoginCallbackHandler implements CallbackHandler {
private final transient String username;
private final transient String password;
public LoginCallbackHandler(final String username,
final String password) {
this.username = username;
this.password = password;
}
@Override
@SuppressWarnings("PMD.UseVarargs") //Can't use varargs here
public void handle(final Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (final Callback callback : callbacks) {
if (callback instanceof NameCallback) {
((NameCallback) callback).setName(username);
} else if (callback instanceof PasswordCallback) {
((PasswordCallback) callback).setPassword(password
.toCharArray());
} else {
throw new UnsupportedCallbackException(callback);
}
}
}
}
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import java.security.Principal;
import java.util.Objects;
import org.libreccm.core.User;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class UserPrincipal implements Principal {
private final User user;
public UserPrincipal(final User user) {
this.user = user;
}
public User getUser() {
return user;
}
@Override
public String getName() {
return user.getScreenName();
}
@Override
public int hashCode() {
int hash = 5;
hash = 41 * Objects.hash(user);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserPrincipal other = (UserPrincipal) obj;
return Objects.equals(user, other.getUser());
}
@Override
public String toString() {
return String.format("%s{ "
+ "user = %s"
+ " }",
super.toString(),
Objects.toString(user));
}
}

View File

@ -18,6 +18,8 @@
*/
package org.libreccm.security;
import static org.libreccm.core.CoreConstants.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.libreccm.core.CcmObject;
@ -50,14 +52,14 @@ public class PermissionChecker {
* @param privilege The privilege granted by the permission.
*
* @return {@code true} if the current subject has as permission granting
* the provided {@code privilege}, {@code false} otherwise.
* the provided {@code privilege}, {@code false} otherwise.
*/
public boolean isPermitted(final String privilege) {
if (subject.isAuthenticated()) {
return subject.isPermitted(generatePermissionString(privilege));
} else {
return shiro.getPublicUser().isPermitted(generatePermissionString(
privilege));
privilege));
}
}
@ -67,19 +69,19 @@ public class PermissionChecker {
* implements the {@link InheritsPermissions} interface.
*
* @param privilege The granted privilege.
* @param object The object on which the privilege is granted.
* @param object The object on which the privilege is granted.
*
* @return {@code true} if the there is a permission granting the provided
* {@code privilege} on the provided {@code subject}.
* {@code privilege} on the provided {@code subject}.
*/
public boolean isPermitted(final String privilege, final CcmObject object) {
final boolean result;
if (subject.isAuthenticated()) {
result = subject.isPermitted(generatePermissionString(
privilege, object));
privilege, object));
} else {
result = shiro.getPublicUser().isPermitted(generatePermissionString(
privilege, object));
privilege, object));
}
if (result) {
return result;
@ -101,48 +103,38 @@ public class PermissionChecker {
* privilege an {@link AuthorizationExeeption} is thrown.
*
* @param privilege The privilege to check for.
*
* @throws AuthorizationException If the current subject has not permission
* granting the provided privilege.
* granting the provided privilege.
*/
public void checkPermission(final String privilege)
throws AuthorizationException {
throws AuthorizationException {
if (subject.isAuthenticated()) {
subject.checkPermission(generatePermissionString(privilege));
} else {
shiro.getPublicUser().checkPermission(generatePermissionString(
privilege));
privilege));
}
}
/**
* Checks if the current subject has a permission granting the provided
* privilege on the provided object. If there is a permission which grants
* the current subject the provided privilege on the provided object the
* method returns the object. Otherwise an {@link AuthorizationException} is
* thrown. This also the use this method in methods which are loading
* objects from the database like this
* <pre>
* public CcmObject findBy(...) {
* // Do JPA stuff
*
* return permissionChecker.checkPermission($privilege, object);
* }
* </pre>
* privilege on the provided object.
*
* If the object implements the {@link InheritsPermissions} interface the
* method also checks the parent objects for a permission granting the
* provided privilege.
*
* @param privilege The privilige to check for.
* @param object The object on which the privilege is granted.
* @return Th provided object if there is permission granting the current
* subject the provided privilege on the object.
* @throws AuthorizationException If there is not permission granting the
* current subject the provided privilege on the provided object.
* @param object The object on which the privilege is granted.
*
* @throws AuthorizationException If there is no permission granting the
* provided privilege to the current subject
* on the provided object..
*/
public CcmObject checkPermission(final String privilege,
final CcmObject object)
throws AuthorizationException {
public void checkPermission(final String privilege,
final CcmObject object)
throws AuthorizationException {
if (object instanceof InheritsPermissions) {
final boolean result = isPermitted(privilege, object);
@ -160,16 +152,53 @@ public class PermissionChecker {
subject.checkPermission(generatePermissionString(privilege, object));
} else {
shiro.getPublicUser().checkPermission(generatePermissionString(
privilege, object));
privilege, object));
}
}
return object;
/**
* Checks if the current subject has a permission granting the provided
* privilege on the provided object. Returns the object of the current
* subject is permitted to access the object. Otherwise a virtual
* placeholder object is returned with the {@link CcmObject#displayName}
* property set the {@code Access denied}.
*
* @param <T> The type of the object to check.
* @param privilege The privilige to check for.
* @param object The object on which the privilege is granted.
* @param clazz The class of the object.
*
* @return The object if the current subject is permitted to access, a
* placeholder object if not.
*/
public <T extends CcmObject> T checkPermission(final String privilege,
final T object,
final Class<T> clazz) {
final SecuredHelper<T> securedHelper = new SecuredHelper<>(clazz,
privilege);
return securedHelper.canAccess(object);
}
/**
* Checks if a CcmObject is a virtual <i>Access Denied</i> object.
*
* @param object The object to check.
*
* @return {@code true} if the object is a <i>Access denied</i> object,
* {@code false} if not.
*/
public boolean isAccessDeniedObject(final CcmObject object) {
if (object == null) {
return false;
}
return ACCESS_DENIED.equals(object.getDisplayName());
}
/**
* Helper method for converting a privilege into a permission string.
*
* @param privilege
*
* @return
*/
public String generatePermissionString(final String privilege) {
@ -181,6 +210,7 @@ public class PermissionChecker {
*
* @param privilege
* @param object
*
* @return
*/
public String generatePermissionString(final String privilege,

View File

@ -19,6 +19,9 @@
package org.libreccm.security;
import com.arsdigita.util.UncheckedWrapperException;
import static org.libreccm.core.CoreConstants.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
@ -90,7 +93,7 @@ class SecuredHelper<E extends CcmObject> {
protected E generateAccessDeniedObject() {
try {
final E placeholder = clazz.newInstance();
placeholder.setDisplayName("Access denied");
placeholder.setDisplayName(ACCESS_DENIED);
return placeholder;
} catch (InstantiationException | IllegalAccessException ex) {

View File

@ -62,7 +62,7 @@ public class SecuredIterator<E extends CcmObject> implements Iterator<E> {
/**
* Returns the next object of the current subject it permitted to access it
* or a special "Access denied" object if not.
* or a special <i>Access denied</i> object if not.
*
* The method gets the next object from the wrapped {@code Iterator} and
* checks if the current subject has a permission granting the privilege
@ -73,7 +73,8 @@ public class SecuredIterator<E extends CcmObject> implements Iterator<E> {
* {@link CcmObject#displayName} of these placeholder objects is set the
* {@code Access denied}.
*
* @return The next object or a special "Access denied" placeholder object.
* @return The next object or a special <i>Access denied</i> placeholder
* object.
*/
@Override
public E next() {

View File

@ -18,6 +18,8 @@
*/
package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import static org.hamcrest.CoreMatchers.*;
import org.jboss.arquillian.container.test.api.Deployment;

View File

@ -1,348 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class GroupManagerTest {
@Inject
private transient GroupManager groupManager;
@Inject
private transient UserRepository userRepository;
@Inject
private transient GroupRepository groupRepository;
public GroupManagerTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.GroupManagerTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
/**
* Verify the
* {@link GroupManager#isMemberOfGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* method.
*/
@Test
@InSequence(10)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
public void isMemberOfGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Group admins = groupRepository.findByGroupName("admins");
final Group users = groupRepository.findByGroupName("users");
final Group authors = groupRepository.findByGroupName("authors");
assertThat(groupManager.isMemberOfGroup(jdoe, admins), is(false));
assertThat(groupManager.isMemberOfGroup(jdoe, users), is(true));
assertThat(groupManager.isMemberOfGroup(jdoe, authors), is(true));
}
/**
* Verify that
* {@link GroupManager#isMemberOfGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code user}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(20)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldThrowException(IllegalArgumentException.class)
public void isMemberOfGroupNullUser() {
final Group admins = groupRepository.findByGroupName("admins");
groupManager.isMemberOfGroup(null, admins);
}
/**
* Verify that
* {@link GroupManager#isMemberOfGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code group}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(30)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldThrowException(IllegalArgumentException.class)
public void isMemberOfGroupNullGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
groupManager.isMemberOfGroup(jdoe, null);
}
/**
* Verify that the
* {@link GroupManager#addUserToGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* method adds an user to a group and stores the changed group and user
* correctly to the database.
*/
@Test
@InSequence(40)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "after-add-to-group.yml",
excludeColumns = {"membership_id"})
public void addUserToGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Group admins = groupRepository.findByGroupName("admins");
groupManager.addUserToGroup(jdoe, admins);
assertThat(groupManager.isMemberOfGroup(jdoe, admins), is(true));
}
/**
* Verify that
* {@link GroupManager#addUserToGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code user}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(50)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
@ShouldThrowException(IllegalArgumentException.class)
public void addUserToGroupNullUser() {
final Group admins = groupRepository.findByGroupName("admins");
groupManager.addUserToGroup(null, admins);
}
/**
* Verify that
* {@link GroupManager#addUserToGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code group}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(60)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
@ShouldThrowException(IllegalArgumentException.class)
public void addUserToGroupNullGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
groupManager.addUserToGroup(jdoe, null);
}
/**
* Verify that the
* {@link GroupManager#addUserToGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* does nothing if the provided user is already a member of the provided
* group.
*/
@Test
@InSequence(70)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
public void addUserToGroupAlreadyMember() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Group authors = groupRepository.findByGroupName("authors");
groupManager.addUserToGroup(jdoe, authors);
}
/**
* Verify that
* {@link GroupManager#removeUserFromGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* really removes a user from a group and stores the changed user and group
* in the database.
*/
@Test
@InSequence(80)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "after-remove-from-group.yml",
excludeColumns = {"membership_id"})
public void removeUserFromGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Group authors = groupRepository.findByGroupName("authors");
groupManager.removeUserFromGroup(jdoe, authors);
assertThat(groupManager.isMemberOfGroup(jdoe, authors), is(false));
}
/**
* Verify that
* {@link GroupManager#removeUserFromGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code user}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(90)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
@ShouldThrowException(IllegalArgumentException.class)
public void removeUserFromGroupNullUser() {
final Group authors = groupRepository.findByGroupName("authors");
groupManager.removeUserFromGroup(null, authors);
}
/**
* Verify that
* {@link GroupManager#removeUserFromGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* throws an {@link IllegalArgumentException} if the provided {@code group}
* is {@code null}.
*/
@Test(expected = IllegalArgumentException.class)
@InSequence(100)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
@ShouldThrowException(IllegalArgumentException.class)
public void removeUserFromGroupNullGroup() {
final User jdoe = userRepository.findByScreenName("jdoe");
groupManager.removeUserFromGroup(jdoe, null);
}
/**
* Verify that
* {@link GroupManager#removeUserFromGroup(org.libreccm.core.User, org.libreccm.core.Group)}
* does nothing if the provided {@code user} is not a member of the provided
* {@code group}.
*/
@Test
@InSequence(110)
@UsingDataSet("datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/GroupManagerTest/"
+ "users-groups.yml",
excludeColumns = {"membership_id"})
public void removeUserFromGroupNotMember() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Group admins = groupRepository.findByGroupName("admins");
groupManager.removeUserFromGroup(jdoe, admins);
}
}

View File

@ -1,209 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class GroupRepositoryTest {
@Inject
private transient GroupRepository groupRepository;
public GroupRepositoryTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
private void verifyGroups(final Group admins,
final Group users,
final Group authors,
final Group none) {
assertThat(admins, is(not(nullValue())));
assertThat(admins.getName(), is(equalTo("admins")));
assertThat(users, is(not(nullValue())));
assertThat(users.getName(), is(equalTo("users")));
assertThat(authors, is(not(nullValue())));
assertThat(authors.getName(), is(equalTo("authors")));
assertThat(none, is(nullValue()));
}
@Test
@InSequence
@UsingDataSet("datasets/org/libreccm/core/GroupRepositoryTest/data.yml")
public void findGroupById() {
final Group admins = groupRepository.findById(-10L);
final Group users = groupRepository.findById(-20L);
final Group authors = groupRepository.findById(-30L);
final Group none = groupRepository.findById(-999L);
verifyGroups(admins, users, authors, none);
}
@Test
@InSequence(20)
@UsingDataSet("datasets/org/libreccm/core/GroupRepositoryTest/data.yml")
public void findGroupByName() {
final Group admins = groupRepository.findByGroupName("admins");
final Group users = groupRepository.findByGroupName("users");
final Group authors = groupRepository.findByGroupName("authors");
final Group none = groupRepository.findByGroupName("none");
verifyGroups(admins, users, authors, none);
}
@Test
@InSequence(30)
@UsingDataSet("datasets/org/libreccm/core/GroupRepositoryTest/data.yml")
@ShouldMatchDataSet(value
= "datasets/org/libreccm/core/GroupRepositoryTest/after-save-new.yml",
excludeColumns = "subject_id")
public void saveNewGroup() {
final Group publishers = new Group();
publishers.setName("publishers");
groupRepository.save(publishers);
}
@Test
@InSequence(40)
@UsingDataSet("datasets/org/libreccm/core/GroupRepositoryTest/data.yml")
@ShouldMatchDataSet(value
= "datasets/org/libreccm/core/GroupRepositoryTest/after-save-changed.yml",
excludeColumns = {"subject_id"})
public void saveChangedGroup() {
final Group group = groupRepository.findByGroupName("authors");
group.setName("editors");
groupRepository.save(group);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(50)
public void saveNullValue() {
groupRepository.save(null);
}
@Test
@InSequence(60)
@UsingDataSet("datasets/org/libreccm/core/GroupRepositoryTest/data.yml")
@ShouldMatchDataSet(
"datasets/org/libreccm/core/GroupRepositoryTest/after-delete.yml")
public void deleteGroup() {
final Group group = groupRepository.findByGroupName("users");
groupRepository.delete(group);
}
}

View File

@ -1,632 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import java.io.File;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.inject.Inject;
import static org.junit.Assert.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class PermissionManagerTest {
private static final String TEST_OBJECT_1 = "Test Object 1";
private static final String TEST_OBJECT_2 = "Test Object 2";
private static final String TEST_OBJECT_3 = "Test Object 3";
private static final String TEST_OBJECT_4 = "Test Object 4";
private static final String TEST_OBJECT_5 = "Test Object 5";
private static final String TEST_OBJECT_6 = "Test Object 6";
private static final String TEST_OBJECT_7 = "Test Object 7";
private static final String TEST_OBJECT_8 = "Test Object 8";
private static final String ADMIN = "admin";
private static final String READ = "read";
private static final String WRITE = "write";
@Inject
private transient PermissionManager permissionManager;
@Inject
private transient PrivilegeRepository privilegeRepository;
@Inject
private transient CcmObjectRepository ccmObjectRepository;
@Inject
private transient UserRepository userRepository;
@Inject
private transient GroupRepository groupRepository;
public PermissionManagerTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
String.format("LibreCCM-%s.war",
PermissionManagerTest.class.getName()))
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
private Map<String, CcmObject> retrieveTestObjects() {
final long[] objectIds = {-10, -20, -30, -40, -50, -60, -70, -80};
final Map<String, CcmObject> objects = new LinkedHashMap<>();
for (final long objectId : objectIds) {
final CcmObject object = ccmObjectRepository.findById(objectId);
objects.put(object.getDisplayName(), object);
}
return objects;
}
private Map<String, Privilege> retrievePrivileges() {
final String[] privilegLabels = {"admin", "read", "write"};
final Map<String, Privilege> privileges = new LinkedHashMap<>();
for (final String label : privilegLabels) {
final Privilege privilege = privilegeRepository.retrievePrivilege(
label);
privileges.put(label, privilege);
}
return privileges;
}
private void verifyIsPermitted(final Subject subject,
final Privilege privilege,
final Map<CcmObject, Boolean> expected) {
final String subjectName;
if (subject instanceof User) {
subjectName = ((User) subject).getScreenName();
} else if (subject instanceof Group) {
subjectName = ((Group) subject).getName();
} else {
subjectName = "???";
}
for (Map.Entry<CcmObject, Boolean> entry : expected.entrySet()) {
assertThat(String.format("isPermitted should return %b for subject "
+ "%s and privilege %s on object %s.",
entry.getValue(),
subjectName,
privilege.getLabel(),
entry.getKey().getDisplayName()),
permissionManager.isPermitted(privilege,
entry.getKey(),
subject),
is(entry.getValue()));
}
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(10)
public void isPermittedWebmasterAdmin() {
final User webmaster = userRepository.findByScreenName("webmaster");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expected = new LinkedHashMap<>();
expected.put(testObjects.get(TEST_OBJECT_1), true);
expected.put(testObjects.get(TEST_OBJECT_2), true);
expected.put(testObjects.get(TEST_OBJECT_3), true);
expected.put(testObjects.get(TEST_OBJECT_4), true);
expected.put(testObjects.get(TEST_OBJECT_5), true);
expected.put(testObjects.get(TEST_OBJECT_6), true);
expected.put(testObjects.get(TEST_OBJECT_7), true);
expected.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(webmaster, privileges.get(ADMIN), expected);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(11)
public void isPermittedWebmasterRead() {
final User webmaster = userRepository.findByScreenName("webmaster");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expected = new LinkedHashMap<>();
expected.put(testObjects.get(TEST_OBJECT_1), true);
expected.put(testObjects.get(TEST_OBJECT_2), true);
expected.put(testObjects.get(TEST_OBJECT_3), true);
expected.put(testObjects.get(TEST_OBJECT_4), true);
expected.put(testObjects.get(TEST_OBJECT_5), true);
expected.put(testObjects.get(TEST_OBJECT_6), true);
expected.put(testObjects.get(TEST_OBJECT_7), true);
expected.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(webmaster, privileges.get(READ), expected);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(12)
public void isPermittedWebmasterWrite() {
final User webmaster = userRepository.findByScreenName("webmaster");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expected = new LinkedHashMap<>();
expected.put(testObjects.get(TEST_OBJECT_1), true);
expected.put(testObjects.get(TEST_OBJECT_2), true);
expected.put(testObjects.get(TEST_OBJECT_3), true);
expected.put(testObjects.get(TEST_OBJECT_4), true);
expected.put(testObjects.get(TEST_OBJECT_5), true);
expected.put(testObjects.get(TEST_OBJECT_6), true);
expected.put(testObjects.get(TEST_OBJECT_7), true);
expected.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(webmaster, privileges.get(WRITE), expected);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(20)
public void isPermittedJdoe() {
final User jdoe = userRepository.findByScreenName("jdoe");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expectedRead = new LinkedHashMap<>();
expectedRead.put(testObjects.get(TEST_OBJECT_1), true);
expectedRead.put(testObjects.get(TEST_OBJECT_2), true);
expectedRead.put(testObjects.get(TEST_OBJECT_3), true);
expectedRead.put(testObjects.get(TEST_OBJECT_4), true);
expectedRead.put(testObjects.get(TEST_OBJECT_5), true);
expectedRead.put(testObjects.get(TEST_OBJECT_6), false);
expectedRead.put(testObjects.get(TEST_OBJECT_7), false);
expectedRead.put(testObjects.get(TEST_OBJECT_8), true);
final Map<CcmObject, Boolean> expectedWrite = new LinkedHashMap<>();
expectedWrite.put(testObjects.get(TEST_OBJECT_1), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_2), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_3), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_4), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_5), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_6), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_7), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(jdoe, privileges.get(READ), expectedRead);
verifyIsPermitted(jdoe, privileges.get(WRITE), expectedWrite);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(30)
public void isPermittedMmuster() {
final User mmuster = userRepository.findByScreenName("mmuster");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expectedRead = new LinkedHashMap<>();
expectedRead.put(testObjects.get(TEST_OBJECT_1), true);
expectedRead.put(testObjects.get(TEST_OBJECT_2), true);
expectedRead.put(testObjects.get(TEST_OBJECT_3), true);
expectedRead.put(testObjects.get(TEST_OBJECT_4), true);
expectedRead.put(testObjects.get(TEST_OBJECT_5), true);
expectedRead.put(testObjects.get(TEST_OBJECT_6), true);
expectedRead.put(testObjects.get(TEST_OBJECT_7), false);
expectedRead.put(testObjects.get(TEST_OBJECT_8), true);
final Map<CcmObject, Boolean> expectedWrite = new LinkedHashMap<>();
expectedWrite.put(testObjects.get(TEST_OBJECT_1), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_2), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_3), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_4), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_5), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_6), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_7), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(mmuster, privileges.get(READ), expectedRead);
verifyIsPermitted(mmuster, privileges.get(WRITE), expectedWrite);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(40)
public void isPermittedPublicUser() {
final User publicUser = userRepository.findByScreenName("public-user");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expectedRead = new LinkedHashMap<>();
expectedRead.put(testObjects.get(TEST_OBJECT_1), true);
expectedRead.put(testObjects.get(TEST_OBJECT_2), true);
expectedRead.put(testObjects.get(TEST_OBJECT_3), true);
expectedRead.put(testObjects.get(TEST_OBJECT_4), true);
expectedRead.put(testObjects.get(TEST_OBJECT_5), true);
expectedRead.put(testObjects.get(TEST_OBJECT_6), false);
expectedRead.put(testObjects.get(TEST_OBJECT_7), false);
expectedRead.put(testObjects.get(TEST_OBJECT_8), true);
final Map<CcmObject, Boolean> expectedWrite = new LinkedHashMap<>();
expectedWrite.put(testObjects.get(TEST_OBJECT_1), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_2), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_3), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_4), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_5), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_6), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_7), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_8), false);
verifyIsPermitted(publicUser, privileges.get(READ), expectedRead);
verifyIsPermitted(publicUser, privileges.get(WRITE), expectedWrite);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(50)
public void isPermittedUsers() {
final Group users = groupRepository.findByGroupName("users");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expectedRead = new LinkedHashMap<>();
expectedRead.put(testObjects.get(TEST_OBJECT_1), true);
expectedRead.put(testObjects.get(TEST_OBJECT_2), true);
expectedRead.put(testObjects.get(TEST_OBJECT_3), true);
expectedRead.put(testObjects.get(TEST_OBJECT_4), true);
expectedRead.put(testObjects.get(TEST_OBJECT_5), false);
expectedRead.put(testObjects.get(TEST_OBJECT_6), false);
expectedRead.put(testObjects.get(TEST_OBJECT_7), false);
expectedRead.put(testObjects.get(TEST_OBJECT_8), true);
final Map<CcmObject, Boolean> expectedWrite = new LinkedHashMap<>();
expectedWrite.put(testObjects.get(TEST_OBJECT_1), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_2), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_3), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_4), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_5), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_6), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_7), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_8), false);
verifyIsPermitted(users, privileges.get(READ), expectedRead);
verifyIsPermitted(users, privileges.get(WRITE), expectedWrite);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(60)
public void isPermittedAuthors() {
final Group authors = groupRepository.findByGroupName("authors");
final Map<String, CcmObject> testObjects = retrieveTestObjects();
final Map<String, Privilege> privileges = retrievePrivileges();
final Map<CcmObject, Boolean> expectedRead = new LinkedHashMap<>();
expectedRead.put(testObjects.get(TEST_OBJECT_1), true);
expectedRead.put(testObjects.get(TEST_OBJECT_2), true);
expectedRead.put(testObjects.get(TEST_OBJECT_3), true);
expectedRead.put(testObjects.get(TEST_OBJECT_4), true);
expectedRead.put(testObjects.get(TEST_OBJECT_5), false);
expectedRead.put(testObjects.get(TEST_OBJECT_6), false);
expectedRead.put(testObjects.get(TEST_OBJECT_7), false);
expectedRead.put(testObjects.get(TEST_OBJECT_8), true);
final Map<CcmObject, Boolean> expectedWrite = new LinkedHashMap<>();
expectedWrite.put(testObjects.get(TEST_OBJECT_1), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_2), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_3), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_4), true);
expectedWrite.put(testObjects.get(TEST_OBJECT_5), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_6), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_7), false);
expectedWrite.put(testObjects.get(TEST_OBJECT_8), true);
verifyIsPermitted(authors, privileges.get(READ), expectedRead);
verifyIsPermitted(authors, privileges.get(WRITE), expectedWrite);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(70)
public void isPermittedNullPrivilege() {
final CcmObject object = ccmObjectRepository.findById(-10L);
final User user = userRepository.findByScreenName("webmaster");
permissionManager.isPermitted(null, object, user);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(80)
public void isPermittedNullObject() {
final Privilege privilege = privilegeRepository
.retrievePrivilege(READ);
final User user = userRepository.findByScreenName("webmaster");
assertThat(permissionManager.isPermitted(privilege, null, user), is(true));
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(100)
public void checkPermissionValid() throws UnauthorizedAcccessException {
final Privilege privilege = privilegeRepository
.retrievePrivilege(READ);
final CcmObject object = ccmObjectRepository.findById(-10L);
final User user = userRepository.findByScreenName("jdoe");
permissionManager.checkPermission(privilege, object, user);
}
@Test(expected = UnauthorizedAcccessException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(UnauthorizedAcccessException.class)
@InSequence(110)
public void checkPermissionInValid() throws UnauthorizedAcccessException {
final Privilege privilege = privilegeRepository
.retrievePrivilege(READ);
final CcmObject object = ccmObjectRepository.findById(-60L);
final User user = userRepository.findByScreenName("jdoe");
permissionManager.checkPermission(privilege, object, user);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(120)
public void checkPermissionNullPrivilege() throws
UnauthorizedAcccessException {
final CcmObject object = ccmObjectRepository.findById(-10L);
final User user = userRepository.findByScreenName("webmaster");
permissionManager.checkPermission(null, object, user);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(130)
public void checkPermissionNullObject() throws UnauthorizedAcccessException {
final Privilege privilege = privilegeRepository
.retrievePrivilege(READ);
final User user = userRepository.findByScreenName("webmaster");
permissionManager.checkPermission(privilege, null, user);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@InSequence(140)
public void checkPermissionNullSubject() throws UnauthorizedAcccessException {
final Privilege privilege = privilegeRepository
.retrievePrivilege(READ);
final CcmObject object = ccmObjectRepository.findById(-10L);
permissionManager.checkPermission(privilege, object, null);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionManagerTest/after-grant.yml",
excludeColumns = {"permission_id"})
@InSequence(150)
public void grantPermission() {
final Privilege read = privilegeRepository.retrievePrivilege(READ);
final Privilege write = privilegeRepository.retrievePrivilege(WRITE);
final User jdoe = userRepository.findByScreenName("jdoe");
final User mmuster = userRepository.findByScreenName("mmuster");
final CcmObject object6 = ccmObjectRepository.findById(-60L);
final CcmObject object7 = ccmObjectRepository.findById(-70L);
permissionManager.grantPermission(read, object6, jdoe);
permissionManager.grantPermission(read, object7, mmuster);
permissionManager.grantPermission(write, object7, mmuster);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionManagerTest/after-grant-wildcard.yml",
excludeColumns = {"permission_id"})
@InSequence(160)
public void grantWildcardPermission() {
final Privilege read = privilegeRepository.retrievePrivilege(READ);
final User jdoe = userRepository.findByScreenName("jdoe");
permissionManager.grantPermission(read, null, jdoe);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(170)
public void grantPermissionNullPrivilege() {
final User jdoe = userRepository.findByScreenName("jdoe");
final CcmObject object6 = ccmObjectRepository.findById(-60L);
permissionManager.grantPermission(null, object6, jdoe);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(180)
public void grantPermissionNullSubject() {
final Privilege read = privilegeRepository.retrievePrivilege(READ);
final CcmObject object6 = ccmObjectRepository.findById(-60L);
permissionManager.grantPermission(read, object6, null);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionManagerTest/after-revoke.yml",
excludeColumns = {"permission_id"})
@InSequence(190)
public void revokePermission() {
final Privilege read = privilegeRepository.retrievePrivilege(READ);
final Privilege write = privilegeRepository.retrievePrivilege(WRITE);
final User jdoe = userRepository.findByScreenName("jdoe");
final User mmuster = userRepository.findByScreenName("mmuster");
final CcmObject object5 = ccmObjectRepository.findById(-50L);
final CcmObject object6 = ccmObjectRepository.findById(-60L);
permissionManager.revokePermission(read, object5, jdoe);
permissionManager.revokePermission(write, object6, mmuster);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(200)
public void revokePermissionNullPrivilege() {
final User jdoe = userRepository.findByScreenName("jdoe");
final CcmObject object5 = ccmObjectRepository.findById(-50L);
permissionManager.revokePermission(null, object5, jdoe);
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(210)
public void revokePermissionNullSubject() {
final Privilege read = privilegeRepository.retrievePrivilege(READ);
final CcmObject object6 = ccmObjectRepository.findById(-60L);
permissionManager.revokePermission(read, object6, null);
}
}

View File

@ -1,447 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import java.util.Collections;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class PermissionRepositoryTest {
@Inject
private transient PermissionRepository permissionRepository;
@Inject
private transient UserRepository userRepository;
@Inject
private transient GroupRepository groupRepository;
@Inject
private transient CcmObjectRepository ccmObjectRepository;
@Inject
private transient EntityManager entityManager;
public PermissionRepositoryTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionRepositoryTest/"
+ "data.yml")
@InSequence(10)
public void findPermissionsForSubject() {
final User jdoe = userRepository.findByScreenName("jdoe");
final User mmuster = userRepository.findByScreenName("mmuster");
final Group admins = groupRepository.findByGroupName("admins");
final Group users = groupRepository.findByGroupName("users");
final Group authors = groupRepository.findByGroupName("authors");
assertThat(jdoe, is(not(nullValue())));
assertThat(mmuster, is(not(nullValue())));
assertThat(admins, is(not(nullValue())));
assertThat(users, is(not(nullValue())));
assertThat(authors, is(not(nullValue())));
final List<Permission> permissionsJdoe = permissionRepository
.findPermissionsForSubject(jdoe);
assertThat(permissionsJdoe.size(), is(1));
assertThat(permissionsJdoe.get(0).getObject().getDisplayName(),
is(equalTo("Test Object 2")));
assertThat(permissionsJdoe.get(0).getGrantedPrivilege().getLabel(),
is(equalTo("read")));
final List<Permission> permissionsMmuster = permissionRepository
.findPermissionsForSubject(mmuster);
assertThat(permissionsMmuster.size(), is(0));
final List<Permission> permissionsAdmins = permissionRepository
.findPermissionsForSubject(admins);
assertThat(permissionsAdmins.size(), is(1));
assertThat(permissionsAdmins.get(0).getObject(), is(nullValue()));
assertThat(permissionsAdmins.get(0).getGrantedPrivilege().getLabel(),
is("admin"));
final List<Permission> permissionsUsers = permissionRepository
.findPermissionsForSubject(users);
assertThat(permissionsUsers.size(), is(1));
assertThat(permissionsUsers.get(0).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
assertThat(permissionsUsers.get(0).getGrantedPrivilege().getLabel(),
is(equalTo("read")));
final List<Permission> permissionsAuthors = permissionRepository
.findPermissionsForSubject(authors);
assertThat(permissionsAuthors.size(), is(2));
assertThat(permissionsAuthors.get(0).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
assertThat(permissionsAuthors.get(1).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
final Set<String> privileges = new HashSet<>();
privileges.add(permissionsAuthors.get(0).getGrantedPrivilege()
.getLabel());
privileges.add(permissionsAuthors.get(1).getGrantedPrivilege()
.getLabel());
assertThat(privileges, hasItem("read"));
assertThat(privileges, hasItem("write"));
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(11)
public void findPermissionsForNullSubject() {
permissionRepository.findPermissionsForSubject(null);
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@InSequence(20)
public void findPermissionsForUser() {
final User jdoe = userRepository.findByScreenName("jdoe");
final User mmuster = userRepository.findByScreenName("mmuster");
assertThat(jdoe, is(not(nullValue())));
assertThat(mmuster, is(not(nullValue())));
final List<Permission> jdoePermissions = permissionRepository
.findPermissionsForUser(jdoe);
assertThat(jdoePermissions.size(), is(4));
Collections.sort(jdoePermissions, new Comparator<Permission>() {
@Override
public int compare(final Permission permission1,
final Permission permission2) {
int result = permission1.getGrantedPrivilege().getLabel()
.compareToIgnoreCase(permission2.getGrantedPrivilege()
.getLabel());
if (result == 0) {
result = permission1.getObject().getDisplayName().compareTo(
permission2.getObject().getDisplayName());
} else {
return result;
}
if (result == 0) {
return permission1.getGrantee().getClass().getName()
.compareTo(permission2.getGrantee().getClass().
getName());
} else {
return result;
}
}
});
assertThat(jdoePermissions.get(0).getGrantedPrivilege().getLabel(),
is(equalTo("read")));
assertThat(jdoePermissions.get(0).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
assertThat(jdoePermissions.get(1).getGrantedPrivilege().getLabel(),
is(equalTo("read")));
assertThat(jdoePermissions.get(1).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
assertThat(jdoePermissions.get(2).getGrantedPrivilege().getLabel(),
is(equalTo("read")));
assertThat(jdoePermissions.get(2).getObject().getDisplayName(),
is(equalTo("Test Object 2")));
assertThat(jdoePermissions.get(3).getGrantedPrivilege().getLabel(),
is(equalTo("write")));
assertThat(jdoePermissions.get(3).getObject().getDisplayName(),
is(equalTo("Test Object 1")));
final List<Permission> mmusterPermissions = permissionRepository
.findPermissionsForUser(mmuster);
assertThat(mmusterPermissions.size(), is(1));
assertThat(mmusterPermissions.get(0).getGrantedPrivilege()
.getLabel(),
is(equalTo("admin")));
assertThat(mmusterPermissions.get(0).getObject(), is(nullValue()));
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(21)
public void findPermissionsForNullUser() {
permissionRepository.findPermissionsForUser(null);
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@InSequence(30)
public void findPermissionsForCcmObject() {
final CcmObject object1 = ccmObjectRepository.findById(-10L);
final CcmObject object2 = ccmObjectRepository.findById(-20L);
final CcmObject object3 = ccmObjectRepository.findById(-30L);
final List<Permission> object1Permissions = permissionRepository
.findPermissionsForCcmObject(object1);
assertThat(object1Permissions.size(), is(3));
Collections.sort(object1Permissions, new Comparator<Permission>() {
@Override
public int compare(final Permission permission1,
final Permission permission2) {
return Long.compare(permission1.getPermissionId(),
permission2.getPermissionId());
}
});
assertThat(object1Permissions.get(0).getGrantedPrivilege()
.getLabel(),
is(equalTo("read")));
assertThat(object1Permissions.get(0).getGrantee(),
is(instanceOf(Group.class)));
assertThat(((Group) object1Permissions.get(0).getGrantee()).getName(),
is(equalTo("authors")));
assertThat(object1Permissions.get(1).getGrantedPrivilege()
.getLabel(),
is(equalTo("write")));
assertThat(object1Permissions.get(1).getGrantee(),
is(instanceOf(Group.class)));
assertThat(((Group) object1Permissions.get(1).getGrantee()).getName(),
is(equalTo("authors")));
assertThat(object1Permissions.get(2).getGrantedPrivilege()
.getLabel(),
is(equalTo("read")));
assertThat(object1Permissions.get(2).getGrantee(),
is(instanceOf(Group.class)));
assertThat(((Group) object1Permissions.get(2).getGrantee()).getName(),
is(equalTo("users")));
final List<Permission> object2Permissions = permissionRepository
.findPermissionsForCcmObject(object2);
assertThat(object2Permissions.size(), is(1));
assertThat(object2Permissions.get(0).getGrantedPrivilege()
.getLabel(),
is(equalTo("read")));
assertThat(object2Permissions.get(0).getGrantee(),
is(instanceOf(User.class)));
assertThat(((User) object2Permissions.get(0).getGrantee())
.getScreenName(),
is(equalTo("jdoe")));
final List<Permission> object3Permissions = permissionRepository
.findPermissionsForCcmObject(object3);
assertThat(object3Permissions, is(empty()));
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(31)
public void findPermissionsForNullObject() {
permissionRepository.findPermissionsForCcmObject(null);
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionRepositoryTest/after-save-new.yml",
excludeColumns = {"permission_id"})
@InSequence(40)
public void saveNewPermission() {
final User mmuster = userRepository.findByScreenName("mmuster");
final TypedQuery<Privilege> query1 = entityManager.createQuery(
"SELECT p FROM Privilege p WHERE p.label = 'read'",
Privilege.class);
final TypedQuery<Privilege> query2 = entityManager.createQuery(
"SELECT p FROM Privilege p WHERE p.label = 'write'",
Privilege.class);
final CcmObject object = ccmObjectRepository.findById(-40L);
final Privilege read = query1.getSingleResult();
final Privilege write = query2.getSingleResult();
assertThat(mmuster, is(not(nullValue())));
assertThat(read, is(not(nullValue())));
assertThat(write, is(not(nullValue())));
assertThat(object, is(not(nullValue())));
final Permission permission1 = new Permission();
permission1.setGrantee(mmuster);
permission1.setGrantedPrivilege(read);
permission1.setObject(object);
final Permission permission2 = new Permission();
permission2.setGrantee(mmuster);
permission2.setGrantedPrivilege(write);
permission2.setObject(object);
permissionRepository.save(permission1);
permissionRepository.save(permission2);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(41)
public void saveNullPermission() {
permissionRepository.save(null);
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionRepositoryTest/after-save-changed.yml",
excludeColumns = {"permission_id"})
@InSequence(50)
public void saveChangedPermission() {
final Permission permission = entityManager.find(Permission.class, -40L);
final Group users = groupRepository.findByGroupName("users");
assertThat(permission, is(not(nullValue())));
assertThat(users, is(not(nullValue())));
permission.setGrantee(users);
permissionRepository.save(permission);
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/PermissionRepositoryTest/data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PermissionRepositoryTest/after-delete.yml",
excludeColumns = {"permission_id"})
@InSequence(60)
public void deletePermission() {
final Permission permission = entityManager.find(Permission.class, -35L);
permissionRepository.delete(permission);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(61)
public void deleteNullPermission() {
permissionRepository.delete(null);
}
}

View File

@ -1,201 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import javax.inject.Inject;
import static org.junit.Assert.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class PrivilegeRepositoryTest {
@Inject
private transient PrivilegeRepository privilegeRepository;
public PrivilegeRepositoryTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PrivilegeRepositoryTest/"
+ "data.yml")
@InSequence(10)
public void retrievePrivilege() {
final Privilege admin = privilegeRepository.retrievePrivilege("admin");
final Privilege read = privilegeRepository.retrievePrivilege("read");
final Privilege write = privilegeRepository.retrievePrivilege("write");
assertThat(admin, is(not(nullValue())));
assertThat(read, is(not(nullValue())));
assertThat(write, is(not(nullValue())));
assertThat(admin.getLabel(), is(equalTo("admin")));
assertThat(read.getLabel(), is(equalTo("read")));
assertThat(write.getLabel(), is(equalTo("write")));
}
@Test(expected = UnknownPrivilegeException.class)
@UsingDataSet("datasets/org/libreccm/core/PrivilegeRepositoryTest/"
+ "data.yml")
@ShouldThrowException(UnknownPrivilegeException.class)
@InSequence(20)
public void retrieveNotExitingPrivilege() {
privilegeRepository.retrievePrivilege("publish");
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PrivilegeRepositoryTest/"
+ "data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PrivilegeRepositoryTest/after-create.yml",
excludeColumns = {"privilege_id"})
@InSequence(30)
public void createNewPrivilege() {
privilegeRepository.createPrivilege("publish");
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PrivilegeRepositoryTest/"
+ "data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/"
+ "PrivilegeRepositoryTest/after-delete.yml",
excludeColumns = {"privilege_id"})
@InSequence(40)
public void deletePrivilege() {
privilegeRepository.deletePrivilege("write");
}
@Test(expected = UnknownPrivilegeException.class)
@UsingDataSet("datasets/org/libreccm/core/PrivilegeRepositoryTest/"
+ "data.yml")
@ShouldThrowException(UnknownPrivilegeException.class)
@InSequence(41)
public void deleteNullPrivilege() {
privilegeRepository.deletePrivilege(null);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/PermissionRepositoryTest/"
+ "data.yml")
@InSequence(50)
public void checkIsPermissionInUse() {
assertThat(privilegeRepository.isPrivilegeInUse("admin"), is(true));
assertThat(privilegeRepository.isPrivilegeInUse("write"), is(true));
assertThat(privilegeRepository.isPrivilegeInUse("read"), is(true));
assertThat(privilegeRepository.isPrivilegeInUse("used"), is(false));
}
@Test(expected = IllegalArgumentException.class)
@UsingDataSet("datasets/org/libreccm/core/PermissionRepositoryTest/"
+ "data.yml")
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(60)
public void deleteInUsePrivilege() {
privilegeRepository.deletePrivilege("admin");
}
}

View File

@ -1,368 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import java.util.List;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class RoleRepositoryTest {
@Inject
private transient RoleRepository roleRepository;
@Inject
private transient GroupRepository groupRepository;
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.RoleRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
private void verifyAuthor(final Role author) {
assertThat(author, is(not(nullValue())));
assertThat(author.getName(), is(equalTo("Author")));
assertThat(author.getDescription(),
is(equalTo("Creates new content")));
assertThat(author.getImplicitGroup().getName(),
is(equalTo("info Administration Author")));
assertThat(author.getSourceGroup().getName(),
is(equalTo("info Administration")));
}
private void verifyEditor(final Role editor) {
assertThat(editor, is(not(nullValue())));
assertThat(editor.getName(), is(equalTo("Editor")));
assertThat(editor.getDescription(),
is(equalTo("Reviews and approves the author's work")));
assertThat(editor.getImplicitGroup().getName(),
is(equalTo("info Administration Editor")));
assertThat(editor.getSourceGroup().getName(),
is(equalTo("info Administration")));
}
private void verifyPublisher(final Role publisher) {
assertThat(publisher, is(not(nullValue())));
assertThat(publisher.getName(), is(equalTo("Publisher")));
assertThat(publisher.getDescription(),
is(equalTo("Deploys the content to the web site")));
assertThat(publisher.getImplicitGroup().getName(),
is(equalTo("info Administration Publisher")));
assertThat(publisher.getSourceGroup().getName(),
is(equalTo("info Administration")));
}
private void verifyManager(final Role manager) {
assertThat(manager, is(not(nullValue())));
assertThat(manager.getName(), is(equalTo("Manager")));
assertThat(manager.getDescription(),
is(equalTo("Manages the overall content section")));
assertThat(manager.getImplicitGroup().getName(),
is(equalTo("info Administration Manager")));
assertThat(manager.getSourceGroup().getName(),
is(equalTo("info Administration")));
}
private void verifyTrustedUser(final Role trustedUser) {
assertThat(trustedUser, is(not(nullValue())));
assertThat(trustedUser.getName(), is(equalTo("Trusted User")));
assertThat(trustedUser.getDescription(),
is(equalTo("A trusted user is allowed to create and publish "
+ "items without review")));
assertThat(trustedUser.getImplicitGroup().getName(),
is(equalTo("info Administration Trusted User")));
assertThat(trustedUser.getSourceGroup().getName(),
is(equalTo("info Administration")));
}
private void verifyContentReader(final Role contentReader) {
assertThat(contentReader, is(not(nullValue())));
assertThat(contentReader.getName(), is(equalTo("Content Reader")));
assertThat(contentReader.getDescription(),
is(equalTo("Can view published pages within this section")));
assertThat(contentReader.getImplicitGroup().getName(),
is(equalTo("info Viewers Content Reader")));
assertThat(contentReader.getSourceGroup().getName(),
is(equalTo("info Viewers")));
}
private void verifyAlertRecipient(final Role alertRecipient) {
assertThat(alertRecipient, is(not(nullValue())));
assertThat(alertRecipient.getName(), is(equalTo("Alert Recipient")));
assertThat(alertRecipient.getDescription(),
is(equalTo("Receive alerts regarding expiration of "
+ "published content")));
assertThat(alertRecipient.getImplicitGroup().getName(),
is(equalTo("info Administration Alert Recipient")));
assertThat(alertRecipient.getSourceGroup().getName(),
is(equalTo("info Viewers")));
}
@Test
@InSequence(10)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
public void findRoleById() {
final Role author = roleRepository.findById(-10L);
final Role editor = roleRepository.findById(-20L);
final Role publisher = roleRepository.findById(-30L);
final Role manager = roleRepository.findById(-40L);
final Role trustedUser = roleRepository.findById(-50L);
final Role contentReader = roleRepository.findById(-60L);
final Role alertRecipient = roleRepository.findById(-70L);
verifyAuthor(author);
verifyEditor(editor);
verifyPublisher(publisher);
verifyManager(manager);
verifyTrustedUser(trustedUser);
verifyContentReader(contentReader);
verifyAlertRecipient(alertRecipient);
}
@Test
@InSequence(20)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
public void findRoleByName() {
final List<Role> authors = roleRepository.findRolesForName("Author");
final List<Role> editors = roleRepository.findRolesForName("Editor");
final List<Role> publishers = roleRepository.findRolesForName(
"Publisher");
final List<Role> managers = roleRepository.findRolesForName("Manager");
final List<Role> trustedUsers = roleRepository.findRolesForName(
"Trusted User");
final List<Role> contentReaders = roleRepository.findRolesForName(
"Content Reader");
final List<Role> alertRecipients = roleRepository.findRolesForName(
"Alert Recipient");
assertThat(authors.size(), is(1));
assertThat(editors.size(), is(1));
assertThat(publishers.size(), is(1));
assertThat(managers.size(), is(1));
assertThat(trustedUsers.size(), is(1));
assertThat(contentReaders.size(), is(1));
assertThat(alertRecipients.size(), is(1));
final Role author = authors.get(0);
final Role editor = editors.get(0);
final Role publisher = publishers.get(0);
final Role manager = managers.get(0);
final Role trustedUser = trustedUsers.get(0);
final Role contentReader = contentReaders.get(0);
final Role alertRecipient = alertRecipients.get(0);
verifyAuthor(author);
verifyEditor(editor);
verifyPublisher(publisher);
verifyManager(manager);
verifyTrustedUser(trustedUser);
verifyContentReader(contentReader);
verifyAlertRecipient(alertRecipient);
}
@Test
@InSequence(30)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
public void findRolesForSourceGroup() {
final Group group = groupRepository.findByGroupName(
"info Administration");
assertThat(group, is(not(nullValue())));
final List<Role> roles = roleRepository.findRolesForSourceGroup(group);
assertThat(roles.size(), is(5));
verifyAuthor(roles.get(0));
verifyEditor(roles.get(1));
verifyManager(roles.get(2));
verifyPublisher(roles.get(3));
verifyTrustedUser(roles.get(4));
}
@Test
@InSequence(40)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
public void findRolesForImplicitGroup() {
final Group authorsGroup = groupRepository.findByGroupName(
"info Administration Author");
assertThat(authorsGroup, is(not(nullValue())));
final List<Role> authors = roleRepository.findRolesForImplicitGroup(
authorsGroup);
assertThat(authors.size(), is(1));
verifyAuthor(authors.get(0));
final Group editorsGroup = groupRepository.findByGroupName(
"info Administration Editor");
assertThat(editorsGroup, is(not(nullValue())));
final List<Role> editors = roleRepository.findRolesForImplicitGroup(
editorsGroup);
assertThat(editors.size(), is(1));
verifyEditor(editors.get(0));
final Group publisherGroup = groupRepository.findByGroupName(
"info Administration Publisher");
assertThat(publisherGroup, is(not(nullValue())));
final List<Role> publishers = roleRepository.findRolesForImplicitGroup(
publisherGroup);
assertThat(publishers.size(), is(1));
verifyPublisher(publishers.get(0));
}
@Test
@InSequence(50)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/RoleRepositoryTest/"
+ "after-save-new.yml",
excludeColumns = {"role_id"})
public void saveNewRole() {
final Group infoAdmin = groupRepository.findByGroupName(
"info Administration");
final Group readers = groupRepository.findByGroupName(
"info Viewers Content Reader");
final Role role = new Role();
role.setName("Test");
role.setDescription("New role for testing");
role.setImplicitGroup(infoAdmin);
role.setSourceGroup(readers);
roleRepository.save(role);
}
@Test
@InSequence(60)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
@ShouldMatchDataSet(value = "datasets/org/libreccm/core/RoleRepositoryTest/"
+ "after-save-changed.yml",
excludeColumns = {"role_id"})
public void saveChangedRole() {
final Role role = roleRepository.findById(-60L);
role.setName("Reader");
roleRepository.save(role);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(70)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
public void saveNullValue() {
roleRepository.save(null);
}
@Test
@InSequence(80)
@UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.yml")
@ShouldMatchDataSet("datasets/org/libreccm/core/RoleRepositoryTest/"
+ "after-delete.yml")
public void deleteRole() {
final Role role = roleRepository.findById(-50L);
roleRepository.delete(role);
}
}

View File

@ -1,290 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.apache.commons.codec.binary.Base64;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.persistence.CreateSchema;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import static org.junit.Assert.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class UserManagerTest {
@Inject
private transient UserRepository userRepository;
@Inject
private transient UserManager userManager;
@PersistenceContext
private transient EntityManager entityManager;
public UserManagerTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserManagerTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@Test
@InSequence(10)
public void userRepoIsInjected() {
assertThat(userRepository, is(not(nullValue())));
}
@Test
@InSequence(20)
public void userManagerIsInjected() {
assertThat(userManager, is(not(nullValue())));
}
@Test
@InSequence(30)
public void entityManagerIsInjected() {
assertThat(entityManager, is(not(nullValue())));
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@InSequence(100)
public void updatePassword() throws NoSuchAlgorithmException,
UnsupportedEncodingException {
final User jdoe = userRepository.findById(-10L);
assertThat(jdoe, is(not(nullValue())));
assertThat(jdoe.getScreenName(), is("jdoe"));
final String newPassword = "foobar";
userManager.updatePassword(jdoe, newPassword);
final Base64 base64 = new Base64();
final User user = entityManager.find(User.class, -10L);
final byte[] passwordBytes = newPassword.getBytes(
StandardCharsets.UTF_8);
final String salt = user.getSalt();
final byte[] saltBytes = base64.decode(salt);
assertThat(saltBytes.length, is(userManager.getSaltLength()));
final MessageDigest digest = MessageDigest.getInstance(userManager
.getHashAlgorithm());
final byte[] saltedPassword = new byte[passwordBytes.length
+ saltBytes.length];
System.arraycopy(passwordBytes,
0,
saltedPassword,
0,
passwordBytes.length);
System.arraycopy(saltBytes,
0,
saltedPassword,
passwordBytes.length,
saltBytes.length);
final byte[] hashedBytes = digest.digest(saltedPassword);
final String hashed = base64.encodeToString(hashedBytes);
assertThat(user.getPassword(), is(equalTo(hashed)));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(200)
public void verifyPasswordForUser() {
final User user = userRepository.findById(-10L);
//userManager.updatePassword(user, "foobar");
final boolean result = userManager.verifyPasswordForUser(user, "foobar");
assertThat(result, is(true));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(300)
public void verifyPasswordForScreenname() throws UserNotFoundException {
final boolean result = userManager.verifyPasswordForScreenname(
"jdoe", "foobar");
assertThat(result, is(true));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(400)
public void verifyPasswordForEmail() throws UserNotFoundException {
final boolean result = userManager.verifyPasswordForEmail(
"john.doe@example.com", "foobar");
assertThat(result, is(true));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(500)
public void verifyPasswordForUserWrongPassword() {
final User user = userRepository.findById(-10L);
final boolean result = userManager.verifyPasswordForUser(user, "wrong");
assertThat(result, is(false));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(600)
public void verifyPasswordForScreennameWrongPassword() throws
UserNotFoundException {
final boolean result = userManager.verifyPasswordForScreenname(
"jdoe", "wrong");
assertThat(result, is(false));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(400)
public void verifyPasswordForEmailWrongPassword() throws
UserNotFoundException {
final boolean result = userManager.verifyPasswordForEmail(
"john.doe@example.com", "wrong");
assertThat(result, is(false));
}
@Test(expected = UserNotFoundException.class)
@ShouldThrowException(UserNotFoundException.class)
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(700)
public void verifyPasswordForScreennameNoUser() throws UserNotFoundException {
userManager.verifyPasswordForScreenname("nobody", "foobar");
}
@Test(expected = UserNotFoundException.class)
@ShouldThrowException(UserNotFoundException.class)
@UsingDataSet(
"datasets/org/libreccm/core/UserManagerTest/verify-password.yml")
@InSequence(800)
public void verifyPasswordForEmailNoUser() throws UserNotFoundException {
userManager.verifyPasswordForEmail("nobody@example.com", "foobar");
}
}

View File

@ -1,337 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.io.File;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.tests.categories.IntegrationTest;
import java.util.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class UserRepositoryTest {
private static final String NOBODY = "nobody";
private static final String JOE = "joe";
private static final String MMUSTER = "mmuster";
private static final String JDOE = "jdoe";
@Inject
private transient UserRepository userRepository;
@PersistenceContext
private transient EntityManager entityManager;
public UserRepositoryTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom.
importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@Test
public void repoIsInjected() {
assertThat(userRepository, is(not(nullValue())));
}
@Test
public void entityManagerIsInjected() {
assertThat(entityManager, is(not(nullValue())));
}
private void checkUsers(final User jdoe,
final User mmuster,
final User joe,
final User nobody) {
assertThat(jdoe, is(not(nullValue())));
assertThat(jdoe.getSubjectId(), is(-10L));
assertThat(jdoe.getScreenName(), is(JDOE));
assertThat(jdoe.getName().getFamilyName(), is(equalTo("Doe")));
assertThat(jdoe.getName().getMiddleName(), is(nullValue()));
assertThat(jdoe.getName().getGivenName(), is(equalTo("John")));
assertThat(jdoe.getHashAlgorithm(), is("MD5"));
assertThat(jdoe.getPassword(), is("604622dc8a888eb093454ebd77ca1675"));
assertThat(jdoe.getSalt(), is("axg8ira8fa"));
assertThat(mmuster, is(not(nullValue())));
assertThat(mmuster.getSubjectId(), is(-20L));
assertThat(mmuster.getScreenName(), is(equalTo(MMUSTER)));
assertThat(mmuster.getName().getFamilyName(), is(equalTo("Mustermann")));
assertThat(mmuster.getName().getMiddleName(), is(nullValue()));
assertThat(mmuster.getName().getGivenName(), is(equalTo("Max")));
assertThat(mmuster.getHashAlgorithm(), is(equalTo("SHA-512")));
assertThat(mmuster.getPassword(), is(equalTo(
"1c9626af429a6291766d15cbfb38689bd8d49450520765973de70aecaf644b7d4fda711266ba9ec8fb6df30c8ab391d40330829aa85adf371bcde6b4c9bc01e6")));
assertThat(mmuster.getSalt(), is(equalTo("fjiajhigafgapoa")));
assertThat(joe, is(not(nullValue())));
assertThat(joe.getSubjectId(), is(-30L));
assertThat(joe.getScreenName(), is(equalTo(JOE)));
assertThat(joe.getName().getFamilyName(), is(equalTo("Public")));
assertThat(joe.getName().getMiddleName(), is(nullValue()));
assertThat(joe.getName().getGivenName(), is(equalTo("Joe")));
assertThat(joe.getHashAlgorithm(), is(equalTo("SHA-512")));
assertThat(joe.getPassword(), is(equalTo(
"4e39eba7f2927182a532cd8700bf251e58d4b0359fbb832e6af21db7501d7a49e6d8b950e0d4b15b1841af0f786c8edaa0c09ef7f474804254f7e895969d2975")));
assertThat(joe.getSalt(), is(equalTo("axg8ira8fa")));
assertThat(nobody, is(nullValue()));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@InSequence(100)
public void findUserById() {
final User jdoe = userRepository.findById(-10L);
final User mmuster = userRepository.findById(-20L);
final User joe = userRepository.findById(-30L);
final User nobody = userRepository.findById(-999L);
checkUsers(jdoe, mmuster, joe, nobody);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@InSequence(200)
public void findUserByScreenName() {
final User jdoe = userRepository.findByScreenName(JDOE);
final User mmuster = userRepository.findByScreenName(MMUSTER);
final User joe = userRepository.findByScreenName(JOE);
final User nobody = userRepository.findByScreenName(NOBODY);
checkUsers(jdoe, mmuster, joe, nobody);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@InSequence(300)
public void findUserByEmail() {
final User jdoe = userRepository.findByEmailAddress(
"john.doe@example.com");
final User mmuster1 = userRepository.findByEmailAddress(
"max.mustermann@example.org");
final User mmuster2 = userRepository
.findByEmailAddress("mm@example.com");
final User joe = userRepository.findByEmailAddress(
"joe.public@example.com");
final User nobody = userRepository
.findByEmailAddress("nobody@example.org");
checkUsers(jdoe, mmuster1, joe, nobody);
assertThat(mmuster2, is(equalTo(mmuster1)));
}
@Test(expected = MultipleMatchingUserException.class)
@ShouldThrowException(MultipleMatchingUserException.class)
@UsingDataSet(
"datasets/org/libreccm/core/UserRepositoryTest/data-email-duplicate.yml")
@InSequence(350)
public void findByEmailAddressDuplicate() {
userRepository.findByEmailAddress("max.mustermann@example.org");
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@InSequence(400)
public void findAllUsers() {
final List<User> users = userRepository.findAll();
assertThat(users.size(), is(3));
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@ShouldMatchDataSet(value
= "datasets/org/libreccm/core/UserRepositoryTest/after-save-new.yml",
excludeColumns = {"subject_id", "user_id"})
@InSequence(500)
public void saveNewUser() {
final User user = new User();
final PersonName personName = new PersonName();
personName.setGivenName("Jane");
personName.setMiddleName("Anna");
personName.setFamilyName("Doe");
personName.setTitlePre("Dr.");
user.setName(personName);
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jane.doe@example.org");
emailAddress.setBouncing(false);
emailAddress.setVerified(false);
user.addEmailAddress(emailAddress);
user.setScreenName("jane");
user.setPassword(
"32d2a830fb03f201bda975ae70a62c207716705a049e054cf6701de1cec546d3a9e03a094be2e98e4d125af996ebbfa5a7754754a1e9d2fe063a0d9921cb201d");
user.setHashAlgorithm("SHA-512");
user.setSalt("maifgaoapafga9");
user.setPasswordResetRequired(false);
userRepository.save(user);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@ShouldMatchDataSet(value
= "datasets/org/libreccm/core/UserRepositoryTest/after-save-changed.yml",
excludeColumns = {"subject_id"})
@InSequence(600)
public void saveChangedUser() {
final User user = userRepository.findById(-10L);
user.getName().setTitlePre("Dr.");
user.setHashAlgorithm("SHA-512");
user.setPassword(
"19f69a0f8eab3e6124d1b40ca2ae1fc3ece311cf86dde4e9560521e881fb8f063817cf1da1234144825f40fc9b9acd1563cafcb35fb8533544a1b6c3615160e3");
user.setSalt("fafjiaddfja0a");
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jd@example.com");
emailAddress.setBouncing(false);
emailAddress.setVerified(true);
user.addEmailAddress(emailAddress);
final EmailAddress old = user.getEmailAddresses().get(0);
user.removeEmailAddress(old);
userRepository.save(user);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(700)
public void saveNullValue() {
userRepository.save(null);
}
@Test
@UsingDataSet("datasets/org/libreccm/core/UserRepositoryTest/data.yml")
@ShouldMatchDataSet(value
= "datasets/org/libreccm/core/UserRepositoryTest/after-delete.yml",
excludeColumns = {"subject_id"})
@InSequence(800)
public void deleteUser() {
final User user = userRepository.findByScreenName("mmuster");
userRepository.delete(user);
}
@Test(expected = IllegalArgumentException.class)
@ShouldThrowException(IllegalArgumentException.class)
@InSequence(900)
public void deleteNullValue() {
userRepository.delete(null);
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import java.util.Arrays;
import java.util.Collection;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.libreccm.tests.categories.UnitTest;
import org.libreccm.testutils.EqualsVerifier;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RunWith(Parameterized.class)
@Category(UnitTest.class)
public class EqualsAndHashCodeTest extends EqualsVerifier {
@Parameterized.Parameters(name = "{0}")
public static Collection<Class<?>> data() {
return Arrays.asList(new Class<?>[] {
UserPrincipal.class
});
}
public EqualsAndHashCodeTest(final Class<?> entityClass) {
super(entityClass);
}
}

View File

@ -1,270 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.CreateSchema;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.EmailAddress;
import org.libreccm.core.Subject;
import org.libreccm.core.User;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import javax.inject.Inject;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
@CreateSchema({"create_ccm_core_schema.sql"})
public class LoginManagerTest {
@Inject
private transient LoginManager loginManager;
@Inject
private transient CcmSessionContext ccmSessionContext;
public LoginManagerTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
final String[] config = new String[]{
String.format("Register:%s:requisite",
LocalLoginModule.class.getName())};
final LoginConfigBuilder loginConfigBuilder = new LoginConfigBuilder(
config);
Configuration.setConfiguration(loginConfigBuilder.build());
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom
.importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.authentication.LoginManagerTest.war")
.addPackage(CcmObject.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage())
.addPackage(org.libreccm.cdi.utils.CdiUtil.class.getPackage())
.addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.core.authentication.LoginManager.class
.getPackage())
.addPackage(com.arsdigita.kernel.KernelConfig.class.getPackage())
.addPackage(com.arsdigita.runtime.AbstractConfig.class.getPackage())
.addPackage(com.arsdigita.util.parameter.AbstractParameter.class
.getPackage())
.addPackage(com.arsdigita.util.UncheckedWrapperException.class
.getPackage())
.addPackage(com.arsdigita.xml.XML.class
.getPackage())
.addPackage(com.arsdigita.xml.formatters.DateTimeFormatter.class
.getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addPackage(com.arsdigita.web.CCMApplicationContextListener.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/ccm-core.config",
"ccm-core.config")
.addAsWebInfResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/registry.properties",
"conf/registry/registry.properties")
.addAsWebInfResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/kernel.properties",
"conf/registry/ccm-core/kernel.properties")
.addAsResource(
"com/arsdigita/kernel/KernelConfig_parameter.properties",
"com/arsdigita/kernel/KernelConfig_parameter.properties")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@InSequence(1)
public void isLoginManagerInjected() {
assertThat(loginManager, is(not(nullValue())));
}
@InSequence(2)
public void isCcmSessionContextInjected() {
assertThat(ccmSessionContext, is(not(nullValue())));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(10)
public void loginValidCredentials() throws LoginException {
loginManager.login("jdoe@example.com", "foobar");
assertThat(ccmSessionContext.getCurrentSubject(), is(not(nullValue())));
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jdoe@example.com");
emailAddress.setBouncing(false);
emailAddress.setVerified(true);
final Subject subject = ccmSessionContext.getCurrentSubject();
assertThat(subject, is(instanceOf(User.class)));
final User user = (User) subject;
assertThat(user.getEmailAddresses(), contains(equalTo(emailAddress)));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(20)
public void loginWrongCredentials() throws LoginException {
try {
loginManager.login("jdoe@example.com", "wrong-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentSubject(), is(nullValue()));
return;
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(30)
public void loginEmptyPassword() {
try {
loginManager.login("jdoe@example.com", "");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentSubject(), is(nullValue()));
return;
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(40)
public void loginEmptyUserName() {
try {
loginManager.login("", "correct-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentSubject(), is(nullValue()));
return;
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(50)
public void loginNullPassword() {
try {
loginManager.login("jdoe@example.com", null);
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentSubject(), is(nullValue()));
return;
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.yml")
@InSequence(60)
public void loginNullUsername() {
try {
loginManager.login(null, "correct-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentSubject(), is(nullValue()));
return;
}
fail("No login exception was thrown.");
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core.authentication;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class UserPrincipalToStringTest {
public UserPrincipalToStringTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void verifyToString() throws IllegalArgumentException,
IllegalAccessException {
final UserPrincipal principal = new UserPrincipal(null);
final Field[] fields = principal.getClass().getDeclaredFields();
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())
&& !field.getType().isPrimitive()) {
field.setAccessible(true);
field.set(principal, null);
}
}
try {
principal.toString();
} catch (NullPointerException ex) {
final StringWriter strWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(strWriter);
ex.printStackTrace(writer);
Assert.fail(String.format(
"toString() implementation of of class \"%s\" "
+ "is not null safe:%n %s",
principal.getClass().getName(),
strWriter.toString()));
}
}
}

View File

@ -27,6 +27,8 @@ import com.arsdigita.web.CCMApplicationContextListener;
import com.arsdigita.xml.XML;
import com.arsdigita.xml.formatters.DateTimeFormatter;
import static org.libreccm.core.CoreConstants.*;
import java.io.File;
import java.util.concurrent.Callable;
@ -57,6 +59,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.categorization.Categorization;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository;
import org.libreccm.jpa.EntityManagerProducer;
@ -68,6 +71,9 @@ import org.libreccm.testutils.EqualsVerifier;
import org.libreccm.web.CcmApplication;
import org.libreccm.workflow.Workflow;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@ -129,8 +135,8 @@ public class PermissionCheckerTest {
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.security.PermissionCheckerTest.war")
.addPackage(User.class.getPackage())
"LibreCCM-org.libreccm.security.PermissionCheckerTest.war").
addPackage(User.class.getPackage())
.addPackage(CcmObject.class.getPackage())
.addPackage(Categorization.class.getPackage())
.addPackage(LocalizedString.class.getPackage())
@ -148,6 +154,7 @@ public class PermissionCheckerTest {
.addPackage(CCMApplicationContextListener.class.getPackage())
.addPackage(XML.class.getPackage())
.addPackage(DateTimeFormatter.class.getPackage())
.addPackage(CdiUtil.class.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
@ -184,7 +191,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(100)
@InSequence(1100)
public void isPermittedAuthenticatedUser() {
final UsernamePasswordToken token = new UsernamePasswordToken("jdoe",
"foo123");
@ -198,7 +205,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(200)
@InSequence(1200)
public void isPermittedUnAuthenticatedUser() {
assertThat(permissionChecker.isPermitted("privilege1"), is(false));
assertThat(permissionChecker.isPermitted("privilege2"), is(false));
@ -207,7 +214,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(200)
@InSequence(1300)
public void isPermittedSystemUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject object2 = objectRepository.findById(-20002L);
@ -243,7 +250,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(400)
@InSequence(1400)
public void isPermittedObjectAuthenticatedUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject object2 = objectRepository.findById(-20002L);
@ -264,7 +271,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(500)
@InSequence(1500)
public void isPermittedObjectUnAuthenticatedUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject object2 = objectRepository.findById(-20002L);
@ -281,7 +288,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(600)
@InSequence(2100)
public void checkPermissionAuthenticatedUser() {
final UsernamePasswordToken token = new UsernamePasswordToken("mmuster",
"foo123");
@ -294,14 +301,14 @@ public class PermissionCheckerTest {
@Test(expected = AuthorizationException.class)
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@ShouldThrowException(AuthorizationException.class)
@InSequence(600)
@InSequence(2200)
public void checkPermissionUnAuthenticatedUser() {
permissionChecker.checkPermission("privilege1");
}
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(600)
@InSequence(2300)
public void checkPermissionObjectAuthenticatedUser() {
final CcmObject object2 = objectRepository.findById(-20002L);
@ -316,7 +323,7 @@ public class PermissionCheckerTest {
@Test(expected = AuthorizationException.class)
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@ShouldThrowException(AuthorizationException.class)
@InSequence(600)
@InSequence(2400)
public void checkPermissionObjectUnAuthenticatedUser() {
final CcmObject object2 = objectRepository.findById(-20002L);
@ -325,7 +332,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(600)
@InSequence(2500)
public void checkPermissionObjectPublicUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
@ -334,7 +341,7 @@ public class PermissionCheckerTest {
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(600)
@InSequence(2600)
public void checkPermissionObjectSystemUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject object2 = objectRepository.findById(-20002L);
@ -358,4 +365,98 @@ public class PermissionCheckerTest {
});
}
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(3100)
public void checkPermissionReturnObjectAuthenticatedUser() {
final CcmObject object2 = objectRepository.findById(-20002L);
final UsernamePasswordToken token = new UsernamePasswordToken("jdoe",
"foo123");
token.setRememberMe(true);
subject.login(token);
final CcmObject result = permissionChecker.checkPermission(
"privilege2", object2, CcmObject.class);
assertThat(result.getDisplayName(), is(equalTo("object2")));
assertThat(permissionChecker.isAccessDeniedObject(result), is(false));
assertThat(result, is(equalTo(object2)));
}
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(3200)
public void checkPermissionReturnObjectUnAuthenticatedUser() {
final CcmObject object2 = objectRepository.findById(-20002L);
final CcmObject result = permissionChecker.checkPermission(
"privilege2", object2, CcmObject.class);
assertThat(result.getDisplayName(), is(equalTo(ACCESS_DENIED)));
assertThat(permissionChecker.isAccessDeniedObject(result), is(true));
assertThat(result, is(not(equalTo(object2))));
}
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(600)
public void checkPermissionReturnObjectPublicUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject result = permissionChecker.checkPermission(
"privilege3", object1, CcmObject.class);
assertThat(result.getDisplayName(), is(equalTo("object1")));
assertThat(permissionChecker.isAccessDeniedObject(result), is(false));
assertThat(result, is(equalTo(object1)));
}
@Test
@UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
@InSequence(3200)
public void checkPermissionReturnObjectSystemUser() {
final CcmObject object1 = objectRepository.findById(-20001L);
final CcmObject object2 = objectRepository.findById(-20002L);
final CcmObject object3 = objectRepository.findById(-20003L);
final List<CcmObject> results = shiro.getSystemUser().execute(
new Callable<List<CcmObject>>() {
@Override
public List<CcmObject> call() {
permissionChecker.checkPermission("privilege1");
permissionChecker.checkPermission("privilege2");
permissionChecker.checkPermission("privilege3");
final CcmObject result3 = permissionChecker.checkPermission(
"privilege1", object3, CcmObject.class);
final CcmObject result1 = permissionChecker.checkPermission(
"privilege2", object1, CcmObject.class);
final CcmObject result2 = permissionChecker.checkPermission(
"privilege3", object2, CcmObject.class);
final List<CcmObject> results = new ArrayList<>();
results.add(result1);
results.add(result2);
results.add(result3);
return results;
}
});
final CcmObject result1 = results.get(0);
final CcmObject result2 = results.get(1);
final CcmObject result3 = results.get(2);
assertThat(result1.getDisplayName(), is(equalTo("object1")));
assertThat(permissionChecker.isAccessDeniedObject(result1), is(false));
assertThat(result1, is(equalTo(object1)));
assertThat(result2.getDisplayName(), is(equalTo("object2")));
assertThat(permissionChecker.isAccessDeniedObject(result2), is(false));
assertThat(result2, is(equalTo(object2)));
assertThat(result3.getDisplayName(), is(equalTo("object3")));
assertThat(permissionChecker.isAccessDeniedObject(result3), is(false));
assertThat(result3, is(equalTo(object3)));
}
}