/*
* (c) 2008- RANDI2 Core Development Team
*
* This file is part of RANDI2.
*
* RANDI2 is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* RANDI2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* RANDI2. If not, see <http://www.gnu.org/licenses/>.
*/
package de.randi2.utility.security;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import de.randi2.dao.HibernateAclService;
import de.randi2.model.AbstractDomainObject;
import de.randi2.model.Login;
import de.randi2.model.Person;
import de.randi2.model.Role;
import de.randi2.model.Trial;
import de.randi2.model.TrialSite;
import de.randi2.model.TrialSubject;
import de.randi2.model.security.PermissionHibernate;
/**
* <p>
* This class realize the mapping between the roles and rights in the RANDI2
* system.
* </p>
*
* @author Lukasz Plotnicki <lplotni@users.sourceforge.net>
* @author Daniel Schrimpf <dschrimpf@users.sourceforge.net>
*/
public class RolesAndRights {
@Autowired
private HibernateAclService aclService;
protected EntityManager entityManager;
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Transactional(propagation = Propagation.REQUIRED)
public void grantRights(AbstractDomainObject object, TrialSite scope) {
// if(scope== null || object == null){
// throw new RuntimeException();
// }else
if (object instanceof Login) {
grantRightsUserObjectWithScope((Login) object, scope);
grantRightsUserObjectWithOutScope((Login) object);
} else if (object instanceof TrialSite) {
grantRightsTrialSiteObject((TrialSite) object);
} else if (object instanceof Trial) {
grantRightsTrialObjectWithScope((Trial) object, scope);
grantRightsTrialObjectWithOutScope((Trial) object);
} else if (object instanceof TrialSubject) {
grantRightsTrialSubject((TrialSubject) object);
}
}
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsUserObjectWithScope(Login object, TrialSite scope) {
// BEGIN grant rights with trial site scope
// BEGIN Added all acls for logins with a trial site scope
List<Role> roles = entityManager
.createQuery(
"from Role r where (r.writeOtherUser = true and r.scopeUserWrite = true ) or (r.readOtherUser = true and r.scopeUserRead = true)")
.getResultList();// TODO named query
for (Role r : roles) {
List<Login> logins = entityManager
.createNamedQuery(
"login.AllLoginsWithSpecificRoleAndTrialSite")
.setParameter(1, r.getId()).setParameter(2, scope.getId())
.getResultList();
for (Login l : logins) {
if (r.isWriteOtherUser() && r.isScopeUserWrite()) {
/*
* Grant WRITE permission on the new user to the current
* user
*/
grantRightLogin(object, l.getUsername(), r.getName(),
PermissionHibernate.WRITE);
}
if (r.isReadOtherUser() && r.isScopeUserRead()) {
/*
* IF there is no site-constraint (all users are shown to
* the current user)
*/
grantRightLogin(object, l.getUsername(), r.getName(),
PermissionHibernate.READ);
}
}
}
}
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsUserObjectWithOutScope(Login object) {
// Set Rights for ROLE_ANONYMOUS
aclService.createAclwithPermissions(object,
Role.ROLE_ANONYMOUS.getName(),
new PermissionHibernate[] { PermissionHibernate.READ },
Role.ROLE_ANONYMOUS.getName());
aclService.createAclwithPermissions(((Login) object).getPerson(),
Role.ROLE_ANONYMOUS.getName(),
new PermissionHibernate[] { PermissionHibernate.READ },
Role.ROLE_ANONYMOUS.getName());
List<Role> roles = entityManager
.createQuery(
"from Role r where (r.writeOtherUser = true and r.scopeUserWrite = false ) or (r.readOtherUser = true and r.scopeUserRead = false) or r.adminOtherUser = true")
.getResultList();// TODO named query
for (Role r : roles) {
List<Login> logins = entityManager
.createNamedQuery("login.AllLoginsWithSpecificRole")
.setParameter(1, r.getId()).getResultList();
for (Login l : logins) {
if (r.isWriteOtherUser() && !r.isScopeUserWrite()) {
/*
* IF there is no site-constraint (all users are editable to
* the current user)
*/
grantRightLogin(object, l.getUsername(), r.getName(),
PermissionHibernate.WRITE);
}
if (r.isReadOtherUser() && !r.isScopeUserRead()) {
/*
* IF there is no site-constraint (all users are shown to
* the current user)
*/
grantRightLogin(object, l.getUsername(), r.getName(),
PermissionHibernate.READ);
}
if (r.isAdminOtherUser()) {
/*
* If the current user can administrate others
*/
grantRightLogin(object, l.getUsername(), r.getName(),
PermissionHibernate.ADMINISTRATION);
}
}
}
}
private void grantRightLogin(Login newLogin, String userName,
String roleName, PermissionHibernate... permissions) {
aclService.createAclwithPermissions(newLogin, userName, permissions,
roleName);
aclService.createAclwithPermissions(newLogin.getPerson(), userName,
permissions, roleName);
}
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsTrialSiteObject(TrialSite trialSite) {
// Set Right for ROLE_ANONYMOUS
aclService.createAclwithPermissions(
trialSite,
Role.ROLE_ANONYMOUS.getName(),
Role.ROLE_ANONYMOUS.getTrialSitePermissions().toArray(
new PermissionHibernate[Role.ROLE_ANONYMOUS
.getTrialSitePermissions().size()]),
Role.ROLE_ANONYMOUS.getName());
// Set Rights for other User
// find all roles without a trialSite scope and the flags read, write,
// admin trialSite
List<Role> roles = entityManager
.createQuery(
"from Role r where (r.adminTrialSite=true) or (r.scopeTrialSiteView = false and r.readTrialSite = true) or (r.scopeTrialWrite = false and r.writeTrialSite = true)")
.getResultList(); // TODO named query
for (Role r : roles) {
// find every user with the specific role
List<Login> logins = entityManager
.createNamedQuery("login.AllLoginsWithSpecificRole")
.setParameter(1, r.getId()).getResultList();
// set acls for the logins
for (Login l : logins) {
// grant administration rights
if (r.isAdminTrialSite()) {
aclService
.createAclwithPermissions(
trialSite,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.ADMINISTRATION },
r.getName());
}
// grant rights to read the trial site
if (!r.isScopeTrialSiteView() && r.isReadTrialSite()) {
aclService
.createAclwithPermissions(
trialSite,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
r.getName());
}
// grant rights to write/update the trial site
if (!r.isScopeTrialSiteWrite() && r.isWriteTrialSite()) {
aclService
.createAclwithPermissions(
trialSite,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
r.getName());
}
}
}
}
/**
* Generates all acls for user with trial rights and a trial site scope.
*
* @param trial
* The new trial object.
* @param scope
* The trial site scope.
*/
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsTrialObjectWithScope(Trial trial, TrialSite scope) {
if (scope == null)
return;
// BEGIN Added all acls for logins with a trial site scope
List<Role> roles = entityManager
.createQuery(
"from Role r where (r.scopeTrialRead = true and r.readTrial = true ) or (r.scopeTrialWrite = true and r.writeTrial = true)")
.getResultList();// TODO named query
for (Role r : roles) {
List<Login> logins = new ArrayList<Login>();
List<Login> logs = entityManager.createQuery("from Login")
.getResultList();
for (Login l : logs) {
// every user from a participating site
for (TrialSite site : trial.getParticipatingSites()) {
site = entityManager.find(TrialSite.class, site.getId());
if (site.getMembers().contains(l.getPerson())
&& l.getRoles().contains(r)) {
logins.add(l);
}
}
}
for (Login l : logins) {
// added read permission for this new trial
if (r.isReadTrial()) {
aclService
.createAclwithPermissions(
trial,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
r.getName());
}
// added write permission for this new trial
if (r.isWriteTrial()) {
aclService
.createAclwithPermissions(
trial,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
r.getName());
}
}
}
// END
}
/**
* Generates all acls for user with trial rights and without any trial site
* scope.
*
* @param trial
* The new trial object.
* @param scope
* The trial site scope.
*/
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsTrialObjectWithOutScope(Trial trial) {
// BEGIN Added all acls for logins without a trial site scope
List<Role> roles = entityManager
.createQuery(
"from Role r where (r.scopeTrialRead = false and r.readTrial = true ) or (r.scopeTrialWrite = false and r.writeTrial = true) or r.adminTrial = true")
.getResultList();// TODO named query
for (Role r : roles) {
List<Login> logins = entityManager
.createNamedQuery("login.AllLoginsWithSpecificRole")
.setParameter(1, r.getId()).getResultList();
for (Login l : logins) {
// added read permission for this new trial
if (!r.isScopeTrialRead() && r.isReadTrial()) {
aclService
.createAclwithPermissions(
trial,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
r.getName());
}
// added write permission for this new trial
if (!r.isScopeTrialWrite() && r.isWriteTrial()) {
aclService
.createAclwithPermissions(
trial,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
r.getName());
}
// added admin permission for this new trial
if (r.isAdminTrial()) {
aclService
.createAclwithPermissions(
trial,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.ADMINISTRATION },
r.getName());
}
}
}
}
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
private void grantRightsTrialSubject(TrialSubject trialSubject) {
// all logins which can read the trial from the trialSubject
List<Login> logins = entityManager
.createNamedQuery("login.LoginsWithPermission")
.setParameter(1, Trial.class.getCanonicalName())
.setParameter(2, trialSubject.getArm().getTrial().getId())
.setParameter(3, PermissionHibernate.READ.getCode())
.getResultList();
for (Login l : logins) {
for (Role r : l.getRoles()) {
if (r.isReadTrialSubject()) {
aclService
.createAclwithPermissions(
trialSubject,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
r.getName());
}
if (r.isWriteTrialSubject()) {
aclService
.createAclwithPermissions(
trialSubject,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
r.getName());
}
if (r.isAdminTrialSubject()) {
aclService
.createAclwithPermissions(
trialSubject,
l.getUsername(),
new PermissionHibernate[] { PermissionHibernate.ADMINISTRATION },
r.getName());
}
}
}
}
@SuppressWarnings("unchecked")
@Transactional(propagation = Propagation.REQUIRED)
public void registerPersonRole(Login login, Role role) {
role = entityManager.find(Role.class, role.getId());
login = entityManager.find(Login.class, login.getId());
if (role.equals(Role.ROLE_USER)) {
aclService.createAclwithPermissions(
login,
login.getUsername(),
role.getOwnUserPermissions().toArray(
new PermissionHibernate[role
.getOwnUserPermissions().size()]), role
.getName());
aclService.createAclwithPermissions(
login.getPerson(),
login.getUsername(),
role.getOwnUserPermissions().toArray(
new PermissionHibernate[role
.getOwnUserPermissions().size()]), role
.getName());
} else {
TrialSite site = null;
try {
site = (TrialSite) entityManager
.createNamedQuery("trialSite.getPersonsTrialSite")
.setParameter(1, login.getPerson().getId())
.getSingleResult();
} catch (NoResultException e) {
}
newPersonGrantUserRights(login, role, site);
newPersonGrantUserTrialSite(login, role, site);
newPersonGrantUserTrial(login, role, site);
newPersonGrantUserTrialSubject(login, role, site);
}
}
@Transactional(propagation = Propagation.REQUIRED)
public void removedPersonRole(Login login, Role role){
aclService.removeACEs(login.getUsername(), role.getName());
}
@Transactional(propagation = Propagation.REQUIRED)
private void newPersonGrantUserRights(Login login, Role role,
TrialSite usersSite) {
// grant create user rights
if (role.isCreateUser()) {
aclService.createAclwithPermissions(new Login(),
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.CREATE },
role.getName());
aclService.createAclwithPermissions(new Person(),
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.CREATE },
role.getName());
}
if (role.isReadOtherUser()) {
List<Login> list = new ArrayList<Login>();
if (role.isScopeUserRead()) {
if (usersSite != null) {
list = entityManager
.createNamedQuery("login.AllLoginsWithSpecificTrialSite")
.setParameter(1, usersSite.getId()).getResultList();
}
} else {
list = entityManager.createQuery("from Login").getResultList();
}
for (Login l : list) {
if (l != null) {
grantRightLogin(l, login.getUsername(), role.getName(),
PermissionHibernate.READ);
}
}
}
/*
* the role can edit other users
*/
if (role.isWriteOtherUser()) {
List<Login> list = new ArrayList<Login>();
/*
* with this role the user can edit other users in the same trial
* site, but only if the role contains all roles of the other user
*/
if (role.isScopeUserWrite()) {
if (usersSite != null) {
List<Login> tempList = entityManager
.createNamedQuery("login.AllLoginsWithSpecificTrialSite")
.setParameter(1, usersSite.getId()).getResultList();
for (Login l : tempList) {
if (role.getRolesToAssign().containsAll(l.getRoles())) {
list.add(l);
}
}
}
}/*
* with this role the user can edit all users
*/
else {
list = entityManager.createQuery("from Login").getResultList();
}
for (Login l : list) {
grantRightLogin(l, login.getUsername(), role.getName(),
PermissionHibernate.WRITE);
}
}
if (role.isAdminOtherUser()) {
List<Person> list = entityManager.createQuery("from Person")
.getResultList();
for (Person p : list) {
if (p.getLogin() != null) {
grantRightLogin(p.getLogin(), login.getUsername(),
role.getName(), PermissionHibernate.ADMINISTRATION);
}
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
private void newPersonGrantUserTrialSite(Login login, Role role,
TrialSite usersSite) {
if (role.isCreateTrialSite()) {
aclService.createAclwithPermissions(new TrialSite(),
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.CREATE },
role.getName());
}
// TrialSite rights
if (role.isReadTrialSite()) {
if (role.isScopeTrialSiteView()) {
if (usersSite != null) {
aclService
.createAclwithPermissions(
usersSite,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
role.getName());
}
} else {
List<TrialSite> list = entityManager.createQuery(
"from TrialSite").getResultList();
for (TrialSite t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
role.getName());
}
}
}
if (role.isWriteTrialSite()) {
if (role.isScopeTrialSiteWrite()) {
if (usersSite != null) {
aclService
.createAclwithPermissions(
usersSite,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
role.getName());
}
} else {
List<TrialSite> list = entityManager.createQuery(
"from TrialSite").getResultList();
for (TrialSite t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
role.getName());
}
}
}
if (role.isAdminTrialSite()) {
List<TrialSite> list = entityManager.createQuery("from TrialSite")
.getResultList();
for (TrialSite t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.ADMINISTRATION },
role.getName());
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
private void newPersonGrantUserTrial(Login login, Role role,
TrialSite usersSite) {
if (role.isCreateTrial()) {
aclService.createAclwithPermissions(new Trial(),
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.CREATE },
role.getName());
}
// Trial rights
if (role.isReadTrial()) {
if (role.isScopeTrialRead()) {
if (usersSite != null) {
for (Trial t : usersSite.getTrials()) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
role.getName());
}
// other Trials
Query query = entityManager
.createNamedQuery("trial.AllTrialsWithSpecificParticipatingTrialSite");
query = query.setParameter(1, usersSite.getId());
List<Trial> trials = query.getResultList();
for (Trial t : trials) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
role.getName());
}
}
} else {
List<Trial> list = entityManager.createQuery("from Trial")
.getResultList();
for (Trial t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.READ },
role.getName());
}
}
}
if (role.isWriteTrial()) {
if (role.isScopeTrialWrite()) {
if (usersSite != null) {
for (Trial t : usersSite.getTrials()) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
role.getName());
}
}
} else {
List<Trial> list = entityManager.createQuery("from Trial")
.getResultList();
for (Trial t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.WRITE },
role.getName());
}
}
}
if (role.isAdminTrial()) {
List<Trial> list = entityManager.createQuery("from Trial")
.getResultList();
for (Trial t : list) {
aclService
.createAclwithPermissions(
t,
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.ADMINISTRATION },
role.getName());
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
private void newPersonGrantUserTrialSubject(Login login, Role role,
TrialSite usersSite) {
if (role.isCreateTrialSubject()) {
aclService.createAclwithPermissions(new TrialSubject(),
login.getUsername(),
new PermissionHibernate[] { PermissionHibernate.CREATE },
role.getName());
}
// TrialSubject rights
// TODO TrialSubject
}
@Transactional(propagation = Propagation.REQUIRED)
public void registerPerson(Login login) {
for (Role role : login.getRoles()) {
registerPersonRole(login, role);
}
}
}