com.nesscomputing.config.util.LocalHttpService.java Source code

Java tutorial

Introduction

Here is the source code for com.nesscomputing.config.util.LocalHttpService.java

Source

/**
 * Copyright (C) 2012 Ness Computing, Inc.
 *
 * Licensed 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.
 */
package com.nesscomputing.config.util;

import java.io.IOException;
import java.net.URL;
import java.security.Principal;

import javax.security.auth.Subject;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.security.DefaultIdentityService;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.MappedLoginService.KnownUser;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.util.ssl.SslContextFactory;

import com.google.common.io.Resources;
import com.nesscomputing.testing.lessio.AllowNetworkListen;

@AllowNetworkListen(ports = { 0 })
public class LocalHttpService {
    private final Server server = new Server();
    private final Connector connector;

    public static LocalHttpService forHandler(final Handler handler) {
        return new LocalHttpService(handler, getHttpConnector());
    }

    public static LocalHttpService forSecureHandler(final Handler handler, final String login,
            final String password) {
        return new LocalHttpService(getSecuredHandler(handler, login, password), getHttpConnector());
    }

    public static LocalHttpService forSSLHandler(final Handler handler) {
        return new LocalHttpService(handler, getSSLHttpConnector());
    }

    public static LocalHttpService forSecureSSLHandler(final Handler handler, final String login,
            final String password) {
        return new LocalHttpService(getSecuredHandler(handler, login, password), getSSLHttpConnector());
    }

    public static LocalHttpService forSSLClientSSLServerHandler(final Handler handler, String truststore,
            String truststorePassword, String keystore, String keystorePassword, String keystoreType) {
        return new LocalHttpService(handler, getSSLClientCertHttpConnector(truststore, truststorePassword, keystore,
                keystorePassword, keystoreType));
    }

    private static Connector getHttpConnector() {
        final SelectChannelConnector scc = new SelectChannelConnector();
        scc.setPort(0);
        scc.setHost("localhost");
        return scc;
    }

    private static Connector getSSLHttpConnector() {
        final URL keystoreUrl = Resources.getResource(LocalHttpService.class, "/test-server-keystore.jks");

        final SslContextFactory contextFactory = new SslContextFactory();

        contextFactory.setKeyStorePath(keystoreUrl.toString());
        contextFactory.setKeyStorePassword("changeit");
        contextFactory.setKeyManagerPassword("changeit");
        final SslSelectChannelConnector scc = new SslSelectChannelConnector(contextFactory);
        scc.setPort(0);
        scc.setHost("localhost");

        return scc;
    }

    private static Connector getSSLClientCertHttpConnector(String truststore, String truststorePassword,
            String keystore, String keystorePassword, String keystoreType) {
        final URL keystoreUrl = Resources.getResource(LocalHttpService.class, keystore);

        final SslContextFactory contextFactory = new SslContextFactory();
        contextFactory.setKeyStorePath(keystoreUrl.toString());
        contextFactory.setKeyStorePassword(keystorePassword);
        contextFactory.setKeyManagerPassword(keystorePassword);
        contextFactory.setKeyStoreType(keystoreType);

        final URL truststoreUrl = Resources.getResource(LocalHttpService.class, truststore);
        contextFactory.setTrustStore(truststoreUrl.toString());
        contextFactory.setTrustStorePassword(truststorePassword);
        contextFactory.setTrustStoreType("JKS");

        contextFactory.setNeedClientAuth(true);

        final SslSelectChannelConnector scc = new SslSelectChannelConnector(contextFactory);
        scc.setPort(0);
        scc.setHost("localhost");

        return scc;
    }

    private static Handler getSecuredHandler(final Handler handler, final String login, final String password) {
        final SecurityHandler securityHandler = new DummySecurityHandler(login);
        securityHandler.setAuthenticator(new BasicAuthenticator());
        securityHandler.setIdentityService(new DefaultIdentityService());
        securityHandler.setLoginService(new DummyLoginService(login, password));

        securityHandler.setHandler(handler);

        return securityHandler;
    }

    /**
     * @deprecated Use {@link LocalHttpService#forHandler(Handler)}.
     */
    @Deprecated
    public LocalHttpService(final Handler handler) {
        this(handler, getHttpConnector());
    }

    private LocalHttpService(final Handler handler, final Connector connector) {
        this.connector = connector;
        server.setConnectors(new Connector[] { connector });
        server.setHandler(handler);
    }

    public void start() {
        try {
            server.start();
        } catch (Exception e) {
            throw new IllegalStateException("LocalHttpService did not start properly!");
        }
    }

    public void stop() {
        try {
            server.stop();
        } catch (Exception e) {
            throw new IllegalStateException("LocalHttpService did not stop properly!");
        }

        try {
            server.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    public String getHost() {
        return connector.getHost();
    }

    public int getPort() {
        return connector.getLocalPort();
    }

    private static class DummySecurityHandler extends SecurityHandler {
        private final String login;

        private DummySecurityHandler(final String login) {
            this.login = login;
        }

        @Override
        protected Object prepareConstraintInfo(String pathInContext, Request request) {
            return null;
        }

        @Override
        protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response,
                Object constraintInfo) throws IOException {
            return true;
        }

        @Override
        protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo) {
            return true;
        }

        @Override
        protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response,
                Object constraintInfo, UserIdentity userIdentity) throws IOException {
            return userIdentity != null && StringUtils.equals(login, userIdentity.getUserPrincipal().getName());
        }
    }

    private static class DummyLoginService implements LoginService {
        private final String login;
        private final String password;

        private DummyLoginService(final String login, final String password) {
            this.login = login;
            this.password = password;
        }

        @Override
        public String getName() {
            return "test";
        }

        @Override
        public UserIdentity login(String username, Object credentials) {
            if (StringUtils.equals(login, username) && StringUtils.equals(password, String.valueOf(credentials))) {
                final Credential c = new Password(String.valueOf(credentials));
                final Principal p = new KnownUser(username, c);
                final Subject subject = new Subject();
                subject.getPrincipals().add(p);
                subject.getPrivateCredentials().add(c);

                return new UserIdentity() {

                    @Override
                    public Subject getSubject() {
                        return subject;
                    }

                    @Override
                    public Principal getUserPrincipal() {
                        return p;
                    }

                    @Override
                    public boolean isUserInRole(String role, Scope scope) {
                        return true;
                    }

                };
            } else {
                return null;
            }
        }

        @Override
        public void logout(UserIdentity user) {
        }

        @Override
        public boolean validate(UserIdentity user) {
            return false;
        }

        private IdentityService identityService;

        @Override
        public IdentityService getIdentityService() {
            return identityService;
        }

        @Override
        public void setIdentityService(IdentityService service) {
            this.identityService = service;
        }

    }
}