package codeine; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.security.DefaultIdentityService; import org.eclipse.jetty.security.SpnegoLoginService; import org.eclipse.jetty.security.authentication.FormAuthenticator; import org.eclipse.jetty.security.authentication.SpnegoAuthenticator; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.security.Constraint; import codeine.command_peer.CommandFileWriter; import codeine.configuration.PathHelper; import codeine.executer.PeriodicExecuter; import codeine.jsons.auth.AuthenticationMethod; import codeine.jsons.global.GlobalConfigurationJsonStore; import codeine.jsons.peer_status.PeersProjectsStatus; import codeine.jsons.peer_status.PeersProjectsStatusInWebServer; import codeine.mail.NotificationsFetchAndUpdateTask; import codeine.model.Constants; import codeine.servlet.UsersManager; import codeine.servlets.AngularServlet; import codeine.statistics.IMonitorStatistics; import codeine.statistics.MonitorsStatistics; import codeine.users.LogoutServlet; import com.google.common.collect.Lists; import com.google.inject.Injector; import com.google.inject.Module; public class CodeineWebServerBootstrap extends AbstractCodeineBootstrap { public CodeineWebServerBootstrap(Injector injector) { super(injector); } public CodeineWebServerBootstrap() { } public static void main(String[] args) { System.setProperty("org.eclipse.jetty.server.Request.maxFormContentSize", "10000000"); boot(Component.WEB, CodeineWebServerBootstrap.class); } @Override protected void execute() { log.info("executing web server bootstrap"); new PeriodicExecuter(PeersProjectsStatusInWebServer.SLEEP_TIME ,injector().getInstance(PeersProjectsStatus.class)).runInThread(); try { log.info("updating projects in db"); injector().getInstance(ConfigurationManagerServer.class).updateDb(); } catch (Exception e) { log.error("fail to update projects in db", e); } new PeriodicExecuter(MonitorsStatistics.SLEEP_TIME ,injector().getInstance(IMonitorStatistics.class)).runInThreadSleepFirst(); new PeriodicExecuter(TimeUnit.SECONDS.toMillis(5), injector().getInstance(NotificationsFetchAndUpdateTask.class)).runInThreadSleepFirst(); new PeriodicExecuter(TimeUnit.SECONDS.toMillis(5), injector().getInstance(CommandFileWriter.class)).runInThreadSleepFirst(); } @Override protected void createAdditionalServlets(ServletContextHandler handler) { handler.addServlet(AngularServlet.class, "/*"); } @Override protected List<Module> getGuiceModules() { return Lists.<Module>newArrayList(new WebServerModule(), new ServerServletModule()); } @Override public int getHttpPort() { return injector().getInstance(GlobalConfigurationJsonStore.class).get().web_server_port(); } @Override protected ServletContextHandler createServletContextHandler() { AuthenticationMethod a = injector().getInstance(GlobalConfigurationJsonStore.class).get().authentication_method(); if (Boolean.getBoolean("ignoreSecurity")){ a = AuthenticationMethod.Disabled; } switch (a){ case Disabled: return super.createServletContextHandler(); case WindowsCredentials: return createServletContextHandlerSpnego(); case Builtin: return createServletContextHandlerBasic(); } throw new IllegalArgumentException("auth method not found " + a); } @Override protected void specificCreateFileServer(ContextHandlerCollection contexts){ PathHelper pathHelper = injector().getInstance(PathHelper.class); addHandler(Constants.PROJECT_FILES_CONTEXT, pathHelper.getProjectsDir() , contexts); addHandler(Constants.ANGULAR_RESOURCES_CONTEXT_PATH, Constants.getAngularDir(), contexts); addHandler("/components", Constants.getAngularDir() + "/components", contexts); addHandler("/styles", Constants.getAngularDir() + "/styles", contexts); addHandler("/scripts", Constants.getAngularDir() + "/scripts", contexts); addHandler("/fonts", Constants.getAngularDir() + "/fonts", contexts); addHandler("/bower_components", Constants.getAngularDir() + "/bower_components", contexts); addHandler("/images", Constants.getAngularDir() + "/images", contexts); addHandler("/views", Constants.getAngularDir() + "/views", contexts); addHandler("/lib", Constants.getAngularDir() + "/lib", contexts); } private ServletContextHandler createServletContextHandlerBasic(){ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY); context.addServlet(new ServletHolder(injector().getInstance(LogoutServlet.class)), "/logout"); ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); UsersManager usersManager = injector().getInstance(UsersManager.class); usersManager.initUsers(); securityHandler.setLoginService(usersManager.loginService()); FormAuthenticator authenticator = new FormAuthenticator();//"/login", "/login", false); securityHandler.setAuthenticator(authenticator); context.setSecurityHandler(securityHandler); return context; } private ServletContextHandler createServletContextHandlerSpnego() { GlobalConfigurationJsonStore config = injector().getInstance(GlobalConfigurationJsonStore.class); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY); Constraint constraint = new Constraint(); constraint.setName(Constraint.__SPNEGO_AUTH); constraint.setRoles(config.get().roles()); constraint.setAuthenticate(true); ConstraintMapping constraintMapping = new ConstraintMapping(); constraintMapping.setConstraint(constraint); constraintMapping.setPathSpec("/*"); ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(){ @Override public void handle(String pathInContext, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.addHeader("Access-Control-Allow-Origin", "*"); if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { response.addHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE"); response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept"); } super.handle(pathInContext, baseRequest, request, response); } }; Constraint constraint2 = new Constraint(); constraint2.setAuthenticate(false); constraint.setName("reporter"); constraint.setRoles(config.get().roles()); ConstraintMapping constraintMapping2 = new ConstraintMapping(); constraintMapping2.setConstraint(constraint2); constraintMapping2.setPathSpec(Constants.apiContext(Constants.REPORTER_CONTEXT)); Constraint constraint3 = new Constraint(); constraint3.setAuthenticate(false); constraint.setName("api_with_token"); constraint.setRoles(config.get().roles()); ConstraintMapping constraintMapping3 = new ConstraintMapping(); constraintMapping3.setConstraint(constraint3); constraintMapping3.setPathSpec(Constants.apiTokenContext("/*")); securityHandler.addConstraintMapping(constraintMapping3); securityHandler.addConstraintMapping(constraintMapping2); securityHandler.addConstraintMapping(constraintMapping); SpnegoLoginService loginService = new SpnegoLoginService(null, Constants.getSpnegoPropertiesPath()); securityHandler.setLoginService(loginService); final DefaultIdentityService idService = new DefaultIdentityService(); loginService.setIdentityService(idService); SpnegoAuthenticator authenticator = new SpnegoAuthenticator(); securityHandler.setAuthenticator(authenticator); context.setSecurityHandler(securityHandler); return context; } }