/* * (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.model; import java.util.Collection; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.Locale; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.ManyToMany; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToOne; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.security.acls.model.Permission; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.UserDetails; import de.randi2.model.security.PermissionHibernate; import de.randi2.utility.validations.EMailRANDI2; import de.randi2.utility.validations.Password; /** * The Class Login. */ @Entity @NamedQueries( { @NamedQuery(name = "login.AllLoginsWithRolesAndNotTrialSiteScope", query = "select login from Login as login join login.roles role where role.scopeTrialSiteView = false AND not (role.name = 'ROLE_USER') group by login"), @NamedQuery(name = "login.LoginsWriteOtherUser", query = "select login from Login as login join login.roles role where role.writeOtherUser = true group by login"), @NamedQuery(name = "login.LoginsWithPermission", query = "from Login as login where login.username in (select ace.sid.sidname from AccessControlEntryHibernate as ace where ace.acl.objectIdentity.type = ? and ace.acl.objectIdentity.identifier = ? and ace.permission.code = ?)"), @NamedQuery(name = "login.AllLoginsWithSpecificRole" ,query= "select l from Login as l join l.roles role where role.id = ?" ), @NamedQuery(name = "login.AllLoginsWithSpecificRoleAndTrialSite" ,query= "select l from Login as l join l.roles role where role.id = ? and l in (select p.login from TrialSite as site join site.members p where site.id = ?)"), @NamedQuery(name = "login.AllLoginsWithSpecificTrialSite" ,query= "select l from Login as l where l in (select p.login from TrialSite as site join site.members p where site.id = ?)") }) @EqualsAndHashCode(callSuper = true) public @Data class Login extends AbstractDomainObject implements UserDetails { /** The Constant serialVersionUID. */ private final static long serialVersionUID = -6809229052570773439L; /** The Constant MAX_WRONG_LOGINS. */ public final static byte MAX_WRONG_LOGINS = 3; /** The Constant MILIS_TO_LOCK_USER (15 min). */ public final static int MILIS_TO_LOCK_USER = 900000; /** The Constant MAX_USERNAME_LENGTH. */ public final static int MAX_USERNAME_LENGTH = 100; /** The Constant MIN_USERNAME_LENGTH. */ public final static int MIN_USERNAME_LENGTH = 5; /** The Constant MAX_PASSWORD_LENGTH. */ public final static int MAX_PASSWORD_LENGTH = 30; /** The Constant MIN_PASSWORD_LENGTH. */ public final static int MIN_PASSWORD_LENGTH = 8; /** The Constant HASH_PASSWORD_LENGTH. */ public final static int HASH_PASSWORD_LENGTH = 64; /** The pref locale. */ private Locale prefLocale = null; /** The person. */ @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @NotNull private Person person = null; /** The username. */ @Column(unique = true) @Size(min = MIN_USERNAME_LENGTH, max = MAX_USERNAME_LENGTH) @EMailRANDI2 @NotEmpty private String username = ""; /** The password. */ @Password(max = MAX_PASSWORD_LENGTH, min = MIN_PASSWORD_LENGTH, hash_length = HASH_PASSWORD_LENGTH) private String password = null; /** The last logged in. */ private GregorianCalendar lastLoggedIn = null; /** The active. */ private boolean active = false; /** The number wrong logins. */ private byte numberWrongLogins = 0; /** The lock time. */ private GregorianCalendar lockTime; /** The roles. */ @ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.REFRESH) private Set<Role> roles = new HashSet<Role>(); /* * (non-Javadoc) * * @see * org.springframework.security.userdetails.UserDetails#getAuthorities() */ @Override public Collection<GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>(); for (Role role : roles) { grantedAuthorities.add(new GrantedAuthorityImpl(role.getName())); } return grantedAuthorities; } /* * (non-Javadoc) * * @see * org.springframework.security.userdetails.UserDetails#isAccountNonExpired * () */ @Override public boolean isAccountNonExpired() { return true; } /* * (non-Javadoc) * * @see * org.springframework.security.userdetails.UserDetails#isAccountNonLocked() */ @Override public boolean isAccountNonLocked() { if (numberWrongLogins >= MAX_WRONG_LOGINS) { return false; } else return true; } /* * (non-Javadoc) * * @see * org.springframework.security.userdetails.UserDetails#isCredentialsNonExpired * () */ @Override public boolean isCredentialsNonExpired() { return true; } /* * (non-Javadoc) * * @see org.springframework.security.userdetails.UserDetails#isEnabled() */ @Override public boolean isEnabled() { return true; } /** * Adds a role to this login object. * If the role is unequal to role anonymous the role user added * and the role anonymous removed automatically. * * @param role * the role */ public void addRole(Role role) { if (this.roles != null) { this.roles.add(role); if (!role.equals(Role.ROLE_ANONYMOUS)) { if (this.roles.contains(Role.ROLE_ANONYMOUS) && this.roles.size() > 1) { this.roles.remove(Role.ROLE_ANONYMOUS); } if (!this.roles.contains(Role.ROLE_USER) && !this.roles.contains(Role.ROLE_ANONYMOUS)) { this.roles.add(Role.ROLE_USER); } } } } /** * Removes the role. * * @param role * the role */ public void removeRole(Role role) { this.roles.remove(role); } /** * This method checks, if the Login has the specified role. * * @param role * the role * * @return true, if checks for role */ public boolean hasRole(Role role) { return this.roles.contains(role); } /** * This method checks, if the Login has the specified permission. * * @param clazz * the clazz * @param permission * the permission * * @return true, if checks for permission */ public boolean hasPermission(Class<? extends AbstractDomainObject> clazz, Permission permission) { // TODO Check permission delete boolean hasPermission = false; if (clazz.equals(Login.class) || clazz.equals(Person.class)) { for (Role r : roles) { if (permission.getMask() == PermissionHibernate.CREATE .getMask()) { hasPermission = hasPermission || r.isCreateUser(); } else if (permission.getMask() == PermissionHibernate.WRITE .getMask()) { hasPermission = hasPermission || r.isWriteOtherUser(); } else if (permission.getMask() == PermissionHibernate.READ .getMask()) { hasPermission = hasPermission || r.isReadOtherUser(); } else if (permission.getMask() == PermissionHibernate.ADMINISTRATION .getMask()) { hasPermission = hasPermission || r.isAdminOtherUser(); } } } else if (clazz.equals(TrialSite.class)) { for (Role r : roles) { if (permission.getMask() == PermissionHibernate.CREATE .getMask()) { hasPermission = hasPermission || r.isCreateTrialSite(); } else if (permission.getMask() == PermissionHibernate.WRITE .getMask()) { hasPermission = hasPermission || r.isWriteTrialSite(); } else if (permission.getMask() == PermissionHibernate.READ .getMask()) { hasPermission = hasPermission || r.isReadTrialSite(); } else if (permission.getMask() == PermissionHibernate.ADMINISTRATION .getMask()) { hasPermission = hasPermission || r.isAdminTrialSite(); } } } else if (clazz.equals(Trial.class)) { for (Role r : roles) { if (permission.getMask() == PermissionHibernate.CREATE .getMask()) { hasPermission = hasPermission || r.isCreateTrial(); } else if (permission.getMask() == PermissionHibernate.WRITE .getMask()) { hasPermission = hasPermission || r.isWriteTrial(); } else if (permission.getMask() == PermissionHibernate.READ .getMask()) { hasPermission = hasPermission || r.isReadTrial(); } else if (permission.getMask() == PermissionHibernate.ADMINISTRATION .getMask()) { hasPermission = hasPermission || r.isAdminTrial(); } } } else if (clazz.equals(TrialSubject.class)) { for (Role r : roles) { if (permission.getMask() == PermissionHibernate.CREATE .getMask()) { hasPermission = hasPermission || r.isCreateTrialSubject(); } else if (permission.getMask() == PermissionHibernate.WRITE .getMask()) { hasPermission = hasPermission || r.isWriteTrialSubject(); } else if (permission.getMask() == PermissionHibernate.READ .getMask()) { hasPermission = hasPermission || r.isReadTrialSubject(); } else if (permission.getMask() == PermissionHibernate.ADMINISTRATION .getMask()) { hasPermission = hasPermission || r.isAdminTrialSubject(); } } } return hasPermission; } /* * (non-Javadoc) * * @see de.randi2.model.AbstractDomainObject#getUIName() */ @Override public String getUIName() { return this.getPerson().getSurname() + ", " + this.getPerson().getFirstname(); } }