package de.hsadmin.mods.dom; import java.util.Date; import java.util.LinkedList; import java.util.List; 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.HSAdminException; import de.hsadmin.mods.dom.Domain.Status; import de.hsadmin.mods.email.EMailAddress; import de.hsadmin.mods.pac.Pac; import de.hsadmin.mods.user.UnixUser; public class DomainModuleImpl extends AbstractModuleImpl { @Override public AbstractEntity initialize(AbstractEntity newEntity) throws AuthorisationException { AbstractEntity newDom = super.initialize(newEntity); if (newDom instanceof Domain) { ((Domain) newDom).setUser(getTransaction().getLoginUser()); return newDom; } return null; } @Override public AbstractEntity find(Class entityClass, Object key) throws HSAdminException { // do query AbstractEntity res = super.find(entityClass, key); // check access rights needsReadAccessOn(res, "find"); // return clean result return res; } @Override public AbstractEntity findByString(Class entityClass, String key) throws HSAdminException { // do query AbstractEntity res = super.findByString(entityClass, key); // check access rights if (res != null) needsReadAccessOn(res, "findByString"); // return clean result return res; } @Override public List search(Class entityClass, String condition, String orderBy) throws HSAdminException { // do query if (orderBy == null || orderBy.length() == 0) { orderBy = "ORDER BY obj.name ASC"; } List res = super.search(entityClass, condition, orderBy); List ret = new LinkedList(); // remove entities where login user has no access rights for (AbstractEntity entity : res) { try { needsReadAccessOn(entity, "search"); ret.add(entity); } catch (AuthorisationException exc) { } // ignore } // return clean result return ret; } @Override public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException { Domain dom = (Domain) newEntity; Date now = new Date(); dom.setFiled(now); dom.setStatus(Status.SELF); dom.setStatusChanged(now); dom.setDnsMaster("dns.hostsharing.net"); if (dom.getName() == null || dom.getName().length() == 0) { throw new HSAdminException("domain name required"); } UnixUser admin = dom.getUser(); if (admin == null || admin.getName() == null || admin.getName().length() == 0) { throw new HSAdminException("domain admin required"); } EntityManager em = getTransaction().getEntityManager(); 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"); String superior = dom.getName(); while (superior.contains(".")) { if (dom.isPacDomain()) { break; } superior = superior.substring(superior.indexOf('.') + 1); domainQuery.setParameter("domainName", superior); List resultList = domainQuery.getResultList(); if (resultList.size() > 0) { Domain superDom = (Domain) resultList.get(0); if (superDom.isPacDomain()) { throw new HSAdminException("subdomains to pacdomain " + superDom.getName() + " are not allowed"); } if (loginUser.hasPacAdminRoleFor(superDom.getUser().getPac())) { break; // same pac } if (loginUser.hasCustomerRoleFor(superDom.getUser().getPac().getCustomer())) { break; // same customer } } } } Query adminQuery = em.createQuery("SELECT u FROM UnixUsers u WHERE u.name = :adminName"); adminQuery.setParameter("adminName", admin.getName()); dom.setUser((UnixUser) adminQuery.getSingleResult()); needsWriteAccessOn(newEntity, "add"); em.persist(dom); if (dom.isPacDomain()) { em.persist(new EMailAddress("owner", "", dom, dom.getUser().getPac().getCustomer().getName().substring(6) + "@hostsharing.net")); em.persist(new EMailAddress("admin", "", dom, dom.getUser().getPac().getName() + "@hostsharing.net")); em.persist(new EMailAddress(dom.getUser().getPac().getName(), "", dom, dom.getUser().getPac().getName() + "@hostsharing.net")); } else { em.persist(new EMailAddress("abuse", "", dom, admin.getName())); em.persist(new EMailAddress("postmaster", "", dom, admin.getName())); em.persist(new EMailAddress("webmaster", "", dom, admin.getName())); } return super.add(dom); } @Override public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException { Domain updatedDom = (Domain) existingEntity; if (updatedDom.getName() == null || updatedDom.getName().length() == 0) { throw new HSAdminException("domain name required"); } UnixUser loginUser = getTransaction().getLoginUser(); EntityManager em = getTransaction().getEntityManager(); Domain oldDom = em.find(Domain.class, updatedDom.getId()); UnixUser admin = updatedDom.getUser(); if (admin == null || admin.getName() == null || admin.getName().length() == 0) { throw new HSAdminException("domain admin required"); } if (!admin.getName().equals(oldDom.getUser().getName())) { throw new AuthorisationException(loginUser, "update", existingEntity, "user"); } Query q = em.createQuery("SELECT opt FROM " + DomainOption.class.getAnnotation(javax.persistence.Entity.class).name() + " opt WHERE opt.name=:optName"); for (DomainOption opt : updatedDom.getDomainOptions()) { q.setParameter("optName", opt.getName()); List list = q.getResultList(); if (list.size() != 1) { throw new HSAdminException("invalid domain option: " + opt.getName()); } } needsWriteAccessOn(existingEntity, "update"); return super.update(existingEntity); } @Override public void delete(AbstractEntity existingEntity) throws HSAdminException { needsWriteAccessOn(existingEntity, "delete"); Domain dom = (Domain) existingEntity; EntityManager em = getTransaction().getEntityManager(); Query query = em.createQuery("SELECT adr FROM " + EMailAddress.class.getAnnotation(javax.persistence.Entity.class).name() + " adr WHERE adr.domain.name='" + dom.getName() + "'"); List resultList = query.getResultList(); for (Object obj : resultList) { EMailAddress eMailAddress = (EMailAddress) obj; em.remove(eMailAddress); } super.delete(existingEntity); } private void needsReadAccessOn(AbstractEntity ent, String method) throws AuthorisationException { UnixUser loginUser = getTransaction().getLoginUser(); if (ent instanceof Domain) { Domain dom = (Domain) ent; 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 = loginUser.hasHostmasterRole(); if (!isDomAdmin && !isPacAdmin && !isCustomer && !isHostmaster) { throw new AuthorisationException(loginUser, method, dom); } } else { throw new AuthorisationException(loginUser, method, ent); } } private void needsWriteAccessOn(AbstractEntity entity, String method) throws AuthorisationException { UnixUser loginUser = getTransaction().getLoginUser(); if (entity instanceof Domain) { Domain dom = (Domain) entity; String aLoginUserName = loginUser.getName(); UnixUser domUser = dom.getUser(); Pac domPac = domUser.getPac(); boolean isDomAdmin = aLoginUserName.equals(domUser.getName()); boolean isPacAdmin = loginUser.hasPacAdminRoleFor(domPac); boolean isCustomer = aLoginUserName.equals(domPac.getCustomer().getName()); boolean isHostmaster = loginUser.hasHostmasterRole(); if (!isPacAdmin && !isCustomer && !isHostmaster) { if (!isDomAdmin && !"update".equals(method)) { throw new AuthorisationException(loginUser, method, dom); } } if (dom.isPacDomain() && !dom.getUser().getName().equals(domPac.getName())) { throw new AuthorisationException(loginUser, method, dom); } if (dom.isPacDomain() && !isHostmaster && !"add".equals(method)) { throw new AuthorisationException(loginUser, method, dom); } } else { throw new AuthorisationException(loginUser, method, entity); } } }