001package org.apache.archiva.redback.rest.services;
002/*
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 */
020
021import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
022import org.apache.archiva.redback.keys.AuthenticationKey;
023import org.apache.archiva.redback.keys.KeyManagerException;
024import org.apache.archiva.redback.policy.PasswordEncoder;
025import org.apache.archiva.redback.policy.PasswordRuleViolationException;
026import org.apache.archiva.redback.policy.PasswordRuleViolations;
027import org.apache.archiva.redback.rest.api.model.ErrorMessage;
028import org.apache.archiva.redback.rest.api.services.PasswordService;
029import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
030import org.apache.archiva.redback.rest.services.utils.PasswordValidator;
031import org.apache.archiva.redback.system.SecuritySystem;
032import org.apache.archiva.redback.users.User;
033import org.apache.archiva.redback.users.UserManagerException;
034import org.apache.archiva.redback.users.UserNotFoundException;
035import org.apache.commons.lang3.StringUtils;
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038import org.springframework.stereotype.Service;
039
040import javax.inject.Inject;
041import javax.inject.Named;
042import javax.servlet.http.HttpServletRequest;
043import javax.ws.rs.core.Context;
044import javax.ws.rs.core.Response;
045import java.util.ArrayList;
046import java.util.Arrays;
047import java.util.List;
048
049/**
050 * @deprecated Use the new V2 version {@link org.apache.archiva.redback.rest.services.v2.DefaultAuthenticationService}
051 * @author Olivier Lamy
052 * @since 1.4
053 */
054@Deprecated
055@Service("passwordService#rest")
056public class DefaultPasswordService
057    implements PasswordService
058{
059
060    private Logger log = LoggerFactory.getLogger( getClass() );
061
062    private SecuritySystem securitySystem;
063
064    private HttpAuthenticator httpAuthenticator;
065
066    private PasswordValidator passwordValidator;
067
068    @Context
069    private HttpServletRequest httpServletRequest;
070
071    @Inject
072    public DefaultPasswordService( SecuritySystem securitySystem,
073                                   @Named("httpAuthenticator#basic") HttpAuthenticator httpAuthenticator,
074                                   PasswordValidator passwordValidator )
075    {
076        this.securitySystem = securitySystem;
077        this.httpAuthenticator = httpAuthenticator;
078        this.passwordValidator = passwordValidator;
079    }
080
081    public org.apache.archiva.redback.rest.api.model.User changePasswordWithKey( String password,
082                                                                                 String passwordConfirmation,
083                                                                                 String key )
084        throws RedbackServiceException
085    {
086
087        String principal = null;
088
089        if ( StringUtils.isEmpty( password ) )
090        {
091            throw new RedbackServiceException( "password cannot be empty", Response.Status.FORBIDDEN.getStatusCode() );
092        }
093        if ( StringUtils.isEmpty( passwordConfirmation ) )
094        {
095            throw new RedbackServiceException( "password confirmation cannot be empty",
096                                               Response.Status.FORBIDDEN.getStatusCode() );
097        }
098        if ( !StringUtils.equals( password, passwordConfirmation ) )
099        {
100            throw new RedbackServiceException( "password confirmation must be same as password",
101                                               Response.Status.FORBIDDEN.getStatusCode() );
102        }
103
104        try
105        {
106            AuthenticationKey authKey = securitySystem.getKeyManager().findKey( key );
107
108            principal = authKey.getForPrincipal();
109
110            String encodedPassword = passwordValidator.validatePassword( password, principal );
111
112            User user = securitySystem.getUserManager().findUser( principal, false );
113            user.setPassword( password );
114            user.setEncodedPassword( encodedPassword );
115            user = securitySystem.getUserManager().updateUser( user );
116
117            return new org.apache.archiva.redback.rest.api.model.User( user );
118
119        }
120        catch ( KeyManagerException e )
121        {
122            log.info( "issue to find key {}: {}", key, e.getMessage() );
123            throw new RedbackServiceException( "issue with key", Response.Status.FORBIDDEN.getStatusCode() );
124        }
125        catch ( UserNotFoundException e )
126        {
127            log.info( "user {} not found", e.getMessage() );
128            List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>( 2 );
129            ErrorMessage errorMessage = new ErrorMessage( "cannot.update.user.not.found", new String[]{ principal } );
130            errorMessages.add( errorMessage );
131            errorMessage = new ErrorMessage( "admin.deleted.account" );
132            errorMessages.add( errorMessage );
133            throw new RedbackServiceException( errorMessages );
134        }
135        catch ( UserManagerException e )
136        {
137            log.info( "UserManagerException: {}", e.getMessage() );
138            List<ErrorMessage> errorMessages =
139                Arrays.asList( new ErrorMessage().message( "UserManagerException: " + e.getMessage() ) );
140            throw new RedbackServiceException( errorMessages );
141        }
142        catch ( PasswordRuleViolationException e )
143        {
144            PasswordRuleViolations violations = e.getViolations();
145            List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>( violations.getViolations().size() );
146            if ( violations != null )
147            {
148                for ( String violation : violations.getLocalizedViolations() )
149                {
150                    errorMessages.add( new ErrorMessage( violation ) );
151                }
152            }
153            throw new RedbackServiceException( errorMessages );
154        }
155
156    }
157
158    public org.apache.archiva.redback.rest.api.model.User changePassword( String userName, String previousPassword,
159                                                                          String password, String passwordConfirmation )
160        throws RedbackServiceException
161    {
162        if ( StringUtils.isEmpty( userName ) )
163        {
164            throw new RedbackServiceException( new ErrorMessage( "username.cannot.be.empty" ),
165                                               Response.Status.BAD_REQUEST.getStatusCode() );
166        }
167        if ( StringUtils.isEmpty( previousPassword ) )
168        {
169            throw new RedbackServiceException( new ErrorMessage( "password.previous.empty" ),
170                                               Response.Status.BAD_REQUEST.getStatusCode() );
171        }
172        if ( StringUtils.isEmpty( password ) )
173        {
174            throw new RedbackServiceException( new ErrorMessage( "password.empty" ),
175                                               Response.Status.BAD_REQUEST.getStatusCode() );
176        }
177        if ( StringUtils.isEmpty( passwordConfirmation ) )
178        {
179            throw new RedbackServiceException( new ErrorMessage( "password.confirmation.empty" ),
180                                               Response.Status.BAD_REQUEST.getStatusCode() );
181        }
182
183        if ( !StringUtils.equals( password, passwordConfirmation ) )
184        {
185            throw new RedbackServiceException( new ErrorMessage( "password.confirmation.same" ),
186                                               Response.Status.BAD_REQUEST.getStatusCode() );
187        }
188        try
189        {
190            User u = securitySystem.getUserManager().findUser( userName );
191
192            String previousEncodedPassword = u.getEncodedPassword();
193
194            // check oldPassword with the current one
195
196            PasswordEncoder encoder = securitySystem.getPolicy().getPasswordEncoder();
197
198            if ( !encoder.isPasswordValid( previousEncodedPassword, previousPassword ) )
199            {
200
201                throw new RedbackServiceException( new ErrorMessage( "password.provided.does.not.match.existing" ),
202                                                   Response.Status.BAD_REQUEST.getStatusCode() );
203            }
204
205            u.setPassword( password );
206
207            u = securitySystem.getUserManager().updateUser( u );
208            return new org.apache.archiva.redback.rest.api.model.User( u );
209        }
210        catch ( UserNotFoundException e )
211        {
212            throw new RedbackServiceException( new ErrorMessage( "user.not.found" ),
213                                               Response.Status.BAD_REQUEST.getStatusCode() );
214        }
215        catch ( UserManagerException e )
216        {
217            log.info( "UserManagerException: {}", e.getMessage() );
218            List<ErrorMessage> errorMessages =
219                Arrays.asList( new ErrorMessage().message( "UserManagerException: " + e.getMessage() ) );
220            throw new RedbackServiceException( errorMessages );
221        }
222
223    }
224}