hs.hsadmin/hsarback/src/de/hsadmin/mods/db/DatabaseUser.java

210 lines
5.6 KiB
Java

package de.hsadmin.mods.db;
import static javax.persistence.FetchType.EAGER;
import static javax.persistence.GenerationType.SEQUENCE;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AnnFieldIO;
import de.hsadmin.core.model.ReadWriteAccess;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
@Entity
@Table(name = "database_user")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="engine", discriminatorType=DiscriminatorType.STRING)
@SequenceGenerator(name = "DatabaseUserSeqGen", sequenceName = "dbuser_dbuser_id_seq")
public abstract class DatabaseUser extends AbstractEntity implements Serializable {
private static final long serialVersionUID = -4840133372566213014L;
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "DatabaseUserSeqGen")
@Column(name = "dbuser_id", columnDefinition = "integer", updatable=false, insertable=false)
private long id;
@AnnFieldIO(validation="[a-z0-9\\_]*", rw=ReadWriteAccess.WRITEONCE)
@Column(name = "name", columnDefinition = "character varying(24)", updatable=false)
private String name;
@AnnFieldIO(validation="[^']*", rw=ReadWriteAccess.WRITEONLY)
@Transient
private String password;
@AnnFieldIO(validation="[a-zA-Z]*", rw=ReadWriteAccess.WRITEONCE)
@Column(name = "engine", columnDefinition = "character varying(12)", updatable=false)
protected String instance;
@JoinColumn(name = "packet_id", columnDefinition = "integer", updatable=false)
@ManyToOne(fetch = EAGER)
@AnnFieldIO(validation="[a-z0-9]*", rw=ReadWriteAccess.WRITEONCE)
protected Pac pac;
protected DatabaseUser() {
}
protected DatabaseUser(String instance, Pac pac, String name,
String password) {
this.instance = instance;
this.pac = pac;
this.name = name;
this.password = password;
}
@Override
public void initialize(EntityManager em, UnixUser loginUser) {
pac = loginUser.getPac(); // a default useful for the pac admin
}
public void complete(EntityManager em, UnixUser loginUser) {
if (pac == null && name != null && name.length() > 0) {
// TODO: it's ugly having this code here, needs refactoring
String pacName = name.substring(0, 5);
try {
// get the entities name (query part from FROM to WHERE)
javax.persistence.Entity entityAnnot = Pac.class
.getAnnotation(javax.persistence.Entity.class);
String queryString = "SELECT obj FROM " + entityAnnot.name() + " obj WHERE "
+ Pac.createQueryFromStringKey(pacName);
// set parameters
Query query = em.createQuery(queryString);
AbstractModuleImpl.setQueryParameter(query, queryString, "loginUser", loginUser);
AbstractModuleImpl.setQueryParameter(query, queryString, "loginUserName", loginUser.getName());
AbstractModuleImpl.setQueryParameter(query, queryString, "loginUserPac", loginUser.getPac());
pac = (Pac) query.getSingleResult();
} catch (NoResultException exc) {
throw new SecurityException("packet '" + pacName
+ "' not found or access denied");
}
}
}
@Override
public String createStringKey() {
return getName();
}
@Override
public long id() {
return id;
}
public long getId() {
return id;
}
protected void setId(long id) {
this.id = id;
}
public String getInstance() {
return instance;
}
public void setInstance(String instance) {
this.instance = instance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Pac getPac() {
return pac;
}
public void setPac(Pac pac) {
this.pac = pac;
}
@Override
public boolean isNew() {
return id == 0;
}
@Override
public DatabaseUser merge(EntityManager em, UnixUser loginUser) {
DatabaseUser dbEntity = (DatabaseUser) super.merge(em, loginUser);
dbEntity.setPassword(this.getPassword());
return dbEntity;
}
@Override
public String getHiveName() {
if (isNew())
return null;
else
return getPac().getHiveName();
}
@Override
public UnixUser owningUser(EntityManager em) {
return getPac().owningUser(em);
}
/**
* determines whether the given user has full read access on all merged
* fields of this entity
*/
@Override
public boolean isReadAllowedFor(UnixUser loginUser) {
return loginUser.hasPacAdminRoleFor(getPac());
}
/**
* determines whether the given user has full write access on all merged
* fields of this entity
*/
@Override
public boolean isWriteAllowedFor(UnixUser loginUser) {
String pacName = pac.getName();
if (!name.equals(pacName) && !name.startsWith(pacName + "_"))
return false;
return loginUser.hasPacAdminRoleFor(getPac());
}
/**
* query restriction for access control
*/
public static String restriction() {
return
// all databases of all pacs of customer
"obj.pac.customer.name=:loginUserName OR " +
// all aliases of packet admin
"obj.pac.name=:loginUserName";
}
}