Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 948 → Rev 949

/sun/hostadmiral/trunk/src/ak/hostadmiral/core/action/LoginAction.java
28,7 → 28,7
DynaActionForm theForm = (DynaActionForm)form;
 
User user = UserManager.getInstance().loginUser(
(String)theForm.get("login"), (String)theForm.get("password"));
(String)theForm.get("login"), (String)theForm.get("password"), request.getRemoteAddr());
 
if(user == null) {
ActionErrors errors = new ActionErrors();
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/action/UserLoginsAction.java
0,0 → 1,41
package ak.hostadmiral.core.action;
 
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionForward;
 
import ak.hostadmiral.util.StringConverter;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserManager;
 
public final class UserLoginsAction
extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
User user = (User)request.getSession().getAttribute("user");
 
DynaActionForm theForm = (DynaActionForm)form;
Long userId = StringConverter.parseLong(theForm.get("id"));
User u = UserManager.getInstance().get(user, userId);
List logins = new ArrayList(u.getLogins());
 
Collections.sort(logins, UserManager.LOGINS_TIME_COMPARATOR);
Collections.reverse(logins);
request.setAttribute("u", u);
request.setAttribute("logins", logins);
 
return mapping.findForward("default");
}
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/action/UserAction.java
3,6 → 3,7
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashSet;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
106,7 → 107,8
 
request.setAttribute("action", "/user/delete.do");
request.setAttribute("object", u);
request.setAttribute("cascade", UserManager.getInstance().beforeDelete(user, u));
request.setAttribute("cascade",
UserManager.getInstance().beforeDelete(user, u, new HashSet()));
 
return mapping.findForward("default");
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/action/FailedLoginsAction.java
0,0 → 1,36
package ak.hostadmiral.core.action;
 
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionForward;
 
import ak.hostadmiral.util.StringConverter;
import ak.hostadmiral.core.model.User;
import ak.hostadmiral.core.model.UserManager;
 
public final class FailedLoginsAction
extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
User user = (User)request.getSession().getAttribute("user");
List logins = new ArrayList(UserManager.getInstance().listFailedLogins(user));
 
Collections.sort(logins, UserManager.LOGINS_TIME_COMPARATOR);
Collections.reverse(logins);
request.setAttribute("logins", logins);
 
return mapping.findForward("default");
}
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/CoreResources.properties
22,7 → 22,7
ak.hostadmiral.core.password.dontMatch=The passwords you entered doesn't match
 
ak.hostadmiral.core.user.login.nonunique=The user login already exists
ak.hostadmiral.core.user.password.change.id.wrong=Please select an user from the list
ak.hostadmiral.core.user.id.wrong=Please select an user from the list
ak.hostadmiral.core.user.deletemeself=Can not delete the user you are logged in
ak.hostadmiral.core.user.boss.id.wrong=Please select a boss from the list
ak.hostadmiral.core.user.system.uid.nonunique=The UID already exists
102,7 → 102,23
ak.hostadmiral.page.user.list.view=view
ak.hostadmiral.page.user.list.add=add new user
ak.hostadmiral.page.user.list.back=back
ak.hostadmiral.page.user.list.logins.failed=failed logins
 
ak.hostadmiral.page.user.failedLogins.title=Host Admiral - users - failed logins
ak.hostadmiral.page.user.failedLogins.login=Login
ak.hostadmiral.page.user.failedLogins.user.exists=User Exists
ak.hostadmiral.page.user.failedLogins.time=Login Time
ak.hostadmiral.page.user.failedLogins.success=Success
ak.hostadmiral.page.user.failedLogins.ip=IP
ak.hostadmiral.page.user.failedLogins.back=back
 
ak.hostadmiral.page.user.logins.title=Host Admiral - user - logins
ak.hostadmiral.page.user.logins.login=Logins of user
ak.hostadmiral.page.user.logins.time=Login Time
ak.hostadmiral.page.user.logins.success=Success
ak.hostadmiral.page.user.logins.ip=IP
ak.hostadmiral.page.user.logins.back=back
 
ak.hostadmiral.page.user.edit.title=Host Admiral - user - edit
ak.hostadmiral.page.user.edit.login=Login
ak.hostadmiral.page.user.edit.password=Password
116,6 → 132,7
ak.hostadmiral.page.user.edit.comment=Comment
ak.hostadmiral.page.user.edit.submit=submit
ak.hostadmiral.page.user.edit.back=back
ak.hostadmiral.page.user.edit.logins=login history
 
ak.hostadmiral.page.user.view.title=Host Admiral - user - view
ak.hostadmiral.page.user.view.login=Login
129,6 → 146,7
ak.hostadmiral.page.user.view.enabled.false=no
ak.hostadmiral.page.user.view.comment=Comment
ak.hostadmiral.page.user.view.back=back
ak.hostadmiral.page.user.view.logins=login history
 
ak.hostadmiral.page.user.system.list.title=Host Admiral - system users - list
ak.hostadmiral.page.user.system.list.uid=System ID
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/SystemUserManager.java
8,8 → 8,16
import ak.hostadmiral.util.ModelSecurityException;
 
public class SystemUserManager
implements UserBeforeDeleteListener
{
private static SystemUserManager systemUserManager = null;
private static boolean registered = false;
 
public static SystemUserManager getInstance()
{
return systemUserManager;
}
 
protected static void register()
{
synchronized(SystemUserManager.class) {
19,6 → 27,8
try {
HibernateUtil.getConfiguration().addResource(
"/ak/hostadmiral/core/model/SystemUser.hbm.xml");
 
systemUserManager = new SystemUserManager();
}
catch(Exception ex) {
ex.printStackTrace();
31,8 → 41,11
register();
}
 
private Collection beforeDeleteListeners = new ArrayList();
 
private SystemUserManager()
{
UserManager.getInstance().addBeforeDeleteListener(this);
}
 
public SystemUser create(User editor)
165,6 → 178,31
}
}
 
public void addBeforeDeleteListener(SystemUserBeforeDeleteListener listener)
{
beforeDeleteListeners.add(listener);
}
 
public void removeBeforeDeleteListener(SystemUserBeforeDeleteListener listener)
{
beforeDeleteListeners.remove(listener);
}
 
public Collection beforeDelete(User editor, SystemUser user, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
 
for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
SystemUserBeforeDeleteListener listener = (SystemUserBeforeDeleteListener)i.next();
Collection subcascade = listener.systemUserBeforeDelete(editor, user, known);
if(subcascade != null)
cascade.addAll(subcascade);
}
 
return cascade;
}
 
public void delete(User editor, SystemUser systemUser)
throws ModelException
{
216,14 → 254,38
}
}
 
private static SystemUserManager systemUserManager = null;
 
public static SystemUserManager getInstance()
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException
{
if(systemUserManager == null)
systemUserManager = new SystemUserManager();
Collection systemUsers;
 
return systemUserManager;
try {
systemUsers = HibernateUtil.currentSession().find(
"from SystemUser where owner = ?",
user, Hibernate.entity(User.class) );
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
 
Collection cascade = new ArrayList();
for(Iterator i = systemUsers.iterator(); i.hasNext(); ) {
SystemUser u = (SystemUser)i.next();
if(u.viewableBy(editor)) {
if(u.deleteableBy(editor))
cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.DELETE,
this.beforeDelete(editor, u, known)));
else
cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.FORBIDDEN, null));
}
else {
cascade.add(new CascadeDeleteElement(SystemUser.createLimitedCopy(u),
CascadeDeleteElement.FORBIDDEN, null));
}
}
 
return cascade;
}
 
public static final Comparator UID_COMPARATOR = new UidComparator();
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/User.java
1,5 → 1,8
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import java.util.Collections;
 
import ak.hostadmiral.util.Digest;
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.util.ModelSecurityException;
11,10 → 14,11
public class User
extends GeneralModelObject
{
private String login;
private String password;
private User boss;
private Boolean superuser;
private String login;
private String password;
private User boss;
private Boolean superuser;
private Collection loginHistory;
 
protected User()
{
133,6 → 137,27
this.superuser = superuser;
}
 
/**
*
* @hibernate.set lazy="true"
* @hibernate.collection-key column="usr"
* @hibernate.collection-one-to-many class="ak.hostadmiral.core.model.UserLogin"
*/
protected Collection getLoginHistory()
{
return loginHistory;
}
 
public Collection getLogins()
{
return Collections.unmodifiableCollection(loginHistory);
}
 
protected void setLoginHistory(Collection loginHistory)
{
this.loginHistory = loginHistory;
}
 
public boolean equals(Object o)
{
if(o == null || !(o instanceof User)) return false;
189,6 → 214,11
return user.isSuperuser() && !user.equals(this);
}
 
public boolean mayViewAllLogins()
{
return isSuperuser();
}
 
protected static boolean allowedToCreate(UserManager manager, User editor)
throws ModelException
{
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/InetDomainManager.java
15,9 → 15,6
 
public static InetDomainManager getInstance()
{
if(inetDomainManager == null)
inetDomainManager = new InetDomainManager();
 
return inetDomainManager;
}
 
44,6 → 41,8
register();
}
 
private Collection beforeDeleteListeners = new ArrayList();
 
private InetDomainManager()
{
UserManager.getInstance().addBeforeDeleteListener(this);
140,18 → 139,28
}
}
 
public Collection beforeDelete(User editor, InetDomain domain)
public void addBeforeDeleteListener(SystemUserBeforeDeleteListener listener)
{
beforeDeleteListeners.add(listener);
}
 
public void removeBeforeDeleteListener(SystemUserBeforeDeleteListener listener)
{
beforeDeleteListeners.remove(listener);
}
 
public Collection beforeDelete(User editor, InetDomain domain, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
/*
 
for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
InetDomainBeforeDeleteListener listener = (InetDomainBeforeDeleteListener)i.next();
Collection subcascade = listener.userBeforeDelete(editor, domain);
Collection subcascade = listener.inetDomainBeforeDelete(editor, domain, known);
if(subcascade != null)
cascade.addAll(subcascade);
}
*/
 
return cascade;
}
 
204,7 → 213,7
}
}
 
public Collection userBeforeDelete(User editor, User user)
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException
{
Collection domains;
212,7 → 221,7
try {
domains = HibernateUtil.currentSession().find(
"from InetDomain where owner = ?",
user, Hibernate.entity(InetDomain.class) );
user, Hibernate.entity(User.class) );
}
catch(HibernateException ex)
{
225,7 → 234,7
if(d.viewableBy(editor)) {
if(d.deleteableBy(editor))
cascade.add(new CascadeDeleteElement(d, CascadeDeleteElement.DELETE,
this.beforeDelete(editor, d)));
this.beforeDelete(editor, d, known)));
else
cascade.add(new CascadeDeleteElement(d, CascadeDeleteElement.FORBIDDEN, null));
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/SystemUser.java
123,4 → 123,12
{
return editor.isSuperuser();
}
 
protected static SystemUser createLimitedCopy(SystemUser origin)
{
SystemUser u = new SystemUser();
u.setUid(origin.getUid());
u.setName(origin.getName());
return u;
}
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailboxManager.java
8,8 → 8,19
import ak.hostadmiral.util.ModelSecurityException;
 
public class MailboxManager
implements
UserBeforeDeleteListener,
SystemUserBeforeDeleteListener,
InetDomainBeforeDeleteListener
{
private static MailboxManager mailboxManager = null;
private static boolean registered = false;
 
public static MailboxManager getInstance()
{
return mailboxManager;
}
 
protected static void register()
{
synchronized(MailboxManager.class) {
19,6 → 30,8
try {
HibernateUtil.getConfiguration().addResource(
"/ak/hostadmiral/core/model/Mailbox.hbm.xml");
 
mailboxManager = new MailboxManager();
}
catch(Exception ex) {
ex.printStackTrace();
31,8 → 44,13
register();
}
 
private Collection beforeDeleteListeners = new ArrayList();
 
private MailboxManager()
{
UserManager.getInstance().addBeforeDeleteListener(this);
SystemUserManager.getInstance().addBeforeDeleteListener(this);
InetDomainManager.getInstance().addBeforeDeleteListener(this);
}
 
public Mailbox create(User editor)
130,6 → 148,31
}
}
 
public void addBeforeDeleteListener(MailboxBeforeDeleteListener listener)
{
beforeDeleteListeners.add(listener);
}
 
public void removeBeforeDeleteListener(MailboxBeforeDeleteListener listener)
{
beforeDeleteListeners.remove(listener);
}
 
public Collection beforeDelete(User editor, Mailbox mailbox, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
 
for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
MailboxBeforeDeleteListener listener = (MailboxBeforeDeleteListener)i.next();
Collection subcascade = listener.mailboxBeforeDelete(editor, mailbox, known);
if(subcascade != null)
cascade.addAll(subcascade);
}
 
return cascade;
}
 
public void delete(User editor, Mailbox mailbox)
throws ModelException
{
188,14 → 231,81
}
}
 
private static MailboxManager mailboxManager = null;
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException
{
Collection mailboxes;
 
public static MailboxManager getInstance()
try {
mailboxes = HibernateUtil.currentSession().find(
"from Mailbox where owner = ?",
user, Hibernate.entity(User.class) );
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
 
return iterateBeforeDelete(editor, mailboxes, known);
}
 
public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
throws ModelException
{
if(mailboxManager == null)
mailboxManager = new MailboxManager();
Collection mailboxes;
 
return mailboxManager;
try {
mailboxes = HibernateUtil.currentSession().find(
"from Mailbox where domain = ?",
domain, Hibernate.entity(InetDomain.class) );
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
 
return iterateBeforeDelete(editor, mailboxes, known);
}
 
public Collection systemUserBeforeDelete(User editor, SystemUser user, Collection known)
throws ModelException
{
Collection mailboxes;
 
try {
mailboxes = HibernateUtil.currentSession().find(
"from Mailbox where systemUser = ?",
user, Hibernate.entity(SystemUser.class) );
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
 
return iterateBeforeDelete(editor, mailboxes, known);
}
 
private Collection iterateBeforeDelete(User editor, Collection mailboxes, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
Mailbox mailbox = (Mailbox)i.next();
if(mailbox.viewableBy(editor)) {
if(mailbox.deleteableBy(editor))
cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.DELETE,
this.beforeDelete(editor, mailbox, known)));
else
cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.FORBIDDEN,
null));
}
else {
cascade.add(new CascadeDeleteElement(Mailbox.createLimitedCopy(mailbox),
CascadeDeleteElement.FORBIDDEN, null));
}
}
 
return cascade;
}
 
public static final Comparator LOGIN_COMPARATOR = new LoginComparator();
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/ModelObject.java
2,6 → 2,8
 
public interface ModelObject
{
public Long getId();
 
public String getTypeKey();
 
public String getIdentKey();
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserBeforeDeleteListener.java
10,9 → 10,11
*
* @param editor who is doing the operation
* @param user the user to delete
* @param known Collection(Object) - already known objects which are touched by current operation,
* to avoid loops
* @return Collection(CascadeDeleteElement) - object which are touched by deleting the user
* FIXME: limit deep of load?
*/
public Collection userBeforeDelete(User editor, User user)
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException;
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/Mailbox.java
220,5 → 220,12
return editor.isSuperuser()
|| InetDomainManager.getInstance().areInetDomainsAvailable(editor);
}
 
protected static Mailbox createLimitedCopy(Mailbox origin)
{
Mailbox u = new Mailbox();
u.setLogin(origin.getLogin());
u.setDomain(origin.getDomain());
return u;
}
}
 
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/SystemUserBeforeDeleteListener.java
0,0 → 1,20
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface SystemUserBeforeDeleteListener
{
/**
* called if some system user is about to be deleted.
*
* @param editor who is doing the operation
* @param user the user to delete
* @param known Collection(Object) - already known objects which are touched by current operation,
* to avoid loops
* @return Collection(CascadeDeleteElement) - object which are touched by deleting the user
* FIXME: limit deep of load?
*/
public Collection systemUserBeforeDelete(User editor, SystemUser user, Collection known)
throws ModelException;
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/InetDomainBeforeDeleteListener.java
0,0 → 1,20
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface InetDomainBeforeDeleteListener
{
/**
* called if some domain is about to be deleted.
*
* @param editor who is doing the operation
* @param domain the domain to delete
* @param known Collection(Object) - already known objects which are touched by current operation,
* to avoid loops
* @return Collection(CascadeDeleteElement) - object which are touched by deleting the domain
* FIXME: limit deep of load?
*/
public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
throws ModelException;
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserLogin.java
0,0 → 1,114
package ak.hostadmiral.core.model;
 
import java.util.Date;
 
/**
*
* @hibernate.class table="userlogins"
*/
public class UserLogin
{
private Long id;
private User user;
private String login;
private Date loginTime;
private Boolean success;
private String ip;
 
protected UserLogin()
{
}
 
protected UserLogin(User user, String login, Date loginTime, Boolean success, String ip)
{
this.user = user;
this.login = login;
this.loginTime = loginTime;
this.success = success;
this.ip = ip;
}
 
/**
*
* @hibernate.id generator-class="native"
*/
public Long getId()
{
return id;
}
 
protected void setId(Long id)
{
this.id = id;
}
 
/**
*
* @hibernate.many-to-one column="usr"
*/
public User getUser()
{
return user;
}
 
protected void setUser(User user)
{
this.user = user;
}
 
/**
*
* @hibernate.property
*/
public String getLogin()
{
return login;
}
 
protected void setLogin(String login)
{
this.login = login;
}
 
/**
*
* @hibernate.property
*/
public Date getLoginTime()
{
return loginTime;
}
 
protected void setLoginTime(Date loginTime)
{
this.loginTime = loginTime;
}
 
/**
*
* @hibernate.property
*/
public Boolean getSuccess()
{
return success;
}
 
protected void setSuccess(Boolean success)
{
this.success = success;
}
 
/**
*
* @hibernate.property
*/
public String getIp()
{
return ip;
}
 
protected void setIp(String ip)
{
this.ip = ip;
}
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailboxBeforeDeleteListener.java
0,0 → 1,20
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface MailboxBeforeDeleteListener
{
/**
* called if some mailbox is about to be deleted.
*
* @param editor who is doing the operation
* @param mailbox the mailbox to delete
* @param known Collection(Object) - already known objects which are touched by current operation,
* to avoid loops
* @return Collection(CascadeDeleteElement) - object which are touched by deleting the mailbox
* FIXME: limit deep of load?
*/
public Collection mailboxBeforeDelete(User editor, Mailbox mailbox, Collection known)
throws ModelException;
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/MailAliasBeforeDeleteListener.java
0,0 → 1,21
package ak.hostadmiral.core.model;
 
import java.util.Collection;
import ak.hostadmiral.util.ModelException;
 
public interface MailAliasBeforeDeleteListener
{
/**
* called if some mail alias is about to be deleted.
*
* @param editor who is doing the operation
* @param alias the mail alias to delete
* @param known Collection(Object) - already known objects which are touched by current operation,
* to avoid loops
* @return Collection(CascadeDeleteElement)
* - object which are touched by deleting the mail alias
* FIXME: limit deep of load?
*/
public Collection mailAliasBeforeDelete(User editor, MailAlias mailAlias, Collection known)
throws ModelException;
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/model/UserManager.java
27,6 → 27,8
try {
HibernateUtil.getConfiguration().addResource(
"/ak/hostadmiral/core/model/User.hbm.xml");
HibernateUtil.getConfiguration().addResource(
"/ak/hostadmiral/core/model/UserLogin.hbm.xml");
 
userManager = new UserManager();
}
108,7 → 110,9
{
try {
List list = HibernateUtil.currentSession().find(
"from User where login=? and enabled='1'", login, Hibernate.STRING);
"from User where login = ? and enabled = ?",
new Object[] { login, new Boolean(true) },
new Type[] { Hibernate.STRING, Hibernate.BOOLEAN } );
 
if(list.size() == 0)
return null;
151,7 → 155,7
beforeDeleteListeners.remove(listener);
}
 
public Collection beforeDelete(User editor, User user)
public Collection beforeDelete(User editor, User user, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
158,7 → 162,7
 
for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
UserBeforeDeleteListener listener = (UserBeforeDeleteListener)i.next();
Collection subcascade = listener.userBeforeDelete(editor, user);
Collection subcascade = listener.userBeforeDelete(editor, user, known);
if(subcascade != null)
cascade.addAll(subcascade);
}
222,26 → 226,50
}
}
 
public User loginUser(String login, String password)
public User loginUser(String login, String password, String ip)
throws ModelException
{
if(login == null || password == null)
return null;
User user = (login == null || password == null) ? null : findForLogin(login);
boolean success = (user == null) ? false : user.checkPassword(password);
UserLogin userLogin = new UserLogin(user, login, new Date(), new Boolean(success), ip);
 
User user = findForLogin(login);
 
if(user != null) {
if(user.checkPassword(password))
return user;
// save login information
try {
HibernateUtil.currentSession().saveOrUpdate(userLogin);
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
 
// wrong login or password
return null;
if(success)
return user;
else
return null; // wrong login or password
}
 
public Collection userBeforeDelete(User editor, User user)
public Collection listFailedLogins(User editor)
throws ModelException
{
if(!editor.mayViewAllLogins())
{
throw new ModelSecurityException();
}
 
try {
return HibernateUtil.currentSession().find(
"from UserLogin where success = ?",
new Boolean(false), Hibernate.BOOLEAN);
}
catch(HibernateException ex)
{
throw new ModelException(ex);
}
}
 
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException
{
Collection subusers;
 
try {
260,7 → 288,7
if(u.viewableBy(editor)) {
if(u.deleteableBy(editor))
cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.DELETE,
this.beforeDelete(editor, u)));
this.beforeDelete(editor, u, known)));
else
cascade.add(new CascadeDeleteElement(u, CascadeDeleteElement.FORBIDDEN, null));
}
274,6 → 302,7
}
 
public static final Comparator LOGIN_COMPARATOR = new LoginComparator();
public static final Comparator LOGINS_TIME_COMPARATOR = new LoginsTimeComparator();
 
private static class LoginComparator
implements Comparator
301,4 → 330,31
return (obj instanceof LoginComparator);
}
}
 
private static class LoginsTimeComparator
implements Comparator
{
public int compare(Object o1, Object o2)
{
if(!(o1 instanceof UserLogin) || !(o2 instanceof UserLogin))
throw new ClassCastException("not a UserLogin");
 
UserLogin a1 = (UserLogin)o1;
UserLogin a2 = (UserLogin)o2;
 
if(a1 == null && a2 == null)
return 0;
else if(a1 == null && a2 != null)
return -1;
else if(a1 != null && a2 == null)
return 1;
else
return a1.getLoginTime().compareTo(a2.getLoginTime());
}
 
public boolean equals(Object obj)
{
return (obj instanceof LoginComparator);
}
}
}
/sun/hostadmiral/trunk/src/ak/hostadmiral/core/servlet/ProfilerFilter.java
0,0 → 1,47
package ak.hostadmiral.core.servlet;
 
import java.io.IOException;
import java.net.URLEncoder;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
 
/**
* Prints out time of request execution.
*/
public class ProfilerFilter
implements Filter
{
private static final Logger logger = Logger.getLogger(ProfilerFilter.class);
 
public void init(FilterConfig filterConfig)
throws ServletException
{
}
 
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
logger.debug("begin");
 
long t1 = System.currentTimeMillis();
chain.doFilter(request, response);
long t2 = System.currentTimeMillis();
 
logger.info((t2 - t1) + " ms");
}
 
public void destroy()
{
}
}
/sun/hostadmiral/trunk/webapp/deleting.jsp
0,0 → 1,41
<%@ 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" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/ak-backpath.tld" prefix="backpath" %>
<%@ taglib uri="/WEB-INF/hostadmiral-core.tld" prefix="core" %>
<html>
 
<head>
<meta http-equiv="expires" content="0">
<title><bean:message key="ak.hostadmiral.page.index.title" /></title>
</head>
 
<body>
 
<h1><bean:message key="ak.hostadmiral.page.index.title" /></h1>
 
<p>Object: <bean:write name="object" property="identKey" /></p>
<p>Action: <bean:write name="action" /></p>
<p>Cascade: <bean:write name="cascade" /></p>
 
<ul>
<%
Collection cascade = (Collection)request.getAttribute("cascade");
 
for(Iterator i = cascade.iterator(); i.hasNext(); ) {
CascadeDeleteElement e = (CascadeDeleteElement)i.next();
pageContext.setAttribute("e", e);
 
%><li><bean:write name="e" property="object.identKey" /></li><%
}
%>
</ul>
 
<br>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.list.back" /></backpath:backlink>
 
</body>
 
</html>
/sun/hostadmiral/trunk/webapp/WEB-INF/.cvsignore
File deleted
/sun/hostadmiral/trunk/webapp/WEB-INF/web.xml
7,6 → 7,10
<web-app>
 
<filter>
<filter-name>Profiler Filter</filter-name>
<filter-class>ak.hostadmiral.core.servlet.ProfilerFilter</filter-class>
</filter>
<filter>
<filter-name>Encoding Filter</filter-name>
<filter-class>ak.hostadmiral.core.servlet.EncodingFilter</filter-class>
</filter>
39,6 → 43,10
</filter>
 
<filter-mapping>
<filter-name>Profiler Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/sun/hostadmiral/trunk/webapp/WEB-INF/struts-config.xml
28,6 → 28,12
</form-bean>
 
<form-bean
name="ak.hostadmiral.core.form.UserLoginsForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="id" type="java.lang.String" />
</form-bean>
 
<form-bean
name="ak.hostadmiral.core.form.UserEditForm"
type="ak.hostadmiral.core.form.UserPasswordForm">
<form-property name="id" type="java.lang.String" />
191,6 → 197,23
</action>
 
<action
path="/user/logins"
type="ak.hostadmiral.core.action.UserLoginsAction"
name="ak.hostadmiral.core.form.UserLoginsForm"
validate="true"
scope="request"
>
<forward name="default" path="/user/logins.jsp" />
</action>
 
<action
path="/user/failedLogins"
type="ak.hostadmiral.core.action.FailedLoginsAction"
>
<forward name="default" path="/user/failedLogins.jsp" />
</action>
 
<action
path="/user/list"
type="ak.hostadmiral.core.action.UserAction"
parameter="list"
/sun/hostadmiral/trunk/webapp/WEB-INF/validation.xml
32,13 → 32,20
 
<form name="ak.hostadmiral.core.form.UserForm">
<field property="id" depends="long">
<msg name="long" key="ak.hostadmiral.core.user.password.change.id.wrong" />
<msg name="long" key="ak.hostadmiral.core.user.id.wrong" />
</field>
</form>
 
<form name="ak.hostadmiral.core.form.UserLoginsForm">
<field property="id" depends="required,long">
<msg name="required" key="ak.hostadmiral.core.user.id.wrong" />
<msg name="long" key="ak.hostadmiral.core.user.id.wrong" />
</field>
</form>
 
<form name="ak.hostadmiral.core.form.UserEditForm">
<field property="id" depends="long">
<msg name="long" key="ak.hostadmiral.core.user.password.change.id.wrong" />
<msg name="long" key="ak.hostadmiral.core.user.id.wrong" />
</field>
<field property="login" depends="required">
<msg name="required" key="ak.hostadmiral.core.login.required" />
/sun/hostadmiral/trunk/webapp/user/edit.jsp
77,6 → 77,10
 
</html:form>
 
<p>
<backpath:link action="/user/logins" paramId="id" paramName="u" paramProperty="id"><bean:message key="ak.hostadmiral.page.user.edit.logins" /></backpath:link>
</p>
 
</body>
 
</html>
/sun/hostadmiral/trunk/webapp/user/view.jsp
66,6 → 66,10
</tr>
</table>
 
<p>
<backpath:link action="/user/logins" paramId="id" paramName="u" paramProperty="id"><bean:message key="ak.hostadmiral.page.user.view.logins" /></backpath:link>
</p>
 
</body>
 
</html>
/sun/hostadmiral/trunk/webapp/user/list.jsp
61,7 → 61,7
</td>
<td>
<core:deleteable name="u">
<backpath:link action="/user/delete" paramId="id" paramName="u" paramProperty="id"><bean:message key="ak.hostadmiral.page.user.list.delete" /></backpath:link>
<backpath:link action="/user/deleting" paramId="id" paramName="u" paramProperty="id"><bean:message key="ak.hostadmiral.page.user.list.delete" /></backpath:link>
</core:deleteable>
<core:notDeleteable name="u">
&nbsp;
73,6 → 73,8
 
<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>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.list.back" /></backpath:backlink>
 
</body>
/sun/hostadmiral/trunk/webapp/user/logins.jsp
0,0 → 1,49
<%@ 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" %>
<%@ taglib uri="/WEB-INF/ak-backpath.tld" prefix="backpath" %>
<%@ taglib uri="/WEB-INF/hostadmiral-core.tld" prefix="core" %>
<html>
 
<head>
<meta http-equiv="expires" content="0">
<title><bean:message key="ak.hostadmiral.page.user.logins.title" /></title>
</head>
 
<body>
 
<h1><bean:message key="ak.hostadmiral.page.user.logins.title" /></h1>
 
<html:errors/>
 
<p>
<bean:message key="ak.hostadmiral.page.user.logins.login" />
<strong><bean:write name="u" property="login" /></strong>
</p>
 
<table border=1>
<tr>
<th><bean:message key="ak.hostadmiral.page.user.logins.time" /></th>
<th><bean:message key="ak.hostadmiral.page.user.logins.success" /></th>
<th><bean:message key="ak.hostadmiral.page.user.logins.ip" /></th>
</tr>
 
<logic:iterate name="logins" id="l">
<tr>
<td><bean:write name="l" property="loginTime" /></td>
<td>
<logic:equal name="l" property="success" value="true">x</logic:equal>
<logic:notEqual name="l" property="success" value="true">&nbsp;</logic:notEqual>
</td>
<td><bean:write name="l" property="ip" /></td>
</tr>
</logic:iterate>
</table>
 
<br>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.logins.back" /></backpath:backlink>
 
</body>
 
</html>
/sun/hostadmiral/trunk/webapp/user/failedLogins.jsp
0,0 → 1,51
<%@ 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" %>
<%@ taglib uri="/WEB-INF/ak-backpath.tld" prefix="backpath" %>
<%@ taglib uri="/WEB-INF/hostadmiral-core.tld" prefix="core" %>
<html>
 
<head>
<meta http-equiv="expires" content="0">
<title><bean:message key="ak.hostadmiral.page.user.failedLogins.title" /></title>
</head>
 
<body>
 
<h1><bean:message key="ak.hostadmiral.page.user.failedLogins.title" /></h1>
 
<html:errors/>
 
<table border=1>
<tr>
<th><bean:message key="ak.hostadmiral.page.user.failedLogins.login" /></th>
<th><bean:message key="ak.hostadmiral.page.user.failedLogins.user.exists" /></th>
<th><bean:message key="ak.hostadmiral.page.user.failedLogins.time" /></th>
<th><bean:message key="ak.hostadmiral.page.user.failedLogins.success" /></th>
<th><bean:message key="ak.hostadmiral.page.user.failedLogins.ip" /></th>
</tr>
 
<logic:iterate name="logins" id="l">
<tr>
<td><bean:write name="l" property="login" /></td>
<td>
<logic:present name="l" property="user">x</logic:present>
<logic:notPresent name="l" property="user">&nbsp;</logic:notPresent>
</td>
<td><bean:write name="l" property="loginTime" /></td>
<td>
<logic:equal name="l" property="success" value="true">x</logic:equal>
<logic:notEqual name="l" property="success" value="true">&nbsp;</logic:notEqual>
</td>
<td><bean:write name="l" property="ip" /></td>
</tr>
</logic:iterate>
</table>
 
<br>
<backpath:backlink><bean:message key="ak.hostadmiral.page.user.failedLogins.back" /></backpath:backlink>
 
</body>
 
</html>
/sun/hostadmiral/trunk/sql/00.tables.sql
28,6 → 28,20
constraint users_boss foreign key (boss) references users(id)
);
 
-- login tries. "usr" is set if the user is found only
create table userlogins
(
id integer not null,
usr integer,
login varchar(255) not null,
logintime timestamp not null,
success char(1) default '0' check (success = '1' or success = '0'),
ip inet not null,
 
constraint userlogins_prim primary key (id),
constraint userlogins_user foreign key (usr) references users(id)
);
 
-- default user admin:admin
insert into users (id, login, password, superuser) values (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '1');
select nextval('hibernate_sequence'); -- skip id of the default user
/sun/hostadmiral/trunk/doc/todo.txt
1,3 → 1,6
Host Admiral TODO
=================
 
+ Save user id for all db-update operations.
 
Set 'editor' for an object by loading and not require it for each property change?
5,10 → 8,60
 
Specification for the model.
 
Test cases for model, based on the specification. Check all bound conditions - e.g. security exceptions.
Write a complete scenario to start with default database, login as admin, create users, domaind, logout,
login as normal user, create/delete/modify mailboxes and aliases etc.
Test cases for model, based on the specification. Check all bound conditions
- e.g. security exceptions. Write a complete scenario to start with default database;
login as admin, create users, domains, logout; login as normal user,
create/delete/modify mailboxes and aliases etc.
 
Test cases for actions, not so detailed as for the model (because it makes no sense to parse html pages).
Test cases for actions, not so detailed as for the model
(because it makes no sense to parse html pages).
The scenario for the model test can be used.
 
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.
 
Check passwords quality (make a separate project for this).
 
Show filters, search.
 
Multi-page lists.
 
Sort options for lists.
 
Different user name schemes, not only user@domain. Define an interface to allow admin
implement an own one. Implement a few common ones.
 
Taglig to show ActionMessages in right way (add it to the StrutsX project).
 
Allow to use existing system users: enter uid or name only, check in system for full
information.
 
I18n. Switch language of page on the fly. Save selection in DB for each user.
Allow admin to define default language for server and domain.
 
Split CoreResources.properties to several files.
 
Show domain for user which is in the domain.
 
Check, if it's possible to create (or change) an object by admin that the object's owner
is not allowed to see it.
 
Check maxlength.
 
Make hierarchy of domains.
 
Allow user to create domains (?) and subdomains in his domains.
 
Change shell password for system user if its onwer's password is changed (?).
 
Catch-all mail alias. Only one per domain.
 
+ 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.