001package org.apache.archiva.redback.rest.services.interceptors;
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.AuthenticationException;
023import org.apache.archiva.redback.authentication.AuthenticationResult;
024import org.apache.archiva.redback.authorization.RedbackAuthorization;
025import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
026import org.apache.archiva.redback.policy.AccountLockedException;
027import org.apache.archiva.redback.policy.MustChangePasswordException;
028import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
029import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
030import org.apache.archiva.redback.system.SecuritySession;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033import org.springframework.core.annotation.AnnotationUtils;
034
035import javax.servlet.http.HttpServletRequest;
036import javax.servlet.http.HttpServletResponse;
037import javax.ws.rs.container.ContainerRequestContext;
038import javax.ws.rs.container.ResourceInfo;
039import javax.ws.rs.core.Context;
040import java.lang.reflect.Method;
041import java.util.HashMap;
042import java.util.Map;
043
044/**
045 * @author Olivier Lamy
046 * @since 1.3
047 */
048public abstract class AbstractInterceptor
049{
050
051    private static final Logger log = LoggerFactory.getLogger( AbstractInterceptor.class );
052
053    private static final String API_DOCS = "api-docs";
054    private static final String OPENAPI_JSON = "openapi.json";
055    private static final String API_DOCS1 = "api-docs/";
056
057    private Map<Method, RedbackAuthorization> authorizationCache = new HashMap<>( );
058
059    public static final String AUTHENTICATION_RESULT = "org.apache.archiva.authResult";
060    public static final String SECURITY_SESSION = "org.apache.archiva.securitySession";
061
062    @Context
063    private HttpServletRequest httpServletRequest;
064
065    @Context
066    private HttpServletResponse httpServletResponse;
067
068    public HttpServletRequest getHttpServletRequest( )
069    {
070        return httpServletRequest;
071    }
072
073    public HttpServletResponse getHttpServletResponse( )
074    {
075        return httpServletResponse;
076    }
077
078    protected void setHttpServletRequest(HttpServletRequest request) {
079        this.httpServletRequest = request;
080    }
081
082    protected void setHttpServletResponse(HttpServletResponse response) {
083        this.httpServletResponse = response;
084    }
085
086
087    public static final boolean ignoreAuth(final String requestPath) {
088        final int len = requestPath.length( );
089        return len >= 8 && ( ( len == 12 && OPENAPI_JSON.equals( requestPath ) ) ||
090            ( requestPath.startsWith( API_DOCS ) && ( len == 8 || requestPath.startsWith( API_DOCS1 ) ) ) );
091    }
092
093    public RedbackAuthorization getRedbackAuthorization( ResourceInfo resourceInfo ) {
094        Method method = resourceInfo.getResourceMethod( );
095        RedbackAuthorization redbackAuthorization = getAuthorizationForMethod( method );
096        log.debug( "resourceClass {}, method {}, redbackAuthorization {}", //
097                resourceInfo.getResourceClass( ), //
098                method, //
099                redbackAuthorization );
100        return redbackAuthorization;
101    }
102
103    private RedbackAuthorization getAuthorizationForMethod(Method method) {
104        if (authorizationCache.containsKey( method )) {
105            return authorizationCache.get( method );
106        } else {
107            RedbackAuthorization authorization = AnnotationUtils.findAnnotation( method, RedbackAuthorization.class );
108            authorizationCache.put( method, authorization );
109            return authorization;
110        }
111    }
112
113    protected SecuritySession getSecuritySession(ContainerRequestContext containerRequestContext, HttpAuthenticator httpAuthenticator,
114    HttpServletRequest request) {
115        if ( containerRequestContext.getProperty( SECURITY_SESSION ) != null ) {
116            return (SecuritySession) containerRequestContext.getProperty( SECURITY_SESSION );
117        }
118        RedbackRequestInformation info = RedbackAuthenticationThreadLocal.get( );
119        SecuritySession securitySession = info == null ? null : info.getSecuritySession( );
120        if  (securitySession!=null) {
121            return securitySession;
122        } else
123        {
124            return httpAuthenticator.getSecuritySession( request.getSession( true ) );
125        }
126    }
127
128    protected AuthenticationResult getAuthenticationResult( ContainerRequestContext containerRequestContext, HttpAuthenticator httpAuthenticator, HttpServletRequest request )
129    {
130        AuthenticationResult authenticationResult = null;
131
132        if ( containerRequestContext.getProperty( AUTHENTICATION_RESULT ) == null )
133        {
134            try
135            {
136                authenticationResult =
137                    httpAuthenticator.getAuthenticationResult( request, getHttpServletResponse( ) );
138
139                if (authenticationResult!=null) {
140                    containerRequestContext.setProperty( AUTHENTICATION_RESULT, authenticationResult );
141                }
142
143                log.debug( "authenticationResult from request: {}", authenticationResult );
144            }
145            catch ( AuthenticationException e )
146            {
147                log.debug( "failed to authenticate for path {}", containerRequestContext.getUriInfo().getRequestUri() );
148            }
149            catch ( AccountLockedException e )
150            {
151                log.debug( "account locked for path {}", containerRequestContext.getUriInfo().getRequestUri() );
152            }
153            catch ( MustChangePasswordException e )
154            {
155                log.debug( "must change password for path {}", containerRequestContext.getUriInfo().getRequestUri() );
156            }
157        } else {
158            authenticationResult = (AuthenticationResult) containerRequestContext.getProperty( AUTHENTICATION_RESULT );
159        }
160        log.debug( "authenticationResult from message: {}", authenticationResult );
161        return authenticationResult;
162    }
163}