001/* 002 * Copyright (c) 2016 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2017-09-04 12:58:02 -0700 (Mon, 04 Sep 2017) $' 007 * '$Revision: 1405 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.webview.server; 030 031import java.io.File; 032import java.util.HashSet; 033import java.util.LinkedList; 034import java.util.List; 035import java.util.Set; 036 037import org.apache.commons.httpclient.util.HttpURLConnection; 038import org.kepler.CommandLineArgument; 039import org.kepler.build.modules.Module; 040import org.kepler.configuration.ConfigurationManager; 041import org.kepler.configuration.ConfigurationProperty; 042import org.kepler.util.DotKeplerManager; 043import org.kepler.webview.server.auth.DrupalAuth; 044import org.kepler.webview.server.auth.NoneAuth; 045import org.kepler.webview.server.auth.SimpleAuth; 046 047import io.vertx.ext.auth.AuthProvider; 048 049/** Utility class to read WebView configuration. 050 * 051 * @author Daniel Crawl 052 * @version $Id: WebViewConfiguration.java 1405 2017-09-04 19:58:02Z crawl $ 053 */ 054public class WebViewConfiguration { 055 056 /** This class cannot be instantiated. */ 057 private WebViewConfiguration() { 058 059 } 060 061 /** Returns true if the http server table of contents should be enabled. */ 062 public static boolean enableHttpServerTableOfContents() { 063 return _getConfigurationBoolean("server.tableOfContents.enable", false); 064 } 065 066 /** Returns true if the http server should use ssl. */ 067 public static boolean enableHttps() { 068 return _getConfigurationBoolean("server.ssl.enable", false); 069 } 070 071 /** Returns any models to be preloaded. */ 072 public static Set<String> getPreloadModels() { 073 return _getConfigurationStrings("server.preload.model"); 074 } 075 076 /** Returns the auth token for ROHUB. */ 077 public static String getROHubAuthToken() { 078 return _getConfigurationString("server.roHub.authToken", null); 079 } 080 081 /** Returns the URI for ROHUB REST API. */ 082 public static String getROHubURI() { 083 return _getConfigurationString("server.roHub.uri", null); 084 } 085 086 /** Get the authorization group. 087 * @param username The user name. 088 * @param password The password. 089 * @return Returns null if username not found, or password does not match. 090 */ 091 public static String getSimpleAuthGroup(String username, String password) { 092 for(ConfigurationProperty property : _getConfigurationProperties("server.auth.entity")) { 093 if(property.getProperty("user").getValue().equals(username)) { 094 if(property.getProperty("password").getValue().equals(password)) { 095 return property.getProperty("group").getValue(); 096 } 097 // found user, but incorrect password. 098 return null; 099 } 100 } 101 // did not find user. 102 return null; 103 } 104 105 /** Get the class name of an app. */ 106 public static String getAppClassName(String appName) { 107 for(ConfigurationProperty property : _getConfigurationProperties("server.apps.app")) { 108 if(property.getProperty("name").getValue().equals(appName)) { 109 return property.getProperty("class").getValue(); 110 } 111 } 112 return null; 113 } 114 115 /** Get config properties for an app. */ 116 public static List<ConfigurationProperty> getAppProperties(String appName, String confName) { 117 118 for(ConfigurationProperty property : _getConfigurationProperties("server.apps.app")) { 119 if(property.getProperty("name").getValue().equals(appName)) { 120 return property.getProperties(confName); 121 } 122 } 123 return new LinkedList<ConfigurationProperty>(); 124 } 125 126 /** Get an authentication provider based on the authentication type 127 * specified in the configuration. 128 */ 129 public static AuthProvider getAuthProvider() { 130 String authType = _getConfigurationString("server.auth.type", null); 131 if(authType == null || authType.equals("simple")) { 132 return new SimpleAuth(); 133 } else if(authType.equals("none")) { 134 System.err.println("WARNING: WebView server authentication disabled."); 135 return new NoneAuth(); 136 } else if(authType.equals("drupal")) { 137 return new DrupalAuth(_getConfigurationString("server.auth.drupal.host", null), 138 _getConfigurationString("server.auth.drupal.service", null), 139 _getConfigurationString("server.auth.drupal.role", null), 140 _getConfigurationString("server.auth.drupal.groupsField", null), 141 _getConfigurationString("server.auth.drupal.fullNameField", null)); 142 143 } else if(authType.equals("class")) { 144 String className = _getConfigurationString("server.auth.class", null); 145 if(className != null) { 146 try { 147 Class<?> clazz = Class.forName(className); 148 return (AuthProvider)clazz.newInstance(); 149 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 150 System.err.println("ERROR: could not instantiate auth class " + className + ": " + e.getMessage()); 151 e.printStackTrace(); 152 } 153 } 154 } else { 155 System.err.println("ERROR: unknown type of authentication: " + authType); 156 } 157 return null; 158 } 159 160 /** Get the CORS allow origin pattern. */ 161 public static String getHttpServerCorsAllowOriginPattern() { 162 return _getConfigurationString("server.cors.allowOrigin", null); 163 } 164 165 /** Returns true if the http server allows CORS. */ 166 public static boolean getHttpServerCorsEnabled() { 167 return _getConfigurationBoolean("server.cors.enable", false); 168 } 169 170 /** Returns true if the http server allows workflows to be downloaded. */ 171 public static boolean getHttpServerAllowWorkflowDownloads() { 172 return _getConfigurationBoolean("server.allowWorkflowDownloads", false); 173 } 174 175 public static boolean getHttpServerAppendIndexHtml() { 176 return _getConfigurationBoolean("server.appendIndexHtml", false); 177 } 178 179 /** Get list of server directories that can be indexed. */ 180 public static Set<String> getHttpServerDirectoriesToIndex() { 181 return _getConfigurationStrings("server.directoryIndex.dir"); 182 } 183 184 /** Get the number of instances of http servers to start. */ 185 public static int getHttpServerInstances() { 186 187 boolean wasParsed = CommandLineArgument.wasParsed(WEBVIEW_SERVER_INSTANCES_FLAG); 188 if(wasParsed) { 189 return Integer.valueOf( 190 CommandLineArgument.get(WEBVIEW_SERVER_INSTANCES_FLAG).getValue()) 191 .intValue(); 192 } 193 194 return _getConfigurationInteger("server.instances", DEFAULT_WEBVIEW_SERVER_INSTANCES); 195 } 196 197 /** Get the log directory and file name for the http server. */ 198 public static String getHttpServerLogPath() { 199 return _getConfigurationString("server.logPath", 200 DotKeplerManager.getInstance().getPersistentModuleDirectory("web-view") + 201 File.separator + 202 "server.log"); 203 } 204 205 /** Get the metadata file name. */ 206 public static String getHttpServerMetadataFileName() { 207 String fileName = _getConfigurationString("server.metadataFile", null); 208 if(fileName != null && !fileName.startsWith(File.separator)) { 209 fileName = _getConfigurationModule("server.metadataFile").getConfigurationsDir() + 210 File.separator + fileName; 211 } 212 return fileName; 213 } 214 215 /* Get the port number for the http server. */ 216 public static int getHttpServerPort() { 217 218 boolean wasParsed = CommandLineArgument.wasParsed(WEBVIEW_SERVER_PORT_FLAG); 219 if(wasParsed) { 220 return Integer.valueOf( 221 CommandLineArgument.get(WEBVIEW_SERVER_PORT_FLAG).getValue()) 222 .intValue(); 223 } 224 225 return _getConfigurationInteger("server.port", DEFAULT_WEBVIEW_SERVER_PORT); 226 } 227 228 /** Get the http redirect status code. */ 229 public static int getHttpServerRedirectStatus() { 230 return _getConfigurationInteger("server.ssl.redirectHttp.status", HttpURLConnection.HTTP_MOVED_PERM); 231 } 232 233 /** Get the hostname to redirect http requests to. */ 234 public static String getHttpServerRedirectHostname() { 235 return _getConfigurationString("server.ssl.redirectHttp.hostname", "localhost"); 236 } 237 238 /** Get the port to redirect http requests to. */ 239 public static int getHttpServerRedirectPort() { 240 return _getConfigurationInteger("server.ssl.redirectHttp.port", DEFAULT_WEBVIEW_SECURE_SERVER_PORT); 241 } 242 243 /** Returns the root directory for the HTTP Server. If none specified, 244 * returns null. 245 */ 246 public static String getHttpServerRootDir() { 247 248 boolean wasParsed = CommandLineArgument.wasParsed(WEBVIEW_SERVER_ROOT_DIR_FLAG); 249 if(wasParsed) { 250 return CommandLineArgument.get(WEBVIEW_SERVER_ROOT_DIR_FLAG).getValue(); 251 } 252 253 return _getConfigurationString("server.rootDir", null); 254 } 255 256 /** Get the timeout, in milliseconds, for the session if not accessed. */ 257 public static long getHttpServerSessionTimeout() { 258 return _getConfigurationLong("server.sessionTimeout", 259 DEFAULT_WEBVIEW_SERVER_SESSION_TIMEOUT); 260 } 261 262 /** Get the path regex of the http server table of contents. */ 263 public static String getHttpServerTableOfContentsPath() { 264 return _getConfigurationString("server.tableOfContents.pathRegex", null); 265 } 266 267 /** Returns the number of threads for the worker pool. */ 268 public static int getHttpServerWorkerThreads() { 269 return _getConfigurationInteger("server.workerThreads", 1); 270 } 271 272 /** Get the timeout, in milliseconds, for workflow execution. 273 * Returns -1 for no timeout. 274 */ 275 public static long getHttpServerWorkflowTimeout() { 276 return _getConfigurationLong("server.workflowTimeout", -1); 277 } 278 279 /** Get the port number for the https server. */ 280 public static int getHttpsServerPort() { 281 return _getConfigurationInteger("server.ssl.port", DEFAULT_WEBVIEW_SECURE_SERVER_PORT); 282 } 283 284 /** Get the SSL PEM Key file path. */ 285 public static String getHttpsPEMKeyPath() { 286 return _getConfigurationString("server.ssl.key", null); 287 } 288 289 /** Get the SSL PEM Certificate file path.*/ 290 public static String getHttpsPEMCertPath() { 291 return _getConfigurationString("server.ssl.cert", null); 292 } 293 294 public static boolean shouldHttpServerRedirect() { 295 return _getConfigurationBoolean("server.ssl.redirectHttp.enable", false); 296 } 297 298 /** Returns true if the web view http server should start. */ 299 public static boolean shouldStartHttpServer() { 300 301 boolean retval = CommandLineArgument.wasParsed(WEBVIEW_START_SERVER_FLAG); 302 303 if(!retval) { 304 retval = _getConfigurationBoolean("server.startServer", false); 305 } 306 307 return retval; 308 } 309 310 /** Returns true if the web view http server should start in daemon mode. */ 311 public static boolean shouldStartHttpServerAsDaemon() { 312 313 boolean retval = CommandLineArgument.wasParsed(WEBVIEW_SERVER_DAEMON_FLAG); 314 315 if(!retval) { 316 return _getConfigurationBoolean("server.daemon", false); 317 } 318 319 return retval; 320 } 321 322 /////////////////////////////////////////////////////////////////// 323 //// public variables //// 324 325 /** Command line flag to specify the server port. */ 326 public final static String WEBVIEW_SERVER_PORT_FLAG = "-wvport"; 327 328 /** The default server port. */ 329 public final static int DEFAULT_WEBVIEW_SERVER_PORT = 9122; 330 331 /** The default secure sever port. */ 332 public final static int DEFAULT_WEBVIEW_SECURE_SERVER_PORT = 8443; 333 334 /** Command line flag to specify the root directory. */ 335 public final static String WEBVIEW_SERVER_ROOT_DIR_FLAG = "-wvroot"; 336 337 /** The default root directory. */ 338 public final static String DEFAULT_WEBVIEW_SERVER_ROOT_DIR = "web-view/resources/html"; 339 340 /** Command line flag to start the server. */ 341 public final static String WEBVIEW_START_SERVER_FLAG = "-wv"; 342 343 /** Command line flag to run the server in daemon mode. */ 344 public final static String WEBVIEW_SERVER_DAEMON_FLAG = "-wvd"; 345 346 /** Command line flag to specify the number of server instances. */ 347 public final static String WEBVIEW_SERVER_INSTANCES_FLAG = "-wvnum"; 348 349 /** The default number of server instances. */ 350 public final static int DEFAULT_WEBVIEW_SERVER_INSTANCES = 1; 351 352 /////////////////////////////////////////////////////////////////// 353 //// private methods //// 354 355 /** Get a configuration property in the web-view config file. */ 356 private static ConfigurationProperty _getConfigurationProperty(String path) { 357 return ConfigurationManager.getInstance() 358 .getProperty(ConfigurationManager.getModule("web-view")).getProperty(path); 359 } 360 361 /** Get a list of configuration properties in the web-view config file. */ 362 private static List<ConfigurationProperty> _getConfigurationProperties(String path) { 363 return ConfigurationManager.getInstance() 364 .getProperties(ConfigurationManager.getModule("web-view"), path); 365 } 366 367 /** Get a configuration value in the web-view config file. Returns 368 * the default value if the path does not exist or is not set. 369 */ 370 private static String _getConfigurationString(String path, String defaultValue) { 371 ConfigurationProperty property = _getConfigurationProperty(path); 372 if(property != null) { 373 String value = property.getValue(); 374 if(value != null) { 375 return value; 376 } 377 } 378 return defaultValue; 379 } 380 381 /** Get set of strings from multiple configuration values with the same name. */ 382 private static Set<String> _getConfigurationStrings(String path) { 383 Set<String> retval = new HashSet<String>(); 384 for(ConfigurationProperty property: _getConfigurationProperties(path)) { 385 retval.add(property.getValue()); 386 } 387 return retval; 388 } 389 390 /** Get a boolean configuration value in the web-view config file. */ 391 private static boolean _getConfigurationBoolean(String path, boolean defaultValue) { 392 String value = _getConfigurationString(path, null); 393 if(value != null) { 394 return Boolean.valueOf(value); 395 } 396 return defaultValue; 397 } 398 399 /** Get an integer configuration value in the web-view config file. */ 400 private static int _getConfigurationInteger(String path, int defaultValue) { 401 String value = _getConfigurationString(path, null); 402 if(value != null) { 403 return Integer.valueOf(value); 404 } 405 return defaultValue; 406 } 407 408 /** Get a long configuration value in the web-view config file. */ 409 private static long _getConfigurationLong(String path, long defaultValue) { 410 String value = _getConfigurationString(path, null); 411 if(value != null) { 412 return Long.valueOf(value); 413 } 414 return defaultValue; 415 } 416 417 private static Module _getConfigurationModule(String path) { 418 ConfigurationProperty property = _getConfigurationProperty(path); 419 if(property != null) { 420 return property.getModule(); 421 } 422 return null; 423 } 424 425 /** Default session timeout in milliseconds */ 426 private static final long DEFAULT_WEBVIEW_SERVER_SESSION_TIMEOUT = 3600*1000; 427 428 public static boolean deployInKubernetes() { 429 return _getConfigurationBoolean("server.cluster.deployInKubernetes", false); 430 } 431 432 public static String getHazelcastDiscoveryDnsServiceName() { 433 return _getConfigurationString("server.cluster.hazelcastDiscoveryK8sDnsService", null); 434 } 435 436 /** Get if vertx should use hazelcast for clustered mode. */ 437 public static boolean shouldStartClusterHazelcast() { 438 String typeStr = _getConfigurationString("server.cluster.type", null); 439 return (typeStr != null && typeStr.equals("hazelcast")); 440 } 441 442 /** Get if vertx should start in clustered mode. */ 443 public static boolean shouldStartCluster() { 444 String typeStr = _getConfigurationString("server.cluster.type", null); 445 return (typeStr != null && typeStr.trim().length() > 0 && 446 !typeStr.toLowerCase().equals("none") && 447 !typeStr.toLowerCase().equals("false")); 448 } 449 450}