ItEr36S10ArquitecturaServidorItEr35S11: Added persistence support for modeling users and roles.

Added persistence support for modeling users and roles. Spring security is not integrated with this support yet.
This commit is contained in:
Fernando Bellas Permuy 2009-11-26 15:28:43 +01:00 committed by Javier Moran Rua
parent b3fea396d7
commit 68a0634407
10 changed files with 386 additions and 10 deletions

View file

@ -22,6 +22,7 @@ package org.navalplanner.business.common;
import org.navalplanner.business.advance.daos.IAdvanceTypeDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.users.daos.IUserDAO;
import org.springframework.beans.factory.annotation.Autowired;
/**
@ -43,6 +44,9 @@ public class Registry {
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private IUserDAO userDAO;
private Registry() {
}
@ -58,4 +62,8 @@ public class Registry {
return getInstance().criterionTypeDAO;
}
public static IUserDAO getUserDAO() {
return getInstance().userDAO;
}
}

View file

@ -0,0 +1,39 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.users.daos;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.users.entities.User;
/**
* DAO interface for the <code>User</code> entity.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
public interface IUserDAO extends IGenericDAO<User, Long>{
public User findByLoginName(String loginName)
throws InstanceNotFoundException;
public boolean exists(String loginName);
}

View file

@ -0,0 +1,69 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.users.daos;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.users.entities.User;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* Hibernate DAO for the <code>User</code> entity.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
@Repository
public class UserDAO extends GenericDAOHibernate<User, Long>
implements IUserDAO {
@Override
public User findByLoginName(String loginName)
throws InstanceNotFoundException {
Criteria c = getSession().createCriteria(User.class);
c.add(Restrictions.eq("loginName", loginName));
User user = (User) c.uniqueResult();
if (user == null) {
throw new InstanceNotFoundException(loginName,
User.class.getName());
} else {
return user;
}
}
@Override
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public boolean exists(String loginName) {
try {
findByLoginName(loginName);
return true;
} catch (InstanceNotFoundException e) {
return false;
}
}
}

View file

@ -0,0 +1,110 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.users.entities;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.users.daos.IUserDAO;
/**
* Entity for modeling a user.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
public class User extends BaseEntity {
@NotEmpty(message="login name not specified")
private String loginName;
@NotEmpty(message="password not specified")
private String password;
@NotEmpty(message="user roles not specified")
private Set<UserRole> roles = new HashSet<UserRole>();
/**
* Necessary for Hibernate. Please, do not call it.
*/
public User() {}
private User(String loginName, String password, Set<UserRole> roles) {
this.loginName = loginName;
this.password = password;
this.roles = roles;
}
public static User create(String loginName, String password,
Set<UserRole> roles) {
return create(new User(loginName, password, roles));
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<UserRole> getRoles() {
return roles;
}
public void setRoles(Set<UserRole> roles) {
this.roles = roles;
}
@AssertTrue(message="login name is already being used by another user")
public boolean checkConstraintUniqueLoginName() {
IUserDAO userDAO = Registry.getUserDAO();
if (isNewObject()) {
return !userDAO.exists(loginName);
} else {
try {
User u = userDAO.findByLoginName(loginName);
return u.getId().equals(getId());
} catch (InstanceNotFoundException e) {
return true;
}
}
}
}

View file

@ -29,21 +29,15 @@ import static org.navalplanner.business.i18n.I18nHelper._;
*/
public enum UserRole {
ROLE_ADMINISTRATION("ROLE_ADMINISTRATION", _("Administration")),
ROLE_BASIC_USER("ROLE_BASIC_USER", _("Basic user"));
ROLE_BASIC_USER(_("Basic user")),
ROLE_ADMINISTRATION(_("Administration"));
private final String name;
private final String displayName;
private UserRole(String name, String displayName) {
this.name = name;
private UserRole(String displayName) {
this.displayName = displayName;
}
public String getName() {
return name;
}
public String getDisplayName() {
return displayName;
}

View file

@ -55,6 +55,9 @@
<value>
org/navalplanner/business/materials/entities/Materials.hbm.xml
</value>
<value>
org/navalplanner/business/users/entities/Users.hbm.xml
</value>
</list>
</property>
</bean>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.navalplanner.business.users.entities"
default-access="field">
<!--
IMPORTANT: The default name for User's table ("User") is not valid
for some databases (e.g. PostgreSQL).
-->
<class name="User" table="NAVAL_USER">
<!--
IMPORTANT: type="long" must be specified (otherwise,
Hibernate infers type="integer".
-->
<id name="id" access="property" type="long">
<generator class="hilo">
<param name="max_lo">100</param>
</generator>
</id>
<version name="version" access="property" type="long" />
<property name="loginName" not-null="true" unique="true"/>
<property name="password" not-null="true"/>
<set name="roles" table="USER_ROLES">
<key column="userId"/>
<element>
<type name="org.hibernate.type.EnumType">
<param name="enumClass">org.navalplanner.business.users.entities.UserRole</param>
<!-- 12 is java.sql.Types.VARCHAR -->
<param name="type">12</param>
</type>
</element>
</set>
</class>
</hibernate-mapping>

View file

@ -0,0 +1,114 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.test.users.daos;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.users.daos.IUserDAO;
import org.navalplanner.business.users.entities.User;
import org.navalplanner.business.users.entities.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.NotTransactional;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Tests for <code>IUserDAO</code>.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
BUSINESS_SPRING_CONFIG_TEST_FILE })
@Transactional
public class UserDAOTest {
@Autowired
private IAdHocTransactionService transactionService;
@Autowired
private IUserDAO userDAO;
@Test
public void testBasicSave() throws InstanceNotFoundException {
User user = createUser(getUniqueName());
userDAO.save(user);
User user2 = userDAO.find(user.getId());
assertEquals(user, user2);
}
@Test
@NotTransactional
public void testSaveWithExistingLoginName() {
final String loginName = getUniqueName();
IOnTransaction<Void> createUser = new IOnTransaction<Void>() {
@Override
public Void execute() {
userDAO.save(createUser(loginName));
return null;
}
};
transactionService.runOnTransaction(createUser);
try {
transactionService.runOnTransaction(createUser);
fail("ValidationException expected");
} catch (ValidationException e) {
}
}
private String getUniqueName() {
return UUID.randomUUID().toString();
}
private User createUser(String loginName) {
Set<UserRole> roles = new HashSet<UserRole>();
roles.add(UserRole.ROLE_BASIC_USER);
roles.add(UserRole.ROLE_ADMINISTRATION);
return User.create(loginName, "XXX", roles);
}
}

View file

@ -63,6 +63,9 @@
<value>
org/navalplanner/business/materials/entities/Materials.hbm.xml
</value>
<value>
org/navalplanner/business/users/entities/Users.hbm.xml
</value>
<value>
TestEntities.hbm.xml
</value>

View file

@ -33,7 +33,7 @@ public final class SecurityUtils {
private SecurityUtils() {}
public final static boolean isUserInRole(UserRole role) {
return Executions.getCurrent().isUserInRole(role.getName());
return Executions.getCurrent().isUserInRole(role.name());
}
}