blob: ca8ded4f741a52858753c2089b303507922e253f [file] [log] [blame]
package org.apache.archiva.redback.rest.services.v2;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.apache.archiva.redback.authentication.Token;
import org.apache.archiva.redback.authentication.jwt.JwtAuthenticator;
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.rest.api.services.v2.AuthenticationService;
import org.apache.archiva.redback.rest.services.BaseSetup;
import org.apache.archiva.redback.rest.services.FakeCreateAdminService;
import org.apache.archiva.redback.rest.services.FakeCreateAdminServiceImpl;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.commons.lang3.SystemUtils;
import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.context.ContextLoaderListener;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author Olivier Lamy
*/
@ExtendWith( SpringExtension.class )
@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
public abstract class AbstractRestServicesTestV2
{
private JwtAuthenticator jwtAuthenticator;
private UserManager userManager;
protected Logger log = LoggerFactory.getLogger( getClass() );
private static AtomicReference<Server> server = new AtomicReference<>();
private static AtomicReference<ServerConnector> serverConnector = new AtomicReference<>();
private RoleManager roleManager;
protected void init() {
}
protected void destroy() {
this.jwtAuthenticator = null;
this.userManager = null;
}
/**
* Returns the server that was started, or null if not initialized before.
* @return
*/
public Server getServer() {
return this.server.get();
}
public int getServerPort() {
ServerConnector connector = serverConnector.get();
if (connector!=null) {
return connector.getLocalPort();
} else {
return 0;
}
}
public JwtAuthenticator getJwtAuthenticator() {
if (this.jwtAuthenticator == null) {
JwtAuthenticator auth = ContextLoaderListener.getCurrentWebApplicationContext( )
.getBean( JwtAuthenticator.class );
assertNotNull( auth );
this.jwtAuthenticator = auth;
}
return this.jwtAuthenticator;
}
public UserManager getUserManager() {
if (this.userManager==null) {
UserManager userManager = ContextLoaderListener.getCurrentWebApplicationContext( )
.getBean( "userManager#default", UserManager.class );
assertNotNull( userManager );
this.userManager = userManager;
}
return this.userManager;
}
public RoleManager getRoleManager() {
if (this.roleManager==null) {
RoleManager roleManager = ContextLoaderListener.getCurrentWebApplicationContext( )
.getBean( "roleManager", RoleManager.class );
assertNotNull( roleManager );
this.roleManager = roleManager;
}
return this.roleManager;
}
JacksonJaxbJsonProvider getJsonProvider() {
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider( );
ObjectMapper mapper = new ObjectMapper( );
mapper.registerModule( new JavaTimeModule( ) );
mapper.setAnnotationIntrospector( new JaxbAnnotationIntrospector( mapper.getTypeFactory() ) );
mapper.setDateFormat( new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ" ) );
provider.setMapper( mapper );
return provider;
}
protected boolean exists( DirContext context, String dn )
{
Object result = null;
try {
result = context.lookup( dn );
}
catch ( NameNotFoundException e ) {
return false;
}
catch ( NamingException e )
{
log.error( "Unknown error during lookup: {}", e.getMessage( ) );
}
return result != null;
}
protected void deleteUser(User user) {
if (user!=null)
{
deleteUser( user.getUsername( ) );
}
}
protected User addUser( String userId, String password, String fullName, String email ) throws UserManagerException
{
return addUser( userId, password, fullName, email, null );
}
protected User addUser( String userId, String password, String fullName, String email, Consumer<User> updateFunction ) throws UserManagerException
{
UserManager um = getUserManager( );
User user = um.createUser( userId, fullName, email );
user.setPassword( password );
user.setPermanent( false );
user.setPasswordChangeRequired( false );
user.setLocked( false );
user.setValidated( true );
user = um.addUser( user );
// We need this additional round, because new users have the password change flag set to true
user.setPasswordChangeRequired( false );
if (updateFunction!=null) {
updateFunction.accept( user );
}
um.updateUser( user );
return user;
}
protected void deleteUser(String userName) {
if (userName!=null)
{
try
{
getUserManager( ).deleteUser( userName );
}
catch ( UserNotFoundException e )
{
// ignore
}
catch ( UserManagerException e )
{
log.error( "Could not delete user {}", userName );
}
}
}
/**
* Returns true, if the server does exist and is running.
* @return true, if server does exist and is running.
*/
public boolean isServerRunning() {
return this.server.get() != null && this.server.get().isRunning();
}
/**
* Returns the timeout in ms for rest requests. The timeout can be set by
* the system property <code>rest.test.timeout</code>.
* @return The timeout value in ms.
*/
public long getTimeout()
{
return Long.getLong( "rest.test.timeout", 1000000 );
}
public static String encode( String uid, String password )
{
return "Basic " + Base64Utility.encode( ( uid + ":" + password ).getBytes() );
}
public String getAdminAuthzHeader()
{
assertNotNull( getJwtAuthenticator());
String adminUser = RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME;
Token token = getJwtAuthenticator().generateToken( adminUser );
return "Bearer " + token.getData( );
}
public String getAuthHeader(String userId) {
assertNotNull( getJwtAuthenticator() );
Token token = getJwtAuthenticator().generateToken( userId );
return "Bearer " + token.getData( );
}
protected String getSpringConfigLocation()
{
return "classpath*:spring-context.xml,classpath*:META-INF/spring-context.xml";
}
protected String getRestServicesPath()
{
return "api";
}
public void startServer()
throws Exception
{
log.info("Starting server");
Server myServer = new Server();
this.server.set(myServer);
this.serverConnector.set(new ServerConnector( myServer, new HttpConnectionFactory()));
myServer.addConnector(serverConnector.get());
ServletHolder servletHolder = new ServletHolder( new CXFServlet() );
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setResourceBase( SystemUtils.JAVA_IO_TMPDIR );
context.setSessionHandler( new SessionHandler( ) );
context.addServlet( servletHolder, "/" + getRestServicesPath() + "/*" );
context.setInitParameter( "contextConfigLocation", getSpringConfigLocation() );
context.addEventListener(new ContextLoaderListener());
getServer().setHandler( context );
getServer().start();
if (log.isDebugEnabled())
{
log.debug( "Jetty dump: {}", getServer().dump() );
}
log.info( "Started server on port {}", getServerPort() );
UserManager um = getUserManager( );
User adminUser = null;
try
{
adminUser = um.findUser( RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME );
} catch ( UserNotFoundException e ) {
// ignore
}
adminUser = um.createUser( RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME, "Administrator", "admin@local.home" );
adminUser.setUsername( RedbackRoleConstants.ADMINISTRATOR_ACCOUNT_NAME );
adminUser.setPassword( BaseSetup.getAdminPwd() );
adminUser.setFullName( "the admin user" );
adminUser.setEmail( "toto@toto.fr" );
adminUser.setPermanent( true );
adminUser.setValidated( true );
adminUser.setLocked( false );
adminUser.setPasswordChangeRequired( false );
if (adminUser==null)
{
um.addUser( adminUser );
getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
} else {
um.updateUser( adminUser, false );
getRoleManager( ).assignRole( "system-administrator", adminUser.getUsername( ) );
}
FakeCreateAdminService fakeCreateAdminService = getFakeCreateAdminService();
this.jwtAuthenticator = null;
//assertTrue( res.booleanValue() );
}
protected FakeCreateAdminService getFakeCreateAdminService()
{
return JAXRSClientFactory.create(
"http://localhost:" + getServerPort()+ "/" + getRestServicesPath() + "/fakeCreateAdminService/",
FakeCreateAdminService.class, Collections.singletonList( getJsonProvider() ) );
}
public void stopServer()
throws Exception
{
if ( getServer() != null )
{
log.info("Stopping server");
getServer().stop();
}
}
protected AuthenticationService getLoginServiceV2( String authzHeader )
{
AuthenticationService service =
JAXRSClientFactory.create( "http://localhost:" + getServerPort() + "/" + getRestServicesPath() + "/v2/redback/",
AuthenticationService.class, Collections.singletonList( getJsonProvider() ) );
// for debuging purpose
WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( getTimeout() );
if ( authzHeader != null )
{
WebClient.client( service ).header( "Authorization", authzHeader );
}
WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
return service;
}
}