/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.assured; import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.security.Credential; import org.eclipse.jetty.util.security.Password; import org.everrest.assured.util.AvailablePortFinder; import org.everrest.assured.util.IoUtil; import org.everrest.core.DependencySupplier; import org.everrest.core.ResourceBinder; import org.everrest.core.impl.ApplicationProviderBinder; import org.everrest.core.impl.ApplicationProviderBinderHelper; import org.everrest.core.impl.ApplicationPublisher; import org.everrest.core.impl.ResourceBinderImpl; import org.everrest.core.servlet.EverrestInitializedListener; import org.everrest.core.servlet.EverrestServlet; import org.everrest.groovy.BaseResourceId; import org.everrest.groovy.GroovyResourcePublisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.Filter; import javax.ws.rs.core.Application; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.EventListener; import java.util.Random; public class JettyHttpServer { public static final String UNSECURE_REST = "/rest"; public static final String UNSECURE_PATH_SPEC = UNSECURE_REST + "/*"; public static final String SECURE_PATH = "/private"; public static final String SECURE_REST = UNSECURE_REST + SECURE_PATH; public static final String SECURE_PATH_SPEC = SECURE_REST + "/*"; public final static String ADMIN_USER_NAME = "cldadmin"; public final static String ADMIN_USER_PASSWORD = "tomcat"; public final static String MANAGER_USER_NAME = "cldmanager"; public final static String MANAGER_USER_PASSWORD = "manager"; public final static String UNAUTHORIZED_USER = "user"; private static final Logger LOG = LoggerFactory.getLogger(JettyHttpServer.class); private final static Random portRandomizer = new Random(); protected final int port; protected final Server server; protected ServletContextHandler context; /** * */ public JettyHttpServer() { this(AvailablePortFinder.getNextAvailable(10000 + portRandomizer.nextInt(2000))); } public JettyHttpServer(int port) { this.port = port; this.server = new Server(port); this.context = null; } public int getPort() { return port; } public void start() throws Exception { RequestLogHandler handler = new RequestLogHandler(); if (context == null) { context = new ServletContextHandler(handler, "/", ServletContextHandler.SESSIONS); } context.setEventListeners(new EventListener[]{new EverrestInitializedListener()}); ServletHolder servletHolder = new ServletHolder(new EverrestServlet()); context.addServlet(servletHolder, UNSECURE_PATH_SPEC); context.addServlet(servletHolder, SECURE_PATH_SPEC); //set up security Constraint constraint = new Constraint(); constraint.setName(Constraint.__BASIC_AUTH); constraint.setRoles(new String[]{"cloud-admin", "users", "user", "temp_user"}); constraint.setAuthenticate(true); ConstraintMapping constraintMapping = new ConstraintMapping(); constraintMapping.setConstraint(constraint); constraintMapping.setPathSpec(SECURE_PATH_SPEC); ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); securityHandler.addConstraintMapping(constraintMapping); HashLoginService loginService = new HashLoginService(); loginService.putUser(ADMIN_USER_NAME, new Password(ADMIN_USER_PASSWORD), new String[]{"cloud-admin", "users", "user", "temp_user", "developer", "admin", "workspace/developer", "workspace/admin", "account/owner", "account/member", "system/admin", "system/manager" }); loginService.putUser(MANAGER_USER_NAME, new Password(MANAGER_USER_PASSWORD), new String[]{"cloud-admin", "user", "temp_user", "users"}); securityHandler.setLoginService(loginService); securityHandler.setAuthenticator(new BasicAuthenticator()); context.setSecurityHandler(securityHandler); server.setHandler(handler); server.start(); ResourceBinder binder = (ResourceBinder)context.getServletContext().getAttribute(ResourceBinder.class.getName()); DependencySupplier dependencies = (DependencySupplier)context.getServletContext().getAttribute(DependencySupplier.class.getName()); GroovyResourcePublisher groovyPublisher = new GroovyResourcePublisher(binder, dependencies); context.getServletContext().setAttribute(GroovyResourcePublisher.class.getName(), groovyPublisher); } public void stop() throws Exception { context = null; server.stop(); } public void addUser(String userName, Credential credential, String[] roles) { ((HashLoginService)context.getSecurityHandler().getLoginService()).putUser(userName, credential, roles); } public void publish(Application application){ ResourceBinder binder = (ResourceBinder)context.getServletContext().getAttribute(ResourceBinder.class.getName()); ApplicationProviderBinder providerBinder = (ApplicationProviderBinder)context.getServletContext().getAttribute(ApplicationProviderBinder.class.getName()); ApplicationPublisher applicationPublisher = new ApplicationPublisher(binder, providerBinder); applicationPublisher.publish(application); } public void publishPerRequestGroovyScript(String resourcePath, String name) { GroovyResourcePublisher groovyPublisher = (GroovyResourcePublisher)context.getServletContext().getAttribute(GroovyResourcePublisher.class.getName()); BaseResourceId publishedResourceId = new BaseResourceId(name); groovyPublisher.publishPerRequest(IoUtil.getResource(resourcePath), publishedResourceId, null, null, null); } public void addFilter(Filter filter, String pathSpec) { context.addFilter(new FilterHolder(filter), pathSpec, null); } public void addFilter(Class<? extends Filter> filterClass, String pathSpec) { context.addFilter(filterClass, pathSpec, null); } public void resetFilter() { context.getServletHandler().setFilters(null); try { Field filterMappings = ServletHandler.class.getDeclaredField("_filterMappings"); filterMappings.setAccessible(true); filterMappings.set(context.getServletHandler(), null); Method updateMappingsMethod = ServletHandler.class.getDeclaredMethod("updateMappings"); updateMappingsMethod.setAccessible(true); updateMappingsMethod.invoke(context.getServletHandler()); } catch (ReflectiveOperationException e) { LOG.error(e.getLocalizedMessage(), e); } } /** @return the context */ public ServletContextHandler getContext() { return context; } public void resetFactories() { LOG.debug("reset >>"); ResourceBinder binder = (ResourceBinder)context.getServletContext().getAttribute(ResourceBinder.class.getName()); ((ResourceBinderImpl)binder).clear(); ApplicationProviderBinder providerBinder = (ApplicationProviderBinder)context.getServletContext().getAttribute(ApplicationProviderBinder.class.getName()); ApplicationProviderBinderHelper.resetApplicationProviderBinder(providerBinder); } }