Paket-Modul

This commit is contained in:
Peter Hormanns 2011-03-22 22:02:06 +00:00
parent c00b2ef3c4
commit 6ca3aac648
52 changed files with 1710 additions and 97 deletions

View File

@ -19,6 +19,12 @@
<class>de.hsadmin.mods.dom.Domain</class>
<class>de.hsadmin.mods.email.EMailAddress</class>
<class>de.hsadmin.mods.email.EMailAlias</class>
<!--
<class>de.hsadmin.mods.db.MySqlUser</class>
<class>de.hsadmin.mods.db.MySqlDatabase</class>
<class>de.hsadmin.mods.db.PgSqlUser</class>
<class>de.hsadmin.mods.db.PgSqlDatabase</class>
-->
<properties>
<property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
<!--

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
package de.hsadmin.core.model;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldValidation {
String value();
}

View File

@ -1,6 +1,10 @@
package de.hsadmin.core.model;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -29,6 +33,7 @@ public class GenericModuleImpl implements ModuleInterface {
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
validateFields(newEntity);
if (!newEntity.isNew())
throw new HSAdminException("cannot add an already persistent entity");
log.trace("add(" + newEntity + ")");
@ -60,6 +65,7 @@ public class GenericModuleImpl implements ModuleInterface {
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
validateFields(existingEntity);
if (existingEntity.isNew())
return add(existingEntity);
log.debug("update(" + existingEntity + ")");
@ -75,4 +81,68 @@ public class GenericModuleImpl implements ModuleInterface {
wrapper.delete(existingEntity);
}
private void validateFields(AbstractEntity anEntity) throws HSAdminException {
Class<? extends AbstractEntity> clasz = anEntity.getClass();
Field[] fields = clasz.getDeclaredFields();
for (Field f : fields) {
FieldValidation fieldValidation = f.getAnnotation(FieldValidation.class);
if (fieldValidation != null) {
try {
Method method = clasz.getMethod(getterName(f));
Object valueObject = method.invoke(anEntity);
if (valueObject instanceof String) {
if (!Pattern.matches(fieldValidation.value(), (String) valueObject)) {
throw new HSAdminException("validation of field " + f.getName() + " failed");
}
}
} catch (SecurityException e) {
throw new HSAdminException(e);
} catch (NoSuchMethodException e) {
throw new HSAdminException(e);
} catch (IllegalArgumentException e) {
throw new HSAdminException(e);
} catch (IllegalAccessException e) {
throw new HSAdminException(e);
} catch (InvocationTargetException e) {
throw new HSAdminException(e);
}
}
}
// Bei Datenbanken und DB-Usern stehen die Attribute in der Oberklasse
Class<?> superclass = clasz.getSuperclass();
if (superclass != AbstractEntity.class) {
fields = superclass.getDeclaredFields();
for (Field f : fields) {
FieldValidation fieldValidation = f.getAnnotation(FieldValidation.class);
if (fieldValidation != null) {
try {
Method method = superclass.getMethod(getterName(f));
Object valueObject = method.invoke(anEntity);
if (valueObject instanceof String) {
if (!Pattern.matches(fieldValidation.value(), (String) valueObject)) {
throw new HSAdminException("validation of field " + f.getName() + " failed");
}
}
} catch (SecurityException e) {
throw new HSAdminException(e);
} catch (NoSuchMethodException e) {
throw new HSAdminException(e);
} catch (IllegalArgumentException e) {
throw new HSAdminException(e);
} catch (IllegalAccessException e) {
throw new HSAdminException(e);
} catch (InvocationTargetException e) {
throw new HSAdminException(e);
}
}
}
}
}
private String getterName(Field f) {
String name = f.getName();
char firstChar = Character.toUpperCase(name.charAt(0));
return "get" + firstChar + name.substring(1);
}
}

View File

@ -210,7 +210,6 @@ public class Customer extends de.hsadmin.core.model.AbstractEntity implements Se
// virtual attribute contractualContact
// TODO: currently only a single contact can be managed
@javax.persistence.Transient
public Contact getContractualContact() {
return getContacts().iterator().next();
}

View File

@ -0,0 +1,222 @@
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.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
@MappedSuperclass
@SearchFilter("pac = :loginUserPac OR pac.customer.memberCode = :loginUserName")
public abstract class Database extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 6243815106074846080L;
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "DatabaseSeqGen")
@Column(name = "database_id", columnDefinition = "integer", updatable=false, insertable=false)
private long id;
@FieldValidation("[a-zA-Z]*")
@Column(name = "engine", columnDefinition = "character varying(12)", updatable=false)
private String instance;
@FieldValidation("[a-z0-9\\_]*")
@Column(name = "name", columnDefinition = "character varying(24)", updatable=false)
private String name;
@FieldValidation("[a-z0-9\\_]*")
@Column(name = "owner", columnDefinition = "character varying(24)")
private String owner;
@JoinColumn(name = "packet_id", columnDefinition = "integer", updatable=false)
@ManyToOne(fetch = EAGER)
private Pac pac;
@FieldValidation("[A-Za-z0-9\\_\\-]*")
@Column(name = "encoding", columnDefinition = "character varying(24)", updatable=false)
private String encoding;
protected Database() {
encoding = "UTF-8";
}
protected Database(String instance, Pac pac, String name, String owner,
String encoding) {
this.instance = instance;
this.pac = pac;
this.name = name;
this.owner = owner;
this.encoding = encoding;
}
@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) {
if (name.length() < 7 || name.charAt(5) != '_') {
throw new SecurityException("database name '" + name
+ "' not allowed");
}
// 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(Entity.class);
String queryString = "FROM " + entityAnnot.name() + " 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");
}
}
}
public static String createQueryFromStringKey(String humanKey) {
return "name='" + humanKey + "'";
}
@Override
public String createStringKey() {
return getName();
}
@Override
public boolean isNew() {
return id == 0;
}
/**
* returns the encoding in the style of the specific database
*/
public abstract String getSystemEncoding();
@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(pac);
}
public abstract Class<? extends DatabaseUser> getSqlUserClass();
@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 getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Pac getPac() {
return pac;
}
public void setPac(Pac pac) {
this.pac = pac;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* query restriction for access control
*/
public static String restriction() {
return
// all databases of all pacs of customer
"pac.customer.memberCode=:loginUserName OR " +
// all aliases of packet admin
"pac.name=:loginUserName";
}
}

View File

@ -0,0 +1,200 @@
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.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.Transient;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
@MappedSuperclass
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;
@FieldValidation("[a-z0-9\\_]*")
@Column(name = "name", columnDefinition = "character varying(24)", updatable=false)
private String name;
@FieldValidation("[^']*")
@Transient
private String password;
@FieldValidation("[a-zA-Z]*")
@Column(name = "engine", columnDefinition = "character varying(12)", updatable=false)
protected String instance;
@JoinColumn(name = "packet_id", columnDefinition = "integer", updatable=false)
@ManyToOne(fetch = EAGER)
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 = "FROM " + entityAnnot.name() + " 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
"pac.customer.memberCode=:loginUserName OR " +
// all aliases of packet admin
"pac.name=:loginUserName";
}
}

View File

@ -0,0 +1,89 @@
package de.hsadmin.mods.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import de.hsadmin.core.qserv.AbstractProcessor;
import de.hsadmin.core.qserv.ProcessorException;
import de.hsadmin.core.util.Config;
public class JDBCProcessor extends AbstractProcessor {
private static final long serialVersionUID = 7702753017749022325L;
private String driver;
private String url;
private String user;
private String password;
private List<String> sql;
public JDBCProcessor(String driver, String url, String user, String password) {
this.driver = driver;
this.url = url;
this.user = user;
this.password = password;
}
public JDBCProcessor(String driver, String url) {
this.driver = driver;
this.url = url;
}
public void addSQL(String sqlStatement) {
if (sql == null)
sql = new ArrayList<String>();
sql.add(sqlStatement);
}
public Object process() throws ProcessorException {
Connection c = null;
Config config = Config.getInstance();
if ("com.mysql.jdbc.Driver".equals(driver)) {
if (user == null)
user = config.getProperty("mysqladmin.user", "root");
if (password == null)
password = config.getProperty("mysqladmin.password");
}
if ("org.postgresql.Driver".equals(driver)) {
if (user == null)
user = config.getProperty("pgsqladmin.user", "postgres");
if (password == null)
password = config.getProperty("pgsqladmin.password");
}
if (user == null || password == null) {
throw new ProcessorException("database admin-user configuration failed");
}
try {
Class.forName(driver);
c = DriverManager.getConnection(url, user, password);
if (c == null)
throw new ProcessorException("cannot connect to '" + url + "'");
Statement s = c.createStatement();
for (String sqlStatement : sql) {
s.addBatch(sqlStatement);
System.out.println("SQL: " + sqlStatement);
}
return s.executeBatch();
} catch (SQLException aSqlExc) {
Exception exc = aSqlExc.getNextException();
if (exc == null)
exc = aSqlExc;
System.out.println("ERR: " + exc.getMessage());
throw new ProcessorException(aSqlExc.getMessage() + ", reason: "
+ exc.getMessage());
} catch (Exception aExc) {
throw new ProcessorException(aExc.getMessage());
} finally {
if (c != null) {
try {
c.close();
} catch (Exception exc) {
}
}
}
}
}

View File

@ -0,0 +1,46 @@
package de.hsadmin.mods.db;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
@Entity(name = "MySqlDatabases")
@Table(name = "database")
@SequenceGenerator(name = "DatabaseSeqGen", sequenceName = "database_database_id_seq")
@EntityInfo(name = "MySQL Datenbank")
@SearchFilter("instance = 'mysql' AND (" + " pac = :loginUserPac OR "
+ " pac.customer.memberCode = :loginUserName )")
public class MySqlDatabase extends Database implements Serializable {
private static final long serialVersionUID = 2862112440807946042L;
public MySqlDatabase() {
setInstance("mysql");
setEncoding("UTF-8");
}
public MySqlDatabase(Pac pac, String name, String owner, String encoding) {
super("mysql", pac, name, owner, encoding);
}
public String getSystemEncoding() {
String sysEnc = getEncoding().toLowerCase().replaceAll("-", "");
return sysEnc;
}
@Override
public Class<? extends DatabaseUser> getSqlUserClass() {
return MySqlUser.class;
}
public static String restriction() {
return "instance='mysql' AND ( " + Database.restriction() + " )";
}
}

View File

@ -0,0 +1,42 @@
package de.hsadmin.mods.db;
import java.util.List;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.mods.user.UnixUser;
public class MySqlDatabaseModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY name ASC";
}
return super.search(entityClass, condition, orderBy);
}
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
EntityManager em = getTransaction().getEntityManager();
UnixUser unixUser = getLoginUser();
MySqlDatabase detachtedDB = (MySqlDatabase) existingEntity;
MySqlDatabase attachedDB = em.find(MySqlDatabase.class, detachtedDB.getId());
if (!attachedDB.getName().equals(detachtedDB.getName())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "name");
}
if (!attachedDB.getEncoding().equals(detachtedDB.getEncoding())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "encoding");
}
if (!attachedDB.getInstance().equals(detachtedDB.getInstance())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "instance");
}
return super.update(existingEntity);
}
}

View File

@ -0,0 +1,75 @@
package de.hsadmin.mods.db;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
/** Factory class which creates Processor instances for dealing with UNIX user accounts.
*
* @author mi
*/
public class MySqlDatabaseProcessorFactory implements EntityProcessorFactory {
/// creates a JDBCProcessor for MySQL and the given user
public static JDBCProcessor createMySqlProcessor( String database, String user, String password )
{
return new JDBCProcessor( "com.mysql.jdbc.Driver",
"jdbc:mysql://localhost/" + database,
user, password );
}
/// creates a JDBCProcessor for the MySQL admin user
public static JDBCProcessor createMySqlAdminProcessor()
{
return new JDBCProcessor( "com.mysql.jdbc.Driver", "jdbc:mysql://localhost/" );
}
/// @return a Processor which creates a new database
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity)
{
Database db = (Database) entity;
assert db.getInstance().equals("mysql");
JDBCProcessor aJDBCP = null;
String aName = AbstractEntity.escapeString( db.getName() );
String aOwner = AbstractEntity.escapeString( db.getOwner() );
String aEncoding = AbstractEntity.escapeString( db.getSystemEncoding() );
aJDBCP = createMySqlAdminProcessor();
aJDBCP.addSQL( "CREATE DATABASE " + aName + " " +
"DEFAULT CHARACTER SET '" + aEncoding + "'");
aJDBCP.addSQL( "GRANT ALL ON " + aName + ".* TO '" + aOwner + "'@'%' WITH GRANT OPTION" );
return aJDBCP;
}
/// @return a Processor which updates a preexisting database
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity)
{
Database db = (Database) entity;
assert db.getInstance().equals("mysql");
String aName = AbstractEntity.escapeString( db.getName() );
String aOwner = AbstractEntity.escapeString( db.getOwner() );
String aEncoding = AbstractEntity.escapeString( db.getSystemEncoding() );
JDBCProcessor aJDBCP = null;
aJDBCP = createMySqlAdminProcessor();
aJDBCP.addSQL( "ALTER DATABASE " + aName + " DEFAULT CHARACTER SET '" + aEncoding + "'" );
aJDBCP.addSQL( "GRANT ALL ON " + aName + ".* TO '" + aOwner + "'@'%'" );
// TODO: alte Admin-Rechte entziehen
return aJDBCP;
}
/// @return a Processor which deletes an existing database
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity)
{
Database db = (Database) entity;
assert db.getInstance().equals("mysql");
JDBCProcessor aJDBCP = createMySqlAdminProcessor();
String aName = AbstractEntity.escapeString( db.getName() );
String aOwner = AbstractEntity.escapeString( db.getOwner() );
aJDBCP.addSQL( "REVOKE ALL ON " + aName + ".* FROM '" + aOwner + "'@'%'" );
aJDBCP.addSQL( "DROP DATABASE " + aName );
return aJDBCP;
}
}

View File

@ -0,0 +1,43 @@
package de.hsadmin.mods.db;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
@Entity(name = "MySqlUsers")
@Table(name = "database_user")
@SequenceGenerator(name = "DatabaseUserSeqGen", sequenceName = "dbuser_dbuser_id_seq")
@EntityInfo(name = "MySQL Konto")
@SearchFilter("instance = 'mysql' AND ("
+ " pac = :loginUserPac OR "
+ " pac.customer.memberCode = :loginUserName )")
public class MySqlUser extends DatabaseUser implements Serializable {
private static final long serialVersionUID = 6218494776881999478L;
public static String createQueryFromStringKey(String humanKey) {
return "name='" + humanKey + "' AND instance='mysql'";
}
public MySqlUser() {
setInstance("mysql");
}
public MySqlUser(Pac pac, String name, String password) {
super("mysql", pac, name, password);
}
/**
* query restriction for access control
*/
public static String restriction() {
return "instance='mysql' AND ( " + DatabaseUser.restriction() + " )";
}
}

View File

@ -0,0 +1,30 @@
package de.hsadmin.mods.db;
import java.util.List;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.HSAdminException;
public class MySqlUserModuleImpl extends AbstractModuleImpl {
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
MySqlUser user = (MySqlUser) newEntity;
if (user.getName().length() > 16) {
throw new AuthorisationException(getLoginUser(), "add", newEntity);
}
return super.add(newEntity);
}
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY name ASC";
}
return super.search(entityClass, condition, orderBy);
}
}

View File

@ -0,0 +1,49 @@
package de.hsadmin.mods.db;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
/**
* Factory class which creates Processor instances for dealing with UNIX user
* accounts.
*
* @author mi
*/
public class MySqlUserProcessorFactory implements EntityProcessorFactory {
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("mysql");
JDBCProcessor aJDBCP = MySqlDatabaseProcessorFactory.createMySqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
String aPassword = AbstractEntity.escapeString(dbu.getPassword());
aJDBCP.addSQL("CREATE USER '" + aName + "'@'%'" + " IDENTIFIED BY '" + aPassword + "'");
return aJDBCP;
}
public <T extends AbstractEntity> Processor createUpdateProcessor(
EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("mysql");
JDBCProcessor aJDBCP = MySqlDatabaseProcessorFactory.createMySqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
String aPassword = AbstractEntity.escapeString(dbu.getPassword());
aJDBCP.addSQL("SET PASSWORD FOR '" + aName + "'@'%'" + " = PASSWORD('" + aPassword + "')");
return aJDBCP;
}
public <T extends AbstractEntity> Processor createDeleteProcessor(
EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("mysql");
JDBCProcessor aJDBCP = MySqlDatabaseProcessorFactory.createMySqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
aJDBCP.addSQL("REVOKE ALL PRIVILEGES, GRANT OPTION FROM '" + aName + "'@'%'");
aJDBCP.addSQL("DROP USER '" + aName + "'@'%'");
return aJDBCP;
}
}

View File

@ -0,0 +1,50 @@
package de.hsadmin.mods.db;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
@Entity(name = "PgSqlDatabases")
@Table(name = "database")
@SequenceGenerator(name = "DatabaseSeqGen", sequenceName = "database_database_id_seq")
@EntityInfo(name = "PostgreSQL Datenbank")
@SearchFilter("instance = 'pgsql' AND ("
+ " pac = :loginUserPac OR "
+ " pac.customer.memberCode = :loginUserName )")
public class PgSqlDatabase extends Database implements Serializable {
private static final long serialVersionUID = 6688358817554938015L;
public PgSqlDatabase() {
setInstance("pgsql");
setEncoding("UTF-8");
}
public PgSqlDatabase(Pac pac, String name, String owner, String encoding) {
super("pgsql", pac, name, owner, encoding);
}
@Override
public Class<? extends DatabaseUser> getSqlUserClass() {
return PgSqlUser.class;
}
public String getSystemEncoding() {
return getEncoding();
}
/**
* query restriction for access control
*/
public static String restriction() {
return "instance='pgsql' AND ( " + Database.restriction() + " )";
}
}

View File

@ -0,0 +1,41 @@
package de.hsadmin.mods.db;
import java.util.List;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.mods.user.UnixUser;
public class PgSqlDatabaseModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY name ASC";
}
return super.search(entityClass, condition, orderBy);
}
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
EntityManager em = getTransaction().getEntityManager();
UnixUser unixUser = getLoginUser();
MySqlDatabase detachtedDB = (MySqlDatabase) existingEntity;
MySqlDatabase attachedDB = em.find(MySqlDatabase.class, detachtedDB.getId());
if (!attachedDB.getName().equals(detachtedDB.getName())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "name");
}
if (!attachedDB.getEncoding().equals(detachtedDB.getEncoding())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "encoding");
}
if (!attachedDB.getInstance().equals(detachtedDB.getInstance())) {
throw new AuthorisationException(unixUser, "update", existingEntity, "instance");
}
return super.update(existingEntity);
}
}

View File

@ -0,0 +1,77 @@
package de.hsadmin.mods.db;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
/**
* Factory class which creates Processor instances for dealing with UNIX user
* accounts.
*
* @author mi
*/
public class PgSqlDatabaseProcessorFactory implements EntityProcessorFactory {
/**
* creates a JDBCProcessor for PostgreSQL and the given user
*
* @param user
* @param password
* @return
*/
public static JDBCProcessor createPostgreSqlProcessor(String user, String password) {
return new JDBCProcessor("org.postgresql.Driver",
"jdbc:postgresql://localhost/template1", user, password);
}
/**
* creates a JDBCProcessor for the PostgreSQL admin user
*
* @return
*/
public static JDBCProcessor createPostgreSqlAdminProcessor() {
return new JDBCProcessor("org.postgresql.Driver", "jdbc:postgresql://localhost/template1");
}
/**
* @return a Processor which creates a new database
*/
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) {
Database db = (Database) entity;
assert db.getInstance().equals("pgsql");
JDBCProcessor aJDBCP = null;
String aName = AbstractEntity.escapeString(db.getName());
String aOwner = AbstractEntity.escapeString(db.getOwner());
String aEncoding = AbstractEntity.escapeString(db.getEncoding());
aJDBCP = createPostgreSqlAdminProcessor();
aJDBCP.addSQL("CREATE DATABASE " + aName + " OWNER=" + aOwner + " ENCODING='" + aEncoding + "' TEMPLATE template0");
return aJDBCP;
}
/**
* @return a Processor which updates a preexisting database
*/
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity) {
Database db = (Database) entity;
assert db.getInstance().equals("pgsql");
String aName = AbstractEntity.escapeString(db.getName());
String aOwner = AbstractEntity.escapeString(db.getOwner());
JDBCProcessor aJDBCP = null;
aJDBCP = createPostgreSqlAdminProcessor();
aJDBCP.addSQL("ALTER DATABASE " + aName + " OWNER TO " + aOwner);
return aJDBCP;
}
/**
* @return a Processor which deletes an existing database
*/
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity) {
Database db = (Database) entity;
assert db.getInstance().equals("pgsql");
JDBCProcessor aJDBCP = createPostgreSqlAdminProcessor();
String aName = AbstractEntity.escapeString(db.getName());
aJDBCP.addSQL("DROP DATABASE " + aName);
return aJDBCP;
}
}

View File

@ -0,0 +1,42 @@
package de.hsadmin.mods.db;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
@Entity(name = "PgSqlUsers")
@Table(name = "database_user")
@SequenceGenerator(name = "DatabaseUserSeqGen", sequenceName = "dbuser_dbuser_id_seq")
@EntityInfo(name = "PostgreSQL Konto")
@SearchFilter("instance = 'pgsql' AND (" + " pac = :loginUserPac OR "
+ " pac.customer.memberCode = :loginUserName )")
public class PgSqlUser extends DatabaseUser implements Serializable {
private static final long serialVersionUID = -1097602753310286629L;
public static String createQueryFromStringKey(String humanKey) {
return "name='" + humanKey + "' AND instance='pgsql'";
}
public PgSqlUser() {
setInstance("pgsql");
}
public PgSqlUser(Pac pac, String name, String password) {
super("pgsql", pac, name, password);
}
/**
* query restriction for access control
*/
public static String restriction() {
return "instance='pgsql' AND ( " + DatabaseUser.restriction() + " )";
}
}

View File

@ -0,0 +1,20 @@
package de.hsadmin.mods.db;
import java.util.List;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.HSAdminException;
public class PgSqlUserModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY name ASC";
}
return super.search(entityClass, condition, orderBy);
}
}

View File

@ -0,0 +1,48 @@
package de.hsadmin.mods.db;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
/**
* Factory class which creates Processor instances for dealing with UNIX user
* accounts.
*
* @author mi
*/
public class PgSqlUserProcessorFactory implements EntityProcessorFactory {
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("pgsql");
JDBCProcessor aJDBCP = PgSqlDatabaseProcessorFactory.createPostgreSqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
String aPassword = AbstractEntity.escapeString(dbu.getPassword());
aJDBCP.addSQL("CREATE USER " + aName + " NOCREATEDB NOCREATEUSER" + " ENCRYPTED PASSWORD '" + aPassword + "'");
return aJDBCP;
}
public <T extends AbstractEntity> Processor createUpdateProcessor(
EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("pgsql");
JDBCProcessor aJDBCP = PgSqlDatabaseProcessorFactory.createPostgreSqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
String aPassword = AbstractEntity.escapeString(dbu.getPassword());
aJDBCP.addSQL("ALTER USER " + aName + " WITH ENCRYPTED PASSWORD '" + aPassword + "'");
return aJDBCP;
}
public <T extends AbstractEntity> Processor createDeleteProcessor(
EntityManager em, T entity) {
DatabaseUser dbu = (DatabaseUser) entity;
assert dbu.getInstance().equals("pgsql");
JDBCProcessor aJDBCP = PgSqlDatabaseProcessorFactory.createPostgreSqlAdminProcessor();
String aName = AbstractEntity.escapeString(dbu.getName());
aJDBCP.addSQL("DROP USER " + aName);
return aJDBCP;
}
}

View File

@ -6,7 +6,10 @@ import static javax.persistence.GenerationType.SEQUENCE;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
@ -14,27 +17,30 @@ import javax.persistence.Table;
import javax.persistence.Temporal;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.mods.user.UnixUser;
@javax.persistence.Entity(name = "Domains")
@Entity(name = "Domains")
@Table(name = "domain")
@SequenceGenerator(name = "DomainsSeqGen", sequenceName = "domain_domain_id_seq")
public class Domain extends AbstractEntity {
private static final long serialVersionUID = -7496110900868795840L;
@javax.persistence.Id
@javax.persistence.Column(name = "domain_id", columnDefinition = "integer")
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "DomainsSeqGen")
@Id
@Column(name = "domain_id", columnDefinition = "integer")
@GeneratedValue(strategy = SEQUENCE, generator = "DomainsSeqGen")
private long id;
@javax.persistence.Column(name = "domain_name", columnDefinition = "character varying(256)", nullable = false)
@FieldValidation("[a-z0-9\\-\\.]*")
@Column(name = "domain_name", columnDefinition = "character varying(256)", nullable = false)
private String name;
@JoinColumn(name = "domain_owner", columnDefinition = "integer", nullable = false)
@ManyToOne(fetch = EAGER)
private UnixUser user;
@FieldValidation("[a-z]*")
@Column(name = "domain_status", columnDefinition = "character varying(12)", nullable = false)
private String status;
@ -54,6 +60,7 @@ public class Domain extends AbstractEntity {
@Temporal(javax.persistence.TemporalType.DATE)
private Date until;
@FieldValidation("[a-z0-9\\-\\.]*")
@Column(name = "domain_dns_master", columnDefinition = "character varying(64)")
private String dnsMaster;
@ -105,7 +112,6 @@ public class Domain extends AbstractEntity {
this.user = user;
}
@javax.persistence.Transient
public Status getStatus() {
return Status.valueFor(status);
}

View File

@ -18,6 +18,7 @@ import javax.persistence.Transient;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.dom.Domain;
@ -42,9 +43,11 @@ public class EMailAddress extends AbstractEntity implements Serializable {
@Column(name = "emailaddr_id", columnDefinition = "integer")
private long id;
@FieldValidation("[A-Za-z0-9\\_\\-\\.\\+]*")
@Column(name = "localpart", updatable = false, nullable= false)
private String localpart = "";
@FieldValidation("[a-z0-9\\-\\.]*")
@Column(name = "subdomain")
private String subdomain;
@ -52,15 +55,16 @@ public class EMailAddress extends AbstractEntity implements Serializable {
@JoinColumn(name = "domain_id", columnDefinition = "integer", updatable = false)
private Domain domain;
@FieldValidation("[a-zA-Z0-9\\_\\-\\.\\|\\\"\\/\\@\\,\\+]*")
@Column(name = "target", nullable= false)
private String target;
public EMailAddress() {
}
public EMailAddress(String localPart, String subdomain, Domain domain,
public EMailAddress(String localpart, String subdomain, Domain domain,
String target) {
this.localpart = localPart;
this.localpart = localpart;
this.subdomain = subdomain;
this.domain = domain;
this.target = target;
@ -92,7 +96,7 @@ public class EMailAddress extends AbstractEntity implements Serializable {
@Override
public String createStringKey() {
String key = getDomain() != null ? (getLocalPart() + "@" + getFullDomain())
String key = getDomain() != null ? (getLocalpart() + "@" + getFullDomain())
: "?@?";
return key;
}
@ -110,12 +114,12 @@ public class EMailAddress extends AbstractEntity implements Serializable {
this.id = id;
}
public String getLocalPart() {
public String getLocalpart() {
return localpart == null ? "" : localpart;
}
public void setLocalPart(String localPart) {
this.localpart = trimToEmpty(localPart);
public void setLocalpart(String localpart) {
this.localpart = trimToEmpty(localpart);
}
public String getSubdomain() {

View File

@ -29,8 +29,8 @@ public class EMailAddressModuleImpl extends AbstractModuleImpl {
if (adr.getTarget() == null || adr.getTarget().length() == 0) {
throw new HSAdminException("target required");
}
if (adr.getLocalPart() == null) {
adr.setLocalPart("");
if (adr.getLocalpart() == null) {
adr.setLocalpart("");
}
if (adr.getDomain() == null
|| adr.getDomain().getName() == null
@ -59,9 +59,9 @@ public class EMailAddressModuleImpl extends AbstractModuleImpl {
detachedAddr.setSubdomain(attachedAddr.getSubdomain());
throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "subdomain");
}
String localPart = detachedAddr.getLocalPart();
if (localPart != null && !localPart.equals(attachedAddr.getLocalPart())) {
detachedAddr.setLocalPart(attachedAddr.getLocalPart());
String localPart = detachedAddr.getLocalpart();
if (localPart != null && !localPart.equals(attachedAddr.getLocalpart())) {
detachedAddr.setLocalpart(attachedAddr.getLocalpart());
throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "localpart");
}
String target = detachedAddr.getTarget();

View File

@ -15,9 +15,10 @@ import javax.persistence.Query;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
@ -44,9 +45,11 @@ public class EMailAlias extends AbstractEntity implements Serializable {
@JoinColumn(name = "pac_id", columnDefinition = "integer")
private Pac pac;
@FieldValidation("[a-z0-9\\_\\-\\.\\+]*")
@Column(updatable=false)
private String name;
@FieldValidation("[a-zA-Z0-9\\_\\-\\.\\|\\\"\\/\\@\\,\\+\\ ]*")
@Column
private String target;

View File

@ -24,7 +24,7 @@ public class BaseComponent extends de.hsadmin.core.model.AbstractEntity implemen
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "BaseComponentsSeqGen")
@Column(name = "basecomponent_id", columnDefinition = "integer")
private long id;
private long baseComponentId;
@Column(name = "basecomponent_code", columnDefinition = "character varying(10)")
private String feature;
@ -59,15 +59,7 @@ public class BaseComponent extends de.hsadmin.core.model.AbstractEntity implemen
@Override
public long id() {
return id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
return baseComponentId;
}
public String getFeature() {
@ -104,11 +96,19 @@ public class BaseComponent extends de.hsadmin.core.model.AbstractEntity implemen
@Override
public boolean isNew() {
return id == 0;
return baseComponentId == 0;
}
@Override
public UnixUser owningUser(EntityManager em) {
return null; // TODO: kinda somebody like root needed
}
public void setBaseComponentId(long baseComponentId) {
this.baseComponentId = baseComponentId;
}
public long getBaseComponentId() {
return baseComponentId;
}
}

View File

@ -38,7 +38,7 @@ public class BasePac implements Serializable {
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "BasePacsSeqGen")
@Column(name = "basepacket_id", columnDefinition = "integer")
private long id;
private long basePacId;
@Column(name = "basepacket_code", columnDefinition = "character varying(10)")
private String name;
@ -59,12 +59,16 @@ public class BasePac implements Serializable {
@JoinTable(name = "packet_component", joinColumns = @JoinColumn(name = "packet_id"), inverseJoinColumns = @JoinColumn(name = "basepacket_id"))
private Set<Pac> pacs;
public long getId() {
return id;
public long id() {
return basePacId;
}
public void setId(long id) {
this.id = id;
public long getBasePacId() {
return basePacId;
}
public void setBasePacId(long id) {
this.basePacId = id;
}
public String getName() {
@ -136,7 +140,7 @@ public class BasePac implements Serializable {
if (aOther == null || aOther.getClass() != getClass())
return false;
BasePac aOtherBP = (BasePac) aOther;
if (id != aOtherBP.id)
if (basePacId != aOtherBP.basePacId)
return false;
if (name != null && !name.equals(aOtherBP.name))
return false;

View File

@ -6,6 +6,8 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity(name = "Components")
@ -16,9 +18,19 @@ public class Component implements Serializable {
private static final long serialVersionUID = 970709621200712794L;
@Id
private BasePac basePac;
@Column(name="basepacket_id", insertable=false, updatable=false)
private long basePacId;
@Id
@Column(name="basecomponent_id", insertable=false, updatable=false)
private long baseComponentId;
@ManyToOne
@JoinColumn(name="basepacket_id")
private BasePac basePac;
@ManyToOne
@JoinColumn(name="basecomponent_id")
private BaseComponent baseComponent;
@Column(name = "min_quantity", columnDefinition = "integer")
@ -44,7 +56,9 @@ public class Component implements Serializable {
public Component(BasePac basePac, BaseComponent baseComp, int min, int max,
int def, int incr, int incl, boolean adminOnly) {
this.setBasePacId(basePac.id());
this.basePac = basePac;
this.setBaseComponentId(baseComp.id());
this.baseComponent = baseComp;
this.minimumQuantity = min;
this.maximimumQuantity = max;
@ -59,6 +73,7 @@ public class Component implements Serializable {
}
public void setBasePac(BasePac basePac) {
this.setBasePacId(basePac.id());
this.basePac = basePac;
}
@ -67,6 +82,7 @@ public class Component implements Serializable {
}
public void setBaseComponent(BaseComponent baseComponent) {
this.setBaseComponentId(baseComponent.id());
this.baseComponent = baseComponent;
}
@ -118,4 +134,20 @@ public class Component implements Serializable {
this.adminOnly = adminOnly;
}
public void setBasePacId(long basePacId) {
this.basePacId = basePacId;
}
public long getBasePacId() {
return basePacId;
}
public void setBaseComponentId(long baseComponentId) {
this.baseComponentId = baseComponentId;
}
public long getBaseComponentId() {
return baseComponentId;
}
}

View File

@ -1,22 +1,51 @@
package de.hsadmin.mods.pac;
public class ComponentId {
import java.io.Serializable;
public long basePac;
public long baseComponent;
public class ComponentId implements Serializable {
private static final long serialVersionUID = 6213446997257985587L;
private long basePacId;
private long baseComponentId;
public ComponentId() {
}
public ComponentId(long basePacId, long baseComponentId) {
this.setBasePacId(basePacId);
this.setBaseComponentId(baseComponentId);
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof ComponentId) {
ComponentId other = (ComponentId) obj;
return basePac == other.basePac && baseComponent == other.baseComponent;
return getBasePacId() == other.getBasePacId() && getBaseComponentId() == other.getBaseComponentId();
}
return false;
}
@Override
public int hashCode() {
return (new Long(basePac ^ baseComponent % Integer.MAX_VALUE)).intValue();
return (new Long(getBasePacId() ^ getBaseComponentId() % Integer.MAX_VALUE)).intValue();
}
public void setBasePacId(long basePacId) {
this.basePacId = basePacId;
}
public long getBasePacId() {
return basePacId;
}
public void setBaseComponentId(long baseComponentId) {
this.baseComponentId = baseComponentId;
}
public long getBaseComponentId() {
return baseComponentId;
}
}

View File

@ -27,7 +27,7 @@ public class INetAddress extends AbstractEntity implements Serializable {
@Column(name = "inet_addr_id")
private long id;
@Column(name = "inet_addr", columnDefinition = "inet", unique = true)
@Column(name = "inet_addr", unique = true, length=-1)
private String inetAddr;
@Column(name = "description", columnDefinition = "character varying(100)")

View File

@ -7,6 +7,8 @@ import static javax.persistence.GenerationType.SEQUENCE;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -73,13 +75,17 @@ public class Pac extends AbstractEntity implements Serializable {
@ManyToOne(fetch = EAGER)
private INetAddress oldINetAddr;
@OneToMany(fetch = LAZY, cascade = ALL)
private java.util.Set<PacComponent> pacComponents;
@OneToMany(fetch = LAZY, cascade = ALL, mappedBy="pac")
private Set<PacComponent> pacComponents;
@OneToMany(fetch = LAZY, cascade = ALL, mappedBy="pac")
private java.util.Set<UnixUser> unixUser;
private Set<UnixUser> unixUser;
@Transient
private BasePac basepac;
public Pac() {
basepac = null;
}
public Pac(String name, Customer cust, BasePac basePac, Hive hive) {
@ -87,12 +93,12 @@ public class Pac extends AbstractEntity implements Serializable {
this.customer = cust;
this.hive = hive;
this.created = new java.util.Date();
this.created = new Date();
this.webserverGroup = "httpd";
this.curINetAddr = hive.getInetAddr();
pacComponents = new java.util.HashSet<PacComponent>();
java.util.Date today = new java.util.Date();
pacComponents = new HashSet<PacComponent>();
Date today = new Date();
for (Component comp : basePac.getComponents()) {
PacComponent pacComp = new PacComponent(basePac,
comp.getBaseComponent(), this, comp.getDefaultQuantity(),
@ -197,32 +203,25 @@ public class Pac extends AbstractEntity implements Serializable {
this.oldINetAddr = oldINetAddr;
}
// virtual attribute basePac
/*
* This does not work, JPA/Hibernate always wants to create an invalid row
* in packet_component
*
* @ManyToOne(fetch=EAGER, optional=true) // optional
* should be default anyway
*
* @JoinTable( name="packet_component",
* joinColumns=@JoinColumn(name="packet_id"),
* inverseJoinColumns=@JoinColumn(name="basepacket_id") )
*/
@Transient
public BasePac getBasePac() {
return getPacComponents().iterator().next().getBasePac();
public BasePac getBasepac() {
if (basepac == null) {
Set<PacComponent> pacComps = getPacComponents();
if (pacComps != null) {
basepac = pacComps.iterator().next().getBasePac();
}
}
return basepac;
}
public void setBasePac(BasePac basePac) {
// TODO: needs code to change basePac in all pacComponents
public void setBasepac(BasePac basepac) {
this.basepac = basepac;
}
public java.util.Set<PacComponent> getPacComponents() {
public Set<PacComponent> getPacComponents() {
return pacComponents;
}
public void setPacComponents(java.util.Set<PacComponent> pacComponents) {
public void setPacComponents(Set<PacComponent> pacComponents) {
this.pacComponents = pacComponents;
}
@ -233,11 +232,11 @@ public class Pac extends AbstractEntity implements Serializable {
return null;
}
public java.util.Set<UnixUser> getUnixUser() {
public Set<UnixUser> getUnixUser() {
return unixUser;
}
public void setUnixUser(java.util.Set<UnixUser> unixUser) {
public void setUnixUser(Set<UnixUser> unixUser) {
this.unixUser = unixUser;
}
@ -264,7 +263,6 @@ public class Pac extends AbstractEntity implements Serializable {
}
public UnixUser getAdminUser(EntityManager em) {
// TODO Auto-generated method stub
return null;
}

View File

@ -1,8 +1,5 @@
package de.hsadmin.mods.pac;
import static javax.persistence.FetchType.EAGER;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
@ -18,18 +15,30 @@ import javax.persistence.TemporalType;
@Entity(name = "PacComponents")
@Table(name = "packet_component")
@IdClass(PacComponentId.class)
public class PacComponent implements Serializable {
private static final long serialVersionUID = 5359873462163274873L;
public class PacComponent {
@Id
@Column(name="packet_id", insertable=false, updatable=false, columnDefinition = "integer")
private long pacId;
@Id
@Column(name="basepacket_id", insertable=false, updatable=false, columnDefinition = "integer")
private long basePacId;
@Id
@Column(name="basecomponent_id", insertable=false, updatable=false, columnDefinition = "integer")
private long baseComponentId;
@ManyToOne
@JoinColumn(name = "packet_id")
private Pac pac;
@Id
@ManyToOne
@JoinColumn(name = "basecomponent_id")
private BaseComponent baseComponent;
@JoinColumn(name = "basepacket_id", columnDefinition = "integer", nullable = false)
@ManyToOne(fetch = EAGER)
@ManyToOne
@JoinColumn(name = "basepacket_id")
private BasePac basePac;
@Column(name = "quantity", columnDefinition = "integer")
@ -104,4 +113,28 @@ public class PacComponent implements Serializable {
this.cancelled = cancelled;
}
public void setPacId(long pacId) {
this.pacId = pacId;
}
public long getPacId() {
return pacId;
}
public void setBaseComponentId(long baseComponentId) {
this.baseComponentId = baseComponentId;
}
public long getBaseComponentId() {
return baseComponentId;
}
public void setBasePacId(long basePacId) {
this.basePacId = basePacId;
}
public long getBasePacId() {
return basePacId;
}
}

View File

@ -1,23 +1,53 @@
package de.hsadmin.mods.pac;
import java.io.Serializable;
public class PacComponentId {
public long pac;
public long baseComponent;
public class PacComponentId implements Serializable {
private static final long serialVersionUID = -3018368675798315892L;
private long pacId;
private long basePacId;
private long baseComponentId;
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof PacComponentId) {
PacComponentId other = (PacComponentId) obj;
return pac == other.pac && baseComponent == other.baseComponent;
return getPacId() == other.getPacId() && getBaseComponentId() == other.getBaseComponentId() && getBasePacId() == other.getBasePacId();
}
return false;
}
@Override
public int hashCode() {
return (new Long(pac ^ baseComponent % Integer.MAX_VALUE)).intValue();
return (new Long(getPacId() ^ getBaseComponentId() ^ getBasePacId() % Integer.MAX_VALUE)).intValue();
}
public void setPacId(long pacId) {
this.pacId = pacId;
}
public long getPacId() {
return pacId;
}
public void setBaseComponentId(long baseComponentId) {
this.baseComponentId = baseComponentId;
}
public long getBaseComponentId() {
return baseComponentId;
}
public void setBasePacId(long basePacId) {
this.basePacId = basePacId;
}
public long getBasePacId() {
return basePacId;
}
}

View File

@ -0,0 +1,83 @@
package de.hsadmin.mods.pac;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.mods.cust.Customer;
public class PacModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY obj.name ASC";
}
return super.search(entityClass, condition, orderBy);
}
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
Date now = new Date();
EntityManager em = getTransaction().getEntityManager();
Pac pac = (Pac) newEntity;
BasePac basepac = pac.getBasepac();
if (basepac == null || basepac.getName() == null || basepac.getName().length() == 0) {
throw new HSAdminException("basepac required");
}
Query qBasepac = em.createQuery("SELECT b FROM BasePacs b WHERE b.name = :basepacName AND b.valid = :valid");
qBasepac.setParameter("basepacName", basepac.getName());
qBasepac.setParameter("valid", Boolean.TRUE);
basepac = (BasePac) qBasepac.getSingleResult();
pac.setBasepac(basepac);
Query qComponents = em.createQuery("SELECT c FROM Components c WHERE c.basePacId = :basepac");
qComponents.setParameter("basepac", basepac.id());
INetAddress curINetAddr = pac.getCurINetAddr();
if (curINetAddr == null || curINetAddr.getInetAddr() == null || curINetAddr.getInetAddr().length() == 0) {
throw new HSAdminException("curinetaddr required");
}
Query qINetAddr = em.createNativeQuery("SELECT * FROM inet_addr WHERE inet_addr = inet '" + curINetAddr.getInetAddr() + "'", INetAddress.class);
curINetAddr = (INetAddress) qINetAddr.getSingleResult();
pac.setCurINetAddr(curINetAddr);
Customer customer = pac.getCustomer();
if (customer == null || customer.getName() == null || customer.getName().length() == 0) {
throw new HSAdminException("customer required");
}
Query qCustomer = em.createQuery("SELECT c FROM Customers c WHERE c.name = :name");
qCustomer.setParameter("name", customer.getName());
customer = (Customer) qCustomer.getSingleResult();
pac.setCustomer(customer);
Hive hive = pac.getHive();
if (hive == null || hive.getName() == null || hive.getName().length() == 0) {
throw new HSAdminException("hive required");
}
Query qHive = em.createQuery("SELECT h FROM Hives h WHERE h.name = :name");
qHive.setParameter("name", hive.getName());
hive = (Hive) qHive.getSingleResult();
pac.setHive(hive);
// em.persist(newEntity);
List<?> componentsList = qComponents.getResultList();
Set<PacComponent> pacComponents = new HashSet<PacComponent>();
for (Object cObj : componentsList) {
Component comp = (Component) cObj;
PacComponent pacComponent = new PacComponent();
pacComponent.setBaseComponent(comp.getBaseComponent());
pacComponent.setbasePac(comp.getBasePac());
pacComponent.setCreated(now);
pacComponent.setPac(pac);
pacComponent.setQuantity(comp.getDefaultQuantity());
// em.persist(pacComponent);
}
pac.setPacComponents(pacComponents);
return super.add(newEntity);
}
}

View File

@ -17,6 +17,7 @@ import javax.persistence.Table;
import javax.persistence.Transient;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.FieldValidation;
import de.hsadmin.mods.pac.Pac;
@Entity(name = "UnixUsers")
@ -36,9 +37,11 @@ public class UnixUser extends de.hsadmin.core.model.AbstractEntity implements Se
@Column(name = "userid", columnDefinition = "integer", nullable = false, updatable=false)
private long userId;
@FieldValidation("[a-z0-9\\_\\-\\.]*")
@Column(name = "name", columnDefinition = "character varying(24)", unique = true, updatable=false)
private String name;
@FieldValidation("[^:]*")
@Transient
private String password;
@ -46,12 +49,15 @@ public class UnixUser extends de.hsadmin.core.model.AbstractEntity implements Se
@ManyToOne(fetch = EAGER)
private Pac pac;
@FieldValidation("[a-zA-Z0-9\\_\\-\\.\\,\\ ]*")
@Column(name = "comment", columnDefinition = "character varying(128)")
private String comment;
@FieldValidation("[a-z\\/]*")
@Column(name = "shell", columnDefinition = "character varying(32)")
private String shell;
@FieldValidation("[a-z0-9\\/\\_\\-\\.]*")
@Column(name = "homedir", columnDefinition = "character varying(48)", updatable=false)
private String homedir;

View File

@ -16,7 +16,7 @@ public class EMailAddressRemote extends AbstractRemote {
String admin = adr.getDomain().getUser().getName();
String pac = adr.getDomain().getUser().getPac().getName();
String target = adr.getTarget();
String localpart = adr.getLocalPart();
String localpart = adr.getLocalpart();
String subdomain = adr.getSubdomain();
String emailaddress = adr.getEMailAddress();
String fulldomain = adr.getFullDomain();
@ -34,9 +34,9 @@ public class EMailAddressRemote extends AbstractRemote {
@Override
protected void map2entity(Map<String, String> map, AbstractEntity entity) {
EMailAddress adr = (EMailAddress) entity;
String localPart = map.get("localpart");
if (assertNotNull(localPart)) {
adr.setLocalPart(localPart);
String localpart = map.get("localpart");
if (assertNotNull(localpart)) {
adr.setLocalpart(localpart);
}
String subdomain = map.get("subdomain");
if (assertNotNull(subdomain)) {

View File

@ -0,0 +1,75 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.mods.cust.Customer;
import de.hsadmin.mods.pac.BasePac;
import de.hsadmin.mods.pac.Hive;
import de.hsadmin.mods.pac.INetAddress;
import de.hsadmin.mods.pac.Pac;
public class PacRemote extends AbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected void entity2map(AbstractEntity entity, Map<String, String> resultMap) {
Pac pac = (Pac) entity;
resultMap.put("name", pac.getName());
resultMap.put("id", Long.toString(pac.getId()));
resultMap.put("hive", pac.getHiveName());
resultMap.put("customer", pac.getCustomer().getName());
resultMap.put("curinetaddr", pac.getCurINetAddr().getInetAddr());
resultMap.put("created", df.format(pac.getCreated()));
}
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return Pac.class;
}
@Override
protected void map2entity(Map<String, String> setParams, AbstractEntity entity) {
Pac pac = (Pac) entity;
BasePac basePac = pac.getBasepac();
String basePacName = setParams.get("basepac");
if (basePac == null && assertNotNull(basePacName)) {
basePac = new BasePac();
basePac.setName(basePacName);
pac.setBasepac(basePac);
}
pac.setCreated(new Date());
INetAddress curINetAddr = pac.getCurINetAddr();
String inetAddrString = setParams.get("curinetaddr");
if (curINetAddr == null && assertNotNull(inetAddrString)) {
curINetAddr = new INetAddress(inetAddrString);
pac.setCurINetAddr(curINetAddr);
}
Customer customer = pac.getCustomer();
String memberCode = setParams.get("customer");
if (customer == null && assertNotNull(memberCode)) {
customer = new Customer();
customer.setName(memberCode);
pac.setCustomer(customer);
}
Hive hive = pac.getHive();
String hiveName = setParams.get("hive");
if (hive == null && assertNotNull(hiveName)) {
hive = new Hive();
hive.setName(hiveName);
pac.setHive(hive);
}
pac.setName(setParams.get("name"));
}
@Override
protected void regularizeKeys(Map<String, String> whereParams) {
replaceKey(whereParams, "customer", "customer.name");
replaceKey(whereParams, "basepac", "customer.name");
}
}

View File

@ -1,4 +1,5 @@
member=de.hsadmin.remote.CustomerRemote
pac=de.hsadmin.remote.PacRemote
user=de.hsadmin.remote.UnixUserRemote
domain=de.hsadmin.remote.DomainRemote
emailalias=de.hsadmin.remote.EMailAliasRemote

View File

@ -45,7 +45,7 @@ public class DomainTest {
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(36, result.length);
assertEquals(29, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
@ -66,7 +66,7 @@ public class DomainTest {
Map<String, String> setParams = new HashMap<String, String>();
Map<String, String> whereParams = new HashMap<String, String>();
setParams.put("user", "peh00-phor");
whereParams.put("name", "i2null.de");
whereParams.put("name", "smb-linn.de");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };

View File

@ -44,7 +44,7 @@ public class EMailAddressTest {
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(253, result.length);
assertEquals(242, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
@ -204,9 +204,13 @@ public class EMailAddressTest {
Object[] resArray = (Object[]) execute;
assertEquals(1, resArray.length);
Object res = resArray[0];
Map<String, Object> map = (Map<String, Object>) res;
if (res instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) res;
Object idVal = map.get("id");
whereParams.put("id", idVal);
} else {
fail("unexpected type");
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}

View File

@ -0,0 +1,144 @@
package de.hsadmin.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class PacTest {
private static final String MODULE = "pac";
private XmlRpcClient client;
private RemoteCASHelper cas;
@Before
public void setUp() throws Exception {
client = RemoteTestHelper.getClient();
cas = new RemoteCASHelper();
}
@After
public void tearDown() throws Exception {
client = null;
cas = null;
}
@Test
public void testSearchAllAsPacAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(1, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("hsh00-peh", row.get("customer"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testUpdate() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
Map<String, String> whereParams = new HashMap<String, String>();
setParams.put("curinetaddr", "192.168.10.2");
whereParams.put("name", "peh00");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
Object execute = client.execute(MODULE + ".update", params);
assertNotNull(execute);
fail("exception expected");
} catch (XmlRpcException e) {
// System.out.println(e.getMessage());
}
}
@Test
public void testCreate() {
int count = getPacsCount();
String user = "pe";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
setParams.put("name", "peh07");
setParams.put("hive", "h05");
setParams.put("customer", "hsh00-peh");
setParams.put("basepac", "DW/S");
setParams.put("curinetaddr", "212.42.230.178");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
Object execute = client.execute(MODULE + ".add", params);
assertTrue(execute instanceof Map<?, ?>);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count + 1, getPacsCount());
}
@Test
public void testDelete() {
int count = getPacsCount();
String user = "pe";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("name", "peh07");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count - 1, getPacsCount());
}
private int getPacsCount() {
int count = 0;
String user = "pe";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("customer", "hsh00-peh");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
count = result.length;
} catch (XmlRpcException e) {
fail(e.getMessage());
}
return count;
}
}

View File

@ -43,7 +43,7 @@ public class UnixUserTest {
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(22, result.length);
assertEquals(21, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;