001package org.apache.archiva.redback.rest.services;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.redback.authentication.AuthenticationConstants;
023import org.apache.archiva.redback.authentication.AuthenticationException;
024import org.apache.archiva.redback.authentication.AuthenticationFailureCause;
025import org.apache.archiva.redback.authentication.EncryptionFailedException;
026import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
027import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
028import org.apache.archiva.redback.keys.AuthenticationKey;
029import org.apache.archiva.redback.keys.KeyManager;
030import org.apache.archiva.redback.keys.jpa.model.JpaAuthenticationKey;
031import org.apache.archiva.redback.keys.memory.MemoryAuthenticationKey;
032import org.apache.archiva.redback.keys.memory.MemoryKeyManager;
033import org.apache.archiva.redback.policy.AccountLockedException;
034import org.apache.archiva.redback.policy.MustChangePasswordException;
035import org.apache.archiva.redback.rest.api.model.ActionStatus;
036import org.apache.archiva.redback.rest.api.model.ErrorMessage;
037import org.apache.archiva.redback.rest.api.model.LoginRequest;
038import org.apache.archiva.redback.rest.api.model.User;
039import org.apache.archiva.redback.rest.api.services.LoginService;
040import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
041import org.apache.archiva.redback.system.SecuritySession;
042import org.apache.archiva.redback.system.SecuritySystem;
043import org.apache.archiva.redback.users.UserManagerException;
044import org.apache.archiva.redback.users.UserNotFoundException;
045import org.slf4j.Logger;
046import org.slf4j.LoggerFactory;
047import org.springframework.stereotype.Service;
048
049import javax.inject.Inject;
050import javax.inject.Named;
051import javax.servlet.http.HttpServletRequest;
052import javax.servlet.http.HttpSession;
053import javax.ws.rs.core.Context;
054import javax.ws.rs.core.Response;
055import java.util.ArrayList;
056import java.util.Arrays;
057import java.util.Calendar;
058import java.util.List;
059import java.util.TimeZone;
060
061/**
062 * @deprecated You should use new REST API version {@link org.apache.archiva.redback.rest.api.services.v2.AuthenticationService}
063 * @author Olivier Lamy
064 * @since 1.3
065 */
066@Deprecated
067@Service( "loginService#rest" )
068public class DefaultLoginService
069    implements LoginService
070{
071
072    private Logger log = LoggerFactory.getLogger( getClass() );
073
074    private SecuritySystem securitySystem;
075
076    private HttpAuthenticator httpAuthenticator;
077
078    @Context
079    private HttpServletRequest httpServletRequest;
080
081    // validation token lifetime: 3 hours
082    long tokenLifetime = 1000*3600*3;
083
084    @Inject
085    public DefaultLoginService( SecuritySystem securitySystem,
086                                @Named( "httpAuthenticator#basic" ) HttpAuthenticator httpAuthenticator )
087    {
088        this.securitySystem = securitySystem;
089        this.httpAuthenticator = httpAuthenticator;
090    }
091
092
093    public String addAuthenticationKey( String providedKey, String principal, String purpose, int expirationMinutes )
094        throws RedbackServiceException
095    {
096        KeyManager keyManager = securitySystem.getKeyManager();
097        AuthenticationKey key;
098
099        if ( keyManager instanceof MemoryKeyManager )
100        {
101            key = new MemoryAuthenticationKey();
102        }
103        else
104        {
105            key = new JpaAuthenticationKey();
106        }
107
108        key.setKey( providedKey );
109        key.setForPrincipal( principal );
110        key.setPurpose( purpose );
111
112        Calendar now = getNowGMT();
113        key.setDateCreated( now.getTime() );
114
115        if ( expirationMinutes >= 0 )
116        {
117            Calendar expiration = getNowGMT();
118            expiration.add( Calendar.MINUTE, expirationMinutes );
119            key.setDateExpires( expiration.getTime() );
120        }
121
122        keyManager.addKey( key );
123
124        return key.getKey( );
125    }
126
127    public Boolean ping()
128        throws RedbackServiceException
129    {
130        return Boolean.TRUE;
131    }
132
133    public Boolean pingWithAutz()
134        throws RedbackServiceException
135    {
136        return Boolean.TRUE;
137    }
138
139    public User logIn( LoginRequest loginRequest )
140        throws RedbackServiceException
141    {
142        String userName = loginRequest.getUsername(), password = loginRequest.getPassword();
143        PasswordBasedAuthenticationDataSource authDataSource =
144            new PasswordBasedAuthenticationDataSource( userName, password );
145        log.debug("Login for {}",userName);
146        try
147        {
148            SecuritySession securitySession = securitySystem.authenticate( authDataSource );
149            log.debug("Security session {}", securitySession);
150            if ( securitySession.getAuthenticationResult().isAuthenticated() )
151            {
152                org.apache.archiva.redback.users.User user = securitySession.getUser();
153                log.debug("user {} authenticated", user.getUsername());
154                if ( !user.isValidated() )
155                {
156                    log.info( "user {} not validated", user.getUsername() );
157                    return null;
158                }
159                User restUser = buildRestUser( user );
160                restUser.setReadOnly( securitySystem.userManagerReadOnly() );
161                // validationToken only set during login
162                try {
163                    String validationToken = securitySystem.getTokenManager().encryptToken(user.getUsername(), tokenLifetime);
164                    restUser.setValidationToken(validationToken);
165                    log.debug("Validation Token set {}",validationToken);
166
167                } catch (EncryptionFailedException e) {
168                    log.error("Validation token could not be created "+e.getMessage());
169                }
170
171                // here create an http session
172                httpAuthenticator.authenticate( authDataSource, httpServletRequest.getSession( true ) );
173                return restUser;
174            }
175            if ( securitySession.getAuthenticationResult() != null
176                && securitySession.getAuthenticationResult().getAuthenticationFailureCauses() != null )
177            {
178                List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>();
179                for ( AuthenticationFailureCause authenticationFailureCause : securitySession.getAuthenticationResult().getAuthenticationFailureCauses() )
180                {
181                    if ( authenticationFailureCause.getCause() == AuthenticationConstants.AUTHN_NO_SUCH_USER )
182                    {
183                        errorMessages.add( new ErrorMessage( "incorrect.username.password" ) );
184                    }
185                    else
186                    {
187                        errorMessages.add( new ErrorMessage().message( authenticationFailureCause.getMessage() ) );
188                    }
189                }
190
191                throw new RedbackServiceException( errorMessages );
192            }
193            return null;
194        }
195        catch ( AuthenticationException e )
196        {
197            throw new RedbackServiceException( e.getMessage(), Response.Status.FORBIDDEN.getStatusCode() );
198        }
199        catch ( UserNotFoundException | AccountLockedException e )
200        {
201            throw new RedbackServiceException( e.getMessage() );
202        }
203        catch ( MustChangePasswordException e )
204        {
205            return buildRestUser( e.getUser() );
206        }
207        catch ( UserManagerException e )
208        {
209            log.info( "UserManagerException: {}", e.getMessage() );
210            List<ErrorMessage> errorMessages =
211                Arrays.asList( new ErrorMessage().message( "UserManagerException: " + e.getMessage() ) );
212            throw new RedbackServiceException( errorMessages );
213        }
214
215    }
216
217    public User isLogged()
218        throws RedbackServiceException
219    {
220        SecuritySession securitySession = httpAuthenticator.getSecuritySession( httpServletRequest.getSession( true ) );
221        Boolean isLogged = securitySession != null;
222        log.debug( "isLogged {}", isLogged );
223        return isLogged && securitySession.getUser() != null ? buildRestUser( securitySession.getUser() ) : null;
224    }
225
226    public ActionStatus logout()
227        throws RedbackServiceException
228    {
229        HttpSession httpSession = httpServletRequest.getSession();
230        if ( httpSession != null )
231        {
232            httpSession.invalidate();
233        }
234        return ActionStatus.SUCCESS;
235    }
236
237    private Calendar getNowGMT()
238    {
239        return Calendar.getInstance( TimeZone.getTimeZone( "GMT" ) );
240    }
241
242    private User buildRestUser( org.apache.archiva.redback.users.User user )
243    {
244        User restUser = new User();
245        restUser.setEmail( user.getEmail() );
246        restUser.setUsername( user.getUsername() );
247        restUser.setPasswordChangeRequired( user.isPasswordChangeRequired() );
248        restUser.setLocked( user.isLocked() );
249        restUser.setValidated( user.isValidated() );
250        restUser.setFullName( user.getFullName() );
251        return restUser;
252    }
253}