/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,16 → 254,40 |
} |
} |
private static SystemUserManager systemUserManager = null; |
public Collection userBeforeDelete(User editor, User user, Collection known) |
throws ModelException |
{ |
Collection systemUsers; |
public static SystemUserManager getInstance() |
try { |
systemUsers = HibernateUtil.currentSession().find( |
"from SystemUser where owner = ?", |
user, Hibernate.entity(User.class) ); |
} |
catch(HibernateException ex) |
{ |
if(systemUserManager == null) |
systemUserManager = new SystemUserManager(); |
throw new ModelException(ex); |
} |
return systemUserManager; |
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(); |
public static final Comparator NAME_COMPARATOR = new NameComparator(); |
/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; |
15,6 → 18,7 |
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,16 → 231,83 |
} |
} |
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) |
{ |
if(mailboxManager == null) |
mailboxManager = new MailboxManager(); |
throw new ModelException(ex); |
} |
return mailboxManager; |
return iterateBeforeDelete(editor, mailboxes, known); |
} |
public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known) |
throws ModelException |
{ |
Collection mailboxes; |
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(); |
private static class 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,24 → 226,48 |
} |
} |
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); |
// save login information |
try { |
HibernateUtil.currentSession().saveOrUpdate(userLogin); |
} |
catch(HibernateException ex) |
{ |
throw new ModelException(ex); |
} |
if(user != null) { |
if(user.checkPassword(password)) |
if(success) |
return user; |
else |
return null; // wrong login or password |
} |
// wrong login or password |
return null; |
public Collection listFailedLogins(User editor) |
throws ModelException |
{ |
if(!editor.mayViewAllLogins()) |
{ |
throw new ModelSecurityException(); |
} |
public Collection userBeforeDelete(User editor, User user) |
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; |
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"> |
|
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"> </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"> </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"> </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. |