Permalink
Browse files

Merge branch 'rest'

  • Loading branch information...
2 parents 7f5a911 + 883ce0b commit 7ca8b899cab05a9b75b5304a070bbc3fd8d2d465 @labisso labisso committed Mar 19, 2010
Showing with 5,072 additions and 95 deletions.
  1. +5 −1 .gitignore
  2. +82 −0 autocommon/src/org/nimbustools/auto_common/ezpz_ca/CertDN.java
  3. +105 −0 autocommon/src/org/nimbustools/auto_common/ezpz_ca/KeystoreFromPEM.java
  4. +103 −0 bin/create-nimbus-home.sh
  5. +67 −0 bin/install.sh
  6. +49 −0 home/bin/nimbus-configure
  7. +18 −0 home/bin/nimbusctl
  8. +70 −0 home/sbin/nimbusctl.py
  9. +14 −0 home/sbin/run-services.sh
  10. +8 −0 home/sbin/run-web.sh
  11. +407 −0 home/sbin/setup.py
  12. +5 −0 home/var/gridmap.example
  13. +6 −0 messaging/gt4.0-elastic/java/msgbridge/etc/elastic/other/main.conflocator.xml
  14. +11 −0 messaging/gt4.0-elastic/java/msgbridge/etc/elastic/other/main.xml
  15. +4 −0 messaging/gt4.0/java/gar-builder/build.properties
  16. +11 −0 messaging/gt4.0/java/gar-builder/build.xml
  17. +39 −1 messaging/gt4.0/java/gar-builder/etc/post-deploy.xml
  18. +22 −0 messaging/rest/java/source/build.properties
  19. +168 −0 messaging/rest/java/source/build.xml
  20. +77 −0 messaging/rest/java/source/etc/rest/other/main-fake.xml
  21. +28 −0 messaging/rest/java/source/etc/rest/other/main.conflocator.xml
  22. +86 −0 messaging/rest/java/source/etc/rest/other/main.xml
  23. +12 −0 messaging/rest/java/source/etc/rest/rest.conf
  24. BIN messaging/rest/java/source/lib/commons-logging.jar
  25. BIN messaging/rest/java/source/lib/gson-1.4.jar
  26. +13 −0 messaging/rest/java/source/lib/gson.LICENSE
  27. +70 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/AdminResource.java
  28. +30 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/DuplicateUserException.java
  29. +89 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/FakeUsersService.java
  30. +421 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/GridmapUsersService.java
  31. +60 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/NimbusWebException.java
  32. +67 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/NimbusWebExceptionMapper.java
  33. +147 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/OutFaultInterceptor.java
  34. +126 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/ResponseUtil.java
  35. +179 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/RestHttp.java
  36. +29 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/UnknownKeyException.java
  37. +29 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/UnknownUserException.java
  38. +155 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/UsersResource.java
  39. +62 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/UsersService.java
  40. +57 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/repr/AccessKey.java
  41. +38 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/repr/ErrorMessage.java
  42. +58 −0 messaging/rest/java/source/src/org/nimbustools/messaging/rest/repr/User.java
  43. +1 −1 {bin → scripts}/all-build-and-install.sh
  44. +1 −1 {bin → scripts}/all-build.sh
  45. +1 −1 {bin → scripts}/all-clean.sh
  46. +1 −1 {bin → scripts}/all-install.sh
  47. +1 −1 {bin → scripts}/all-uninstall.sh
  48. +1 −1 {bin → scripts}/broker-build-and-install.sh
  49. +1 −1 {bin → scripts}/broker-build.sh
  50. +1 −1 {bin → scripts}/broker-install.sh
  51. +1 −1 {bin → scripts}/clients-only-build-and-install.sh
  52. +1 −1 {bin → scripts}/clients-only-build.sh
  53. +1 −1 {bin → scripts}/clients-only-install.sh
  54. +1 −1 {bin → scripts}/delete-persistence-directory.sh
  55. +3 −0 {bin → scripts}/lib/gt4.0/build/build.properties
  56. +9 −2 {bin → scripts}/lib/gt4.0/build/build.xml
  57. 0 {bin → scripts}/lib/gt4.0/build/run.sh
  58. 0 {bin → scripts}/lib/gt4.0/dist/build.properties
  59. 0 {bin → scripts}/lib/gt4.0/dist/build.xml
  60. 0 {bin → scripts}/lib/gt4.0/dist/scripts/deploy-client-gars.sh
  61. 0 {bin → scripts}/lib/gt4.0/dist/topdocs/LICENSE.txt
  62. 0 {bin → scripts}/lib/gt4.0/dist/topdocs/README.txt
  63. 0 {bin → scripts}/lib/notes.txt
  64. +11 −0 scripts/rest-testserver.sh
  65. +5 −1 web/bin/run-standalone-ssl.sh
  66. BIN web/lib/httplib2-0.6.0.tar.gz
  67. +43 −3 web/lib/libnotes.txt
  68. BIN web/lib/nimbus-autocommon.tar.gz
  69. +605 −0 web/lib/python/ProcessManager.py
  70. 0 web/lib/python/httplib2/nimbusweb.empty.marker
  71. +10 −0 web/nimbusweb.conf
  72. +22 −0 web/sbin/clean-slate.sh
  73. +36 −1 web/sbin/install-deps.sh
  74. +31 −0 web/src/python/nimbusrest/__init__.py
  75. +61 −0 web/src/python/nimbusrest/admin/__init__.py
  76. +79 −0 web/src/python/nimbusrest/admin/connection.py
  77. +46 −0 web/src/python/nimbusrest/admin/tests.py
  78. +127 −0 web/src/python/nimbusrest/connection.py
  79. +80 −0 web/src/python/nimbusrest/error.py
  80. +28 −0 web/src/python/nimbusrest/tests.py
  81. +2 −1 web/src/python/nimbusweb/portal/nimbus/adminops.py
  82. +8 −1 web/src/python/nimbusweb/portal/nimbus/models.py
  83. +41 −0 web/src/python/nimbusweb/portal/nimbus/remote.py
  84. +45 −16 web/src/python/nimbusweb/portal/nimbus/tests.py
  85. +4 −4 web/src/python/nimbusweb/portal/nimbus/views.py
  86. +2 −0 web/src/python/nimbusweb/portal/settings.py
  87. +56 −1 web/src/python/nimbusweb/portal/static/base.css
  88. +1 −0 web/src/python/nimbusweb/portal/templates/404.html
  89. +1 −0 web/src/python/nimbusweb/portal/templates/500.html
  90. +5 −5 web/src/python/nimbusweb/portal/templates/base.html
  91. +74 −26 web/src/python/nimbusweb/portal/templates/nimbus/profile.html
  92. +13 −0 web/src/python/nimbusweb/portal/templates/usercreate/index.html
  93. +12 −0 web/src/python/nimbusweb/portal/templates/usercreate/method.html
  94. +8 −0 web/src/python/nimbusweb/portal/templates/usercreate/success.html
  95. +1 −0 web/src/python/nimbusweb/portal/urls.py
  96. +19 −0 web/src/python/nimbusweb/portal/usercreate/README
  97. 0 web/src/python/nimbusweb/portal/usercreate/__init__.py
  98. +81 −0 web/src/python/nimbusweb/portal/usercreate/create.py
  99. +16 −0 web/src/python/nimbusweb/portal/usercreate/forms.py
  100. +7 −0 web/src/python/nimbusweb/portal/usercreate/urls.py
  101. +16 −0 web/src/python/nimbusweb/portal/usercreate/util.py
  102. +109 −0 web/src/python/nimbusweb/portal/usercreate/views.py
  103. +50 −7 web/src/python/nimbusweb/setup/autoca.py
  104. +10 −8 web/src/python/nimbusweb/setup/checkssl.py
  105. +72 −0 web/src/python/nimbusweb/setup/ezpz_ca.py
  106. +99 −0 web/src/python/nimbusweb/setup/gtcontainer.py
  107. +9 −1 web/src/python/nimbusweb/setup/newconf.py
  108. +25 −0 web/src/python/nimbusweb/setup/pathutil.py
  109. +25 −4 web/src/python/nimbusweb/setup/setup.py
  110. +26 −0 web/src/python/run-tests.sh
View
6 .gitignore
@@ -2,15 +2,19 @@
*.iml
*.ipr
*.iws
+*.swp
build/
dist/
autocontainer/downloads/
autocontainer/gt/
-web/lib/python/
web/lib/java/
+web/lib/python/cherrypy/
+web/lib/python/django/
+web/lib/python/httplib2/
web/src/env.sh
web/src/python/nimbusweb/portal/generated_secrets.py
web/src/python/nimbusweb/portal/generated_settings.py
web/var/
control/var/workspace-control/logs/wclog*
derby.log
+bin/tmp/
View
82 autocommon/src/org/nimbustools/auto_common/ezpz_ca/CertDN.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2009 University of Chicago
+ *
+ * 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 org.nimbustools.auto_common.ezpz_ca;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileReader;
+import java.security.cert.X509Certificate;
+import java.security.Security;
+
+import org.bouncycastle.openssl.PEMReader;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.globus.gsi.CertUtil;
+
+import javax.security.auth.x500.X500Principal;
+
+public class CertDN {
+
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public static String dnFromPath(String path) throws IOException {
+
+ final File certFile = new File(path);
+ if (!certFile.canRead()) {
+ final String msg = "File '" + path + "' can not be read.";
+ throw new IOException(msg);
+ }
+
+ final FileReader fr = new FileReader(certFile);
+ try {
+ final PEMReader reader =
+ new PEMReader(fr, null, BouncyCastleProvider.PROVIDER_NAME);
+ try {
+ final X509Certificate cert = (X509Certificate) reader.readObject();
+ final X500Principal principal = cert.getSubjectX500Principal();
+ final String DN = principal.getName(X500Principal.RFC2253);
+
+ return CertUtil.toGlobusID(DN, false);
+
+ } finally {
+ reader.close();
+ }
+ } finally {
+ fr.close();
+ }
+ }
+
+
+ public static void main(String[] args) {
+
+ if (args == null || args.length != 1) {
+ System.err.println("Needs these arguments:\n" +
+ "1 - the certificate file");
+ System.exit(1);
+ }
+
+ try {
+ final String dn = dnFromPath(args[0]);
+ System.out.println(dn);
+ } catch (Throwable t) {
+ System.err.println("Problem: " + t.getMessage());
+ t.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
View
105 autocommon/src/org/nimbustools/auto_common/ezpz_ca/KeystoreFromPEM.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-2010 University of Chicago
+ *
+ * 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 org.nimbustools.auto_common.ezpz_ca;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMReader;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.KeyPair;
+import java.io.*;
+
+/**
+ * Creates a Java Keystore from PEM encoded cert and private key
+ */
+public class KeystoreFromPEM {
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public static KeyStore createJavaKeystore(X509Certificate cert, PrivateKey key, String password)
+ throws Exception {
+
+ KeyStore store = KeyStore.getInstance("JKS", "SUN");
+ store.load(null, password.toCharArray());
+ store.setKeyEntry("", key, password.toCharArray(),
+ new Certificate[] {cert});
+
+ return store;
+ }
+
+ public static void createJavaKeystore(File certFile, File keyFile,
+ File keystoreFile, String password)
+ throws Exception {
+
+ X509Certificate cert = (X509Certificate) readPemObject(certFile);
+ KeyPair keypair = (KeyPair) readPemObject(keyFile);
+ KeyStore store = createJavaKeystore(cert, keypair.getPrivate(), password);
+ OutputStream outStream = new FileOutputStream(keystoreFile);
+ try {
+ store.store(outStream, password.toCharArray());
+ } finally {
+ outStream.close();
+ }
+ }
+
+ private static Object readPemObject(File file) throws IOException {
+ FileReader reader = new FileReader(file);
+ try {
+ PEMReader pemReader = new PEMReader(reader, null, BouncyCastleProvider.PROVIDER_NAME);
+ return pemReader.readObject();
+ } finally {
+ reader.close();
+ }
+ }
+
+ public static void main(String[] args) {
+
+ if (args == null || args.length != 4) {
+ System.err.println("Needs these arguments:\n" +
+ "1 - the certificate file\n" +
+ "2 = the private key file\n" +
+ "3 - the destination file\n" +
+ "4 - the keystore password\n"
+ );
+ System.exit(1);
+ }
+
+ try {
+ File certFile = new File(args[0]);
+ File keyFile = new File(args[1]);
+ File keystoreFile = new File(args[2]);
+ String password = args[3];
+
+ if (keystoreFile.exists()) {
+ throw new Exception("keystore file already exists!");
+ //TODO maybe it would be better to add to existing keystore?
+ }
+
+ createJavaKeystore(certFile, keyFile, keystoreFile, password);
+
+ } catch (Throwable t) {
+ System.err.println("Problem: " + t.getMessage());
+ t.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
View
103 bin/create-nimbus-home.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+CONTAINER_URL="http://www-unix.globus.org/ftppub/gt4/4.0/4.0.8/ws-core/bin/ws-core-4.0.8-bin.tar.gz"
+CONTAINER_TARNAME="ws-core-4.0.8-bin.tar.gz"
+CONTAINER_UNTARREDNAME="ws-core-4.0.8"
+
+# destination directory inside $NIMBUS_HOME
+CONTAINER_DIRNAME="services"
+
+NIMBUS_SRC_REL="`dirname $0`/.."
+NIMBUS_SRC=`cd $NIMBUS_SRC_REL; pwd`
+
+TMPDIR="$NIMBUS_SRC/bin/tmp"
+
+if [ ! -d $TMPDIR ]; then
+ mkdir $TMPDIR
+ if [ $? -ne 0 ]; then
+ echo "Failed to create temp directory: $TMPDIR"
+ exit 1
+ fi
+fi
+
+if [ "X$1" == "X" ]; then
+ echo ""
+ echo "Usage: $0 destination_dir"
+ echo " You must specify the destination directory.\n"
+ exit 1
+fi
+
+NIMBUS_HOME=$1
+
+if [ ! -d $NIMBUS_HOME ]; then
+ PARENT_DIR=`dirname $NIMBUS_HOME`
+
+ if [ -d $PARENT_DIR ]; then
+
+ echo "Creating destination directory: $NIMBUS_HOME"
+ mkdir $NIMBUS_HOME
+
+ if [ $? -ne 0 ]; then
+ echo "Failed to create destination directory!"
+ exit 1
+ fi
+ else
+ echo "Parent dir of destination does not exist: $PARENT_DIR"
+ exit 1
+ fi
+fi
+
+echo "Deploying skeleton directory structure.."
+cp -fr $NIMBUS_SRC/home/* $NIMBUS_HOME/
+if [ $? -ne 0 ]; then
+ echo "Failed to copy Nimbus home directory"
+ exit 1
+fi
+
+echo "Deploying web application.."
+cp -r $NIMBUS_SRC/web $NIMBUS_HOME/
+if [ $? -ne 0 ]; then
+ echo "Failed to copy Nimbus web directory"
+ exit 1
+fi
+
+CONTAINER_DIR="$NIMBUS_HOME/$CONTAINER_DIRNAME"
+if [ ! -d $CONTAINER_DIR ]; then
+
+ echo "Downloading and installing service container.."
+
+ # fetch GT container if it doesn't already exist
+ if [ ! -f $TMPDIR/$CONTAINER_TARNAME ]; then
+ wget -c -O $TMPDIR/$CONTAINER_TARNAME $CONTAINER_URL
+
+ if [ $? -ne 0 ]; then
+ echo "Failed to download container tarball"
+ exit 1
+ fi
+ fi
+
+ tar xzf $TMPDIR/$CONTAINER_TARNAME -C $TMPDIR
+ if [ $? -ne 0 ]; then
+ echo "Failed to expand Nimbus tarball"
+ exit 1
+ fi
+
+ mv $TMPDIR/$CONTAINER_UNTARREDNAME $CONTAINER_DIR
+ if [ $? -ne 0 ]; then
+ echo "Failed to move container directory to $CONTAINER_DIR"
+ exit 1
+ fi
+else
+ echo "Service container already exists at $CONTAINER_DIR"
+fi
+
+echo "Building and installing Nimbus to service container.."
+
+GLOBUS_LOCATION=$CONTAINER_DIR
+export GLOBUS_LOCATION
+
+$NIMBUS_SRC/scripts/all-build-and-install.sh
+if [ $? -ne 0 ]; then
+ echo "Build and install FAILED!"
+ exit 1
+fi
View
67 bin/install.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+FORCE_FRESH_INSTALL="yes"
+
+NIMBUS_SRC_REL="`dirname $0`/.."
+NIMBUS_SRC=`cd $NIMBUS_SRC_REL; pwd`
+
+if [ "X$1" == "X" ]; then
+ echo ""
+ echo "Usage: $0 destination_dir"
+ echo " You must specify the destination directory.\n"
+ exit 1
+fi
+
+NIMBUS_HOME=$1
+
+if [ -d $NIMBUS_HOME ] && [ "$(ls -A $NIMBUS_HOME)" ]; then
+ if [ $FORCE_FRESH_INSTALL == "yes" ]; then
+ echo ""
+ echo "The destination directory '$NIMBUS_HOME' exists and is not empty."
+ echo "It is not recommended to reinstall Nimbus into an existing install."
+ echo ""
+ echo "If you are making changes to the services, you can build and install those directly:"
+ echo " export GLOBUS_LOCATION=$NIMBUS_HOME/services"
+ echo " scripts/all-build-and-install.sh"
+ echo ""
+ echo "If you know what you are doing and want to reinstall, edit this script:"
+ echo " $0"
+ echo "and change FORCE_FRESH_INSTALL to \"no\""
+ echo ""
+
+ exit 1
+ fi
+fi
+
+$NIMBUS_SRC/bin/create-nimbus-home.sh $NIMBUS_HOME
+
+if [ $? -ne 0 ]; then
+ echo "Nimbus home creation failed!"
+ exit 1
+fi
+
+CONFIG_SCRIPT="$NIMBUS_HOME/bin/nimbus-configure"
+
+if [ ! -f $CONFIG_SCRIPT ]; then
+ echo "Configuration script could not be found: $CONFIG_SCRIPT"
+ exit 1
+fi
+
+$CONFIG_SCRIPT
+
+if [ $? -ne 0 ]; then
+ echo "Nimbus configuration script failed! You may try running it manually:"
+ echo " $CONFIG_SCRIPT"
+ exit 1
+fi
+
+echo ""
+echo "Nimbus installation succeeded!"
+echo "However, additional configuration may be necessary."
+echo "Refer to the Administrator Guide for details."
+echo ""
+echo "You can now start/stop Nimbus services with the nimbusctl command. e.g:"
+echo " $NIMBUS_HOME/bin/nimbusctl start"
+echo ""
+
+exit 0
View
49 home/bin/nimbus-configure
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+PYTHON_EXE="/usr/bin/env python"
+
+NIMBUS_HOME_REL="`dirname $0`/.."
+NIMBUS_HOME=`cd $NIMBUS_HOME_REL; pwd`
+
+NIMBUS_WEBDIR="$NIMBUS_HOME/web"
+
+if [ ! -d $NIMBUS_WEBDIR ]; then
+ echo "Web directory does not exist: $NIMBUS_WEBDIR"
+ echo "Is this a real Nimbus installation?"
+ exit 1
+fi
+
+NIMBUS_CONF="$NIMBUS_HOME/nimbus-setup.conf"
+SETUP_ARGS="--conf $NIMBUS_CONF"
+
+NIMBUS_PYLIB="$NIMBUS_WEBDIR/lib/python"
+NIMBUS_PYSRC="$NIMBUS_WEBDIR/src/python"
+
+PYTHONPATH="$NIMBUS_PYSRC:$NIMBUS_PYLIB:$PYTHONPATH"
+export PYTHONPATH
+
+
+# ------------------------------------------------------------------------------
+
+# The following script expands the tarballs in lib/
+$NIMBUS_WEBDIR/sbin/install-deps.sh $DEBUG
+if [ $? -ne 0 ]; then
+ echo ""
+ echo "Dependencies are not set up properly, exiting."
+ exit 3
+fi
+
+$PYTHON_EXE $NIMBUS_HOME/sbin/setup.py --basedir $NIMBUS_HOME $SETUP_ARGS
+if [ $? -ne 0 ]; then
+ echo ""
+ echo "Nimbus is not set up properly, exiting."
+ exit 2
+fi
+
+#TODO this functionality should be moved into setup.py
+$NIMBUS_WEBDIR/sbin/new-conf.sh
+if [ $? -ne 0 ]; then
+ echo ""
+ echo "Nimbus web is not set up properly, exiting."
+ exit 2
+fi
View
18 home/bin/nimbusctl
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+PYTHON_EXE="/usr/bin/env python"
+
+NIMBUS_HOME_REL="`dirname $0`/.."
+NIMBUS_HOME=`cd $NIMBUS_HOME_REL; pwd`
+export NIMBUS_HOME
+
+NIMBUS_WEBDIR="$NIMBUS_HOME/web"
+
+NIMBUS_PYLIB="$NIMBUS_WEBDIR/lib/python"
+
+PYTHONPATH="$NIMBUS_PYLIB:$PYTHONPATH"
+export PYTHONPATH
+
+$PYTHON_EXE $NIMBUS_HOME/sbin/nimbusctl.py $@
+
+exit $?
View
70 home/sbin/nimbusctl.py
@@ -0,0 +1,70 @@
+#! /usr/bin/env python
+
+import os
+import sys
+
+import ProcessManager
+from ProcessManager import Process
+
+USAGE_TEXT = """\
+
+ nimbusctl [target] command
+
+Omit the target to perform the command for all targets.
+
+Targets:
+%(targets)s\
+
+Commands:
+%(commands)s\
+"""
+
+NIMBUS_HOME = os.getenv("NIMBUS_HOME")
+
+if not NIMBUS_HOME:
+ sys.exit("The NIMBUS_HOME environment variable is not set!")
+
+if not os.path.isdir(NIMBUS_HOME):
+ sys.exit("$NIMBUS_HOME does not exist: "+ NIMBUS_HOME)
+
+NIMBUS_RUN_DIR = os.path.join(NIMBUS_HOME, 'var/run/')
+if not os.path.isdir(NIMBUS_RUN_DIR):
+ try:
+ os.mkdir(NIMBUS_RUN_DIR)
+ except:
+ sys.exit("Failed to create run directory: %s" % NIMBUS_RUN_DIR)
+
+NIMBUS_SERVICES_EXE = os.path.join(NIMBUS_HOME, 'sbin/run-services.sh')
+if not os.path.exists(NIMBUS_SERVICES_EXE):
+ sys.exit("The services executable does not exist: " + NIMBUS_SERVICES_EXE)
+
+NIMBUS_WEB_EXE = os.path.join(NIMBUS_HOME, 'sbin/run-web.sh')
+if not os.path.exists(NIMBUS_WEB_EXE):
+ sys.exit("The web executable does not exist: " + NIMBUS_WEB_EXE)
+
+ProcessManager.init(dataDir = NIMBUS_RUN_DIR)
+
+ProcessManager.add( Process(
+ name = "services",
+ desc = "Nimbus IaaS Services",
+ program = NIMBUS_SERVICES_EXE,
+ args = [],
+ workingDir = NIMBUS_HOME,
+ postStartDelay=5
+ ))
+
+ProcessManager.add( Process(
+ name = "web",
+ desc = "Nimbus Web Application",
+ program = NIMBUS_WEB_EXE,
+ args = [],
+ workingDir = NIMBUS_HOME,
+ postStartDelay=3
+ ))
+
+argv = sys.argv
+if len(argv) == 2:
+ argv = argv[:]
+ argv.insert(1, 'all')
+
+ProcessManager.main(argv=argv, usage=USAGE_TEXT)
View
14 home/sbin/run-services.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+NIMBUS_HOME_REL="`dirname $0`/.."
+NIMBUS_HOME=`cd $NIMBUS_HOME_REL; pwd`
+
+GLOBUS_LOCATION="$NIMBUS_HOME/services"
+export GLOBUS_LOCATION
+
+X509_CERT_DIR="$NIMBUS_HOME/var/ca/trusted-certs"
+export X509_CERT_DIR
+
+LOGFILE="$NIMBUS_HOME/var/services.log"
+
+exec $NIMBUS_HOME/services/bin/globus-start-container > $LOGFILE 2>&1
View
8 home/sbin/run-web.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+NIMBUS_HOME_REL="`dirname $0`/.."
+NIMBUS_HOME=`cd $NIMBUS_HOME_REL; pwd`
+
+LOGFILE="$NIMBUS_HOME/var/web.log"
+
+exec $NIMBUS_HOME/web/bin/run-standalone-ssl.sh > $LOGFILE 2>&1
View
407 home/sbin/setup.py
@@ -0,0 +1,407 @@
+#!/usr/bin/env python
+
+import logging
+import optparse
+import os
+import socket
+import sys
+import traceback
+import ConfigParser
+from StringIO import StringIO
+import readline
+
+from nimbusweb.setup import pathutil,javautil,checkssl,gtcontainer,autoca
+from nimbusweb.setup.setuperrors import *
+
+CONFIGSECTION = 'nimbussetup'
+DEFAULTCONFIG = """
+
+[nimbussetup]
+
+# relative to base directory
+hostcert: var/hostcert.pem
+hostkey: var/hostkey.pem
+ca.dir: var/ca
+
+gridmap: services/etc/nimbus/nimbus-grid-mapfile
+
+keystore: var/keystore.jks
+keystore.pass: changeit
+
+debug: off
+
+"""
+
+def getlog(override=None):
+ """Allow developer to replace logging mechanism, e.g. if this
+ module is incorporated into another program as an API.
+
+ Keyword arguments:
+
+ * override -- Custom logger (default None, uses global variable)
+
+ """
+ global _log
+ if override:
+ _log = override
+ try:
+ _log
+ except:
+ _log = logging.getLogger("nimbussetup")
+ _log.setLevel(logging.DEBUG)
+ return _log
+
+def configureLogging(level, formatstring=None, logger=None):
+ """Configure the logging format and mechanism. Sets global 'log' variable.
+
+ Required parameter:
+
+ * level -- log level
+
+ Keyword arguments:
+
+ * formatstring -- Custom logging format (default None, uses time+level+msg)
+
+ * logger -- Custom logger (default None)
+ """
+
+ global log
+
+ logger = getlog(override=logger)
+
+ if not formatstring:
+ formatstring = "%(asctime)s (%(filename)s:%(lineno)d): %(message)s"
+
+ formatter = logging.Formatter(formatstring)
+ ch = logging.StreamHandler()
+ ch.setLevel(level)
+ ch.setFormatter(formatter)
+ logger.addHandler(ch)
+
+ # set global variable
+ log = logger
+
+ log.debug("debug enabled")
+
+def getconfig(filepath=None):
+ config = ConfigParser.SafeConfigParser()
+
+ fh = StringIO(DEFAULTCONFIG)
+ config.readfp(fh)
+ if filepath:
+ config.read(filepath)
+ return config
+
+class ARGS:
+ """Class for command-line argument constants"""
+
+ BASEDIR_LONG = "--basedir"
+ BASEDIR = "-b"
+ BASEDIR_HELP = "Path to base Nimbus directory"
+
+ CONFIGPATH_LONG = "--conf"
+ CONFIGPATH = "-c"
+ CONFIGPATH_HELP = "Path to configuration file"
+
+ DEBUG_LONG = "--debug"
+ DEBUG = "-d"
+ DEBUG_HELP = "Log debug messages"
+
+ HOSTNAME_LONG = "--hostname"
+ HOSTNAME = "-H"
+ HOSTNAME_HELP = "Fully qualified hostname of machine"
+
+ CANAME_LONG= "--caname"
+ CANAME = "-C"
+ CANAME_HELP = "Unique name to give CA"
+
+def validateargs(opts):
+
+ seeh = "see help (-h)"
+
+ if not opts.basedir:
+ raise InvalidInput("%s required, %s." % (ARGS.BASEDIR_LONG, seeh))
+
+def parsersetup():
+ """Return configured command-line parser."""
+
+ ver = "Nimbus setup"
+ usage = "see help (-h)."
+ parser = optparse.OptionParser(version=ver, usage=usage)
+
+ # ----
+
+ group = optparse.OptionGroup(parser, "Misc options", "-------------")
+
+ group.add_option(ARGS.DEBUG, ARGS.DEBUG_LONG,
+ action="store_true", dest="debug", default=False,
+ help=ARGS.DEBUG_HELP)
+
+ group.add_option(ARGS.CONFIGPATH, ARGS.CONFIGPATH_LONG,
+ dest="configpath", metavar="PATH",
+ help=ARGS.CONFIGPATH_HELP)
+
+ group.add_option(ARGS.BASEDIR, ARGS.BASEDIR_LONG,
+ dest="basedir", metavar="PATH",
+ help=ARGS.BASEDIR_HELP)
+
+ parser.add_option_group(group)
+
+ group = optparse.OptionGroup(parser, "Configuration options",
+ "-------------")
+
+ group.add_option(ARGS.HOSTNAME, ARGS.HOSTNAME_LONG,
+ dest="hostname", metavar="HOST", help=ARGS.HOSTNAME_HELP)
+
+ group.add_option(ARGS.CANAME, ARGS.CANAME_LONG,
+ dest="ca_name", metavar="NAME", help=ARGS.CANAME_HELP)
+
+ return parser
+
+def fold_opts_to_config(opts, config):
+ if opts.hostname:
+ config.set(CONFIGSECTION, 'hostname', opts.hostname)
+ if opts.ca_name:
+ config.set(CONFIGSECTION, 'ca.name', opts.ca_name)
+
+def ask_question(question, valuename, default=None):
+
+ answer = None
+ while not answer:
+ print "\n%s\n" % question
+ if default:
+ print "Press ENTER to use the default (%s)\n"%default
+
+ value = raw_input(valuename+": ")
+ if value:
+ answer = value.strip()
+ elif default:
+ answer = default
+ if not answer:
+ print "Invalid input. You must specify a value. Or hit Ctrl-C to give up."
+ return answer
+
+class NimbusSetup(object):
+ def __init__(self, basedir, config, interactive=True):
+ self.basedir = basedir
+ self.config = config
+ self.interactive = interactive
+
+ def get_config(self, key):
+ try:
+ return self.config.get(CONFIGSECTION, key)
+ except ConfigParser.NoOptionError:
+ return None
+
+ def set_config(self, key, value):
+ return self.config.set(CONFIGSECTION, key, value)
+
+ def validate_environment(self):
+ if not pathutil.is_absolute_path(self.basedir):
+ raise IncompatibleEnvironment(
+ "Base directory setting is not absolute")
+ pathutil.ensure_dir_exists(self.basedir, "base")
+ pathutil.ensure_dir_exists(self.webdir_path(), "web")
+ pathutil.ensure_dir_exists(self.gtdir_path(), "GT container")
+
+ # check that we have some java
+ javautil.check(self.webdir_path(), log)
+
+ def resolve_path(self, path):
+ """
+ Resolves a path relative to base directory.
+ If absolute, returns as-is. If relative,
+ joins with self.basedir and returns.
+ """
+
+ if os.path.isabs(path):
+ return path
+ return os.path.join(self.basedir, path)
+
+ def webdir_path(self):
+ return self.resolve_path('web/')
+
+ def gtdir_path(self):
+ return self.resolve_path('services/')
+
+ def cadir_path(self):
+ path = self.get_config('ca.dir')
+ return self.resolve_path(path or 'var/ca/')
+
+ def hostcert_path(self):
+ path = self.get_config('hostcert')
+ return self.resolve_path(path)
+
+ def hostkey_path(self):
+ path = self.get_config('hostkey')
+ return self.resolve_path(path)
+
+ def keystore_path(self):
+ path = self.get_config('keystore')
+ return self.resolve_path(path)
+
+ def gridmap_path(self):
+ path = self.get_config('gridmap')
+ return self.resolve_path(path)
+
+ def hostname(self):
+ hostguess = self.get_config('hostname')
+ if not hostguess:
+ hostguess = socket.getfqdn()
+
+ if self.interactive:
+ question = "What is the fully qualified hostname of this machine?"
+ hostname = ask_question(question, "Hostname", hostguess)
+ else:
+ print "Using hostname: '%s'" % hostguess
+ hostname = hostguess
+
+ self.set_config('hostname', hostname)
+ return hostname
+
+ def perform_setup(self):
+
+ # first, set up CA and host cert/key
+
+ webdir = self.webdir_path()
+ cadir = self.cadir_path()
+ gtdir = self.gtdir_path()
+ hostcert = self.hostcert_path()
+ hostkey = self.hostkey_path()
+ keystore = self.keystore_path()
+ gridmap = self.gridmap_path()
+
+ # some potentially interactive queries
+ hostname = self.hostname()
+
+ #TODO this may require interaction
+ checkssl.run(webdir, hostcert, hostkey, log, cadir=cadir,
+ hostname=hostname)
+
+ if not os.path.exists(keystore):
+ password = self.get_config('keystore.pass')
+ autoca.createKeystore(hostcert, hostkey, keystore, password,
+ webdir, log)
+
+
+ # then adjust the web config to point to these keys
+
+ webconfpath = pathutil.pathjoin(webdir, 'nimbusweb.conf')
+ webconf = ConfigParser.SafeConfigParser()
+ if not webconf.read(webconfpath):
+ raise IncompatibleEnvironment(
+ "nimbus web config does not exist: %s" % webconfpath)
+ relpath = pathutil.relpath
+ webconf.set('nimbusweb', 'ssl.cert', relpath(hostcert, webdir))
+ webconf.set('nimbusweb', 'ssl.key', relpath(hostkey, webdir))
+ webconf.set('nimbusweb', 'ca.dir', relpath(cadir, webdir))
+
+ try:
+ webconffile = open(webconfpath, 'wb')
+ webconf.write(webconffile)
+ finally:
+ webconffile.close()
+
+ # then setup GT container
+ gtcontainer.adjust_hostname(hostname, webdir, gtdir, log)
+ gtcontainer.adjust_secdesc_path(webdir, gtdir, log)
+ gtcontainer.adjust_host_cert(hostcert, hostkey, webdir, gtdir, log)
+ gtcontainer.adjust_gridmap_file(gridmap, webdir, gtdir, log)
+
+def main(argv=None):
+ if os.name != 'posix':
+ print >>sys.stderr, "Only runs on POSIX systems."
+ return 3
+
+ parser = parsersetup()
+
+ if argv:
+ (opts, args) = parser.parse_args(argv[1:])
+ else:
+ (opts, args) = parser.parse_args()
+
+ global log
+ log = None
+
+ printdebugoutput = False
+
+ try:
+
+ validateargs(opts)
+ config = getconfig(filepath=opts.configpath)
+
+ #Some command line options are folded into the config object
+ fold_opts_to_config(opts, config)
+
+ confdebug = config.get(CONFIGSECTION, "debug")
+ if confdebug == "on":
+ printdebugoutput = True
+ elif opts.debug:
+ printdebugoutput = True
+
+ if printdebugoutput:
+ configureLogging(logging.DEBUG)
+ else:
+ configureLogging(logging.INFO)
+
+ basedir = opts.basedir
+ log.debug("base directory: %s" % basedir)
+
+ setup = NimbusSetup(basedir, config)
+ setup.validate_environment()
+
+ setup.perform_setup()
+
+ if opts.configpath:
+ log.debug("saving settings to %s" % opts.configpath)
+ try:
+ f = None
+ try:
+ f = open(opts.configpath, 'wb')
+ config.write(f)
+ except:
+ log.info("Failed to save settings to %s!" % opts.configpath)
+ finally:
+ if f:
+ f.close()
+
+ except InvalidInput, e:
+ msg = "\nProblem with input: %s" % e.msg
+ print >>sys.stderr, msg
+ return 1
+
+ except InvalidConfig, e:
+ msg = "\nProblem with configuration: %s" % e.msg
+ print >>sys.stderr, msg
+ return 2
+
+ except IncompatibleEnvironment, e:
+ msg = "\nCannot validate environment: %s" % e.msg
+ print >>sys.stderr, msg
+ if printdebugoutput:
+ print >>sys.stderr, "\n---------- stacktrace ----------"
+ traceback.print_tb(sys.exc_info()[2])
+ print >>sys.stderr, "--------------------------------"
+ return 3
+
+if __name__ == "__main__":
+
+ try:
+ sys.exit(main())
+ except SystemExit:
+ raise
+ except KeyboardInterrupt:
+ raise
+ except:
+ exception_type = sys.exc_type
+ try:
+ exceptname = exception_type.__name__
+ except AttributeError:
+ exceptname = exception_type
+ name = str(exceptname)
+ err = str(sys.exc_value)
+ errmsg = "\n==> Uncaught problem, please report all following output:\n %s: %s" % (name, err)
+ print >>sys.stderr, errmsg
+ traceback.print_tb(sys.exc_info()[2])
+ sys.exit(97)
+
View
5 home/var/gridmap.example
@@ -0,0 +1,5 @@
+# This file controls access to the Nimbus services
+#
+# Format: DN account_name
+# Example:
+# "/C=SomeCertificateAuthority/CN=Fakey Mcallister" not_a_real_account
View
6 messaging/gt4.0-elastic/java/msgbridge/etc/elastic/other/main.conflocator.xml
@@ -48,4 +48,10 @@
<property name="placeholderPrefix" value="$QUERY{" />
</bean>
+ <bean id="restSettings"
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="location" value="file://@REST_CONFDIR@/rest.conf" />
+ <property name="placeholderPrefix" value="$REST{" />
+ </bean>
+
</beans>
View
11 messaging/gt4.0-elastic/java/msgbridge/etc/elastic/other/main.xml
@@ -208,6 +208,17 @@
</bean>
+ <!-- TODO this should happen somewhere else... -->
+ <bean id="nimbus-rest.httpserver"
+ class="org.nimbustools.messaging.rest.RestHttp"
+ init-method="startListening">
+ <property name="enabled" value="$REST{rest.enabled}" />
+ <property name="port" value="$REST{rest.port}" />
+ <property name="keystoreLocation" value="$REST{keystore.path}"/>
+ <property name="keystorePassword" value="$REST{keystore.password}"/>
+ <property name="springConfig" value="$REST{rest.spring.path}"/>
+ </bean>
+
<!--
property sources are concentrated in this file
View
4 messaging/gt4.0/java/gar-builder/build.properties
@@ -18,6 +18,7 @@ nimbus.service.api.basedir=${nimbus.basedir}/service-api/java/source
nimbus.messaging.gt4_0.basedir=${nimbus.basedir}/messaging/gt4.0/java
nimbus.messaging.gt4_0-elastic.basedir=${nimbus.basedir}/messaging/gt4.0-elastic/java
nimbus.messaging.query.basedir=${nimbus.basedir}/messaging/query/java/source
+nimbus.messaging.rest.basedir=${nimbus.basedir}/messaging/rest/java/source
nimbus.metadata-server.basedir=${nimbus.basedir}/metadata/java/source
##########################################
@@ -55,6 +56,7 @@ nimbus.messaging.gt4_0.gar.build.bin.dir=${nimbus.messaging.gt4_0.gar.build.dir}
nimbus.service.main.etc.dir=${nimbus.service.main.basedir}/etc
nimbus.messaging.gt4_0-elastic.etc.dir=${nimbus.messaging.gt4_0-elastic.basedir}/msgbridge/etc
nimbus.messaging.query.etc.dir=${nimbus.messaging.query.basedir}/etc
+nimbus.messaging.rest.etc.dir=${nimbus.messaging.rest.basedir}/etc
nimbus.messaging.gt4_0.gar.etc.dir=etc
@@ -89,6 +91,8 @@ nimbus.messaging.gt4_0-elastic.msgbridge.lib.dir=${nimbus.messaging.gt4_0-elasti
nimbus.messaging.query.dist.dir=${nimbus.messaging.query.basedir}/dist/
nimbus.messaging.query.lib.dir=${nimbus.messaging.query.basedir}/lib/
+nimbus.messaging.rest.dist.dir=${nimbus.messaging.rest.basedir}/dist/
+nimbus.messaging.rest.lib.dir=${nimbus.messaging.rest.basedir}/lib/
##################################################################
# JARs we *might* need to put into GLOBUS_LOCATION at install time
View
11 messaging/gt4.0/java/gar-builder/build.xml
@@ -155,6 +155,14 @@
<include name="*.jar"/>
<include name="*LICENSE*"/>
</fileset>
+ <fileset dir="${nimbus.messaging.rest.dist.dir}">
+ <include name="*.jar"/>
+ <include name="*LICENSE*"/>
+ </fileset>
+ <fileset dir="${nimbus.messaging.rest.lib.dir}">
+ <include name="*.jar"/>
+ <include name="*LICENSE*"/>
+ </fileset>
</copy>
</target>
@@ -175,6 +183,9 @@
<fileset dir="${nimbus.messaging.query.etc.dir}" />
</copy>
<copy todir="${nimbus.messaging.gt4_0.gar.build.etc.dir}">
+ <fileset dir="${nimbus.messaging.rest.etc.dir}" />
+ </copy>
+ <copy todir="${nimbus.messaging.gt4_0.gar.build.etc.dir}">
<fileset dir="${nimbus.messaging.gt4_0.gar.etc.dir}" />
</copy>
</target>
View
40 messaging/gt4.0/java/gar-builder/etc/post-deploy.xml
@@ -24,6 +24,9 @@
<property name="query.conf.dir"
value="${base.conf.dir}/query" />
+
+ <property name="rest.conf.dir"
+ value="${base.conf.dir}/rest" />
<property name="workspace.persistence.dir"
value="${deploy.dir}/var/${base.package.name}" />
@@ -84,6 +87,18 @@
<property name="qproperties2.tmp"
location="${query.conf.dir}/query.conf.tmp"/>
+
+ <property name="rproperties.path"
+ location="${rest.conf.dir}/other/main.conflocator.xml"/>
+
+ <property name="rproperties.tmp"
+ location="${rest.conf.dir}/other/main.conflocator.xml.tmp"/>
+
+ <property name="rproperties2.path"
+ location="${rest.conf.dir}/rest.conf"/>
+
+ <property name="rproperties2.tmp"
+ location="${rest.conf.dir}/rest.conf.tmp"/>
<filterset id="absPathFilter">
<filter token="WORKSPACE_CONFDIR"
@@ -92,6 +107,8 @@
value="${elastic.conf.dir}"/>
<filter token="QUERY_CONFDIR"
value="${query.conf.dir}"/>
+ <filter token="REST_CONFDIR"
+ value="${rest.conf.dir}"/>
<filter token="WORKSPACE_PERSISTENCEDIR"
value="${workspace.persistence.dir}"/>
<filter token="DERBY_DIR"
@@ -135,7 +152,8 @@
<target name="setup"
depends="adjust-wproperties, adjust-eproperties,
adjust-wproperties2, adjust-qproperties,
- adjust-qproperties2, adjust-jndi,
+ adjust-qproperties2, adjust-rproperties,
+ adjust-rproperties2, adjust-jndi,
chmodprivate, chmodexes, setupWorkspacePersistence" />
@@ -263,6 +281,26 @@
<delete file="${qproperties2.tmp}"/>
<echo message="Adjusted query.conf paths"/>
</target>
+
+ <target name="adjust-rproperties">
+ <copy file="${rproperties.path}" toFile="${rproperties.tmp}">
+ <filterset refid="absPathFilter"/>
+ </copy>
+ <copy file="${rproperties.tmp}" toFile="${rproperties.path}"
+ overwrite="true" />
+ <delete file="${rproperties.tmp}"/>
+ <echo message="Adjusted rest conf-locator paths"/>
+ </target>
+
+ <target name="adjust-rproperties2">
+ <copy file="${rproperties2.path}" toFile="${rproperties2.tmp}">
+ <filterset refid="absPathFilter"/>
+ </copy>
+ <copy file="${rproperties2.tmp}" toFile="${rproperties2.path}"
+ overwrite="true" />
+ <delete file="${rproperties2.tmp}"/>
+ <echo message="Adjusted rest.conf paths"/>
+ </target>
</project>
View
22 messaging/rest/java/source/build.properties
@@ -0,0 +1,22 @@
+nimbus.messaging.rest.print-noun=Nimbus CXF REST Admin Interface
+
+nimbus.messaging.rest.build.dir=build
+nimbus.messaging.rest.build.dest=build/classes
+nimbus.messaging.rest.src.dir=src
+nimbus.messaging.rest.lib.dir=lib
+nimbus.messaging.rest.dist.dir=dist
+nimbus.messaging.rest.jar.name=nimbus-messaging-rest.jar
+
+nimbus.messaging.rest.testserver.keystore.dest=build/testkeystore.jks
+nimbus.messaging.rest.testserver.keystore.pass=thisisonlyatest.
+
+# Dependencies from source tree
+nimbus.messaging.gt4_0.common.lib.dir=../../../gt4.0/java/common/lib/
+nimbus.messaging.gt4_0.common.dist.dir=../../../gt4.0/java/common/dist/
+nimbus.messaging.query.lib.dir=../../../query/java/source/lib/
+nimbus.service.api.lib.dir=../../../../service-api/java/source/lib/
+nimbus.autocommon.dist.dir=../../../../autocommon/dist
+# you can override this in ~/nimbus.build.properties
+nimbus.java.compilerarg=-nowarn
+
+
View
168 messaging/rest/java/source/build.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+
+<project default="dist" basedir="." name="Nimbus REST interface">
+
+ <description>Nimbus CXF REST Admin Interface</description>
+
+ <!-- load user nimbus.build.properties file, if it exists -->
+ <property file="${user.home}/nimbus.build.properties"/>
+
+ <!-- load defaults from colocated build.properties file -->
+ <property file="build.properties"/>
+
+
+ <!-- *******************************************************************
+ LOCATE GT DEPENDENCIES
+ ******************************************************************* -->
+
+ <property environment="env"/>
+ <property name="abs.deploy.dir" location="${env.GLOBUS_LOCATION}"/>
+ <property name="gt4_0.lib.dir" location="${abs.deploy.dir}/lib"/>
+
+
+ <!-- *******************************************************************
+ CHECK MINIMUM JDK
+ ******************************************************************* -->
+
+ <target name="checkjdk">
+ <available property="jdk1.4+" classname="java.lang.CharSequence"/>
+ <fail message="Aborting: determined you are not building with >= JDK 1.4"
+ unless="jdk1.4+" />
+ </target>
+
+
+ <!-- *******************************************************************
+ INITIALIZE
+ ******************************************************************* -->
+
+ <target name="init" depends="checkjdk">
+ <mkdir dir="${nimbus.messaging.rest.build.dir}"/>
+ <mkdir dir="${nimbus.messaging.rest.build.dest}"/>
+ <mkdir dir="${nimbus.messaging.rest.dist.dir}"/>
+ <mkdir dir="${nimbus.messaging.rest.lib.dir}" />
+ </target>
+
+
+ <!-- *******************************************************************
+ COMPILATION
+ ******************************************************************* -->
+
+ <path id="nimbus.messaging.rest.classpath">
+
+ <fileset dir="${nimbus.messaging.rest.lib.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ <fileset dir="${nimbus.messaging.query.lib.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ <fileset dir="${nimbus.messaging.gt4_0.common.lib.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ <fileset dir="${nimbus.autocommon.dist.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ <fileset dir="${nimbus.service.api.lib.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ <fileset dir="${nimbus.messaging.rest.dist.dir}">
+ <include name="*.jar"/>
+ </fileset>
+
+ </path>
+
+ <target name="compile" depends="init">
+
+ <javac srcdir="${nimbus.messaging.rest.src.dir}"
+ destdir="${nimbus.messaging.rest.build.dest}"
+ classpathref="nimbus.messaging.rest.classpath"
+ debug="on">
+
+ <include name="**/*.java"/>
+ <compilerarg value="${nimbus.java.compilerarg}" />
+
+ </javac>
+
+ <copy todir="${nimbus.messaging.rest.build.dest}" >
+
+ <fileset dir="${nimbus.messaging.rest.src.dir}"
+ includes="**/*.properties" />
+
+ <fileset dir="${nimbus.messaging.rest.src.dir}"
+ includes="**/*.xml" />
+
+ <fileset dir="${nimbus.messaging.rest.src.dir}"
+ includes="**/*.txt" />
+ </copy>
+
+ </target>
+
+
+ <!-- *******************************************************************
+ CREATE ARCHIVE FILE
+ ******************************************************************* -->
+
+ <target name="jar" depends="compile">
+ <jar destfile="${nimbus.messaging.rest.dist.dir}/${nimbus.messaging.rest.jar.name}"
+ basedir="${nimbus.messaging.rest.build.dest}"/>
+ </target>
+
+
+ <!-- *******************************************************************
+ CLEAN
+ ******************************************************************* -->
+
+ <target name="clean">
+ <delete dir="${nimbus.messaging.rest.build.dir}"/>
+ <delete dir="${nimbus.messaging.rest.dist.dir}"/>
+ <echo message="Cleaned: ${basedir}" />
+ </target>
+
+
+ <!-- *******************************************************************
+ CREATE DISTRIBUTION
+ ******************************************************************* -->
+
+ <target name="dist">
+ <echo message="**** Module: ${basedir}" />
+ <echo>Building: ${nimbus.messaging.rest.print-noun}</echo>
+ <antcall target="jar" />
+ <echo>Built: ${nimbus.messaging.rest.print-noun}
+ </echo>
+ </target>
+
+
+ <!-- *******************************************************************
+ TEST SERVER
+ ******************************************************************* -->
+
+ <target name="check-keystore">
+ <available file="${nimbus.messaging.rest.testserver.keystore.dest}"
+ property="keystore.present"/>
+ </target>
+
+ <target name="genkeystore" depends="check-keystore" unless="keystore.present">
+ <genkey alias="testserver-keystore"
+ keystore="${nimbus.messaging.rest.testserver.keystore.dest}"
+ storepass="${nimbus.messaging.rest.testserver.keystore.pass}"
+ dname="CN=Nimbus REST testsever, O=Nimbusproject.org, C=US"/>
+ </target>
+
+ <target name="testserver" depends="dist, genkeystore">
+
+ <java classname="org.nimbustools.messaging.rest.RestHttp"
+ fork="true">
+ <classpath refid="nimbus.messaging.rest.classpath"/>
+ <arg file="etc/rest/other/main-fake.xml"/>
+ <arg value="4443"/>
+ <arg value="${nimbus.messaging.rest.testserver.keystore.dest}"/>
+ <arg value="${nimbus.messaging.rest.testserver.keystore.pass}"/>
+ </java>
+
+ </target>
+
+</project>
View
77 messaging/rest/java/source/etc/rest/other/main-fake.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:security="http://www.springframework.org/schema/security"
+ xsi:schemaLocation="
+http://www.springframework.org/schema/beans
+http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+http://www.springframework.org/schema/aop
+http://www.springframework.org/schema/aop/spring-aop.xsd
+http://www.springframework.org/schema/security
+http://www.springframework.org/schema/security/spring-security-3.0.xsd
+http://cxf.apache.org/jaxrs
+http://cxf.apache.org/schemas/jaxrs.xsd">
+
+ <import resource="classpath:META-INF/cxf/cxf.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
+
+ <security:http auto-config="true">
+ <security:http-basic/>
+ <security:intercept-url pattern="/**" access="ROLE_ADMIN"/>
+ </security:http>
+
+ <security:authentication-manager>
+ <security:authentication-provider>
+ <security:user-service>
+ <security:user name="testadmin" password="secret" authorities="ROLE_ADMIN"/>
+ <security:user name="testuser" password="secret" authorities="ROLE_USER"/>
+ </security:user-service>
+ </security:authentication-provider>
+ </security:authentication-manager>
+
+ <jaxrs:server id="NimbusRestServer"
+ address="/">
+ <jaxrs:serviceBeans>
+ <ref bean="adminResource"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="nimbusWebExceptionMapper"/>
+ </jaxrs:providers>
+ <jaxrs:outFaultInterceptors>
+ <ref bean="outFaultInterceptor"/>
+ </jaxrs:outFaultInterceptors>
+ <jaxrs:properties>
+ <entry key="org.apache.cxf.propogate.exception" value="false"/>
+ </jaxrs:properties>
+ </jaxrs:server>
+
+
+ <bean id="outFaultInterceptor" class="org.nimbustools.messaging.rest.OutFaultInterceptor">
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+ <bean id="nimbusWebExceptionMapper"
+ class="org.nimbustools.messaging.rest.NimbusWebExceptionMapper">
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+
+ <bean id="adminResource" class="org.nimbustools.messaging.rest.AdminResource">
+ <property name="responseUtil" ref="responseUtil"/>
+ <property name="usersResource" ref="usersResource"/>
+ </bean>
+
+ <bean id="usersResource" class="org.nimbustools.messaging.rest.UsersResource">
+ <property name="usersService" ref="fakeUsersService"/>
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+
+ <bean id="fakeUsersService" class="org.nimbustools.messaging.rest.FakeUsersService"/>
+
+ <bean id="responseUtil" class="org.nimbustools.messaging.rest.ResponseUtil"/>
+
+
+</beans>
+
View
28 messaging/rest/java/source/etc/rest/other/main.conflocator.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Discover conf files. The conf files hold name/value pairs that are
+ brought into the XML files in this directory via Spring's nice properties
+ mechanism.
+
+ Concentrate all uses of PropertyPlaceholderConfigurer into this bean
+ config so that the install script can do token replacements for absolute
+ paths throughout the entire spring configuration by just running the
+ token replacement on this file.
+
+ Spring wants "//" in front of absolute filesystem paths so that is why
+ "/TOKEN" is used here instead of "TOKEN"
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+ <bean id="restSettings"
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="location" value="file://@REST_CONFDIR@/rest.conf" />
+ <property name="placeholderPrefix" value="$REST{" />
+ </bean>
+
+</beans>
View
86 messaging/rest/java/source/etc/rest/other/main.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:security="http://www.springframework.org/schema/security"
+ xsi:schemaLocation="
+http://www.springframework.org/schema/beans
+http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+http://www.springframework.org/schema/aop
+http://www.springframework.org/schema/aop/spring-aop.xsd
+http://www.springframework.org/schema/security
+http://www.springframework.org/schema/security/spring-security-3.0.xsd
+http://cxf.apache.org/jaxrs
+http://cxf.apache.org/schemas/jaxrs.xsd">
+
+ <import resource="classpath:META-INF/cxf/cxf.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
+
+ <security:http auto-config="true">
+ <security:http-basic/>
+ <security:intercept-url pattern="/**" access="ROLE_ADMIN"/>
+ </security:http>
+
+ <security:authentication-manager>
+ <security:authentication-provider>
+ <security:user-service>
+ <security:user name="testadmin" password="secret" authorities="ROLE_ADMIN"/>
+ <security:user name="testuser" password="secret" authorities="ROLE_USER"/>
+ </security:user-service>
+ </security:authentication-provider>
+ </security:authentication-manager>
+
+ <jaxrs:server id="NimbusRestServer"
+ address="/">
+ <jaxrs:serviceBeans>
+ <ref bean="adminResource"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="nimbusWebExceptionMapper"/>
+ </jaxrs:providers>
+ <jaxrs:outFaultInterceptors>
+ <ref bean="outFaultInterceptor"/>
+ </jaxrs:outFaultInterceptors>
+ <jaxrs:properties>
+ <entry key="org.apache.cxf.propogate.exception" value="false"/>
+ </jaxrs:properties>
+ </jaxrs:server>
+
+
+ <bean id="outFaultInterceptor" class="org.nimbustools.messaging.rest.OutFaultInterceptor">
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+ <bean id="nimbusWebExceptionMapper"
+ class="org.nimbustools.messaging.rest.NimbusWebExceptionMapper">
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+
+ <bean id="adminResource" class="org.nimbustools.messaging.rest.AdminResource">
+ <property name="responseUtil" ref="responseUtil"/>
+ <property name="usersResource" ref="usersResource"/>
+ </bean>
+
+ <bean id="usersResource" class="org.nimbustools.messaging.rest.UsersResource">
+ <property name="usersService" ref="usersService"/>
+ <property name="responseUtil" ref="responseUtil"/>
+ </bean>
+
+ <bean id="usersService" class="org.nimbustools.messaging.rest.GridmapUsersService">
+ <property name="gridmapResource" value="$REST{gridmap.path}" />
+ <property name="groupAuthzResource" value="$REST{groupauthz.path}"/>
+ <property name="queryUsersResource" value="$REST{query.usermap.path}" />
+ <property name="localUserName" value="$REST{gridmap.localuser}" />
+ </bean>
+
+ <bean id="responseUtil" class="org.nimbustools.messaging.rest.ResponseUtil"/>
+
+ <!--
+ property sources are concentrated in this file
+ -->
+ <import resource="main.conflocator.xml"/>
+
+</beans>
+
View
12 messaging/rest/java/source/etc/rest/rest.conf
@@ -0,0 +1,12 @@
+rest.enabled=false
+rest.port=4443
+
+keystore.path=/path/to/keystore
+keystore.password=secrets
+
+gridmap.path=file:///path/to/grid-mapfile
+groupauthz.path=
+query.usermap.path=file://@QUERY_CONFDIR@/users.txt
+gridmap.localuser=cloudimages
+
+rest.spring.path=file://@REST_CONFDIR@/other/main.xml
View
BIN messaging/rest/java/source/lib/commons-logging.jar
Binary file not shown.
View
BIN messaging/rest/java/source/lib/gson-1.4.jar
Binary file not shown.
View
13 messaging/rest/java/source/lib/gson.LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2008-2009 Google 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.
View
70 messaging/rest/java/source/src/org/nimbustools/messaging/rest/AdminResource.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2009 University of Chicago
+ *
+ * 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 org.nimbustools.messaging.rest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import static org.nimbustools.messaging.rest.ResponseUtil.JSON_CONTENT_TYPE;
+import org.nimbustools.messaging.rest.repr.User;
+import org.springframework.beans.factory.InitializingBean;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+@Path("/admin/")
+public class AdminResource implements InitializingBean {
+
+ private static final Log logger =
+ LogFactory.getLog(AdminResource.class.getName());
+
+ //sub-resources
+ private UsersResource usersResource;
+
+
+ private ResponseUtil responseUtil;
+
+
+ // subresources have annotated getters
+
+ @Path("/users")
+ public UsersResource getUsersResource() {
+ return this.usersResource;
+ }
+
+ public void setUsersResource(UsersResource usersResource) {
+ this.usersResource = usersResource;
+ }
+
+ public ResponseUtil getResponseUtil() {
+ return responseUtil;
+ }
+
+ public void setResponseUtil(ResponseUtil responseUtil) {
+ this.responseUtil = responseUtil;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (responseUtil == null) {
+ throw new IllegalArgumentException("responseUtil may not be null");
+ }
+
+ if (usersResource == null) {
+ throw new IllegalArgumentException("usersResource may not be null");
+ }
+ }
+}
View
30 messaging/rest/java/source/src/org/nimbustools/messaging/rest/DuplicateUserException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2009 University of Chicago
+ *
+ * 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 org.nimbustools.messaging.rest;
+
+public class DuplicateUserException extends Exception {
+ public DuplicateUserException(String message) {
+ super(message);
+ }
+
+ public DuplicateUserException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DuplicateUserException(Throwable cause) {
+ super(cause);
+ }
+}
View
89 messaging/rest/java/source/src/org/nimbustools/messaging/rest/FakeUsersService.java
@@ -0,0 +1,89 @@
+package org.nimbustools.messaging.rest;/*
+ * Copyright 1999-2009 University of Chicago
+ *
+ * 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.
+ */
+
+import org.nimbustools.messaging.rest.UsersService;
+import org.nimbustools.messaging.rest.UnknownKeyException;
+import org.nimbustools.messaging.rest.repr.User;
+import org.nimbustools.messaging.rest.repr.AccessKey;
+import org.springframework.security.core.codec.Base64;
+import org.joda.time.DateTime;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.util.List;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.UUID;
+import java.security.NoSuchAlgorithmException;
+
+public class FakeUsersService implements UsersService {
+
+ HashMap<String,User> users = new HashMap<String, User>();
+ HashMap<String,AccessKey> keys = new HashMap<String, AccessKey>();
+
+ public List<User> getUsers() {
+ return new ArrayList<User>(users.values());
+ }
+
+ public User getUserById(String id) throws UnknownUserException {
+ final User user = users.get(id);
+
+ if (user == null) {
+ throw new UnknownUserException();
+ }
+ return user;
+ }
+
+ public User addUser(User user) {
+
+ user.setId(UUID.randomUUID().toString());
+
+ users.put(user.getId(), user);
+ return user;
+ }
+
+ public AccessKey getAccessKey(User user) throws UnknownKeyException {
+ AccessKey key = keys.get(user.getId());
+ if (key == null) {
+ throw new UnknownKeyException();
+ }
+ return key;
+ }
+
+ public AccessKey createAccessKey(User user) {
+ final KeyGenerator keyGen;
+ try {
+ keyGen = KeyGenerator.getInstance("HmacSHA1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ keyGen.init(256);
+ final SecretKey key = keyGen.generateKey();
+
+ final String secret = new String(Base64.encode(key.getEncoded()));
+
+ AccessKey accessKey = new AccessKey();
+ accessKey.setKey(user.getId());
+ accessKey.setSecret(secret);
+ accessKey.setEnabled(true);
+ accessKey.setCreationTime(new DateTime());
+
+ keys.put(user.getId(), accessKey);
+
+ return accessKey;
+ }
+
+}
View
421 messaging/rest/java/source/src/org/nimbustools/messaging/rest/GridmapUsersService.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright 1999-2010 University of Chicago
+ *
+ * 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 org.nimbustools.messaging.rest;
+
+import org.nimbustools.messaging.rest.repr.User;
+import org.nimbustools.messaging.rest.repr.AccessKey;
+import org.nimbustools.auto_common.ezpz_ca.HashUtil;
+import org.springframework.core.io.Resource;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.core.codec.Base64;
+import org.mortbay.util.QuotedStringTokenizer;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.util.*;
+import java.io.*;
+import java.security.NoSuchAlgorithmException;
+
+public class GridmapUsersService implements UsersService, InitializingBean {
+
+ private static final String DEFAULT_LOCAL_USERNAME = "not_a_real_user";
+
+ private final Object lock = new Object();
+
+ private String localUserName;
+
+ private Resource gridmapResource;
+ private Resource groupAuthzResource;
+ private Resource queryUsersResource;
+
+ private TokenizedFile gridmap;
+ private TokenizedFile queryUsers;
+
+ /**
+ * Retrieve a list of all users
+ *
+ * @return List of users
+ */
+ public List<User> getUsers() {
+
+ List<User> users = new ArrayList<User>();
+
+ synchronized (this.lock) {
+ refreshIfNeeded(gridmap);
+ for (String[] line : this.gridmap.getLines()) {
+ String dn = line[0];
+ String lineId = getUserId(dn);
+
+ User user = new User();
+ user.setId(lineId);
+ user.setDn(dn);
+ users.add(user);
+ }
+ }
+ return users;
+ }
+
+ /**
+ * Retrieve a specific user by ID
+ *
+ * @param id ID of user to retrieve
+ * @return The user
+ * @throws UnknownUserException
+ * A user with specified ID does not exist
+ */
+ public User getUserById(String id) throws UnknownUserException {
+
+ synchronized (this.lock) {
+ refreshIfNeeded(gridmap);
+ String[] line = gridmap.getLinesMap().get(id);
+ if (line == null) {
+ throw new UnknownUserException();
+ }
+ User user = new User();
+ user.setId(id);
+ user.setDn(line[0]);
+ return user;
+ }
+ }
+
+ private void refreshIfNeeded(TokenizedFile file) {
+ try {
+ file.refreshIfNeeded();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Add a new user
+ *
+ * @param user The user
+ * @return The new user, with ID
+ * @throws DuplicateUserException
+ * User already exists
+ */
+ public User addUser(User user) throws DuplicateUserException {
+
+ String dn = user.getDn().trim();
+ final String userId = getUserId(dn);
+
+ synchronized (this.lock) {
+ if (gridmap.getLinesMap().containsKey(userId)) {
+ throw new DuplicateUserException("DN '"+dn+
+ "' already exists in gridmap");
+ }
+
+ final String gridmapLine = "\""+ dn +"\" " + this.localUserName;
+ appendLineToResource(gridmapResource, gridmapLine);
+ if (groupAuthzResource != null) {
+ appendLineToResource(groupAuthzResource, gridmapLine);
+ }
+ }
+
+ user = new User();
+ user.setDn(dn);
+ user.setId(userId);
+ return user;
+ }
+
+ private static void appendLineToResource(Resource resource, String line) {
+ try {
+ final File file = resource.getFile();
+ FileOutputStream f = new FileOutputStream(file, true);
+ OutputStreamWriter writer = new OutputStreamWriter(f);
+ writer.write(line+"\n");
+ writer.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Retrieve the access key for a user
+ *
+ * @param user The user
+ * @return The access key
+ * @throws UnknownKeyException
+ * User does not have an access key
+ */
+ public AccessKey getAccessKey(User user)
+ throws UnknownKeyException {
+
+ if (user == null) {
+ throw new IllegalArgumentException("user may not be null");
+ }
+
+ final String userId = user.getId();
+
+ if (userId == null) {
+ throw new IllegalArgumentException("user's ID may not be null");
+ }
+
+ synchronized (this.lock) {
+ final String[] line = this.queryUsers.getLinesMap().get(userId);
+ if (line == null) {
+ throw new UnknownKeyException();
+ }
+ if (line.length < 3) {
+ throw new UnknownKeyException();
+ }
+ AccessKey accessKey = new AccessKey();
+ accessKey.setKey(line[1]);
+ accessKey.setSecret(line[2]); //uhhhhh
+ accessKey.setEnabled(true);
+ return accessKey;
+ }
+ }
+
+ /**
+ * Creates an access key for user. If a key exists, it will
+ * be discarded and replaced with a new one.
+ *
+ * @param user The user
+ * @return New access key
+ */
+ public AccessKey createAccessKey(User user) {
+
+ if (user == null) {
+ throw new IllegalArgumentException("user may not be null");
+ }
+
+ final String dn = user.getDn();
+
+ if (dn == null) {
+ throw new IllegalArgumentException("user's DN may not be null");
+ }
+
+ final String accessId;
+ try {
+ accessId = getHashUtil().hashDN(dn);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ final String secret = generateSecretKey();
+
+ final String line = "\""+dn+"\" "+accessId+" "+secret;
+
+ appendLineToResource(this.queryUsersResource, line);
+
+ AccessKey accessKey = new AccessKey();
+ accessKey.setEnabled(true);
+ accessKey.setKey(accessId);
+ accessKey.setSecret(secret);
+ return accessKey;
+ }
+
+ private String generateSecretKey() {
+ final KeyGenerator keyGen;
+ try {
+ keyGen = KeyGenerator.getInstance("HmacSHA1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ keyGen.init(256);
+ final SecretKey key = keyGen.generateKey();
+ return new String(Base64.encode(key.getEncoded()));
+ }
+
+ public void initialize() throws Exception {
+ this.gridmap = new TokenizedFile(this.gridmapResource.getFile());
+ this.gridmap.refreshIfNeeded();
+ this.queryUsers = new TokenizedFile(this.queryUsersResource.getFile());
+ this.queryUsers.refreshIfNeeded();
+
+ if (this.groupAuthzResource != null) {
+ if (!this.groupAuthzResource.exists()) {
+ throw new Exception(
+ "groupAuthz file resource specified doesn't exist: "+
+ groupAuthzResource.getFilename());
+ }
+ }
+ }
+
+ public Resource getGridmapResource() {
+ return gridmapResource;
+ }
+
+ public void setGridmapResource(Resource gridmapResource) {
+ this.gridmapResource = gridmapResource;
+ }
+
+ public Resource getGroupAuthzResource() {
+ return groupAuthzResource;
+ }
+
+ public void setGroupAuthzResource(Resource groupAuthzResource) {
+ this.groupAuthzResource = groupAuthzResource;
+ }
+
+ public Resource getQueryUsersResource() {
+ return queryUsersResource;
+ }
+
+ public void setQueryUsersResource(Resource queryUsersResource) {
+ this.queryUsersResource = queryUsersResource;
+ }
+
+ public String getLocalUserName() {
+ return localUserName;
+ }
+
+ public void setLocalUserName(String localUserName) {
+ this.localUserName = localUserName;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (this.gridmapResource == null) {
+ throw new IllegalArgumentException("this.gridmapResource may not be null");
+ }
+ if (this.queryUsersResource == null) {
+ throw new IllegalArgumentException("this.queryUsersResource may not be null");
+ }
+
+ if (this.localUserName == null || this.localUserName.trim().length() == 0) {
+ this.localUserName = DEFAULT_LOCAL_USERNAME;
+ }
+
+ this.initialize();
+ }
+
+ static String getUserId(String dn) {
+ return getUserId(dn, getHashUtil());
+ }
+
+ static String getUserId(String dn, HashUtil hashUtil) {
+ try {
+ return "0-"+hashUtil.hashDN(dn);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static HashUtil getHashUtil() {
+ final HashUtil hashUtil;
+ try {
+ hashUtil = new HashUtil();
+ } catch (NoSuchAlgorithmException e) {