001/*
002 *   Licensed to the Apache Software Foundation (ASF) under one
003 *   or more contributor license agreements.  See the NOTICE file
004 *   distributed with this work for additional information
005 *   regarding copyright ownership.  The ASF licenses this file
006 *   to you under the Apache License, Version 2.0 (the
007 *   "License"); you may not use this file except in compliance
008 *   with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *   Unless required by applicable law or agreed to in writing,
013 *   software distributed under the License is distributed on an
014 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *   KIND, either express or implied.  See the License for the
016 *   specific language governing permissions and limitations
017 *   under the License.
018 *
019 */
020package org.apache.directory.ldap.client.template;
021
022
023import org.apache.directory.api.ldap.codec.api.LdapApiService;
024import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyResponse;
025import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyResponseImpl;
026import org.apache.directory.api.ldap.model.exception.LdapException;
027import org.apache.directory.api.ldap.model.message.Control;
028import org.apache.directory.api.ldap.model.message.Response;
029import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
030import org.apache.directory.api.ldap.model.message.ResultResponse;
031import org.apache.directory.ldap.client.template.exception.PasswordException;
032
033
034/**
035 * A base, abstract, implementation of <code>PasswordPolicyResponder</code>.  
036 * Extend this class and override success(PasswordPolicy), 
037 * fail(ResultResponse, PasswordPolicy, ResultCodeEnum), or
038 * exception(LdapException).  If that does not offer enough
039 * flexibility, you must implement PasswordPolicyResponder yourself.
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 */
043public abstract class AbstractPasswordPolicyResponder implements PasswordPolicyResponder
044{
045    private final PasswordPolicyResponse passwordPolicyResponseControl;
046
047
048    protected AbstractPasswordPolicyResponder( LdapApiService ldapApiService )
049    {
050        this.passwordPolicyResponseControl = new PasswordPolicyResponseImpl();
051    }
052    
053    
054    /**
055     * Translates an <code>LdapException</code> to a 
056     * <code>PasswordException</code> to be thrown when 
057     * {@link #process(PasswordPolicyOperation)} fails.
058     * 
059     * @param e The exception to set
060     * @return The created PasswordException
061     */
062    protected PasswordException exception( LdapException e )
063    {
064        return new PasswordException().setLdapException( e );
065    }
066    
067    
068    /**
069     * Returns an exception to be thrown in the case of a non SUCCESS 
070     * <code>resultCode</code>.
071     * 
072     * @param resultResponse The result response
073     * @param passwordPolicyResponse The password policy in use
074     * @param resultCode The result
075     * @return The created PasswordException
076     */
077    protected PasswordException fail( ResultResponse resultResponse, 
078            PasswordPolicyResponse passwordPolicyResponse, ResultCodeEnum resultCode )
079    {
080        PasswordException exception = new PasswordException();
081        exception.setResultCode( resultCode );
082        
083        if ( passwordPolicyResponse != null
084            && passwordPolicyResponse.getPasswordPolicyError() != null )
085        {
086            exception.setPasswordPolicyError( passwordPolicyResponse.getPasswordPolicyError() );
087        }
088        return exception;
089    }
090
091
092    private PasswordPolicyResponse getPasswordPolicy( Response response )
093    {
094        Control control = response.getControls().get( passwordPolicyResponseControl.getOid() );
095        
096        return control == null
097            ? null
098            : ( PasswordPolicyResponse ) control;
099    }
100
101
102    /**
103     * {@inheritDoc}
104     */
105    @Override
106    public final PasswordWarning process( PasswordPolicyOperation operation )
107        throws PasswordException
108    {
109        try
110        {
111            ResultResponse response = operation.process();
112            PasswordPolicyResponse passwordPolicyResponse = getPasswordPolicy( response );
113            ResultCodeEnum resultCode = response.getLdapResult().getResultCode();
114            
115            if ( resultCode == ResultCodeEnum.SUCCESS )
116            {
117                return success( passwordPolicyResponse );
118            }
119            else
120            {
121                throw fail( response, passwordPolicyResponse, resultCode );
122            }
123        }
124        catch ( LdapException e )
125        {
126            throw new PasswordException().setLdapException( e );
127        }
128    }
129    
130    /**
131     * Returns a <code>PasswordWarning</code>, or <code>null</code> if no 
132     * warnings were present in the supplied <code>passwordPolicy</code>.
133     * 
134     * @param passwordPolicyResponse The PasswordPolicyReponse in use
135     * @return The created PasswordWarning
136     */
137    protected PasswordWarning success( PasswordPolicyResponse passwordPolicyResponse ) 
138    {
139        return passwordPolicyResponse == null
140                ? null
141                : PasswordWarningImpl.newWarning( passwordPolicyResponse );
142    }
143}