001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.security.impl;
018:
019: import java.util.Arrays;
020: import java.util.List;
021:
022: import javax.security.auth.Subject;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.jetspeed.pipeline.PipelineException;
027: import org.apache.jetspeed.pipeline.valve.AbstractValve;
028: import org.apache.jetspeed.pipeline.valve.PageProfilerValve;
029: import org.apache.jetspeed.pipeline.valve.ValveContext;
030: import org.apache.jetspeed.profiler.ProfileLocator;
031: import org.apache.jetspeed.request.RequestContext;
032: import org.apache.jetspeed.security.PasswordCredential;
033: import org.apache.jetspeed.security.SecurityHelper;
034:
035: /**
036: * PasswordCredentialValve
037: *
038: * @author <a href="mailto:ate@apache.org">Ate Douma</a>
039: * @version $Id: PasswordCredentialValveImpl.java 516448 2007-03-09 16:25:47Z ate $
040: */
041: public class PasswordCredentialValveImpl extends AbstractValve
042: implements
043: org.apache.jetspeed.pipeline.valve.PasswordCredentialValve {
044: private static final Log log = LogFactory
045: .getLog(PasswordCredentialValveImpl.class);
046:
047: private static final String CHECKED_KEY = PasswordCredentialValveImpl.class
048: .getName()
049: + ".checked";
050: //private PageManager pageManager;
051: private int[] expirationWarningDays;
052:
053: /**
054: * Create a PasswordCredentialValveImpl which only checks and handles PasswordCredential.isUpdateRequired().
055: *
056: */
057: public PasswordCredentialValveImpl() {
058: expirationWarningDays = new int[] {};
059: }
060:
061: /**
062: * <p>
063: * Creates a PasswordCredentialValveImpl which, besides checking and handling PasswordCredential.isUpdateRequired(),
064: * also provides a warning when a password is about to be expired according to the provided list of
065: * expirationWarningDays.</p>
066: * @param expirationWarningDays the list of days before password expiration when a warning should be presented
067: */
068: public PasswordCredentialValveImpl(List expirationWarningDays) {
069: if (expirationWarningDays != null) {
070: this .expirationWarningDays = new int[expirationWarningDays
071: .size()];
072: for (int i = 0; i < this .expirationWarningDays.length; i++) {
073: this .expirationWarningDays[i] = Integer
074: .parseInt((String) expirationWarningDays.get(i));
075: }
076: Arrays.sort(this .expirationWarningDays);
077: } else {
078: this .expirationWarningDays = new int[0];
079: }
080: }
081:
082: /**
083: * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, org.apache.jetspeed.pipeline.valve.ValveContext)
084: */
085: public void invoke(RequestContext request, ValveContext context)
086: throws PipelineException {
087: try {
088: if (request.getRequest().getUserPrincipal() != null) {
089: Subject subject = request.getSubject();
090: PasswordCredential pwdCredential = SecurityHelper
091: .getPasswordCredential(subject);
092: Integer passwordDaysValid = null;
093:
094: // check for an existing password credential
095: if (pwdCredential != null) {
096: if (pwdCredential.isUpdateRequired()) {
097: passwordDaysValid = new Integer(0); // required change
098: }
099: if (request.getSessionAttribute(CHECKED_KEY) == null) {
100: request.setSessionAttribute(CHECKED_KEY,
101: Boolean.TRUE);
102: if (pwdCredential
103: .getPreviousAuthenticationDate() != null
104: && pwdCredential
105: .getLastAuthenticationDate() != null
106: && pwdCredential.getExpirationDate() != null) {
107: long expirationTime = pwdCredential
108: .getExpirationDate().getTime();
109: long lastAuthTime = pwdCredential
110: .getLastAuthenticationDate()
111: .getTime();
112: int lastAuthDaysBeforeExpiration = (int) ((expirationTime - lastAuthTime) / (24 * 60 * 60 * 1000));
113: if (lastAuthDaysBeforeExpiration < 1) {
114: passwordDaysValid = new Integer(1);
115: } else if (expirationWarningDays.length > 0) {
116: long prevAuthTime = Long.MIN_VALUE;
117: if (pwdCredential
118: .getPreviousAuthenticationDate() != null) {
119: prevAuthTime = pwdCredential
120: .getPreviousAuthenticationDate()
121: .getTime();
122: }
123: int prevAuthDaysBeforeExpiration = (int) ((expirationTime - prevAuthTime) / (24 * 60 * 60 * 1000));
124: if (prevAuthDaysBeforeExpiration > lastAuthDaysBeforeExpiration) {
125: for (int i = 0; i < expirationWarningDays.length; i++) {
126: int daysBefore = expirationWarningDays[i] - 1;
127: if (lastAuthDaysBeforeExpiration == daysBefore
128: || (lastAuthDaysBeforeExpiration < daysBefore && prevAuthDaysBeforeExpiration > daysBefore)) {
129: passwordDaysValid = new Integer(
130: lastAuthDaysBeforeExpiration + 1);
131: break;
132: }
133: }
134: }
135: }
136: }
137: }
138: }
139: if (passwordDaysValid != null) {
140: // enforce the SECURITY_LOCATOR to be used to redirect to a change password portlet page
141: request
142: .setAttribute(
143: PageProfilerValve.PROFILE_LOCATOR_REQUEST_ATTR_KEY,
144: ProfileLocator.SECURITY_LOCATOR);
145: // inform the change password portlet why it is invoked
146: request
147: .setAttribute(
148: PasswordCredential.PASSWORD_CREDENTIAL_DAYS_VALID_REQUEST_ATTR_KEY,
149: passwordDaysValid);
150: }
151: }
152: context.invokeNext(request);
153: } catch (Exception e) {
154: log.error("Exception in request pipeline: "
155: + e.getMessage(), e);
156: throw new PipelineException(e.toString(), e);
157: }
158: }
159:
160: public String toString() {
161: return "PasswordCredentialValve";
162: }
163:
164: }
|