View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17  package org.apache.jetspeed.security.spi.impl;
18  
19  import java.sql.Date;
20  import java.util.Collection;
21  
22  import org.apache.jetspeed.security.SecurityException;
23  import org.apache.jetspeed.security.om.InternalCredential;
24  import org.apache.jetspeed.security.om.InternalUserPrincipal;
25  import org.apache.jetspeed.security.spi.PasswordCredentialProvider;
26  
27  /***
28   * <p>
29   * Enforces a maximum lifespan for a password credential.</p>
30   * When {@link #afterAuthenticated(InternalUserPrincipal, String, InternalCredential, boolean) on authentication}
31   * a password its expiration date is reached, its expired flag is set.
32   * The {@link DefaultCredentialHandler} then will fail the authentication and subsequent authentications
33   * will fail immediately.</p>
34   * <p>
35   * To ensure proper expiration handling, an empty (null) expiration date will be automatically
36   * filled in when the credential is loaded from the persistent store using the {@link #PasswordExpirationInterceptor(int) configured} 
37   * max lifespan in days.</p>
38   * <p>
39   * When a password credential is {@link #beforeCreate(InternalUserPrincipal, Collection, String, InternalCredential, String) created}
40   * or a password is {@link #beforeSetPassword(InternalUserPrincipal, Collection, String, InternalCredential, String, boolean) updated}
41   * a new future expiration date is calculated.</p>
42   * <p>
43   * An existing or already provided higher expiration date will be preserved though. 
44   * This allows to (pre)set a (very) high expiration date, like with {@link InternalCredential#MAX_DATE},
45   * for credentials which shouldn't expire.</p>
46   * 
47   * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
48   * @version $Id$
49   */
50  public class PasswordExpirationInterceptor extends AbstractInternalPasswordCredentialInterceptorImpl
51  {
52      private long maxLifeSpanInMillis;
53      
54      /***
55       * @param maxLifeSpanInDays default lifespan of password credentials in days
56       */
57      public PasswordExpirationInterceptor(int maxLifeSpanInDays)
58      {
59          this.maxLifeSpanInMillis = (long)(maxLifeSpanInDays) * 1000*60*60*24;
60      }
61      
62      /***
63       * @return true when the password credential is now expired
64       * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#afterAuthenticated(org.apache.jetspeed.security.om.InternalUserPrincipal, java.lang.String, org.apache.jetspeed.security.om.InternalCredential, boolean)
65       */
66      public boolean afterAuthenticated(InternalUserPrincipal internalUser, String userName,
67              InternalCredential credential, boolean authenticated) throws SecurityException
68      {
69          boolean update = false;
70          if ( !credential.isExpired() )
71          {
72              long expirationTime = credential.getExpirationDate().getTime();
73              long currentTime     = new java.util.Date().getTime();
74              if (expirationTime <= currentTime)
75              {
76                  credential.setExpired(true);
77                  update = true;
78              }
79          }
80          return update;
81      }
82      
83      /***
84       * @return true when a new default expiration date is set
85       * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#afterLoad(org.apache.jetspeed.security.spi.PasswordCredentialProvider, java.lang.String, org.apache.jetspeed.security.om.InternalCredential)
86       */
87      public boolean afterLoad(PasswordCredentialProvider pcProvider, String userName, InternalCredential credential)
88              throws SecurityException
89      {
90          boolean update = false;
91          if ( credential.getExpirationDate() == null )
92          {
93              credential.setExpirationDate(new Date(new java.util.Date().getTime()+maxLifeSpanInMillis));
94              update = true;
95          }
96          return update;
97      }
98      
99      /***
100      * Calculates and sets the default expiration date and the expired flag to false 
101      * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#beforeCreate(org.apache.jetspeed.security.om.InternalUserPrincipal, java.util.Collection, java.lang.String, InternalCredential, java.lang.String)
102      */
103     public void beforeCreate(InternalUserPrincipal internalUser, Collection credentials, String userName,
104             InternalCredential credential, String password) throws SecurityException
105     {
106         setExpiration(credential);
107     }
108     
109     /***
110      * Sets a new expiration date if a higher expiration date isn't set already and resets the expired flag
111      * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#beforeSetPassword(org.apache.jetspeed.security.om.InternalUserPrincipal, java.util.Collection, java.lang.String, org.apache.jetspeed.security.om.InternalCredential, java.lang.String, boolean)
112      */
113     public void beforeSetPassword(InternalUserPrincipal internalUser, Collection credentials, String userName,
114             InternalCredential credential, String password, boolean authenticated) throws SecurityException
115     {
116         setExpiration(credential);
117     }
118     
119     protected void setExpiration(InternalCredential credential)
120     {
121         Date nextExpirationDate = new Date(new java.util.Date().getTime()+maxLifeSpanInMillis);
122         if ( credential.getExpirationDate() == null || credential.getExpirationDate().before(nextExpirationDate))
123         {
124             credential.setExpirationDate(nextExpirationDate);
125         }
126         credential.setExpired(false);
127     }
128 }