int totalCount=getMessageCount();
if(totalCount>=0){
cell.setTooltipText("Folder contains "+totalCount+" messages");
}
else{
cell.setTooltipText(null);
}
if(getFolderId()!=null){
if(getDetailForm()==null){
MailForm f=new MailForm();
f.setFolderId(getFolderId());
setDetailForm(f);
f.startView();
}
}
for(Object[] row: SERVICES.getService(IMailProcessService.class).getChildFolders(getFolderId())){
MailNodePage page=new MailNodePage();
page.setFolderId((String)row[0]);
page.setFolderName((String)row[1]);
page.setMessageCount((Integer)row[2]);
page.setUnreadMessageCount((Integer)row[4]);
pageList.add(page);
}
getOutline().setStatus(new ProcessingStatus(""+getMessageCount()+" message(s)",IStatus.INFO));
if(rows.length==1){
byte[] data=SERVICES.getService(IMailProcessService.class).getMessage(getFolderId()(),getUidColumn().getValue(rows[0]));
if(data!=null){
try{
getMailField().setValue(new MimeMessage(null,new ByteArrayInputStream(data)));
}
catch(javax.mail.MessagingException e){
throw new ProcessingException(e.getMessage(),e);
}
}
else{
getMailField().setValue(null);
}
}
else{
getMailField().setValue(null);
}
Object[][] data=SERVICES.getService(IMailProcessService.class).getMessageHeaders(getFolderId()());
getMailTableField().getTable().replaceRowsByMatrix(data);
/**
* @return fullName (ID), name, count, newCount, unreadCount
*/
public Object[][] getChildFolders(String parentName) throws ProcessingException;
/**
* @return folderId (ID), uid (ID), from, subject, date, size
*/
public Object[][] getMessageHeaders(String folderId) throws ProcessingException;
/**
* @return MimeMessage
*/
public byte[] getMessage(String folderd,long uid) throws ProcessingException;
private ImapAdapter createImapAdapter(){
ImapPrincipal principal=null;
for(ImapPrincipal p : Subject.getSubject(AccessController.getContext()).getPrincipals(ImapPrincipal.class)){
principal=p;
}
if(principal != null){
ImapAdapter adapter=new ImapAdapter(principal.getHost(), 143, principal.getUsername(), principal.getPassword());
adapter.setUseSSL(true);
return adapter;
}
return null;
}
/**
* @return fullName (ID), name, count, newCount, unreadCount
*/
public Object[][] getChildFolders(String parentName) throws ProcessingException{
ImapAdapter adapter=createImapAdapter();
try{
ArrayList<Object[]> rows=new ArrayList<Object[]>();
adapter.connect();
javax.mail.Folder parent=parentName!=null ? adapter.getStore().getFolder(parentName) : adapter.getStore().getDefaultFolder();
if(parent!=null && parent.exists()){
for(javax.mail.Folder f : parent.list()){
if(f.exists()){
if(f instanceof javax.mail.UIDFolder){
if((f.getType() & javax.mail.Folder.HOLDS_MESSAGES)!=0){
Object[] row=new Object[]{f.getFullName(),f.getName(),f.getMessageCount(),f.getNewMessageCount(),f.getUnreadMessageCount()};
rows.add(row);
}
else if((f.getType() & javax.mail.Folder.HOLDS_FOLDERS)!=0){
Object[] row=new Object[]{f.getFullName(),f.getName(),0,0,0};
rows.add(row);
}
}
}
}
}
return rows.toArray(new Object[0][0]);
}
catch(ProcessingException p){
throw p;
}
catch(Throwable t){
throw new ProcessingException(t.getMessage(),t);
}
finally{
adapter.closeConnection();
}
}
/**
* @return folderName (ID), uid (ID), from, subject, date, size
*/
public Object[][] getMessageHeaders(String folderName) throws ProcessingException{
ImapAdapter adapter=createImapAdapter();
try{
ArrayList<Object[]> rows=new ArrayList<Object[]>();
adapter.connect();
javax.mail.Folder f=adapter.getStore().getFolder(folderName);
if(f!=null && f.exists()){
if(f instanceof javax.mail.UIDFolder){
f.open(javax.mail.Folder.READ_ONLY);
try{
javax.mail.Message[] msgs=f.getMessages();
javax.mail.FetchProfile fp=new javax.mail.FetchProfile();
fp.add(javax.mail.FetchProfile.Item.ENVELOPE);
f.fetch(msgs,fp);
for(javax.mail.Message m: msgs){
if(!m.isExpunged()){
Object[] row=new Object[]{folderName, ((javax.mail.UIDFolder)f).getUID(m),firstAddress(m.getFrom()),m.getSubject(),m.getSentDate(),m.getSize()};
rows.add(row);
}
}
}
finally{
f.close(false);
}
}
}
return rows.toArray(new Object[0][0]);
}
catch(ProcessingException p){
throw p;
}
catch(Throwable t){
throw new ProcessingException(t.getMessage(),t);
}
finally{
adapter.closeConnection();
}
}
public byte[] getMessage(String folderId,long uid) throws ProcessingException{
ImapAdapter adapter=createImapAdapter();
try{
adapter.connect();
javax.mail.Folder f=adapter.getStore().getFolder(folderId);
if(f!=null && f.exists()){
if(f instanceof javax.mail.UIDFolder){
f.open(javax.mail.Folder.READ_ONLY);
try{
javax.mail.Message m=((javax.mail.UIDFolder)f).getMessageByUID(uid);
if(m!=null && !m.isExpunged() && m instanceof javax.mail.internet.MimeMessage){
ByteArrayOutputStream out=new ByteArrayOutputStream();
m.writeTo(out);
return out.toByteArray();
}
}
finally{
f.close(false);
}
}
}
return null;
}
catch(ProcessingException p){
throw p;
}
catch(Throwable t){
throw new ProcessingException(t.getMessage(),t);
}
finally{
adapter.closeConnection();
}
}
private String firstAddress(javax.mail.Address[] a){
if(a!=null && a.length>0 && a[0] instanceof InternetAddress){
InternetAddress ia=(InternetAddress)a[0];
String s=ia.getPersonal();
if(StringUtility.isNullOrEmpty(s)) s=ia.getAddress();
return s;
}
return null;
}
package com.example.mail.server.core;
import java.io.Serializable;
import java.security.Principal;
public class ImapPrincipal implements Principal, Serializable{
private static final long serialVersionUID=1L;
private String m_host;
private String m_username;
private String m_password;
public ImapPrincipal(String host, String username, String password) {
if(host == null) throw new IllegalArgumentException("host must not be null");
if(username == null) throw new IllegalArgumentException("username must not be null");
if(password == null) throw new IllegalArgumentException("password must not be null");
m_host=host;
m_username=username;
m_password=password;
}
public String getName(){
return m_username+"@"+m_host;
}
public String getHost(){
return m_host;
}
public String getPassword(){
return m_password;
}
public String getUsername(){
return m_username;
}
@Override
public int hashCode(){
return getName().hashCode();
}
@Override
public boolean equals(Object other){
if(other == this) return true;
if(!(other instanceof ImapPrincipal)){
return false;
}
else{
String myFullName=getName();
String otherFullName=((ImapPrincipal)other).getName();
return myFullName.equals(otherFullName);
}
}
@Override
public String toString(){
return getName();
}
}
package com.example.mail.server.core;
import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.security.auth.Subject;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.scout.commons.Base64Utility;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.http.servletfilter.FilterConfigInjection;
import org.eclipse.scout.rt.server.services.common.imap.ImapAdapter;
import org.eclipse.scout.rt.server.servlet.filter.SecureHttpServletRequestWrapper;
import org.eclipse.scout.rt.shared.services.common.security.SimplePrincipal;
public class ImapSecurityFilter implements Filter{
private static IScoutLogger LOG=ScoutLogManager.getLogger(ImapSecurityFilter.class);
private FilterConfigInjection m_injection;
private Object m_lock;
private String m_host;
public ImapSecurityFilter(){
m_lock=new Object();
}
public void init(FilterConfig config0) throws ServletException{
m_injection=new FilterConfigInjection(config0, getClass());
FilterConfigInjection.FilterConfig config=m_injection.getAnyConfig();
String host=config.getInitParameter("host");
if(host==null) throw new ServletException("missing init-paramter 'host'");
m_host=host;
}
public void destroy(){
m_host=null;
m_injection=null;
}
public void doFilter(ServletRequest in, ServletResponse out, final FilterChain chain) throws IOException, ServletException{
FilterConfigInjection.FilterConfig config=m_injection.getConfig(in);
if(!config.isActive()){
chain.doFilter(in, out);
return;
}
//
final HttpServletRequest req=(HttpServletRequest)in;
final HttpServletResponse res=(HttpServletResponse)out;
// touch the session so it is effectively used
req.getSession();
// check subject on session
Subject subject;
synchronized(m_lock){
subject=findSubjectOnSession(req, res);
if(subject == null || subject.getPrincipals().size() == 0){
// try negotiate
Principal p=negotiate(req, res);
if(p==null){
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
if(subject == null || subject.isReadOnly()){
subject=new Subject();
}
subject.getPrincipals().add(p);
subject.setReadOnly();
req.getSession().setAttribute(Subject.class.getName(), subject);
}
}
// run in subject
if(Subject.getSubject(AccessController.getContext()) != null){
doFilterInternal(req, res, chain);
}
else{
try{
Subject.doAs(subject, new PrivilegedExceptionAction(){
public Object run() throws Exception{
doFilterInternal(req, res, chain);
return null;
}
});
}
catch(PrivilegedActionException e){
Throwable t=e.getCause();
if(t instanceof IOException){
throw (IOException)t;
}
else if(t instanceof ServletException){
throw (ServletException)t;
}
else{
throw new ServletException(t);
}
}
}
}
private void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException{
if(req.getRemoteUser() == null && req.getUserPrincipal() == null){
Principal principal=Subject.getSubject(AccessController.getContext()).getPrincipals().iterator().next();
chain.doFilter(new SecureHttpServletRequestWrapper(req, principal, "BASIC"), res);
}
else{
chain.doFilter(req, res);
}
}
private Subject findSubjectOnSession(HttpServletRequest req, HttpServletResponse resp){
// check if we are already authenticated
Subject subject=null;
if(subject == null){
subject=Subject.getSubject(AccessController.getContext());
}
if(subject == null){
Object o=null;
o=req.getSession().getAttribute(Subject.class.getName());
if(o instanceof Subject){
subject=(Subject)o;
}
}
if(subject == null){
Principal principal=req.getUserPrincipal();
if(principal == null || principal.getName() == null || principal.getName().trim().length() == 0){
principal=null;
String name=req.getRemoteUser();
if(name != null && name.trim().length() > 0){
principal=new SimplePrincipal(name);
}
}
if(principal != null){
subject=new Subject();
subject.getPrincipals().add(principal);
subject.setReadOnly();
req.getSession().setAttribute(Subject.class.getName(), subject);
}
}
return subject;
}
/**
* set the 'WWW-Authenticate' value on the response to enforce the client to
* provide login data.
*
* @param req
* @param resp
* @return
*/
protected Principal negotiate(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException{
String h=req.getHeader("Authorization");
if(h != null && h.matches("Basic .*")){
String[] a=new String(Base64Utility.decode(h.substring(6))).split(":", 2);
String user=a[0].toLowerCase();
String pass=a[1];
if(user != null && pass != null){
ImapAdapter adapter=new ImapAdapter(m_host,143,user,pass);
adapter.setUseSSL(true);
try{
adapter.connect();
adapter.closeConnection();
return new ImapPrincipal(m_host,user,pass);
}
catch(Throwable t){
//nop, failed
}
}
}
resp.setHeader("WWW-Authenticate", "Basic realm=\""+m_host+"\"");
return null;
}
}