hs.hsadmin/hsarback/src/de/hsadmin/mods/user/UnixUserModuleImpl.java

274 lines
10 KiB
Java
Raw Normal View History

2010-10-01 21:52:51 +02:00
package de.hsadmin.mods.user;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AuthorisationException;
2010-10-04 19:44:49 +02:00
import de.hsadmin.core.model.AbstractEntity;
2010-10-01 21:52:51 +02:00
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.model.Transaction;
import de.hsadmin.hostsharing.MultiOption;
2010-10-01 21:52:51 +02:00
import de.hsadmin.mods.pac.Pac;
public class UnixUserModuleImpl extends AbstractModuleImpl {
public UnixUserModuleImpl() {
}
@Override
2010-10-04 19:44:49 +02:00
public AbstractEntity initialize(AbstractEntity newEntity) throws AuthorisationException {
2010-10-01 21:52:51 +02:00
UnixUser newUnixUser = (UnixUser) super.initialize(newEntity);
newUnixUser.setName(getTransaction().getLoginUser().getPac().getName() + '-');
2010-10-01 21:52:51 +02:00
return newUnixUser;
}
@Override
2010-10-04 19:44:49 +02:00
public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
2010-10-01 21:52:51 +02:00
UnixUser res = (UnixUser) super.find(entityClass, key);
needsPartialAccessOnPacOf(res, "find");
return res;
}
@Override
2010-10-04 19:44:49 +02:00
public AbstractEntity findByString(Class<? extends AbstractEntity> entityClass, String key) throws HSAdminException {
2010-10-01 21:52:51 +02:00
// do query
UnixUser res = (UnixUser) super.findByString(entityClass, key);
// return directly (checking rights already done in search within
// findByString)
return res;
}
@Override
2010-10-04 19:44:49 +02:00
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
2010-10-01 21:52:51 +02:00
// do query
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY obj.name ASC";
}
2010-10-04 19:44:49 +02:00
List<AbstractEntity> res = super.search(entityClass, condition, orderBy);
List<AbstractEntity> ret = new LinkedList<AbstractEntity>();
2010-10-01 21:52:51 +02:00
// remove entities where login user has no access rights
if (res != null) {
2010-10-04 19:44:49 +02:00
for (AbstractEntity entity : res) {
2010-10-01 21:52:51 +02:00
try {
UnixUser returnedUnixUser = (UnixUser) entity;
needsPartialAccessOnPacOf(returnedUnixUser, "search");
ret.add(returnedUnixUser);
} catch (AuthorisationException exc) {
} // ignore
}
}
// return clean result
return ret;
}
@Override
2010-10-04 19:44:49 +02:00
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
Transaction transaction = getTransaction();
EntityManager em = transaction.getEntityManager();
UnixUser loginUser = transaction.getLoginUser();
2010-10-01 21:52:51 +02:00
// only allow pac which matches the username (TODO: hard coded
// Hostsharing convention)
UnixUser newUnixUser = (UnixUser) newEntity;
// validation of username and password
String name = newUnixUser.getName();
if (name == null) {
throw new HSAdminException("username is required");
}
String userName = name.toLowerCase().trim();
for (char c : userName.toCharArray()) {
if (!(Character.isLetterOrDigit(c) || c == '.' || c == '-' || c == '_')) {
throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
2010-10-01 21:52:51 +02:00
}
}
if (userName.length() < 7 || userName.charAt(5) != '-' || userName.lastIndexOf('-') > 5) {
throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
2010-10-01 21:52:51 +02:00
}
String passWord = newUnixUser.getPassword();
if (passWord == null || passWord.length() == 0) {
throw new HSAdminException("password is required");
}
if (passWord.indexOf(':') >= 0) {
throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
2010-10-01 21:52:51 +02:00
}
Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
qPac.setParameter("pacName", userName.substring(0, 5));
2010-10-05 21:42:07 +02:00
Object singleResult = qPac.getSingleResult();
Pac pac = (Pac) singleResult;
2010-10-01 21:52:51 +02:00
newUnixUser.setName(userName);
newUnixUser.setHomedir("/home/pacs/" + userName.substring(0, 5) + "/users/" + userName.substring(6));
// no appropriate uid?
if (newUnixUser.getUserId() < 1000) {
// determine next free uid
long nUID = 20000;
Query qUID = em.createQuery("SELECT MAX(u.userId) FROM UnixUsers u");
Long maxUid = (Long) qUID.getSingleResult();
if (maxUid >= nUID)
nUID = maxUid + 1;
newUnixUser.setUserId(nUID);
} else {
// given uid belongs to same pac?
Query q = em.createQuery("SELECT u.userId FROM UnixUsers u WHERE u.userId = :userId");
q.setParameter("userId", newUnixUser.getUserId());
List<?> idExists = q.getResultList();
q = em.createQuery("SELECT u.userId FROM UnixUsers u WHERE u.userId = :userId AND u.pac = :pac");
2010-10-01 21:52:51 +02:00
q.setParameter("userId", newUnixUser.getUserId());
q.setParameter("pac", pac);
List<?> idOfSamePac = q.getResultList();
if (idOfSamePac.isEmpty() && !idExists.isEmpty()) {
throw new AuthorisationException(loginUser, "add", newUnixUser, "userId");
2010-10-01 21:52:51 +02:00
}
}
2013-04-29 20:01:09 +02:00
//TODO: Needs better implementation
String pacType = pac.getBasepac().getName();
if (!pacType.equals(Pac.PAC_WEB) && !pacType.equals(Pac.PAC_DW) && !pacType.equals(Pac.PAC_SW)) {
throw new HSAdminException("not allowed for this packet type");
}
//TODO: Needs better implementation
Query qUnixUsers = em.createQuery("SELECT obj FROM UnixUsers obj WHERE obj.id = :pacId");
qUnixUsers.setParameter("pacId", pac.getId());
if (qUnixUsers.getResultList().size() >= MultiOption.UNIXUSERS_PER_OPTION * pac.getQuantityByComponentName("MULTI")) {
2013-04-29 20:01:09 +02:00
throw new HSAdminException("included unix users exceeded");
}
2010-10-01 21:52:51 +02:00
// don't move this up, it will update the new entity still with wrong
// userid!
newUnixUser.setPac(pac);
newUnixUser.init();
// authorisation check
needsFullAccessOnPacOf(newUnixUser, "add");
// add new entity
return super.add(newEntity);
}
@Override
2010-10-04 19:44:49 +02:00
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
Transaction transaction = getTransaction();
UnixUser loginUser = transaction.getLoginUser();
EntityManager em = transaction.getEntityManager();
2010-10-01 21:52:51 +02:00
UnixUser detachedUnixUser = (UnixUser) existingEntity;
UnixUser attachedUnixUser = em.find(detachedUnixUser.getClass(), detachedUnixUser.getId());
2010-10-01 21:52:51 +02:00
needsFullAccessOnUser(attachedUnixUser, "update");
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");
}
2010-10-01 21:52:51 +02:00
attachedUnixUser.setPassword(detachedUnixUser.getPassword());
if (hasFullAccessOnPacOf(attachedUnixUser)) {
2010-10-01 21:52:51 +02:00
attachedUnixUser.setComment(detachedUnixUser.getComment());
attachedUnixUser.setHomedir(detachedUnixUser.getHomedir());
} 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");
}
}
2010-10-01 21:52:51 +02:00
if (!attachedUnixUser.getShell().equals(detachedUnixUser.getShell()))
if (hasFullAccessOnPacOf(attachedUnixUser)
|| isLoginShell(attachedUnixUser.getShell())
|| !isLoginShell(detachedUnixUser.getShell()))
attachedUnixUser.setShell(detachedUnixUser.getShell());
else
throw new AuthorisationException(loginUser, "update",
2010-10-01 21:52:51 +02:00
detachedUnixUser, "shell");
if (attachedUnixUser.isLocked() != detachedUnixUser.isLocked()) {
throw new AuthorisationException(loginUser, "update", detachedUnixUser, "locked");
}
2010-10-01 21:52:51 +02:00
if (detachedUnixUser.getQuotaSoftlimit() != null) {
if (hasFullAccessOnPacOf(attachedUnixUser)) {
attachedUnixUser.setQuotaSoftlimit(detachedUnixUser.getQuotaSoftlimit());
if (detachedUnixUser.getQuotaHardlimit() != null) {
attachedUnixUser.setQuotaHardlimit(detachedUnixUser.getQuotaHardlimit());
}
}
else {
Integer oldQuota = attachedUnixUser.getQuotaSoftlimit();
Integer newQuota = detachedUnixUser.getQuotaSoftlimit();
if (oldQuota != newQuota && !oldQuota.equals(newQuota)) {
throw new AuthorisationException(loginUser, "update", detachedUnixUser, "quota");
}
2010-10-01 21:52:51 +02:00
}
}
return super.update(attachedUnixUser);
}
@Override
2010-10-04 19:44:49 +02:00
public void delete(AbstractEntity existingEntity) throws HSAdminException {
2010-10-01 21:52:51 +02:00
// get the entity from the database
EntityManager entityManager = getTransaction().getEntityManager();
2010-10-01 21:52:51 +02:00
UnixUser detachedUnixUser = (UnixUser) existingEntity;
UnixUser attachedUnixUser = entityManager.find(detachedUnixUser.getClass(),
2010-10-01 21:52:51 +02:00
detachedUnixUser.getId());
// authorisation check
if (attachedUnixUser.getName().length() < 7) {
throw new AuthorisationException(attachedUnixUser, "delete");
}
needsFullAccessOnPacOf(attachedUnixUser, "delete");
// delete entity
super.delete(attachedUnixUser);
}
// throws an AuthorisationException if the login user has no write acess
// on the pac of the given UnixUser
private boolean hasFullAccessOnPacOf(UnixUser user) {
UnixUser loginUser = getTransaction().getLoginUser();
String loginUserName = loginUser.getName();
return loginUser.hasHostmasterRole()
|| loginUserName.equals(user.getPac().getName())
|| loginUserName.equals(user.getPac().getCustomer().getName());
2010-10-01 21:52:51 +02:00
}
// throws an AuthorisationException if the login user has no write acess
// on the pac of the given UnixUser
private void needsFullAccessOnPacOf(UnixUser user, String method)
throws AuthorisationException {
if (!hasFullAccessOnPacOf(user))
throw new AuthorisationException(getTransaction().getLoginUser(), method, user);
2010-10-01 21:52:51 +02:00
}
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);
}
2010-10-01 21:52:51 +02:00
}
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);
}
2010-10-01 21:52:51 +02:00
}
private static boolean isLoginShell(String shell) {
if (shell.equals("/bin/sh"))
return true;
if (shell.equals("/bin/bash"))
return true;
if (shell.equals("/bin/csh"))
return true;
if (shell.equals("/bin/tcsh"))
return true;
if (shell.equals("/bin/zsh"))
return true;
if (shell.equals("/bin/ksh"))
return true;
return false;
}
}