From 888b109f9edc1c0bf9b6131decfeefd9e3b09f49 Mon Sep 17 00:00:00 2001
From: Peter Hormanns <peter.hormanns@hostsharing.net>
Date: Fri, 12 Aug 2011 16:19:21 +0200
Subject: [PATCH] find module implementations by annotation

---
 hsarback/src/de/hsadmin/mods/cust/Customer.java                 |   11 
 hsarback/src/de/hsadmin/mods/pac/Pac.java                       |    2 
 hsarback/src/de/hsadmin/mods/email/EMailAddress.java            |    2 
 hsarback/src/de/hsadmin/mods/dom/Domain.java                    |    2 
 hsarback/src/de/hsadmin/mods/email/EMailAlias.java              |   13 
 hsarback/test/de/hsadmin/remote/RemoteTest.java                 |   22 
 hsarback/src/de/hsadmin/mods/db/MySqlDatabaseModuleImpl.java    |   14 
 hsarback/src/de/hsadmin/mods/dom/DomainModuleImpl.java          |   19 
 hsarback/src/de/hsadmin/mods/email/EMailAddressModuleImpl.java  |   12 
 hsarback/src/de/hsadmin/mods/pac/PacModuleImpl.java             |    4 
 hsarback/src/de/hsadmin/mods/db/DatabaseUser.java               |   10 
 hsarback/src/de/hsadmin/mods/user/UnixUser.java                 |   29 -
 hsarback/src/de/hsadmin/mods/db/PgSqlDatabase.java              |    2 
 hsarback/src/de/hsadmin/mods/db/PgSqlUser.java                  |    2 
 hsarback/src/de/hsadmin/mods/db/PgSqlDatabaseModuleImpl.java    |   13 
 hsarback/src/de/hsadmin/mods/cust/CustomerModuleImpl.java       |   20 
 hsarback/src/de/hsadmin/mods/db/MySqlUserModuleImpl.java        |   10 
 hsarback/src/de/hsadmin/mods/db/Database.java                   |   20 -
 hsarback/src/de/hsadmin/mods/email/EMailAliasModuleImpl.java    |   10 
 hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java |   35 +-
 hsarback/src/de/hsadmin/mods/db/MySqlDatabase.java              |    2 
 hsarback/src/de/hsadmin/mods/db/MySqlUser.java                  |    2 
 hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java       |  120 +++----
 hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java     |   32 +
 hsarback/src/de/hsadmin/mods/db/PgSqlUserModuleImpl.java        |    8 
 hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java      |  479 +++++++++++--------------------
 26 files changed, 380 insertions(+), 515 deletions(-)

diff --git a/hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java b/hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java
index 85bf1dd..279898b 100644
--- a/hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java
+++ b/hsarback/src/de/hsadmin/core/model/AbstractModuleImpl.java
@@ -1,13 +1,13 @@
 package de.hsadmin.core.model;
 
+import java.lang.reflect.Method;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.persistence.Entity;
 import javax.persistence.EntityManager;
+import javax.persistence.NonUniqueResultException;
 import javax.persistence.Query;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 import de.hsadmin.core.qserv.EntityProcessorFactory;
 import de.hsadmin.core.qserv.Processor;
@@ -21,21 +21,183 @@
  */
 public abstract class AbstractModuleImpl implements ModuleInterface {
 	
-	private static Log log = LogFactory.getLog(AbstractModuleImpl.class);
-
-	private UnixUser loginUser;
 	private Transaction transaction;
 
 	public void construct(Transaction tx) {
 		transaction = tx;
 	}
 
+	public Transaction getTransaction() {
+		return transaction;
+	}
+	
+	public AbstractEntity initialize(AbstractEntity newEntity)
+			throws AuthorisationException {
+		newEntity.initialize(transaction.getEntityManager(), transaction.getLoginUser());
+		return newEntity;
+	}
+
+	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		UnixUser loginUser = transaction.getLoginUser();
+		EntityManager entityManager = transaction.getEntityManager();
+		newEntity.complete(entityManager, loginUser);
+		entityManager.persist(newEntity);
+		if (!newEntity.isWriteAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
+		}
+		EntityProcessorFactory procFact = createProcessorFactory(newEntity.getClass());
+		if (procFact != null) {
+			Processor proc = procFact.createCreateProcessor(entityManager, newEntity);
+			queueProcessor(proc, loginUser, newEntity, "hinzugefuegt");
+		}
+		return newEntity;
+	}
+
+	public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
+		AbstractEntity entity = transaction.getEntityManager().find(entityClass, key);
+		UnixUser loginUser = transaction.getLoginUser();
+		if (!entity.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", entity);
+		}
+		return entity;
+	}
+
+	public AbstractEntity findByString(Class<? extends AbstractEntity> entityClass, String key) throws HSAdminException {
+		Method method = null;
+		try {
+			method = entityClass.getDeclaredMethod("createQueryFromStringKey", String.class);
+		} catch (SecurityException e) {
+			throw new HSAdminException(e);
+		} catch (NoSuchMethodException e) {
+			method = null;
+		}
+		AbstractEntity entity = null;
+		if (method == null) {
+			entity = transaction.getEntityManager().find(entityClass, key);
+		}
+		else {
+			String query = null;
+			try {
+				query = (String) method.invoke(null, key);
+			} catch (Exception e) {
+				throw new HSAdminException(e);
+			}
+			List<AbstractEntity> result = search(entityClass, query, null);
+			if (result.size() > 1) throw new NonUniqueResultException();
+			if (result.size() == 0) return null;
+			entity = result.get(0);
+		}
+		return entity;
+	}
+
+	public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
+		UnixUser loginUser = transaction.getLoginUser();
+		condition = restrict(entityClass, loginUser, condition);
+		Entity entityAnnot = entityClass.getAnnotation(Entity.class);
+		String queryString = "SELECT obj FROM " + entityAnnot.name() + " obj";
+		if (condition != null && condition.length() > 0) {
+			queryString += " WHERE " + condition;
+		}
+		if (condition != null && condition.contains("AND (FALSE)")) {
+			return new LinkedList<AbstractEntity>();
+		}
+		if (orderBy != null) {
+			queryString += " ";
+			queryString += orderBy;
+		}
+		EntityManager entityManager = transaction.getEntityManager();
+		entityManager.clear();
+		Query query = entityManager.createQuery(queryString);
+		query.setParameter("loginUser", loginUser);
+		query.setParameter("loginUserName", loginUser.getName());
+		query.setParameter("loginUserPac", loginUser.getPac());
+		try {
+			List<?> res = query.getResultList();
+			List<AbstractEntity> ret = new LinkedList<AbstractEntity>();
+			// remove entities where login user has no access rights
+			for (Object entity : res) {
+				if (entity instanceof AbstractEntity) {
+					AbstractEntity returnedEntity = (AbstractEntity) entity;
+					if (returnedEntity.isReadAllowedFor(transaction.getLoginUser())) {
+						ret.add(returnedEntity);
+					}
+				}
+			}
+			return ret;
+		} catch (Exception ex) {
+			throw new HSAdminException(ex);
+		}
+	}
+
+	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
+		UnixUser loginUser = transaction.getLoginUser();
+		existingEntity = existingEntity.merge(transaction.getEntityManager(), loginUser);
+		if (!existingEntity.isWriteAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "update", existingEntity);
+		}
+		EntityProcessorFactory procFact = createProcessorFactory(existingEntity.getClass());
+		if (procFact != null) {
+			Processor proc = procFact.createUpdateProcessor(transaction.getEntityManager(), existingEntity);
+			queueProcessor(proc, loginUser, existingEntity, "aktualisiert");
+		}
+		return existingEntity;
+	}
+
+	public void delete(AbstractEntity existingEntity) throws HSAdminException {
+		UnixUser loginUser = transaction.getLoginUser();
+		EntityManager entityManager = transaction.getEntityManager();
+		existingEntity = entityManager.find(existingEntity.getClass(), existingEntity.id());
+		if (!existingEntity.isWriteAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", existingEntity);
+		}
+		entityManager.remove(existingEntity);
+		EntityProcessorFactory procFact = createProcessorFactory(existingEntity.getClass());
+		if (procFact != null) {
+			Processor proc = procFact.createDeleteProcessor(entityManager, existingEntity);
+			queueProcessor(proc, loginUser, existingEntity, "geloescht");
+		}
+	}
+
+	protected EntityProcessorFactory createProcessorFactory(Class<? extends AbstractEntity> entityClass) 
+			throws HSAdminException {
+		String procFactName = entityClass.getCanonicalName() + "ProcessorFactory";
+		Class<?> procFactClass = null;
+		EntityProcessorFactory procFact = null;
+		try {
+			procFactClass = Class.forName(procFactName);
+			if (procFactClass != null) {
+				procFact = (EntityProcessorFactory) procFactClass.newInstance();
+			}
+		} catch (ClassNotFoundException e) {
+			// no processor defined
+		} catch (InstantiationException e) {
+			throw new HSAdminException(e);
+		} catch (IllegalAccessException e) {
+			throw new HSAdminException(e);
+		}
+		return procFact;
+	}
+
+	protected void queueProcessor(Processor proc, UnixUser user, AbstractEntity entity, String action) {
+		EntityInfo entityInfo = entity.getClass().getAnnotation(EntityInfo.class);
+		String entityTypeName = entityInfo != null ? entityInfo.name() : entity.getClass().getSimpleName();
+		StringBuilder details = new StringBuilder();
+		String title = entityTypeName + " (" + entity.createStringKey() + ") " + action;
+		QueueTask task = new QueueTask(user, title, details.toString(), proc);
+		transaction.getEntityManager().persist(task);
+		transaction.enqueue(entity.getHiveName(), task);
+	}
+
+	public String toString(StackTraceElement[] stackTrace) {
+		StringBuilder stack = new StringBuilder();
+		for (StackTraceElement e : stackTrace) {
+			stack.append(e.getFileName() + ":" + e.getLineNumber() + "\n");
+		}
+		return stack.toString();
+	}
+
 	/**
 	 *  apply access restriction to JPA-QL condition.
-	 * @param entityClass
-	 * @param loginUser
-	 * @param condition
-	 * @return
 	 */
 	private String restrict(Class<?> entityClass, UnixUser loginUser, String condition) {
 		String restriction = AbstractEntity.restriction(entityClass, loginUser);
@@ -46,302 +208,5 @@
 		else
 			condition = restriction;
 		return condition;
-	}
-
-	public Transaction getTransaction() {
-		return transaction;
-	}
-	
-	public AbstractEntity initialize(AbstractEntity newEntity)
-			throws AuthorisationException {
-		newEntity.initialize(transaction.getEntityManager(), getLoginUser());
-		return newEntity;
-	}
-
-	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
-		// get the user who is logged in
-		UnixUser loginUser = getLoginUser();
-
-		// create record in database
-		log.debug("merging?");
-		newEntity.complete(transaction.getEntityManager(), loginUser);
-		try {
-			transaction.getEntityManager().persist(newEntity);
-		} catch (Throwable exc) {
-			log.error("exception: " + exc);
-		} finally {
-			log.debug("finally");
-		}
-		log.debug("merged");
-
-		// check rights
-		if (!newEntity.isWriteAllowedFor(loginUser))
-			throw new AuthorisationException(loginUser, "add", newEntity);
-
-		// generically create the processor
-		EntityProcessorFactory procFact = createProcessorFactory(newEntity.getClass());
-		if (procFact == null) {
-			log.debug("no procFact found :-(");
-			return newEntity;
-		}
-		log.debug("procFact found :-)");
-		Processor proc = procFact.createCreateProcessor(transaction.getEntityManager(), newEntity);
-
-		// queue the processor
-		queueProcessor(proc, loginUser, newEntity, "hinzugefuegt");
-
-		// return the added entity
-		return newEntity;
-	}
-
-	public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
-		AbstractEntity entity = transaction.getEntityManager().find(entityClass, key);
-
-		// check rights
-		UnixUser loginUser = getLoginUser();
-		if (!entity.isReadAllowedFor(loginUser))
-			throw new AuthorisationException(loginUser, "add", entity);
-
-		return entity;
-	}
-
-	public AbstractEntity findByString(Class<? extends AbstractEntity> entityClass, String key) throws HSAdminException {
-		// find a static method which creates the query
-		java.lang.reflect.Method method = null;
-		try {
-			method = entityClass.getDeclaredMethod("createQueryFromStringKey", String.class);
-		} catch (SecurityException e) {
-			throw new RuntimeException(e);
-		} catch (NoSuchMethodException e) {
-			method = null;
-		}
-
-		AbstractEntity entity;
-		if (method == null)
-			entity = transaction.getEntityManager().find(entityClass, key);
-		else {
-			// get the query expression from the static method (query part after
-			// WHERE)
-			String query;
-			try {
-				query = (String) method.invoke(null, key);
-			} catch (Exception e) {
-				throw new RuntimeException(e);
-			}
-
-			// perform the query
-			List<AbstractEntity> result = search(entityClass, query, null);
-			if (result.size() > 1)
-				throw new javax.persistence.NonUniqueResultException();
-			if (result.size() == 0)
-				return null;
-			entity = result.get(0);
-
-			// this was maybe thought as a fallback
-			// but is wrong when the above result is empty due to accessibility
-			// entity = em.find(entityClass, key);
-		}
-
-		// return (checking rights already done in search)
-		return entity;
-	}
-
-	public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
-		// restrict query
-		UnixUser loginUser = getLoginUser();
-		condition = restrict(entityClass, loginUser, condition);
-
-		// get the entities name (query part from FROM to WHERE)
-		// TODO: beware SQL injections!!!
-		javax.persistence.Entity entityAnnot = entityClass.getAnnotation(javax.persistence.Entity.class);
-		String queryString = "SELECT obj FROM " + entityAnnot.name() + " obj";
-		if (condition != null && condition.length() > 0)
-			queryString += " WHERE " + condition;
-
-		// Fix problem with queries WHERE .. AND (FALSE) -- pe
-		if (condition != null && condition.contains("AND (FALSE)")) {
-			return new LinkedList<AbstractEntity>();
-		}
-		
-		if (orderBy != null) {
-			queryString += " ";
-			queryString += orderBy;
-		}
-
-		// set parameters
-		EntityManager entityManager = transaction.getEntityManager();
-		entityManager.clear();
-		
-		Query query = entityManager.createQuery(queryString);
-		setQueryParameter(query, queryString, "loginUser", loginUser);
-		setQueryParameter(query, queryString, "loginUserName", loginUser.getName());
-		setQueryParameter(query, queryString, "loginUserPac", loginUser.getPac());
-
-		// do query
-		try {
-			List<?> res = query.getResultList();
-			List<AbstractEntity> ret = new LinkedList<AbstractEntity>();
-
-			// remove entities where login user has no access rights
-			for (Object entity : res) {
-				if (entity instanceof AbstractEntity) {
-					AbstractEntity returnedEntity = (AbstractEntity) entity;
-					if (returnedEntity.isReadAllowedFor(getLoginUser())) {
-						ret.add(returnedEntity);
-					}
-				}
-			}
-
-			// return clean result
-			return ret;
-		} catch (Exception ex) {
-			throw new HSAdminException(ex);
-		}
-	}
-
-	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
-		// get the user who is logged in
-		UnixUser loginUser = getLoginUser();
-
-		// update record in database
-		log.debug("merging:");
-		try {
-			existingEntity = existingEntity.merge(transaction.getEntityManager(), loginUser);
-		} catch (Throwable exc) {
-			log.error("exception: " + exc);
-			throw new RuntimeException(exc);
-		} finally {
-			log.debug("finally");
-		}
-		log.debug("merged!");
-
-		// check rights
-		if (!existingEntity.isWriteAllowedFor(loginUser))
-			throw new AuthorisationException(loginUser, "update",
-					existingEntity);
-
-		// generically create the processor
-		EntityProcessorFactory procFact = 
-			createProcessorFactory(existingEntity.getClass());
-		if (procFact != null) {
-			log.debug("creating processor");
-			Processor proc = procFact.createUpdateProcessor(transaction.getEntityManager(), existingEntity);
-
-			// queue the processor
-			queueProcessor(proc, loginUser, existingEntity, "aktualisiert");
-		}
-
-		// return the merged entity
-		return existingEntity;
-	}
-
-	public void delete(AbstractEntity existingEntity) throws HSAdminException {
-		// get the user who is logged in
-		UnixUser user = getLoginUser();
-
-		// re-attach the entity
-		log.debug("merging:");
-		try {
-			existingEntity = transaction.getEntityManager().find(existingEntity.getClass(), existingEntity.id());
-		} catch (Throwable exc) {
-			log.error("exception: " + exc);
-			throw new RuntimeException(exc);
-		} finally {
-			log.debug("finally");
-		}
-		log.debug("merged!");
-
-		// check rights
-		if (!existingEntity.isWriteAllowedFor(loginUser))
-			throw new AuthorisationException(loginUser, "add", existingEntity);
-
-		// delete record in database
-		log.debug("deleting:");
-		try {
-			transaction.getEntityManager().remove(existingEntity);
-		} catch (Throwable exc) {
-			log.error("exception: " + exc);
-		} finally {
-			log.debug("finally");
-		}
-		log.debug("deleted!");
-
-		// generically create the processor
-		EntityProcessorFactory procFact = createProcessorFactory(existingEntity.getClass());
-		if (procFact == null) {
-			log.debug("no procFact found :-(");
-			return;
-		}
-		log.debug("procFact found :-)");
-		Processor proc = procFact.createDeleteProcessor(transaction.getEntityManager(), existingEntity);
-
-		// queue the processor
-		queueProcessor(proc, user, existingEntity, "geloescht");
-	}
-
-	public EntityProcessorFactory createProcessorFactory(Class<? extends AbstractEntity> entityClass) {
-		try {
-			String procFactName = entityClass.getCanonicalName()
-					+ "ProcessorFactory";
-			Class<?> procFactClass = Class.forName(procFactName);
-			if (procFactClass == null)
-				return null;
-			Object procFact = procFactClass.newInstance();
-			return (EntityProcessorFactory) procFact;
-		} catch (Exception exc) {
-			log.error("exception creating instance: " + exc);
-			return null;
-		}
-	}
-
-	/**
-	 *  get current login user from session context.
-	 * @return
-	 */
-	public UnixUser getLoginUser() {
-		if (loginUser == null) {
-			loginUser = transaction.getLoginUser();
-		}
-		return loginUser;
-	}
-
-	public void queueProcessor(Processor proc, UnixUser user, AbstractEntity entity, String action) {
-		log.debug("queueing processor for user " + user.getId() + "/"
-				+ user.getUserId() + "/" + user.getName());
-		EntityInfo entityInfo = 
-			entity.getClass().getAnnotation(EntityInfo.class);
-		String entityTypeName = 
-			entityInfo != null ? entityInfo.name() : entity.getClass().getSimpleName();
-		StringBuilder details = new StringBuilder();
-		
-		// TODO: add properties of entity to details
-
-		String title = 
-			entityTypeName + " (" + entity.createStringKey() + ") " + action;
-		QueueTask task = new QueueTask(user, title, details.toString(), proc);
-		transaction.getEntityManager().persist(task);
-		transaction.enqueue(entity.getHiveName(), task);
-		log.debug("processor queued");
-	}
-
-	public String toString(StackTraceElement[] stackTrace) {
-		StringBuilder stack = new StringBuilder();
-		for (StackTraceElement e : stackTrace)
-			stack.append(e.getFileName() + ":" + e.getLineNumber() + "\n");
-		return stack.toString();
-	}
-
-	public static void setQueryParameter(Query query, String queryString,
-			String argName, Object argValue) {
-		int argLen = argName.length();
-		int iMax = queryString.length();
-		int i = 0;
-		while ((i = queryString.indexOf(argName, i)) >= 0) {
-			if ((i + argLen) >= iMax || queryString.charAt(i + argLen) < 'A') {
-				query.setParameter(argName, argValue);
-				break;
-			}
-			++i;
-		}
 	}
 }
diff --git a/hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java b/hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java
index edeaf60..39cb3ac 100644
--- a/hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java
+++ b/hsarback/src/de/hsadmin/core/model/EntitySessionHelper.java
@@ -17,17 +17,9 @@
 		// get in instance
 		AbstractModuleImpl impl = null;
 		try {
-			// determine wrapper class
-			ModuleImpl wrapperAnnot = entityClass.getAnnotation(ModuleImpl.class);
-			Class<?> wrapperClass = null;
-			if (wrapperAnnot != null) {
-				wrapperClass = wrapperAnnot.value();
-			} else {
-				wrapperClass = Class.forName(entityClass.getCanonicalName() + "ModuleImpl");
-			}
+			Class<?> wrapperClass = determineModuleImpl(entityClass);
 			// instantiate wrapper
-			impl = (AbstractModuleImpl) wrapperClass.newInstance();
-			impl.construct(tx);
+			impl = instantiateModuleImpl(tx, wrapperClass);
 		} catch (ClassNotFoundException exc) {
 			log.info("entity class '"
 							+ entityClass.getCanonicalName()
@@ -40,4 +32,24 @@
 		return impl;
 	}
 
+	private static AbstractModuleImpl instantiateModuleImpl(Transaction tx, Class<?> wrapperClass) 
+			throws InstantiationException, IllegalAccessException {
+		AbstractModuleImpl impl;
+		impl = (AbstractModuleImpl) wrapperClass.newInstance();
+		impl.construct(tx);
+		return impl;
+	}
+
+	private static Class<?> determineModuleImpl(Class<? extends AbstractEntity> entityClass)
+			throws ClassNotFoundException {
+		ModuleImpl wrapperAnnot = entityClass.getAnnotation(ModuleImpl.class);
+		Class<?> wrapperClass = null;
+		if (wrapperAnnot != null) {
+			wrapperClass = wrapperAnnot.value();
+		} else {
+			wrapperClass = Class.forName(entityClass.getCanonicalName() + "ModuleImpl");
+		}
+		return wrapperClass;
+	}
+
 }
diff --git a/hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java b/hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java
index 2310bfa..30cf430 100644
--- a/hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java
+++ b/hsarback/src/de/hsadmin/core/model/SecureDefaultModuleImpl.java
@@ -3,6 +3,10 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.persistence.EntityManager;
+
+import de.hsadmin.mods.user.UnixUser;
+
 /**
  *  allows access only for hostmasters, used as fallback wrapper.
  */
@@ -15,26 +19,29 @@
 
 	@Override
 	public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
+		Transaction transaction = getTransaction();
 		AbstractEntity entity = super.find(entityClass, key);
-		if (entity != null && !entity.isReadAllowedFor(getLoginUser()))
-			throw new AuthorisationException(getLoginUser(), "find");
+		if (entity != null && !entity.isReadAllowedFor(transaction.getLoginUser()))
+			throw new AuthorisationException(transaction.getLoginUser(), "find");
 		return entity;
 	}
 
 	@Override
 	public AbstractEntity findByString(Class<? extends AbstractEntity> entityClass, String key) throws HSAdminException {
+		Transaction transaction = getTransaction();
 		AbstractEntity entity = super.findByString(entityClass, key);
-		if (entity != null && !entity.isReadAllowedFor(getLoginUser()))
-			throw new AuthorisationException(getLoginUser(), "findByString");
+		if (entity != null && !entity.isReadAllowedFor(transaction.getLoginUser()))
+			throw new AuthorisationException(transaction.getLoginUser(), "findByString");
 		return entity;
 	}
 
 	@Override
 	public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) 
 			throws HSAdminException {
+		Transaction transaction = getTransaction();
 		// restrict query to entities where the loginUser could have rights on
 		SearchFilter filterAnnot;
-		if (!getLoginUser().hasHostmasterRole()
+		if (!transaction.getLoginUser().hasHostmasterRole()
 				&& (filterAnnot = getSecurityFilterAnnotation(entityClass)) != null) {
 			String securityCondition = filterAnnot.value();
 			if (condition != null && condition.length() > 0)
@@ -52,7 +59,7 @@
 		if (res != null) {
 			for (AbstractEntity entity : res) {
 				AbstractEntity returnedEntity = entity;
-				if (returnedEntity.isReadAllowedFor(getLoginUser()))
+				if (returnedEntity.isReadAllowedFor(transaction.getLoginUser()))
 					ret.add(returnedEntity);
 			}
 		}
@@ -88,15 +95,13 @@
 
 	@Override
 	public void delete(AbstractEntity detachedEntity) throws HSAdminException {
-		// get the entity from the database
-		AbstractEntity attachedEntity = getTransaction().getEntityManager().find(detachedEntity.getClass(),
-				detachedEntity.id());
-
-		// does the login user have the right to delete?
-		if (!attachedEntity.isWriteAllowedFor(getLoginUser()))
-			throw new AuthorisationException(getLoginUser(), "delete",
-					detachedEntity);
-
+		Transaction transaction = getTransaction();
+		EntityManager entityManager = transaction.getEntityManager();
+		UnixUser loginUser = transaction.getLoginUser();
+		AbstractEntity attachedEntity = entityManager.find(detachedEntity.getClass(), detachedEntity.id());
+		if (!attachedEntity.isWriteAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "delete", detachedEntity);
+		}
 		super.delete(attachedEntity);
 	}
 
diff --git a/hsarback/src/de/hsadmin/mods/cust/Customer.java b/hsarback/src/de/hsadmin/mods/cust/Customer.java
index 3a80385..772af72 100644
--- a/hsarback/src/de/hsadmin/mods/cust/Customer.java
+++ b/hsarback/src/de/hsadmin/mods/cust/Customer.java
@@ -22,12 +22,15 @@
 import javax.persistence.Temporal;
 import javax.persistence.Transient;
 
+import de.hsadmin.core.model.AbstractEntity;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.mods.pac.Pac;
 import de.hsadmin.mods.user.UnixUser;
 
 @Entity(name = "Customers")
 @Table(name = "business_partner")
-public class Customer extends de.hsadmin.core.model.AbstractEntity implements Serializable {
+@ModuleImpl(de.hsadmin.mods.cust.CustomerModuleImpl.class)
+public class Customer extends AbstractEntity implements Serializable {
 
 	private static final long serialVersionUID = -7450594652238392616L;
 
@@ -253,17 +256,11 @@
 		return null; // TODO: no access yet
 	}
 
-	/** 
-	 * determines whether the given user has full read access on all merged fields of this entity
-	 */
 	@Override
 	public boolean isReadAllowedFor(UnixUser loginUser) {
 		return loginUser.hasCustomerRoleFor(this);
 	}
 
-	/** 
-	 * determines whether the given user has full write access on all merged fields of this entity
-	 */
 	@Override
 	public boolean isWriteAllowedFor(UnixUser loginUser) {
 		return loginUser.hasCustomerRoleFor(this);
diff --git a/hsarback/src/de/hsadmin/mods/cust/CustomerModuleImpl.java b/hsarback/src/de/hsadmin/mods/cust/CustomerModuleImpl.java
index 34c4e27..aca3596 100644
--- a/hsarback/src/de/hsadmin/mods/cust/CustomerModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/cust/CustomerModuleImpl.java
@@ -9,6 +9,7 @@
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.GenericModuleImpl;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.core.util.TextUtil;
 import de.hsadmin.mods.pac.Pac;
 import de.hsadmin.mods.user.UnixUser;
@@ -17,8 +18,9 @@
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
-		if (!getLoginUser().hasHostmasterRole()) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		Transaction transaction = getTransaction();
+		if (!transaction.getLoginUser().hasHostmasterRole()) {
+			throw new AuthorisationException(transaction.getLoginUser(), "add", newEntity);
 		}
 		Customer newCustomer = (Customer) newEntity;
 		assertNotNull("membercode", newCustomer.getName());
@@ -62,16 +64,18 @@
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity)
 			throws HSAdminException {
-		if (!getLoginUser().hasHostmasterRole()) {
-			throw new AuthorisationException(getLoginUser(), "update", existingEntity);
+		Transaction transaction = getTransaction();
+		if (!transaction.getLoginUser().hasHostmasterRole()) {
+			throw new AuthorisationException(transaction.getLoginUser(), "update", existingEntity);
 		}
 		return super.update(existingEntity);
 	}
 
 	@Override
 	public void delete(AbstractEntity existingEntity) throws HSAdminException {
-		if (!getLoginUser().hasHostmasterRole()) {
-			throw new AuthorisationException(getLoginUser(), "delete", existingEntity);
+		Transaction transaction = getTransaction();
+		if (!transaction.getLoginUser().hasHostmasterRole()) {
+			throw new AuthorisationException(transaction.getLoginUser(), "delete", existingEntity);
 		}
 		Customer cust = (Customer) existingEntity;
 		
@@ -81,13 +85,13 @@
 		Date memberUntil = cust.getMemberUntil();
 		if (memberSince != null) {
 			if (memberUntil == null || memberUntil.after(new Date())) {
-				throw new AuthorisationException(getLoginUser(), "delete", existingEntity);
+				throw new AuthorisationException(transaction.getLoginUser(), "delete", existingEntity);
 			}
 		}
 		// keine Pakete mehr!
 		Set<Pac> pacs = cust.getPacs();
 		if (pacs != null && pacs.size() > 0) {
-			throw new AuthorisationException(getLoginUser(), "delete", existingEntity);
+			throw new AuthorisationException(transaction.getLoginUser(), "delete", existingEntity);
 		}
 		
 		GenericModuleImpl helper = new GenericModuleImpl(getTransaction());
diff --git a/hsarback/src/de/hsadmin/mods/db/Database.java b/hsarback/src/de/hsadmin/mods/db/Database.java
index bb64ba5..8645401 100644
--- a/hsarback/src/de/hsadmin/mods/db/Database.java
+++ b/hsarback/src/de/hsadmin/mods/db/Database.java
@@ -22,7 +22,6 @@
 import javax.persistence.Table;
 
 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;
@@ -84,29 +83,20 @@
 	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");
+				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)
 				Entity entityAnnot = Pac.class.getAnnotation(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());
+				query.setParameter("loginUser", loginUser);
+				query.setParameter("loginUserName", loginUser.getName());
+				query.setParameter("loginUserPac", loginUser.getPac());
 				pac = (Pac) query.getSingleResult();
 			} catch (NoResultException exc) {
-				throw new SecurityException("packet '" + pacName
-						+ "' not found or access denied");
+				throw new SecurityException("packet '" + pacName + "' not found or access denied");
 			}
 		}
 	}
diff --git a/hsarback/src/de/hsadmin/mods/db/DatabaseUser.java b/hsarback/src/de/hsadmin/mods/db/DatabaseUser.java
index d352f87..0b8dd1c 100644
--- a/hsarback/src/de/hsadmin/mods/db/DatabaseUser.java
+++ b/hsarback/src/de/hsadmin/mods/db/DatabaseUser.java
@@ -23,7 +23,6 @@
 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;
@@ -87,12 +86,9 @@
 
 				// 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());
+				query.setParameter("loginUser", loginUser);
+				query.setParameter("loginUserName", loginUser.getName());
+				query.setParameter("loginUserPac", loginUser.getPac());
 				pac = (Pac) query.getSingleResult();
 			} catch (NoResultException exc) {
 				throw new SecurityException("packet '" + pacName
diff --git a/hsarback/src/de/hsadmin/mods/db/MySqlDatabase.java b/hsarback/src/de/hsadmin/mods/db/MySqlDatabase.java
index dd19bc1..045b256 100644
--- a/hsarback/src/de/hsadmin/mods/db/MySqlDatabase.java
+++ b/hsarback/src/de/hsadmin/mods/db/MySqlDatabase.java
@@ -6,6 +6,7 @@
 import javax.persistence.Entity;
 
 import de.hsadmin.core.model.EntityInfo;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.pac.Pac;
 
@@ -14,6 +15,7 @@
 @EntityInfo(name = "MySQL Datenbank")
 @SearchFilter("obj.instance = 'mysql' AND (" + "	obj.pac = :loginUserPac OR "
 		+ "	obj.pac.customer.memberCode = :loginUserName )")
+@ModuleImpl(de.hsadmin.mods.db.MySqlDatabaseModuleImpl.class)
 public class MySqlDatabase extends Database implements Serializable {
 	
 	private static final long serialVersionUID = 2862112440807946042L;
diff --git a/hsarback/src/de/hsadmin/mods/db/MySqlDatabaseModuleImpl.java b/hsarback/src/de/hsadmin/mods/db/MySqlDatabaseModuleImpl.java
index 29f916b..6e78959 100644
--- a/hsarback/src/de/hsadmin/mods/db/MySqlDatabaseModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/db/MySqlDatabaseModuleImpl.java
@@ -9,6 +9,7 @@
 import de.hsadmin.core.model.AbstractModuleImpl;
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.pac.Pac;
 import de.hsadmin.mods.user.UnixUser;
 
@@ -25,26 +26,29 @@
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		Transaction transaction = getTransaction();
+		UnixUser loginUser = transaction.getLoginUser();
 		MySqlDatabase database = (MySqlDatabase) newEntity;
 		String name = database.getName();
 		if (name.length() < 7 || name.charAt(5) != '_') {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		EntityManager em = getTransaction().getEntityManager();
 		Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
 		qPac.setParameter("pacName", name.substring(0, 5));
 		Object singleResult = qPac.getSingleResult();
 		Pac pac = (Pac) singleResult;
-		if (pac == null || !pac.isReadAllowedFor(getLoginUser())) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		return super.add(newEntity);
 	}
 	
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
-		EntityManager em = getTransaction().getEntityManager();
-		UnixUser unixUser = getLoginUser();
+		Transaction transaction = getTransaction();
+		EntityManager em = transaction.getEntityManager();
+		UnixUser unixUser = transaction.getLoginUser();
 		MySqlDatabase detachtedDB = (MySqlDatabase) existingEntity;
 		MySqlDatabase attachedDB = em.find(MySqlDatabase.class, detachtedDB.getId());
 		if (!attachedDB.getName().equals(detachtedDB.getName())) {
diff --git a/hsarback/src/de/hsadmin/mods/db/MySqlUser.java b/hsarback/src/de/hsadmin/mods/db/MySqlUser.java
index 8668948..6886c44 100644
--- a/hsarback/src/de/hsadmin/mods/db/MySqlUser.java
+++ b/hsarback/src/de/hsadmin/mods/db/MySqlUser.java
@@ -6,6 +6,7 @@
 import javax.persistence.Entity;
 
 import de.hsadmin.core.model.EntityInfo;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.pac.Pac;
 
@@ -15,6 +16,7 @@
 @SearchFilter("obj.instance = 'mysql' AND ("
 		+ "	obj.pac = :loginUserPac OR "
 		+ "	obj.pac.customer.memberCode = :loginUserName )")
+@ModuleImpl(de.hsadmin.mods.db.MySqlUserModuleImpl.class)
 public class MySqlUser extends DatabaseUser implements Serializable {
 	
 	private static final long serialVersionUID = 6218494776881999478L;
diff --git a/hsarback/src/de/hsadmin/mods/db/MySqlUserModuleImpl.java b/hsarback/src/de/hsadmin/mods/db/MySqlUserModuleImpl.java
index ae0cbbc..cdee8bd 100644
--- a/hsarback/src/de/hsadmin/mods/db/MySqlUserModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/db/MySqlUserModuleImpl.java
@@ -9,16 +9,20 @@
 import de.hsadmin.core.model.AbstractModuleImpl;
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.pac.Pac;
+import de.hsadmin.mods.user.UnixUser;
 
 public class MySqlUserModuleImpl extends AbstractModuleImpl {
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		Transaction transaction = getTransaction();
+		UnixUser loginUser = transaction.getLoginUser();
 		MySqlUser user = (MySqlUser) newEntity;
 		String name = user.getName();
 		if (name.length() < 7 || name.charAt(5) != '_') {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		if (name.length() > 16) {
 			throw new HSAdminException("mysql database name max. length is 16 characters");
@@ -28,8 +32,8 @@
 		qPac.setParameter("pacName", name.substring(0, 5));
 		Object singleResult = qPac.getSingleResult();
 		Pac pac = (Pac) singleResult;
-		if (pac == null || !pac.isReadAllowedFor(getLoginUser())) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		return super.add(newEntity);
 	}
diff --git a/hsarback/src/de/hsadmin/mods/db/PgSqlDatabase.java b/hsarback/src/de/hsadmin/mods/db/PgSqlDatabase.java
index fd6c0c8..c7f443e 100644
--- a/hsarback/src/de/hsadmin/mods/db/PgSqlDatabase.java
+++ b/hsarback/src/de/hsadmin/mods/db/PgSqlDatabase.java
@@ -6,6 +6,7 @@
 import javax.persistence.Entity;
 
 import de.hsadmin.core.model.EntityInfo;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.pac.Pac;
 
@@ -15,6 +16,7 @@
 @SearchFilter("obj.instance = 'pgsql' AND (" 
 		+ "	obj.pac = :loginUserPac OR "
 		+ "	obj.pac.customer.memberCode = :loginUserName )")
+@ModuleImpl(de.hsadmin.mods.db.PgSqlDatabaseModuleImpl.class)
 public class PgSqlDatabase extends Database implements Serializable {
 	
 	private static final long serialVersionUID = 6688358817554938015L;
diff --git a/hsarback/src/de/hsadmin/mods/db/PgSqlDatabaseModuleImpl.java b/hsarback/src/de/hsadmin/mods/db/PgSqlDatabaseModuleImpl.java
index 89e970e..e179f81 100644
--- a/hsarback/src/de/hsadmin/mods/db/PgSqlDatabaseModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/db/PgSqlDatabaseModuleImpl.java
@@ -9,6 +9,7 @@
 import de.hsadmin.core.model.AbstractModuleImpl;
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.pac.Pac;
 import de.hsadmin.mods.user.UnixUser;
 
@@ -24,26 +25,28 @@
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		UnixUser loginUser = getTransaction().getLoginUser();
 		PgSqlDatabase database = (PgSqlDatabase) newEntity;
 		String name = database.getName();
 		if (name.length() < 7 || name.charAt(5) != '_') {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		EntityManager em = getTransaction().getEntityManager();
 		Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
 		qPac.setParameter("pacName", name.substring(0, 5));
 		Object singleResult = qPac.getSingleResult();
 		Pac pac = (Pac) singleResult;
-		if (pac == null || !pac.isReadAllowedFor(getLoginUser())) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		return super.add(newEntity);
 	}
 	
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
-		EntityManager em = getTransaction().getEntityManager();
-		UnixUser unixUser = getLoginUser();
+		Transaction transaction = getTransaction();
+		EntityManager em = transaction.getEntityManager();
+		UnixUser unixUser = transaction.getLoginUser();
 		MySqlDatabase detachtedDB = (MySqlDatabase) existingEntity;
 		MySqlDatabase attachedDB = em.find(MySqlDatabase.class, detachtedDB.getId());
 		if (!attachedDB.getName().equals(detachtedDB.getName())) {
diff --git a/hsarback/src/de/hsadmin/mods/db/PgSqlUser.java b/hsarback/src/de/hsadmin/mods/db/PgSqlUser.java
index 92c171a..c1107d7 100644
--- a/hsarback/src/de/hsadmin/mods/db/PgSqlUser.java
+++ b/hsarback/src/de/hsadmin/mods/db/PgSqlUser.java
@@ -6,6 +6,7 @@
 import javax.persistence.Entity;
 
 import de.hsadmin.core.model.EntityInfo;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.pac.Pac;
 
@@ -14,6 +15,7 @@
 @EntityInfo(name = "PostgreSQL Konto")
 @SearchFilter("obj.instance = 'pgsql' AND (" + "	obj.pac = :loginUserPac OR "
 		+ "	obj.pac.customer.memberCode = :loginUserName )")
+@ModuleImpl(de.hsadmin.mods.db.PgSqlUserModuleImpl.class)
 public class PgSqlUser extends DatabaseUser implements Serializable {
 
 	private static final long serialVersionUID = -1097602753310286629L;
diff --git a/hsarback/src/de/hsadmin/mods/db/PgSqlUserModuleImpl.java b/hsarback/src/de/hsadmin/mods/db/PgSqlUserModuleImpl.java
index 9e9fa31..24ee175 100644
--- a/hsarback/src/de/hsadmin/mods/db/PgSqlUserModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/db/PgSqlUserModuleImpl.java
@@ -10,23 +10,25 @@
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.HSAdminException;
 import de.hsadmin.mods.pac.Pac;
+import de.hsadmin.mods.user.UnixUser;
 
 public class PgSqlUserModuleImpl extends AbstractModuleImpl {
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		UnixUser loginUser = getTransaction().getLoginUser();
 		PgSqlUser user = (PgSqlUser) newEntity;
 		String name = user.getName();
 		if (name.length() < 7 || name.charAt(5) != '_') {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		EntityManager em = getTransaction().getEntityManager();
 		Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
 		qPac.setParameter("pacName", name.substring(0, 5));
 		Object singleResult = qPac.getSingleResult();
 		Pac pac = (Pac) singleResult;
-		if (pac == null || !pac.isReadAllowedFor(getLoginUser())) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		return super.add(newEntity);
 	}
diff --git a/hsarback/src/de/hsadmin/mods/dom/Domain.java b/hsarback/src/de/hsadmin/mods/dom/Domain.java
index 40e150d..832f07d 100644
--- a/hsarback/src/de/hsadmin/mods/dom/Domain.java
+++ b/hsarback/src/de/hsadmin/mods/dom/Domain.java
@@ -18,11 +18,13 @@
 
 import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.FieldValidation;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.mods.user.UnixUser;
 
 @Entity(name = "Domains")
 @Table(name = "domain")
 @SequenceGenerator(name = "DomainsSeqGen", sequenceName = "domain_domain_id_seq")
+@ModuleImpl(de.hsadmin.mods.dom.DomainModuleImpl.class)
 public class Domain extends AbstractEntity {
 
 	@Id
diff --git a/hsarback/src/de/hsadmin/mods/dom/DomainModuleImpl.java b/hsarback/src/de/hsadmin/mods/dom/DomainModuleImpl.java
index ae7c597..9bc06bc 100644
--- a/hsarback/src/de/hsadmin/mods/dom/DomainModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/dom/DomainModuleImpl.java
@@ -7,9 +7,9 @@
 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.AuthorisationException;
-import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.HSAdminException;
 import de.hsadmin.core.util.DNSCheck;
 import de.hsadmin.mods.dom.Domain.Status;
@@ -23,7 +23,7 @@
 	public AbstractEntity initialize(AbstractEntity newEntity) throws AuthorisationException {
 		AbstractEntity newDom = super.initialize(newEntity);
 		if (newDom instanceof Domain) {
-			((Domain) newDom).setUser(getLoginUser());
+			((Domain) newDom).setUser(getTransaction().getLoginUser());
 			return newDom;
 		}
 		return null;
@@ -94,7 +94,7 @@
 		}
 		EntityManager em = getTransaction().getEntityManager();
 
-		UnixUser loginUser = getLoginUser();
+		UnixUser loginUser = getTransaction().getLoginUser();
 		if (!loginUser.hasHostmasterRole()) {
 			// search for domains superior to dom
 			Query domainQuery = em.createQuery("SELECT d FROM Domains d WHERE d.name = :domainName");
@@ -158,7 +158,7 @@
 			dom.setUser((UnixUser) query.getSingleResult());
 		}
 		needsWriteAccessOn(existingEntity, "update");
-		throw new AuthorisationException(getLoginUser(), "update", existingEntity);
+		throw new AuthorisationException(getTransaction().getLoginUser(), "update", existingEntity);
 	}
 
 	@Override
@@ -177,25 +177,26 @@
 	}
 
 	private void needsReadAccessOn(AbstractEntity ent, String method) throws AuthorisationException {
+		UnixUser loginUser = getTransaction().getLoginUser();
 		if (ent instanceof Domain) {
 			Domain dom = (Domain) ent;
-			String aLoginUserName = getLoginUser().getName();
+			String aLoginUserName = loginUser.getName();
 			UnixUser domUser = dom.getUser();
 			Pac domPac = domUser.getPac();
 			boolean isDomAdmin = aLoginUserName.equals(domUser.getName());
 			boolean isPacAdmin = aLoginUserName.equals(domPac.getName());
 			boolean isCustomer = aLoginUserName.equals(domPac.getCustomer().getName());
-			boolean isHostmaster = getLoginUser().hasHostmasterRole();
+			boolean isHostmaster = loginUser.hasHostmasterRole();
 			if (!isDomAdmin && !isPacAdmin && !isCustomer && !isHostmaster) {
-				throw new AuthorisationException(getLoginUser(), method, dom);
+				throw new AuthorisationException(loginUser, method, dom);
 			}
 		} else {
-			throw new AuthorisationException(getLoginUser(), method, ent);
+			throw new AuthorisationException(loginUser, method, ent);
 		}
 	}
 
 	private void needsWriteAccessOn(AbstractEntity ent, String method) throws AuthorisationException {
-		UnixUser loginUser = getLoginUser();
+		UnixUser loginUser = getTransaction().getLoginUser();
 		if (ent instanceof Domain) {
 			Domain dom = (Domain) ent;
 			String aLoginUserName = loginUser.getName();
diff --git a/hsarback/src/de/hsadmin/mods/email/EMailAddress.java b/hsarback/src/de/hsadmin/mods/email/EMailAddress.java
index 4e8434e..a62a54c 100644
--- a/hsarback/src/de/hsadmin/mods/email/EMailAddress.java
+++ b/hsarback/src/de/hsadmin/mods/email/EMailAddress.java
@@ -20,6 +20,7 @@
 import de.hsadmin.core.model.EntityInfo;
 import de.hsadmin.core.model.FieldValidation;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.dom.Domain;
 import de.hsadmin.mods.user.UnixUser;
@@ -34,6 +35,7 @@
 @SearchFilter("domain.user = :loginUser OR "
 		+ "domain.user.pac = :loginUserPac OR "
 		+ "domain.user.pac.customer.name = :loginUserName")
+@ModuleImpl(de.hsadmin.mods.email.EMailAddressModuleImpl.class)
 public class EMailAddress extends AbstractEntity implements Serializable {
 	
 	private static final long serialVersionUID = -2265500181746604429L;
diff --git a/hsarback/src/de/hsadmin/mods/email/EMailAddressModuleImpl.java b/hsarback/src/de/hsadmin/mods/email/EMailAddressModuleImpl.java
index 976e277..5dbd112 100644
--- a/hsarback/src/de/hsadmin/mods/email/EMailAddressModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/email/EMailAddressModuleImpl.java
@@ -9,7 +9,9 @@
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.dom.Domain;
+import de.hsadmin.mods.user.UnixUser;
 
 public class EMailAddressModuleImpl extends AbstractModuleImpl {
 
@@ -46,23 +48,25 @@
 
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
+		Transaction transaction = getTransaction();
+		UnixUser loginUser = transaction.getLoginUser();
 		EMailAddress detachedAddr = (EMailAddress) existingEntity;
-		EntityManager em = getTransaction().getEntityManager();
+		EntityManager em = transaction.getEntityManager();
 		EMailAddress attachedAddr = em.find(EMailAddress.class, detachedAddr.getId());
 		String domain = detachedAddr.getDomain().getName();
 		if (domain != null && !domain.equals(attachedAddr.getDomain().getName())) {
 			detachedAddr.setDomain(attachedAddr.getDomain());
-			throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "domain");
+			throw new AuthorisationException(loginUser, "update", detachedAddr, "domain");
 		}
 		String subdomain = detachedAddr.getSubdomain();
 		if (subdomain != null && !subdomain.equals(attachedAddr.getSubdomain())) {
 			detachedAddr.setSubdomain(attachedAddr.getSubdomain());
-			throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "subdomain");
+			throw new AuthorisationException(loginUser, "update", detachedAddr, "subdomain");
 		}
 		String localPart = detachedAddr.getLocalpart();
 		if (localPart != null && !localPart.equals(attachedAddr.getLocalpart())) {
 			detachedAddr.setLocalpart(attachedAddr.getLocalpart());
-			throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "localpart");
+			throw new AuthorisationException(loginUser, "update", detachedAddr, "localpart");
 		}
 		String target = detachedAddr.getTarget();
 		if (target == null) {
diff --git a/hsarback/src/de/hsadmin/mods/email/EMailAlias.java b/hsarback/src/de/hsadmin/mods/email/EMailAlias.java
index da9b01d..5678a4e 100644
--- a/hsarback/src/de/hsadmin/mods/email/EMailAlias.java
+++ b/hsarback/src/de/hsadmin/mods/email/EMailAlias.java
@@ -17,9 +17,9 @@
 import javax.persistence.Table;
 
 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.ModuleImpl;
 import de.hsadmin.core.model.SearchFilter;
 import de.hsadmin.mods.pac.Pac;
 import de.hsadmin.mods.user.UnixUser;
@@ -33,6 +33,7 @@
 @SequenceGenerator(name = "EMailAliasesSeqGen", sequenceName = "emailalias_emailalias_id_seq")
 @EntityInfo(name = "E-Mail-Alias")
 @SearchFilter("obj.pac = :loginUserPac OR obj.pac.customer.name = :loginUserName")
+@ModuleImpl(de.hsadmin.mods.email.EMailAliasModuleImpl.class)
 public class EMailAlias extends AbstractEntity implements Serializable {
 	
 	private static final long serialVersionUID = -4711415079723587161L;
@@ -73,18 +74,14 @@
 	@Override
 	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)
 				Entity entityAnnot = Pac.class.getAnnotation(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());
+				query.setParameter("loginUser", loginUser);
+				query.setParameter("loginUserName", loginUser.getName());
+				query.setParameter("loginUserPac", loginUser.getPac());
 				pac = (Pac) query.getSingleResult();
 			} catch (NoResultException exc) {
 				throw new SecurityException("packet '" + pacName + "' not found or access denied");
diff --git a/hsarback/src/de/hsadmin/mods/email/EMailAliasModuleImpl.java b/hsarback/src/de/hsadmin/mods/email/EMailAliasModuleImpl.java
index f549199..9cf2ce6 100644
--- a/hsarback/src/de/hsadmin/mods/email/EMailAliasModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/email/EMailAliasModuleImpl.java
@@ -9,7 +9,9 @@
 import de.hsadmin.core.model.AbstractModuleImpl;
 import de.hsadmin.core.model.AuthorisationException;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.pac.Pac;
+import de.hsadmin.mods.user.UnixUser;
 
 public class EMailAliasModuleImpl extends AbstractModuleImpl {
 
@@ -24,18 +26,20 @@
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
+		Transaction transaction = getTransaction();
+		UnixUser loginUser = transaction.getLoginUser();
 		EMailAlias alias = (EMailAlias) newEntity;
 		String name = alias.getName();
 		if (name.length() > 5 && (name.charAt(5) != '-') || name.length() == 6) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		EntityManager em = getTransaction().getEntityManager();
 		Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
 		qPac.setParameter("pacName", name.substring(0, 5));
 		Object singleResult = qPac.getSingleResult();
 		Pac pac = (Pac) singleResult;
-		if (pac == null || !pac.isReadAllowedFor(getLoginUser())) {
-			throw new AuthorisationException(getLoginUser(), "add", newEntity);
+		if (pac == null || !pac.isReadAllowedFor(loginUser)) {
+			throw new AuthorisationException(loginUser, "add", newEntity);
 		}
 		return super.add(newEntity);
 	}
diff --git a/hsarback/src/de/hsadmin/mods/pac/Pac.java b/hsarback/src/de/hsadmin/mods/pac/Pac.java
index ab5bf61..b7e36c5 100644
--- a/hsarback/src/de/hsadmin/mods/pac/Pac.java
+++ b/hsarback/src/de/hsadmin/mods/pac/Pac.java
@@ -26,6 +26,7 @@
 
 import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.EntityInfo;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.mods.cust.Customer;
 import de.hsadmin.mods.user.UnixUser;
 
@@ -33,6 +34,7 @@
 @Table(name = "packet")
 @SequenceGenerator(name = "PacsSeqGen", sequenceName = "packet_packet_id_seq")
 @EntityInfo(name = "Paket")
+@ModuleImpl(de.hsadmin.mods.pac.PacModuleImpl.class)
 public class Pac extends AbstractEntity implements Serializable {
 	
 	private static final long serialVersionUID = 1L;
diff --git a/hsarback/src/de/hsadmin/mods/pac/PacModuleImpl.java b/hsarback/src/de/hsadmin/mods/pac/PacModuleImpl.java
index 8b1ec24..b09b3f5 100644
--- a/hsarback/src/de/hsadmin/mods/pac/PacModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/pac/PacModuleImpl.java
@@ -112,7 +112,7 @@
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity)
 			throws HSAdminException {
-		throw new AuthorisationException(getLoginUser(), "update", existingEntity);
+		throw new AuthorisationException(getTransaction().getLoginUser(), "update", existingEntity);
 	}
 
 	@Override
@@ -122,7 +122,7 @@
 		String pacName = pac.getName();
 		Date dateCancelled = pac.getCancelled();
 		if (dateCancelled == null || dateCancelled.getTime() > System.currentTimeMillis()) {
-			throw new AuthorisationException(getLoginUser(), "delete", existingEntity);
+			throw new AuthorisationException(getTransaction().getLoginUser(), "delete", existingEntity);
 		}
 		GenericModuleImpl helperModule = new GenericModuleImpl(getTransaction());
 		
diff --git a/hsarback/src/de/hsadmin/mods/user/UnixUser.java b/hsarback/src/de/hsadmin/mods/user/UnixUser.java
index baf97a1..14a7519 100644
--- a/hsarback/src/de/hsadmin/mods/user/UnixUser.java
+++ b/hsarback/src/de/hsadmin/mods/user/UnixUser.java
@@ -19,6 +19,7 @@
 import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.EntityInfo;
 import de.hsadmin.core.model.FieldValidation;
+import de.hsadmin.core.model.ModuleImpl;
 import de.hsadmin.core.util.Config;
 import de.hsadmin.mods.pac.Pac;
 
@@ -26,6 +27,7 @@
 @Table(name = "unixuser")
 @SequenceGenerator(name = "UnixUsersSeqGen", sequenceName = "unixuser_unixuser_id_seq")
 @EntityInfo(name = "UNIX-Zugang/Mailbox")
+@ModuleImpl(de.hsadmin.mods.user.UnixUserModuleImpl.class)
 public class UnixUser extends AbstractEntity implements Serializable {
 	
 	private static final long serialVersionUID = 7823071611805642906L;
@@ -187,23 +189,16 @@
 		this.homedir = homedir;
 	}
 
-	/**
-	 * returns true if the user has the default homedir path
-	 */
 	public boolean isDefaultHomedir() {
 		return getHomedir().equals(getDefaultHomedir());
 	}
 
-	/**
-	 * returns the default homedir path
-	 */
 	private String getDefaultHomedir() {
 		String pacName = pac.getName();
 		if (name.equals(pacName))
 			return "/home/pacs/" + pacName;
 		else
-			return "/home/pacs/" + pacName + "/users/"
-					+ name.substring(pacName.length() + 1);
+			return "/home/pacs/" + pacName + "/users/" + name.substring(pacName.length() + 1);
 	}
 
 	public boolean isLocked() {
@@ -266,40 +261,22 @@
 		return getPac().getAdminUser(em);
 	}
 
-	/**
-	 * determines whether this user account is a hostmaster account
-	 */
 	public boolean hasHostmasterRole() {
 		// TODO: hardcoded Hostsharing conventions
 		String login = getName();
 		return login.length() == 2 || ((login.startsWith(Config.getInstance().getProperty("accountprefix.hostmaster", "hsh01") + "-") && login.length() == 8));
 	}
 
-	/**
-	 * determines whether this user account has rights on the given customer
-	 */
 	public boolean hasCustomerRoleFor(de.hsadmin.mods.cust.Customer cust) {
 		// TODO: hardcoded Hostsharing conventions
 		return getName().equals(cust.getName()) || hasHostmasterRole();
 	}
 
-	/**
-	 * determines whether this user account has admin rights on the given pac
-	 */
 	public boolean hasPacAdminRoleFor(de.hsadmin.mods.pac.Pac pac) {
 		return pac != null && 
 			(pac.getName().equals(getName())
 				|| hasCustomerRoleFor(pac.getCustomer()) );
 	}
-
-	/**
-	 * determines whether this user account has admin rights on the given dom
-	 */
-//	public boolean hasDomAdminRoleFor(de.hsadmin.mods.dom.Domain dom) {
-//		// TODO: hardcoded Hostsharing conventions
-//		return this.getId() == dom.getUser().getId()
-//				|| hasPacAdminRoleFor(dom.getUser().getPac());
-//	}
 
 	@Override
 	public boolean isWriteAllowedFor(UnixUser loginUser) {
diff --git a/hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java b/hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java
index ba273e6..111c123 100644
--- a/hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java
+++ b/hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java
@@ -10,6 +10,7 @@
 import de.hsadmin.core.model.AbstractEntity;
 import de.hsadmin.core.model.AbstractModuleImpl;
 import de.hsadmin.core.model.HSAdminException;
+import de.hsadmin.core.model.Transaction;
 import de.hsadmin.mods.pac.Pac;
 
 public class UnixUserModuleImpl extends AbstractModuleImpl {
@@ -20,19 +21,14 @@
 	@Override
 	public AbstractEntity initialize(AbstractEntity newEntity) throws AuthorisationException {
 		UnixUser newUnixUser = (UnixUser) super.initialize(newEntity);
-		newUnixUser.setName(getLoginUser().getPac().getName() + '-');
+		newUnixUser.setName(getTransaction().getLoginUser().getPac().getName() + '-');
 		return newUnixUser;
 	}
 
 	@Override
 	public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
-		// do query
 		UnixUser res = (UnixUser) super.find(entityClass, key);
-
-		// check access rights
 		needsPartialAccessOnPacOf(res, "find");
-
-		// return clean result
 		return res;
 	}
 
@@ -73,7 +69,9 @@
 
 	@Override
 	public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
-		EntityManager em = getEntityManager();
+		Transaction transaction = getTransaction();
+		EntityManager em = transaction.getEntityManager();
+		UnixUser loginUser = transaction.getLoginUser();
 		// only allow pac which matches the username (TODO: hard coded
 		// Hostsharing convention)
 		UnixUser newUnixUser = (UnixUser) newEntity;
@@ -85,18 +83,18 @@
 		String userName = name.toLowerCase().trim();
 		for (char c : userName.toCharArray()) {
 			if (!(Character.isLetterOrDigit(c) || c == '.' || c == '-' || c == '_')) {
-				throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
+				throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
 			}
 		}
 		if (userName.length() < 7 || userName.charAt(5) != '-' || userName.lastIndexOf('-') > 5) {
-			throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
+			throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
 		}
 		String passWord = newUnixUser.getPassword();
 		if (passWord == null || passWord.length() == 0) {
 			throw new HSAdminException("password is required");
 		}
 		if (passWord.indexOf(':') >= 0) {
-			throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
+			throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
 		}
 		if (newUnixUser.getPac() == null || newUnixUser.getPac().getNew()) {
 			
@@ -124,7 +122,7 @@
 			q.setParameter("pac", pac);
 			List<?> idOfSamePac = q.getResultList();
 			if (idOfSamePac.size() == 0) {
-				throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
+				throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
 			}
 		}
 
@@ -142,43 +140,41 @@
 
 	@Override
 	public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
-		// get the entity from the database
+		Transaction transaction = getTransaction();
+		UnixUser loginUser = transaction.getLoginUser();
+		EntityManager em = transaction.getEntityManager();
 		UnixUser detachedUnixUser = (UnixUser) existingEntity;
-		UnixUser attachedUnixUser = getEntityManager().find(detachedUnixUser.getClass(),
-				detachedUnixUser.getId());
-
-		// authorisation check
+		UnixUser attachedUnixUser = em.find(detachedUnixUser.getClass(), detachedUnixUser.getId());
 		needsFullAccessOnUser(attachedUnixUser, "update");
-
-		// update fields where the login user has write access
-		if (attachedUnixUser.getUserId() != detachedUnixUser.getUserId())
-			throw new AuthorisationException(getLoginUser(), "update",
-					detachedUnixUser, "id");
-		attachedUnixUser.setName(detachedUnixUser.getName());
+		if (attachedUnixUser.getUserId() != detachedUnixUser.getUserId()) {
+			throw new AuthorisationException(loginUser, "update", detachedUnixUser, "id");
+		}
+		if (!attachedUnixUser.getName().equals(detachedUnixUser.getName())) {
+			throw new AuthorisationException(loginUser, "update", detachedUnixUser, "name");
+		}
 		attachedUnixUser.setPassword(detachedUnixUser.getPassword());
-		if (hasFullAccessOnPacOf(attachedUnixUser))
+		if (hasFullAccessOnPacOf(attachedUnixUser)) {
 			attachedUnixUser.setComment(detachedUnixUser.getComment());
-		else if (!attachedUnixUser.getComment().equals(
-				detachedUnixUser.getComment()))
-			throw new AuthorisationException(getLoginUser(), "update",
-					detachedUnixUser, "comment");
-		if (hasFullAccessOnPacOf(attachedUnixUser))
 			attachedUnixUser.setHomedir(detachedUnixUser.getHomedir());
-		else if (!attachedUnixUser.getHomedir().equals(
-				detachedUnixUser.getHomedir()))
-			throw new AuthorisationException(getLoginUser(), "update",
-					detachedUnixUser, "homedir");
+		} else {
+			if (!attachedUnixUser.getComment().equals(detachedUnixUser.getComment())) {
+				throw new AuthorisationException(loginUser, "update", detachedUnixUser, "comment");
+			}
+			if (!attachedUnixUser.getHomedir().equals(detachedUnixUser.getHomedir())) {
+				throw new AuthorisationException(loginUser, "update", detachedUnixUser, "homedir");
+			}
+		}
 		if (!attachedUnixUser.getShell().equals(detachedUnixUser.getShell()))
 			if (hasFullAccessOnPacOf(attachedUnixUser)
 					|| isLoginShell(attachedUnixUser.getShell())
 					|| !isLoginShell(detachedUnixUser.getShell()))
 				attachedUnixUser.setShell(detachedUnixUser.getShell());
 			else
-				throw new AuthorisationException(getLoginUser(), "update",
+				throw new AuthorisationException(loginUser, "update",
 						detachedUnixUser, "shell");
-		if (attachedUnixUser.isLocked() != detachedUnixUser.isLocked())
-			throw new AuthorisationException(getLoginUser(), "update",
-					detachedUnixUser, "locked");
+		if (attachedUnixUser.isLocked() != detachedUnixUser.isLocked()) {
+			throw new AuthorisationException(loginUser, "update", detachedUnixUser, "locked");
+		}
 		if (detachedUnixUser.getQuotaSoftlimit() != null) {
 			if (hasFullAccessOnPacOf(attachedUnixUser)) {
 				attachedUnixUser.setQuotaSoftlimit(detachedUnixUser.getQuotaSoftlimit());
@@ -189,21 +185,20 @@
 			else {
 				Integer oldQuota = attachedUnixUser.getQuotaSoftlimit();
 				Integer newQuota = detachedUnixUser.getQuotaSoftlimit();
-				if (oldQuota != newQuota && !oldQuota.equals(newQuota))
-					throw new AuthorisationException(getLoginUser(), "update",
-							detachedUnixUser, "quota");
+				if (oldQuota != newQuota && !oldQuota.equals(newQuota)) {
+					throw new AuthorisationException(loginUser, "update", detachedUnixUser, "quota");
+				}
 			}
 		}
-
-		// update entity
 		return super.update(attachedUnixUser);
 	}
 
 	@Override
 	public void delete(AbstractEntity existingEntity) throws HSAdminException {
 		// get the entity from the database
+		EntityManager entityManager = getTransaction().getEntityManager();
 		UnixUser detachedUnixUser = (UnixUser) existingEntity;
-		UnixUser attachedUnixUser = getEntityManager().find(detachedUnixUser.getClass(),
+		UnixUser attachedUnixUser = entityManager.find(detachedUnixUser.getClass(),
 				detachedUnixUser.getId());
 
 		// authorisation check
@@ -216,16 +211,14 @@
 		super.delete(attachedUnixUser);
 	}
 
-	private EntityManager getEntityManager() {
-		return getTransaction().getEntityManager();
-	}
-
 	// throws an AuthorisationException if the login user has no write acess
 	// on the pac of the given UnixUser
 	private boolean hasFullAccessOnPacOf(UnixUser user) {
-		return getLoginUser().hasHostmasterRole()
-			|| getLoginUser().getName().equals(user.getPac().getName()) 
-			|| getLoginUser().getName().equals(user.getPac().getCustomer().getName());
+		UnixUser loginUser = getTransaction().getLoginUser();
+		String loginUserName = loginUser.getName();
+		return loginUser.hasHostmasterRole()
+			|| loginUserName.equals(user.getPac().getName()) 
+			|| loginUserName.equals(user.getPac().getCustomer().getName());
 	}
 
 	// throws an AuthorisationException if the login user has no write acess
@@ -233,31 +226,24 @@
 	private void needsFullAccessOnPacOf(UnixUser user, String method)
 			throws AuthorisationException {
 		if (!hasFullAccessOnPacOf(user))
-			throw new AuthorisationException(getLoginUser(), method, user);
+			throw new AuthorisationException(getTransaction().getLoginUser(), method, user);
 	}
 
-	// throws an AuthorisationException if the login user has no read acess on
-	// the pac of the given UnixUser
-	private void needsPartialAccessOnPacOf(UnixUser user, String method)
-			throws AuthorisationException {
-		if (!hasFullAccessOnPacOf(user)
-				&& getLoginUser().getPac().id() != user.getPac().id())
-			throw new AuthorisationException(getLoginUser(), method, user);
+	private void needsPartialAccessOnPacOf(UnixUser user, String method) throws AuthorisationException {
+		UnixUser loginUser = getTransaction().getLoginUser();
+		if (!hasFullAccessOnPacOf(user) && loginUser.getPac().id() != user.getPac().id()) {
+			throw new AuthorisationException(loginUser, method, user);
+		}
 	}
 
-	// throws an AuthorisationException if the login user has not even partial
-	// write access on the given UnixUser
-	private void needsFullAccessOnUser(UnixUser user, String method)
-			throws AuthorisationException {
-		// neither pac admin (same name as pac), pac owner (customer) nor the
-		// user itself?
-		if (!hasFullAccessOnPacOf(user) && !getLoginUser().sameIdAs(user))
-			throw new AuthorisationException(getLoginUser(), method, user);
+	private void needsFullAccessOnUser(UnixUser user, String method) throws AuthorisationException {
+		UnixUser loginUser = getTransaction().getLoginUser();
+		if (!hasFullAccessOnPacOf(user) && !loginUser.sameIdAs(user)) {
+			throw new AuthorisationException(loginUser, method, user);
+		}
 	}
 
-	// returns true if the given shell is a login shell
 	private static boolean isLoginShell(String shell) {
-		// TODO: list of login shells should not be hardcoded
 		if (shell.equals("/bin/sh"))
 			return true;
 		if (shell.equals("/bin/bash"))
diff --git a/hsarback/test/de/hsadmin/remote/RemoteTest.java b/hsarback/test/de/hsadmin/remote/RemoteTest.java
index fbdc922..5300cc7 100644
--- a/hsarback/test/de/hsadmin/remote/RemoteTest.java
+++ b/hsarback/test/de/hsadmin/remote/RemoteTest.java
@@ -6,18 +6,18 @@
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
 	InitDataTest.class,
-//	PacTest.class,
-//	UnixUserTest.class,
-//	MysqlUserTest.class,
-//	MysqlDbTest.class,
-//	PgsqlUserTest.class,
-//	PgsqlDbTest.class,
-//	EMailAliasTest.class,
-//	DomainTest.class,
-//	EMailAddressTest.class,
-//	CustomerTest.class
+	PacTest.class,
+	UnixUserTest.class,
+	MysqlUserTest.class,
+	MysqlDbTest.class,
+	PgsqlUserTest.class,
+	PgsqlDbTest.class,
+	EMailAliasTest.class,
+	DomainTest.class,
+	EMailAddressTest.class,
+	CustomerTest.class,
 //	HostmasterTest.class,
-//	QueueTaskTest.class
+	QueueTaskTest.class
 })
 
 public class RemoteTest {

--
Gitblit v1.9.1