MailPortlet User Manual

MailPortlet v2.0.0-alpha-7 User Manual

Foreword

Matt Young and Ren Provey of the Internet Frameworks Services division of Duke University's Office Of Information Technology (OIT) created the original version of this portlet in 2007. With some modifications, it was contributed by Duke University to the JA-SIG community in early 2008. Following that, Jen Bourey (of Yale University), Eric Dalquist (of University of Wisconsin-Madison), Erik A. Olsson (of University of California, Irvine), and Gary Weaver (of Duke University) made contributions. The MailPortlet is a collaborative open-source project whose source control, wiki, and project tracking is hosted by Jasig.

License

Mail Portlet is free under the Apache 2.0 license (note that earlier versions were contributed under the BSD License).

Feedback

If you'd like to ask questions and/or provide feedback on usage and configuration, please contact use via the portlet-user list. Requests for enhancements and discussion of its development can be made via the portlet-dev list and/or via the MPT Jasig-hosted Jira project. Please request support via email on the portlet-user list if it is a matter of just getting it setup/working properly. Please don't make comments to this page or the MailPortlet page unless it is about the portlet or user manual itself. Please don't add bugs/enhancement requests to Jira unless you have read all documentation and attempted to get support via lists first.

Disclaimer

The Mail portlet is capable of fetching email headers from any IMAP server or POP server, although the portlet may display a timeout error to the user in the mail pane for POP servers when there is a lot of email in the user's INBOX. This portlet is not intended to be a rich email client, but rather a dashboard with a quick view of some of the most recent email headers received.

Prerequisites

Before you begin, you should know how to deploy portlets into your portal environment. It is currently running at a few universities using various versions of uPortal (2.5.3 and later). If you discover a shortcoming in our code that we can correct to make the portlet more JSR-168 compliant, please let us know, but note that there has already been some discussion about FSS, PLT.C (CSS) compliance and JSR-168's poor PLT.C definition, so search Nabble first through the jasig-ui, portlet-dev, uportal-user lists for terms like "PLT-C", "PLT.C", "FSS", "MailPortlet".

Roadmap

There is no certain roadmap to the MailPortlet's future, but after Duke finished up with the pre-release version(s) in Fall 2009, Yale (Jen Bourey) may become involved in its further development. Future features/functionality to be added are TBD.

Procurement

To get the latest pre-release version of the source:

svn co https://www.ja-sig.org/svn/sandbox/MailPortlet/tags/rel-2.0.0-alpha-7

To get the latest development version of the source (which may not build and may be buggy and/or unstable):

svn co https://www.ja-sig.org/svn/sandbox/MailPortlet/trunk

Building

To develop/build the portlet, you will need to have Subversion, Maven 2, and a Java 1.5+ compiler installed.

Use the following to build the portlet:

mvn clean install

Deploying

The built portlet (war) is in the target directory. It will need to be deployed in the method specified by your JSR-168-compliant portal. If you are using uPortal, you may via uPortal with deployPortletApp or whatever the approved method for "plutofication" (modifying web.xml and adding portlet.tld, for example) and deployment is for your version of uPortal.

  • If you have trouble publishing it successfully, first be sure that you are using uPortal to deployPortletApp, or at least you're using something that adds the appropriate stuff to web.xml along with the appropriate portlet.tld in the correct place (which for uP 2.5.3 was (tomcat)/webapps/mailportlet/WEB-INF/tld/portlet.tld). If that doesn't help, read the uPortal documentation/your portal documentation, and if using uPortal, ask for help on the uportal-user list.
  • This portlet does not use or support the help view, so when publishing the portlet, in Channel Controls, "Editable" should be checked and "Has Help" and "Has About" should be unchecked.
  • This portlet won't work until you at the very least specify a key for the password encryption in its Spring config as described below.

Configuration/Customization

This portlet has XML and properties-based configuration, so you should be able to change all relevant parameters in XML and properties files rather than changing the source code.

To get up and running with MailPortlet, you only need to do the first two steps to configure it to use a real database and to set it to use your password encryption key. If you don't want to mess with persisting accounts yet, you can even skip the database config part and it will use an in-memory database (for example, if you just want to demo it).

For each of the configuration steps below, you'll either need to restart your webapp server after your changes. If you are just doing an overlay of your portlet, you can often just redeploy the portlet without a webapp server restart.

Configuring the Database

By default, MailPortlet just stores users' preferences in-memory, for testing and demonstration purposes. Since some users don't want portlets creating tables on their own, this works great for testing and demo'ing quickly in those environments.

However, you'll want to persist user account information in production. To set it up, you'll need the JDBC connection string, username, and password from the database administrator and you'll need to set hibernate.dialect to an appropriate value. In the deployed portlet edit WEB-INF/classes/datasource.properties.

Some examples:

## Oracle 10g - example
#hibernate.connection.driver_class=oracle.jdbc.OracleDriver
#hibernate.connection.url=jdbc:oracle:thin:@exampleuniversity.edu:1521:SIDGOESHERE
#hibernate.connection.username=test
#hibernate.connection.password=mypass
#hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

# MySQL - example
#hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.connection.driver_class=com.mysql.jdbc.Driver
#hibernate.connection.url=jdbc:mysql:///test
#hibernate.connection.username=test
#hibernate.connection.password=mypass

## PostgreSQL - example
#hibernate.connection.driver_class=org.postgresql.Driver
#hibernate.connection.url=jdbc:postgresql://exampleuniversity.edu/portal
#hibernate.connection.username=test
#hibernate.connection.password=mypass
#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

## Sybase - example
#hibernate.connection.driver_class=com.sybase.jdbc2.jdbc.SybDriver
#hibernate.connection.username=test
#hibernate.connection.password=mypass
#hibernate.connection.url=jdbc:sybase:Tds:exampleuniversity.edu:3456?ServiceName=STUFF
#hibernate.dialect org.hibernate.dialect.SybaseDialect

## DB2 - example
#hibernate.dialect=org.hibernate.dialect.DB2Dialect
#hibernate.connection.driver_class=com.ibm.db2.jdbc.app.DB2Driver
#hibernate.connection.url=jdbc:db2:test
#hibernate.connection.username=test
#hibernate.connection.password=mypass

For a full list of supported dialects, see the Hibernate 3.2.6 docs. For example JDBC strings see Chui's counterpoint. For other examples, see this example in Bedework.

Schema Creation and Updates

Option 1 - Let Hibernate Create and Update the Schema

It is assumed by default that the user you set in datasource.properties has rights to create and update the tables it needs to in the database automatically.

Option 2 - Autogenerate SQL and Execute SQL By-hand to Create/Update SQL

To generate the SQL for your database, alter the datasource.properties and rebuild. The SQL will be output during the build in the build output. Unfortunately if you are using an overlay build, this change will still need to happen in the original MailPortlet build.

If you are updating MailPortlet to a new version that requires changes to the database, we don't provide the database migration SQL. You will have to look at the SQL it uses for the new creates and generate the SQL for updates by hand.

Specifying Custom Mail Account Templates

Customize the mail account templates in WEB-INF/context/portlet/mailservers.xml. The default mailservers.xml contains examples.

Account Properties

fixed

If you have some way for the user to authenticate without information from them then it is there by default and is a "fixed" account. (Fixed accounts should not require any editing or additional user information.)

If you want to offer any email service to a user that requires additional information, it should not be fixed to avoid the user having errors upon first connection.

Now if someone wanted to, they could contribute a feature to show one or more mail tabs by default that require additional information, but that feature isn't there now. I can see how such a feature might be a good idea in some situations, but for most, I'd imagine the current functionality is probably adequate, since you can do roughly the same thing by just requiring that the user click on add/remove account and add that account.

For non-fixed accounts, you have full ability to default any field to any value so that when the user adds a new account of that type, they have things pre-filled-in, with the exception of password (which is basically a normal password field so it clears when the page reloads).

custom

If you set custom to true <property name="custom" value="true"/> then the user can edit more fields. If it is false, then they can only specify the name of the account, the account's username, and password.

includeInDefault

This was an artifact of earlier development, does nothing, was included as a property up to 2.0.0-alpha-7, but after that was removed for future releases. Please remove it from all of your configuration.

Encrypting User Mail Account Passwords

If you let your users add their own mail accounts then it is likely that they will be storing passwords as well. This means you should really have some level of security on the passwords that are stored. Hopefully you also have your server environment and database locked down among other things, and this is just a little icing on the cake.

If right now you are scared, don't be. With the default configuration of MailPortlet, the following change to set the AES encryption key is the only change you should have to make to the configuration to get it up and running and letting your users connect to their Gmail, AOL, ISP, etc. accounts, although you may want to customize it more, which is why there are other steps below.

Here is an example of a 40-byte hex key that someone might put into WEB-INF/context/portlet/mailsecurity.xml for 128-bit AES encryption, but USE YOUR OWN KEY - do NOT use the 1f1f1f... provided here. If you use 1f1f1f... then you may as well not have encrypted the passwords at all:

...

    <bean name="encryptionTool" class="org.jasig.portlet.mail.encryption.impl.AesEncryptionToolImpl">
        <!-- REPLACE THIS KEY WITH A KEY YOU MAKE UP IN HEX THAT IS THE SAME LENGTH. THIS LENGTH OF KEY IS ONLY ALLOWED IN THE U.S. -->
        <property name="key" value="1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f"/>
    </bean>
...
</beans>

Here is an example of a 16-byte hex key that someone might put into WEB-INF/context/portlet/mailsecurity.xml for 64-bit AES encryption. Again, USE YOUR OWN KEY - do NOT use the 1f1f1f... provided here. If you use 1f1f1f... then you may as well not have encrypted the passwords at all:

...

    <bean name="encryptionTool" class="org.jasig.portlet.mail.encryption.impl.AesEncryptionToolImpl">
        <!-- REPLACE THIS KEY WITH A KEY YOU MAKE UP IN HEX THAT IS THE SAME LENGTH. THIS LENGTH OF KEY IS FOR LOCATIONS OUTSIDE OF THE U.S. -->
        <property name="key" value="1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f"/>
    </bean>
...
</beans>

For those interested, it might also be a good idea to load key/iv for password encryption from one or more files separate from the spring config (that way the portal admin wouldn't necessarily have the key to decrypt passwords if you wanted to set it up that way), but I assume that if someone really wanted to do that they could figure it out on their own. I think you'd involve org.springframework.core.io.FileSystemResource in a bean somewhere, but I'm having trouble finding a good example. If you find one, please add it here (without any confidential info, please).

Using CAS for Mail Server Authentication

Yale University contributed classes and configuration to support CAS. To enable CAS support, modify the spring config files in the exploded war file or file the overlay technique described in this document, specifically (generically) take a look at files in either WEB-INF/context/.xml or WEB-INF/context/portlet/.xml as well as WEB-INF/web.xml.

You will see various sections in those configuration files commented out relating to CAS that you must uncomment and configure for CAS support in your environment.

Note that version 2.0.0-alpha-7 has not been tested with CAS authentication, so it likely needs additional work.

Using UserInfo for Mail Server Authentication

In WEB-INF/context/portlet/mailsecurity.xml be sure that the userInfoCredentialsService is setup (it should be by default):

...
    <bean name="credentialsServiceManager" class="org.jasig.portlet.mail.CredentialsServiceManager">
        <property name="services">
            <map>
                ...
                <entry key="userInfoCredentialsService" value-ref="userInfoCredentialsService"/>
                ...
            </map>
        </property>
    </bean>
    ...
    <bean name="userInfoCredentialsService" class="org.jasig.portlet.mail.service.impl.UserInfoCredentialsService">
        <!-- if you want to get the password from userinfo, change exampleProxyTicket to the name of the attribute
             in userinfo that contains the password -->
        <property name="userInfoPasswordAttributeName" value="exampleProxyTicket"/>
    </bean>
    ...

Be sure that "exampleProxyTicket" is replaced with the UserInfo key that holds the MailServer password. Note that it currently gets the username by calling getRemoteUser() on the PortletRequest. If you would like the UserInfoCredentialsService to get the username from somewhere else, contact us (see the Feedback section).

We suggest that this attribute contain a password that a token that can only be used for the current login session. Passing in a plain-text password via UserInfo is probably not a good idea (for example- what if there were something outputting UserInfo to the screen for debugging purposes in another portlet- then the mailpassword would show up on the screen).

Integrating with Your SSO

First discuss with your provider's mail server support about how you could provide a ticket to use as the password to the POP/IMAP server, so that the portlet (the server) could request email from that mail server, with the intent being for the MailPortlet to display the users' mail message subjects, senders, and datetime sent (and it supports display of a few standard IMAP flags). Webmail is totally separate from this request. While the user's HTTP/HTTPS request to the portal may contain the information needed to authenticate to the mail server, when it gets to the portlet itself, the portlet is making a connection to the POP/IMAP server (via JavaMail, which the portlet makes fully configurable to connect however you want, but typically is via POP3/POP3S/IMAP/IMAPS) and to connect and retrieve mail, it will require a username and password of some sort, the username being the user's mail account username most likely, and a password (in this case, a ticket).

Then you want to determine how you are going to provide that ticket to the portlet. If you use UserInfo to do it, use that class in the config (that's what you would use with Shibboleth for example).

If needed (probably not) you can write your own java class to assist with authN and/or password encryption. The MailPortlet is customizable and pluggable, and all JavaMail properties can be configured per account if needed, so the options are pretty wide-open (if you find a way to get the authN info to the portlet, it can fully utilize the JavaMail to do whatever JavaMail can do to get messages from whatever source you want- JavaMail is also pluggable for non-standard message protocols).

CSS

We tried our best to use some sort of uPortal standard styling that would be most compatible with existing and custom skins.

Note that later versions of uPortal (not sure which ones yet) may possibly change fl-activeTab to a newer class name since that one was changed in 1.0 (or earlier) of Fluid Infusion (or prior). So, if you find that the active tab is not being highlighted properly, then check to make sure that fl-activeTab is defined.

uPortal v2.5.x-v3.0.x, possibly version of uPortal beyond 3.1.x, and Other JSR-168-Compliant Portals

The MailPortlet UI by default depends on FSS classes (Fluid Skinning System CSS) introduced in uPortal 3.1.x.

If you aren't using uPortal 3.1.x (and possibly other later versions of uPortal), it takes only a slight modification to the CSS available on your page (your skin) to implement the classes used: (Please forgive the redefines here - we just copied the FSS and FSS uPortal 3.1 skin redefines with minor modifications).

/* The following is basically copied from uPortal 3.1.1's css with exception of removal of the skin class from the lower-half. Please modify to suit your skins */

.fl-container-flex {width: 100%; clear:both;}

/*
 * Tabs: a quick tab system
 * Dependency: list-based markup ?
 */
.fl-tabs {margin:0.75em 0 0 0; border-bottom:1px solid #000; text-align:center; padding-bottom:0.2em;}
.fl-tabs li {list-style-type:none; display:inline;}
.fl-tabs li a {padding:0.25em 1.25em; background-color:#fff; margin-left:-5px; *margin-bottom:-8px; zoom:1; border:1px solid #000; border-bottom:1px solid #fff;}
.fl-tabs li a:hover {}
.fl-tabs .orderable-drop-marker {padding:0 3px; background-color:#c00;margin:0 5px 0 -5px; zoom:1;}

.fl-tabs .fl-activeTab {}

.fl-tabs-center {text-align:center;}
.fl-tabs-left {text-align:left; padding-left:10px;}
.fl-tabs-right {text-align:right; padding-right:15px;}

/* Helper: Tabs */
.fl-tabs {border-bottom-color:#4070a1;}
.fl-tabs li {background-color:#dfefff;}
.fl-tabs li,
.fl-tabs li a {font-weight:bold; color:#4070a1; border-color:#4070a1; text-decoration:none;}
.fl-tabs li:hover,
.fl-tabs li:hover a,
.fl-tabs li a:hover {background-color:#5a95cf; color:#fff;}
.fl-tabs li.fl-activeTab,
.fl-tabs li.fl-activeTab:hover,
.fl-tabs li.fl-activeTab a,
.fl-tabs li.fl-activeTab a:hover {background-color: #fff; border-bottom-color:#fff; color:#508cc9;}
.fl-tab-content {background-color:#ffffff; color:#000;}

In addition, if you don't have the following JSR-168 PLT.C classes defined (the "portlet-*" classes), you may want to define them to suit your skin's needs. Here are the portlet-* CSS classes it uses as of 2.0-alpha-7:

  • portlet-msg-info
  • portlet-msg-error
  • portlet-form-button
  • portlet-section-header
  • portlet-section-subheader
  • portlet-form-field-label

Note: In older versions of uPortal these PLT.C classes were defined per portlet in the skin, like cartoon_portlet.css in uPortal 2.5.3.1. In comparison, in uPortal 3.1.1, the default skin has a dedicated CSS file in the skin jsr168_portlet_spec.css. Their location will likely change again in later versions of uPortal.

Internationalization/Internationalisation/I18n/Localization/Localisation/L10n/Message Customization

The i18n message files are located in WEB-INF/classes/org/jasig/portlet/mail/i18n/. For example, the modifiable US English default properties are in MailPortlet_en_US.properties.

Advanced Configuration

Restrict/Add JavaMail Providers

To restrict or add custom JavaMail providers/protocols, edit WEB-INF/context/portlet/mailmvc.xml and modify the availableProtocols property of mailService, and restart the portal:

...
    <bean name="mailService" class="org.jasig.portlet.mail.service.impl.MailServiceImpl">
        ...
        <property name="availableProtocols">
            <list>
                <!-- Be sure to include i18n messages for each of these, and this indicates the display order of
                     options as display in the custom create/update view for a mail account. -->
                <value>imaps</value>
                <value>imap</value>
                <!-- Commenting these out because if the user has a ton of email it ties things up -->
                <!--
                <value>pop3s</value>
                <value>pop3</value>
                -->
            </list>
        </property>
        ...
    </bean>
    ...

If you add new providers (protocols), you need to add them to your i18n messages file for your locale. Here are the labels for the ones provided by default:

...
# Protocols
imaps=Secure IMAP (Using SSL)
imap=IMAP
pop3s=Secure POP (Using SSL)
pop3=POP
...

How to Create a Local Maven 2 Overlay Project

Checkout the MailPortlet project and build it per the instructions above. Specifically, install it locally with:

mvn clean install

Create the following file at the root of some new project directory you create. Note that this is only an example and you should tailor the groupId and artifactId up top and the finalName to meet the needs of your environment. Please change the versions to match the version of the Jasig MailPortlet as defined in that version's pom.xml (so, for example, you should change the version on the the MailPortlet dependency war to 2.0-alpha-7 for that tag or 2.0-SNAPSHOT for trunk).

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>edu.example.university</groupId>
    <artifactId>mail</artifactId>
    <packaging>war</packaging>

    <name>Mail</name>
    <version>yourversionnumbergoeshere</version>

    <dependencies>
      <dependency>
        <groupId>org.jasig.portlet</groupId>
        <artifactId>MailPortlet</artifactId>
        <type>war</type>
        <version>2.0.0-alpha-7</version>
      </dependency>
    </dependencies>

    <build>
        <finalName>mailportlet</finalName>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.0</version>
          </plugin>
        </plugins>
    </build>
</project>

Create the following directory structure:

mkdir -P src/main/resources/
mkdir -P src/main/webapp/WEB-INF/context/portlet
mkdir -P src/test

Put the custom datasource.properties and log4j.properties files that you want to use into:

src/main/webapp/WEB-INF/context/portlet

Put the Spring config files (mailsecurity.xml and mailservers.xml usually) that you want to use into:

src/main/webapp/WEB-INF/context/portlet

Build your project:

mvn clean install

A word of warning to those developing the MailPortlet itself: If you automate the build of the MailPortlet as part of your build, and it fails, your overlay build may use an older version of the portlet.

Your built portlet is in the target directory that you can then deploy via uPortal with deployPortletApp or whatever the approved method for "plutofication" and deployment is for your version of uPortal.

Operations

Changing Account Information for All Users

Once an account has been added for a user, even if it is a fixed account, their account information is stored in the database and loaded from there, not from the portlet configuration. However, new users will get their defaults from the portlet configuration. So if you need to do something like change the URL of webmail for a specific account, you will first need to:

  • Modify the portlet configuration (and redeploy/restart, if needed).
  • Update the existing accounts in the database. For example, if the link for webmail needs to change from 'https://old-webmail.acme.com/' to 'https://new-webmail.acme.com/' you would use the following SQL:
    update mail_account set link = 'https://new-webmail.acme.com/' where link = 'https://old-webmail.acme.com/'