Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1009 → Rev 1010

/hostadmiral/trunk/doc/todo.txt
1,8 → 1,14
Host Admiral TODO
=================
 
+ Save user id for all db-update operations.
+/- Listeners for all operations.
 
Allow configuration of each listener.
 
Transaction control for listners.
 
+/- Save user id for all db-update operations.
 
Set 'editor' for an object by loading and not require it for each property change?
Then problem with objects inside (lazy loaded) collections.
 
17,7 → 23,7
(because it makes no sense to parse html pages).
The scenario for the model test can be used.
 
Cascade object deletion, confirmation page.
+/- Cascade object deletion, confirmation page.
 
Store user and malbox passwords in several forms; e.g. clear text, md5, encrypt. Allow
admin to specify which forms to use.
61,8 → 67,6
 
+ User login history.
 
Listeners for all operations.
 
Basic scripts to push changes to the system.
 
If mailbox is created, create an user and a mail alias for it in one step - as option.
/hostadmiral/trunk/src/ak/hostadmiral/core/CoreResources.properties
89,6 → 89,10
ak.hostadmiral.page.system.logout.login=start new session
ak.hostadmiral.page.system.logout.back=return to system
 
ak.hostadmiral.page.deleting.title=Delete an object from system
ak.hostadmiral.page.deleting.delete=delete
ak.hostadmiral.page.deleting.back=back
 
ak.hostadmiral.page.user.password.change.title=Host Admiral - change password
ak.hostadmiral.page.user.password.change.old_password=Old password
ak.hostadmiral.page.user.password.change.new_password=New password
249,7 → 253,7
ak.hostadmiral.page.mail.box.edit.domain=Domain
ak.hostadmiral.page.mail.box.edit.domain.empty=-- please select --
ak.hostadmiral.page.mail.box.edit.owner=Owner
ak.hostadmiral.page.mail.box.edit.owner.empty=-- create an user --
ak.hostadmiral.page.mail.box.edit.owner.empty=-- create a new user --
ak.hostadmiral.page.mail.box.edit.systemuser=System user
ak.hostadmiral.page.mail.box.edit.systemuser.empty=-- please select --
ak.hostadmiral.page.mail.box.edit.viruscheck=check mails for viruses
/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailAliasDestinationManager.java
74,7 → 74,7
if(!mailAliasDestination.editableBy(editor))
throw new ModelSecurityException();
 
mailAliasDestination.setModUser(editor);
//mailAliasDestination.setModUser(editor); // FIXME
// FIXME: the mod_user is not set when changing a destination as element of collection
 
try {
/hostadmiral/trunk/src/ak/hostadmiral/core/model/TransactionController.java
0,0 → 1,34
package ak.hostadmiral.core.model;
 
import java.util.Map;
import java.util.HashMap;
import ak.hostadmiral.util.ModelException;
 
// FIXME: implement it
public class TransactionController
{
private static TransactionController transactionController = null;
 
public static TransactionController getInstance()
{
return transactionController;
}
 
private Map listeners = new HashMap();
 
public void beginTransaction(Object transaction)
{
}
 
public void commitTransaction(Object transaction)
{
}
 
public void rollbackTransaction(Object transaction)
{
}
 
public void addObject(Object transaction, Object object)
{
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/Mailbox.java
206,7 → 206,9
 
public boolean editableBy(User user)
{
return user.isSuperuser() || user.equals(domain.getOwner());
return user.isSuperuser()
|| (domain == null) // just created
|| user.equals(domain.getOwner());
}
 
public boolean deleteableBy(User user)
/hostadmiral/trunk/src/ak/hostadmiral/core/model/TransactionListener.java
0,0 → 1,43
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
/**
* One could implement this interface to receive transaction start, commit and
* rollback events.
* An object will be informed about this events if it actualy interacts with the
* transaction, e.g. if it is registered as listener for object modifications.
*/
public interface TransactionListener
{
/**
* called when this object first time interacts with given transaction,
* before any other callbacks of this object in the transaction
*
* @param id some transaction identifier, the same for all transaction* methods
* @throws ModelException if transaction must be aborted immediately
*/
public void transactionBegin(Object id)
throws ModelException;
 
/**
* called when transaction is commited
*
* @param id some transaction identifier, the same as in corresponding transactionBegin
* method call
* @throws ModelException logged, but ignored
*/
public void transactionCommited(Object id)
throws ModelException;
 
/**
* called when transaction is rolled back
*
* @param id some transaction identifier, the same as in corresponding transactionBegin
* method call
* @throws ModelException logged, but ignored
*/
public void transactionRolledBack(Object id)
throws ModelException;
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailAlias.java
145,7 → 145,9
 
public boolean editableBy(User user)
{
return user.isSuperuser() || user.equals(domain.getOwner());
return user.isSuperuser()
|| (domain == null) // just created
|| user.equals(domain.getOwner());
}
 
public boolean mayChangeDestinations(User user)
/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserManager.java
25,11 → 25,12
 
registered = true;
try {
/*
HibernateUtil.getConfiguration().addResource(
"ak/hostadmiral/core/model/User.hbm.xml");
HibernateUtil.getConfiguration().addResource(
"ak/hostadmiral/core/model/UserLogin.hbm.xml");
 
*/
userManager = new UserManager();
}
catch(Exception ex) {
43,7 → 44,10
register();
}
 
private Collection createdListeners = new ArrayList();
private Collection modifiedListeners = new ArrayList();
private Collection beforeDeleteListeners = new ArrayList();
private Collection deletedListeners = new ArrayList();
private Map loggedinUsers = new WeakHashMap();
 
private UserManager()
56,7 → 60,13
{
if(!allowedToCreate(editor)) throw new ModelSecurityException();
 
return new User();
User user = new User();
 
if(!user.mayChangeBoss(editor)) { // ordinal user can create only own "subusers"
user.setBoss(editor);
}
 
return user;
}
 
public boolean allowedToCreate(User editor)
73,8 → 83,7
try {
user = (User)HibernateUtil.currentSession().load(User.class, id);
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
 
100,8 → 109,7
new Type[] { Hibernate.STRING, Hibernate.entity(User.class) } )
.next()).intValue() > 0;
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
}
120,8 → 128,7
else
return (User)list.get(0);
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
}
135,13 → 142,15
throw new ModelSecurityException();
}
 
user.setModUser(editor);
boolean isNew = user.isNew();
 
//user.setModUser(editor); // FIXME: disabled because hb throws exception
// if user edits itself
 
try {
HibernateUtil.currentSession().saveOrUpdate(user);
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
 
151,8 → 160,44
if(u.equals(user))
u.update(user);
}
 
// inform listeners
if(isNew) {
for(Iterator i = createdListeners.iterator(); i.hasNext(); ) {
UserCreatedListener listener = (UserCreatedListener)i.next();
listener.userCreated(editor, user);
}
}
else {
User oldUser = user.getOrigin();
if(oldUser == null) oldUser = user;
for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) {
UserModifiedListener listener = (UserModifiedListener)i.next();
listener.userModified(editor, user, oldUser);
}
}
}
 
public void addCreatedListener(UserCreatedListener listener)
{
createdListeners.add(listener);
}
 
public void removeCreatedListener(UserCreatedListener listener)
{
createdListeners.remove(listener);
}
 
public void addModifiedListener(UserModifiedListener listener)
{
modifiedListeners.add(listener);
}
 
public void removeModifiedListener(UserModifiedListener listener)
{
modifiedListeners.remove(listener);
}
 
public void addBeforeDeleteListener(UserBeforeDeleteListener listener)
{
beforeDeleteListeners.add(listener);
163,6 → 208,16
beforeDeleteListeners.remove(listener);
}
 
public void addDeletedListener(UserDeletedListener listener)
{
deletedListeners.add(listener);
}
 
public void removeDeletedListener(UserDeletedListener listener)
{
deletedListeners.remove(listener);
}
 
public Collection beforeDelete(User editor, User user, Collection known)
throws ModelException
{
181,16 → 236,26
public void delete(User editor, User user)
throws ModelException
{
// chech rights
if(!user.deleteableBy(editor))
throw new ModelSecurityException();
 
// backup copy
User oldUser = new User(user);
 
// delete it
try {
HibernateUtil.currentSession().delete(user);
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
 
// inform listeners
for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) {
UserDeletedListener listener = (UserDeletedListener)i.next();
listener.userDeleted(editor, oldUser);
}
}
 
public Collection listUsers(User editor)
207,8 → 272,7
new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) } );
}
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
}
228,8 → 292,7
.next()).intValue() > 0;
}
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
}
245,12 → 308,12
try {
HibernateUtil.currentSession().saveOrUpdate(userLogin);
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
 
if(success) {
user = new User(user); // unbind the user from hibernate
loggedinUsers.put(user, Boolean.TRUE);
return user;
}
272,9 → 335,8
"from UserLogin where success = ?",
Boolean.FALSE, Hibernate.BOOLEAN);
}
catch(HibernateException ex)
{
throw new ModelException(ex);
catch(HibernateException ex) {
throw new ModelException(ex);
}
}
 
288,8 → 350,7
"from User where boss = ?",
user, Hibernate.entity(User.class) );
}
catch(HibernateException ex)
{
catch(HibernateException ex) {
throw new ModelException(ex);
}
 
/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserDeletedListener.java
0,0 → 1,20
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface UserDeletedListener
{
/**
* called if some user is just deleted.
*
* @param editor who is doing the operation
* @param user the user deleted
* @throws ModelException in case of any *fatal* errors,
* Note: throw it on fatal errors only, because database transaction
* will be rolled back but any other UserDeletedListeners might be already called
* and (possible) they will not restore their original state.
*/
public void userDeleted(User editor, User user)
throws ModelException;
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserCreatedListener.java
0,0 → 1,20
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface UserCreatedListener
{
/**
* called if new user is just created.
*
* @param editor who is doing the operation
* @param user the new user
* @throws ModelException in case of any *fatal* errors,
* Note: throw it on fatal errors only, because database transaction
* will be rolled back but any other UserCreatedListeners might be already called
* and (possible) they will not restore their original state.
*/
public void userCreated(User editor, User user)
throws ModelException;
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/User.java
2,6 → 2,7
 
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.StringTokenizer;
 
22,11 → 23,37
private Boolean superuser;
private Locale locale = Locale.getDefault();
private Collection loginHistory;
private User origin; // save original object state before any changes
 
protected User()
{
}
 
protected User(User origin)
{
super(origin);
this.login = origin.login;
this.password = origin.password;
this.boss = origin.boss;
this.superuser = origin.superuser;
this.locale = origin.locale;
if(origin.loginHistory == null)
this.loginHistory = null;
else
this.loginHistory = new HashSet(origin.loginHistory);
}
 
protected User getOrigin()
{
return origin;
}
 
protected void backupMe()
{
if(origin == null)
origin = new User(this);
}
 
/**
*
* @hibernate.property
47,6 → 74,10
if(!editableBy(editor))
throw new ModelSecurityException();
 
// FIXME: domain owner is allowed to change user login
// with some patern only, e.g. user@domain.com
 
backupMe();
this.login = login;
}
 
73,6 → 104,7
if(password == null)
throw new NullPointerException("Null password");
 
backupMe();
this.password = Digest.encode(password);
}
 
106,9 → 138,10
public void setBoss(User editor, User boss)
throws ModelException
{
if(!editableBy(editor))
if(!mayChangeBoss(editor))
throw new ModelSecurityException();
 
backupMe();
this.boss = boss;
}
 
137,6 → 170,7
if(!mayChangeSuperuser(editor))
throw new ModelSecurityException();
 
backupMe();
this.superuser = superuser;
}
 
174,6 → 208,7
if(!partEditableBy(editor))
throw new ModelSecurityException();
 
backupMe();
setLocaleName(localeName);
}
 
188,6 → 223,7
if(!partEditableBy(editor))
throw new ModelSecurityException();
 
backupMe();
this.locale = locale;
}
 
272,6 → 308,11
return user.isSuperuser() || user.equals(boss) || user.equals(this);
}
 
public boolean mayChangeBoss(User user)
{
return user.isSuperuser();
}
 
public boolean mayChangeSuperuser(User user)
{
return user.isSuperuser() && !user.equals(this);
285,7 → 326,9
protected static boolean allowedToCreate(UserManager manager, User editor)
throws ModelException
{
return editor.isSuperuser();
return editor.isSuperuser()
|| InetDomainManager.getInstance().areInetDomainsAvailable(editor);
// FIXME: or allow any user to create "subusers"?
}
 
protected static User createLimitedCopy(User origin)
294,4 → 337,9
u.setLogin(origin.getLogin());
return u;
}
 
public String toString()
{
return getClass().getName() + " [" + getId() + "] [" + getLogin() + "]";
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/SystemUserManager.java
167,7 → 167,7
if(!systemUser.editableBy(editor))
throw new ModelSecurityException();
 
systemUser.setModUser(editor);
//systemUser.setModUser(editor); // FIXME
 
try {
HibernateUtil.currentSession().saveOrUpdate(systemUser);
/hostadmiral/trunk/src/ak/hostadmiral/core/model/InetDomainManager.java
128,7 → 128,7
if(!domain.editableBy(editor))
throw new ModelSecurityException();
 
domain.setModUser(editor);
//domain.setModUser(editor); // FIXME
 
try {
HibernateUtil.currentSession().saveOrUpdate(domain);
/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserModifiedListener.java
0,0 → 1,21
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface UserModifiedListener
{
/**
* called if some user is just changed.
*
* @param editor who is doing the operation
* @param user the user in its new state
* @param oldUser copy of user as it was before the operation
* @throws ModelException in case of any *fatal* errors,
* Note: throw it on fatal errors only, because database transaction
* will be rolled back but any other UserCreatedListeners might be already called
* and (possible) they will not restore their original state.
*/
public void userModified(User editor, User user, User oldUser)
throws ModelException;
}
/hostadmiral/trunk/src/ak/hostadmiral/core/model/GeneralModelObject.java
13,6 → 13,27
private Date modStamp;
private User modUser;
 
protected GeneralModelObject()
{
}
 
protected GeneralModelObject(GeneralModelObject origin)
{
this.id = origin.id;
this.enabled = origin.enabled;
this.comment = origin.comment;
this.modStamp = origin.modStamp;
this.modUser = origin.modUser;
}
 
/**
* @return true if the object is not yet saved in DB
*/
public boolean isNew()
{
return (id == null);
}
 
/**
*
* @hibernate.id generator-class="native"
/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailboxManager.java
137,7 → 137,7
if(!mailbox.editableBy(editor))
throw new ModelSecurityException();
 
mailbox.setModUser(editor);
//mailbox.setModUser(editor); // FIXME
 
try {
HibernateUtil.currentSession().saveOrUpdate(mailbox);
/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailAliasManager.java
121,7 → 121,7
if(!mailAlias.editableBy(editor))
throw new ModelSecurityException();
 
mailAlias.setModUser(editor);
//mailAlias.setModUser(editor); // FIXME
 
try {
HibernateUtil.currentSession().saveOrUpdate(mailAlias);
/hostadmiral/trunk/src/ak/hostadmiral/core/servlet/ListenerRegistratorServlet.java
0,0 → 1,75
package ak.hostadmiral.core.servlet;
 
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
 
import org.apache.log4j.Logger;
 
import ak.hostadmiral.core.model.*;
 
public class ListenerRegistratorServlet
extends GenericServlet
{
private static final Logger logger = Logger.getLogger(ListenerRegistratorServlet.class);
 
public void init()
throws ServletException
{
// users
register("UserCreatedListener", new Registrar() {
public void reg(Object o) {
UserManager.getInstance().addCreatedListener((UserCreatedListener)o);
}
});
register("UserModifiedListener", new Registrar() {
public void reg(Object o) {
UserManager.getInstance().addModifiedListener((UserModifiedListener)o);
}
});
register("UserBeforeDeleteListener", new Registrar() {
public void reg(Object o) {
UserManager.getInstance().addBeforeDeleteListener((UserBeforeDeleteListener)o);
}
});
register("UserDeletedListener", new Registrar() {
public void reg(Object o) {
UserManager.getInstance().addDeletedListener((UserDeletedListener)o);
}
});
}
 
private void register(String paramName, Registrar registrar)
{
String param = getInitParameter(paramName);
if(param == null) return;
 
String[] names = param.split("\\s*;\\s*");
for(int i = 0; i < names.length; i++) {
String name = names[i].trim();
if(name.equals("")) continue;
try {
Class c = Class.forName(name);
registrar.reg(c.newInstance());
}
catch(ClassCastException ex) {
logger.error("class " + name + " has wrong type", ex);
}
catch(Exception ex) {
logger.error("cannot get class " + name, ex);
}
}
}
 
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
}
 
private interface Registrar
{
public void reg(Object o);
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/dummy/UserModifiedDummyListener.java
0,0 → 1,16
package ak.hostadmiral.core.listener.dummy;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserModifiedListener;
 
public class UserModifiedDummyListener
implements UserModifiedListener
{
public void userModified(User editor, User user, User oldUser)
throws ModelException
{
System.out.println("UserCreatedDummyListener.userModified: from " + oldUser
+ " to " + user + " by " + editor);
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/dummy/UserDeletedDummyListener.java
0,0 → 1,16
package ak.hostadmiral.core.listener.dummy;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserDeletedListener;
 
public class UserDeletedDummyListener
implements UserDeletedListener
{
public void userDeleted(User editor, User user)
throws ModelException
{
System.out.println("UserCreatedDummyListener.userDeleted: "
+ user + " by " + editor);
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/dummy/UserCreatedDummyListener.java
0,0 → 1,16
package ak.hostadmiral.core.listener.dummy;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserCreatedListener;
 
public class UserCreatedDummyListener
implements UserCreatedListener
{
public void userCreated(User editor, User user)
throws ModelException
{
System.out.println("UserCreatedDummyListener.userCreated: "
+ user + " by " + editor);
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/file/UserCreatedFileListener.java
0,0 → 1,22
package ak.hostadmiral.core.listener.file;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserCreatedListener;
 
import org.apache.log4j.Logger;
 
public class UserCreatedFileListener
implements UserCreatedListener
{
private static final Logger logger = Logger.getLogger(UserCreatedFileListener.class);
 
public void userCreated(User editor, User user)
throws ModelException
{
InterfaceFile.send("user\tcreate\t" + InterfaceFile.escape(user.getLogin()) + "\t"
+ InterfaceFile.escape(/* FIXME user.getPassword() */ "") + "\t"
+ user.getEnabled() + "\t"
+ InterfaceFile.escape(user.getComment()));
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/file/InterfaceFile.java
0,0 → 1,68
package ak.hostadmiral.core.listener.file;
 
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.FileWriter;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserModifiedListener;
 
import org.apache.log4j.Logger;
 
public class InterfaceFile
{
private static final Logger logger = Logger.getLogger(InterfaceFile.class);
 
private static String fileName;
protected static Object lock = new Object();
 
public static final String PROTOCOL_NAME = "HostAdmiral_FileInterface";
public static final String PROTOCOL_VERSION = "0.1";
 
public static String getFileName()
{
return fileName;
}
 
public static void setFileName(String fileName_)
{
fileName = fileName_;
}
 
protected static String escape(String s)
{
// FIXME: any other problem characters? optimize it?
s = s.replaceAll("\0", "\\\\0");
s = s.replaceAll("\\\\", "\\\\\\\\");
s = s.replaceAll("\t", "\\\\t");
s = s.replaceAll("\n", "\\\\n");
return s;
}
 
protected static void send(String message)
throws ModelException
{
synchronized(lock) {
try {
Writer out = new BufferedWriter(new FileWriter(fileName));
if(PROTOCOL_NAME != null) {
out.write(PROTOCOL_NAME);
out.write(" ");
}
if(PROTOCOL_VERSION != null) {
out.write(PROTOCOL_VERSION);
out.write("\n");
}
out.write(message);
out.write("\n\n");
out.close();
}
catch(Exception ex) {
logger.error("Cannot save message to file", ex);
throw new ModelException("Cannot save message to file:" + ex.getMessage());
// FIMXE: or just throw "internal server error" message?
}
}
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/file/UserModifiedFileListener.java
0,0 → 1,23
package ak.hostadmiral.core.listener.file;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserModifiedListener;
 
import org.apache.log4j.Logger;
 
public class UserModifiedFileListener
implements UserModifiedListener
{
private static final Logger logger = Logger.getLogger(UserModifiedFileListener.class);
 
public void userModified(User editor, User user, User oldUser)
throws ModelException
{
InterfaceFile.send("user\tmodify\t" + InterfaceFile.escape(oldUser.getLogin()) + "\t"
+ InterfaceFile.escape(user.getLogin()) + "\t"
+ InterfaceFile.escape(/* FIXME user.getPassword() */ "") + "\t"
+ user.getEnabled() + "\t"
+ InterfaceFile.escape(user.getComment()));
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/file/ConfigServlet.java
0,0 → 1,26
package ak.hostadmiral.core.listener.file;
 
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
 
import org.apache.log4j.Logger;
 
public class ConfigServlet
extends GenericServlet
{
private static final Logger logger = Logger.getLogger(ConfigServlet.class);
 
public void init()
throws ServletException
{
InterfaceFile.setFileName(getInitParameter("fileName"));
}
 
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/listener/file/UserDeletedFileListener.java
0,0 → 1,19
package ak.hostadmiral.core.listener.file;
 
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserDeletedListener;
 
import org.apache.log4j.Logger;
 
public class UserDeletedFileListener
implements UserDeletedListener
{
private static final Logger logger = Logger.getLogger(UserCreatedFileListener.class);
 
public void userDeleted(User editor, User user)
throws ModelException
{
InterfaceFile.send("user\tdelete\t" + InterfaceFile.escape(user.getLogin()));
}
}
/hostadmiral/trunk/src/ak/hostadmiral/core/action/MailAliasAction.java
147,6 → 147,21
throw new UserException("ak.hostadmiral.core.mail.alias.edit.owner.wrong");
}
 
alias.setDomain(user, InetDomainManager.getInstance().get(user,
StringConverter.parseLong(theForm.get("domain"))));
 
String address = (String)theForm.get("address");
if(MailAliasManager.getInstance().addressExists(user, alias, address)) {
handleErrors(mapping, form, request, response);
throw new UserException(CoreResources.NONUNIQUE_MAIL_ALIAS_ADDRESS);
}
alias.setAddress(user, address);
 
alias.setOwner(user, UserManager.getInstance().get(user,
StringConverter.parseLong(theForm.get("owner"))));
alias.setEnabled(user, (Boolean)theForm.get("enabled"));
alias.setComment(user, (String)theForm.get("comment"));
 
alias.getDestinations(user).clear();
for(int i = 0; i < dests.length; i++) {
// FIXME: validate dest id, mailbox id, email
183,21 → 198,6
dest.setComment(user, dests[i].getComment());
}
 
alias.setDomain(user, InetDomainManager.getInstance().get(user,
StringConverter.parseLong(theForm.get("domain"))));
 
String address = (String)theForm.get("address");
if(MailAliasManager.getInstance().addressExists(user, alias, address)) {
handleErrors(mapping, form, request, response);
throw new UserException(CoreResources.NONUNIQUE_MAIL_ALIAS_ADDRESS);
}
alias.setAddress(user, address);
 
alias.setOwner(user, UserManager.getInstance().get(user,
StringConverter.parseLong(theForm.get("owner"))));
alias.setEnabled(user, (Boolean)theForm.get("enabled"));
alias.setComment(user, (String)theForm.get("comment"));
 
// update alias
MailAliasManager.getInstance().save(user, alias);
 
/hostadmiral/trunk/src/ak/hostadmiral/core/action/UserAction.java
69,6 → 69,9
List list = new ArrayList(UserManager.getInstance().listUsers(user));
Collections.sort(list, UserManager.LOGIN_COMPARATOR);
request.setAttribute("users", list);
request.setAttribute("allowedToCreate",
Boolean.valueOf(UserManager.getInstance().allowedToCreate(user)));
request.setAttribute("mayViewAllLogins", Boolean.valueOf(user.mayViewAllLogins()));
 
return mapping.findForward("default");
}
169,13 → 172,15
}
u.setLogin(user, login);
 
if(u.editableBy(user)) {
if(u.mayChangeBoss(user)) {
Long bossId = StringConverter.parseLong(theForm.get("boss"));
if(bossId == null)
u.setBoss(user, null);
else
u.setBoss(user, UserManager.getInstance().get(user, bossId));
}
 
if(u.editableBy(user)) {
u.setLocaleName(user, (String)theForm.get("locale"));
u.setEnabled(user, (Boolean)theForm.get("enabled"));
u.setComment(user, (String)theForm.get("comment"));
/hostadmiral/trunk/build.xml
64,6 → 64,7
>
<fileset dir="src">
<include name="**/*.java" />
<exclude name="ak/hostadmiral/core/servlet/*.java" />
</fileset>
<hibernate version="2.0" />
</hibernatedoclet>
/hostadmiral/trunk/webapp/mail/box/edit.jsp
1,4 → 1,4
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
38,9 → 38,6
<td><html:text property="login" /></td>
</tr>
<tr>
<td colspan=2>FIXME: checkbox to get password from owner</td>
</tr>
<tr>
<th><bean:message key="ak.hostadmiral.page.mail.box.edit.password" /></th>
<td><html:password property="password" redisplay="false" /></td>
</tr>
99,6 → 96,12
</tr>
</table>
 
<p>FIXME: checkbox to create a mail alias if new mailbox is created</p>
<p>FIXME: special case: by editing a mailbox which login is the same
as its user and/or mail alias allow to change all them at once. Do the for
user/mail alias edit pages too?</p>
<p>FIXME: checkbox to get password from owner</p>
 
</html:form>
 
</body>
/hostadmiral/trunk/webapp/deleting.jsp
1,4 → 1,4
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*,ak.hostadmiral.core.model.*" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
10,17 → 10,18
 
<head>
<meta http-equiv="expires" content="0">
<title><bean:message key="ak.hostadmiral.page.index.title" /></title>
<title><bean:message key="ak.hostadmiral.page.deleting.title" /></title>
<link rel="stylesheet" type="text/css" href="<strutsx:root />/style/general.css">
</head>
 
<body>
 
<h1><bean:message key="ak.hostadmiral.page.index.title" /></h1>
<h1><bean:message key="ak.hostadmiral.page.deleting.title" /></h1>
 
<p>Object: <bean:write name="object" property="identKey" /></p>
<p>Object: <bean:write name="object" property="identKey" /> <bean:write name="object" property="id" /></p>
<p>Action: <bean:write name="action" /></p>
 
<p>FIXME: draw a real object tree here</p>
<ul>
<%
Collection cascade = (Collection)request.getAttribute("cascade");
48,7 → 49,8
</ul>
 
<br>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.list.back" /></backpath:backlink>
<backpath:currentlink action="<%= (String)request.getAttribute("action") %>" paramId="id" paramName="object" paramProperty="id"><bean:message key="ak.hostadmiral.page.deleting.delete" /></backpath:currentlink>
<backpath:backlink><bean:message key="ak.hostadmiral.page.deleting.back" /></backpath:backlink>
 
</body>
 
/hostadmiral/trunk/webapp/WEB-INF/lib/hibernate2.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/hostadmiral/trunk/webapp/WEB-INF/lib/backpath.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/hostadmiral/trunk/webapp/WEB-INF/ak-backpath.tld
1,4 → 1,4
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
208,6 → 208,210
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>ondblclick</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onfocus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeydown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeypress</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onkeyup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousedown</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmousemove</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseout</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseover</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onmouseup</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>page</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>paramScope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>tabindex</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>target</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>titleKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>transaction</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathParam</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>backPathIgnore</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>zip</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>currentlink</name>
<tagclass>ak.backpath.taglib.CurrentLinkTag</tagclass>
<attribute>
<name>accesskey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>action</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>forward</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>href</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexed</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>indexId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>linkName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onblur</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
/hostadmiral/trunk/webapp/WEB-INF/web.xml
78,6 → 78,41
<load-on-startup>2</load-on-startup>
</servlet>
 
<servlet>
<servlet-name>ListenerRegistratorServlet</servlet-name>
<servlet-class>ak.hostadmiral.core.servlet.ListenerRegistratorServlet</servlet-class>
<init-param>
<param-name>UserCreatedListener</param-name>
<param-value>
ak.hostadmiral.core.listener.dummy.UserCreatedDummyListener;
ak.hostadmiral.core.listener.file.UserCreatedFileListener;
</param-value>
</init-param>
<init-param>
<param-name>UserModifiedListener</param-name>
<param-value>
ak.hostadmiral.core.listener.dummy.UserModifiedDummyListener;
ak.hostadmiral.core.listener.file.UserModifiedFileListener;
</param-value>
</init-param>
<init-param>
<param-name>UserDeletedListener</param-name>
<param-value>
ak.hostadmiral.core.listener.dummy.UserDeletedDummyListener;
ak.hostadmiral.core.listener.file.UserDeletedFileListener;
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>ak.hostadmiral.core.listener.file.ConfigServlet</servlet-class>
<init-param>
<param-name>fileName</param-name>
<param-value>/tmp/hostadmiral</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
 
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
/hostadmiral/trunk/webapp/user/edit.jsp
1,4 → 1,4
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
48,10 → 48,15
<tr>
<th><bean:message key="ak.hostadmiral.page.user.edit.boss" /></th>
<td>
<html:select property="boss">
<html:option value="" key="ak.hostadmiral.page.user.edit.boss.empty"/>
<core:options collection="users" property="id" />
</html:select>
<core:rights name="u" method="mayChangeBoss">
<html:select property="boss">
<html:option value="" key="ak.hostadmiral.page.user.edit.boss.empty"/>
<core:options collection="users" property="id" />
</html:select>
</core:rights>
<core:noRights name="u" method="mayChangeBoss">
<bean:write name="u" property="boss.login" />
</core:noRights>
</td>
</tr>
<tr>
/hostadmiral/trunk/webapp/user/list.jsp
1,4 → 1,4
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
87,10 → 87,14
</logic:iterate>
</table>
 
<backpath:link action="/user/edit"><bean:message key="ak.hostadmiral.page.user.list.add" /></backpath:link>
<br>
<backpath:link action="/user/failedLogins"><bean:message key="ak.hostadmiral.page.user.list.logins.failed" /></backpath:link>
<br>
<logic:equal name="allowedToCreate" value="true">
<backpath:link action="/user/edit"><bean:message key="ak.hostadmiral.page.user.list.add" /></backpath:link>
<br>
</logic:equal>
<logic:equal name="mayViewAllLogins" value="true">
<backpath:link action="/user/failedLogins"><bean:message key="ak.hostadmiral.page.user.list.logins.failed" /></backpath:link>
<br>
</logic:equal>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.list.back" /></backpath:backlink>
 
</body>
/hostadmiral/trunk/sql/00.tables.sql
1,7 → 1,7
--
-- hostadmiral sql tables
--
-- FIXME: which values has boolean in hibernate - '1':' ' or '1':'0'?
-- FIXME: which values has boolean in hibernate - '1':'0' or '1':'0'?
 
create sequence hibernate_sequence;
 
17,9 → 17,9
login varchar(255) not null,
password varchar(255) not null,
boss integer,
superuser char(1) default ' ' check (superuser = '1' or superuser = ' '),
superuser char(1) default '0' check (superuser = '1' or superuser = '0'),
locale varchar(5) default 'en', -- language_country
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,
54,7 → 54,7
uid integer not null,
name varchar(255) not null,
owner integer,
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,
70,7 → 70,7
id integer not null,
name varchar(255) not null,
owner integer not null,
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,
89,10 → 89,10
password varchar(255), -- if null, then owner's password is used
domain integer not null,
owner integer not null,
virusCheck char(1) default '1' check (virusCheck = '1' or virusCheck = ' '),
spamCheck char(1) default '1' check (spamCheck = '1' or spamCheck = ' '),
virusCheck char(1) default '1' check (virusCheck = '1' or virusCheck = '0'),
spamCheck char(1) default '1' check (spamCheck = '1' or spamCheck = '0'),
systemuser integer,
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,
111,7 → 111,7
address varchar(255) not null,
domain integer not null,
owner integer not null,
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,
128,7 → 128,7
alias integer not null,
mailbox integer,
email varchar(255),
enabled char(1) default '1' check (enabled = '1' or enabled = ' '),
enabled char(1) default '1' check (enabled = '1' or enabled = '0'),
comment text,
mod_stamp timestamp,
mod_user integer,