Merge "Add SecureStore implementation"
This commit is contained in:
		@@ -7,6 +7,7 @@ ANNOTATIONS = [
 | 
				
			|||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXCLUDES = [
 | 
					EXCLUDES = [
 | 
				
			||||||
 | 
					  SRC + 'common/PluginData.java',
 | 
				
			||||||
  SRC + 'common/FileUtil.java',
 | 
					  SRC + 'common/FileUtil.java',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,6 +46,7 @@ java_library(
 | 
				
			|||||||
    '//gerrit-reviewdb:server',
 | 
					    '//gerrit-reviewdb:server',
 | 
				
			||||||
    '//lib:gwtjsonrpc',
 | 
					    '//lib:gwtjsonrpc',
 | 
				
			||||||
    '//lib:gwtorm',
 | 
					    '//lib:gwtorm',
 | 
				
			||||||
 | 
					    '//lib:guava',
 | 
				
			||||||
    '//lib/jgit:jgit',
 | 
					    '//lib/jgit:jgit',
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  visibility = ['PUBLIC'],
 | 
					  visibility = ['PUBLIC'],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2013 The Android Open Source Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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.google.gerrit.common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package com.google.gerrit.common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.common.base.Objects;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class PluginData {
 | 
				
			||||||
 | 
					  public final String name;
 | 
				
			||||||
 | 
					  public final String version;
 | 
				
			||||||
 | 
					  public final File pluginFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public PluginData(String name, String version, File pluginFile) {
 | 
				
			||||||
 | 
					    this.name = name;
 | 
				
			||||||
 | 
					    this.version = version;
 | 
				
			||||||
 | 
					    this.pluginFile = pluginFile;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public boolean equals(Object obj) {
 | 
				
			||||||
 | 
					    if (obj instanceof PluginData) {
 | 
				
			||||||
 | 
					      PluginData o = (PluginData) obj;
 | 
				
			||||||
 | 
					      return Objects.equal(name, o.name) && Objects.equal(version, o.version)
 | 
				
			||||||
 | 
					          && Objects.equal(pluginFile, o.pluginFile);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return super.equals(obj);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public int hashCode() {
 | 
				
			||||||
 | 
					    return Objects.hashCode(name, version, pluginFile);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -38,10 +38,12 @@ import org.objectweb.asm.MethodVisitor;
 | 
				
			|||||||
import org.objectweb.asm.Opcodes;
 | 
					import org.objectweb.asm.Opcodes;
 | 
				
			||||||
import org.objectweb.asm.Type;
 | 
					import org.objectweb.asm.Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.lang.annotation.Annotation;
 | 
					import java.lang.annotation.Annotation;
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.Enumeration;
 | 
					import java.util.Enumeration;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
@@ -92,6 +94,15 @@ public class JarScanner {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public static Iterable<ExtensionMetaData> scan(File file, String pluginName,
 | 
				
			||||||
 | 
					      Class<? extends Annotation> annotation) throws InvalidPluginException,
 | 
				
			||||||
 | 
					      IOException {
 | 
				
			||||||
 | 
					    Map<Class<? extends Annotation>, Iterable<ExtensionMetaData>> result =
 | 
				
			||||||
 | 
					        scan(new JarFile(file), pluginName,
 | 
				
			||||||
 | 
					            Arrays.<Class<? extends Annotation>> asList(annotation));
 | 
				
			||||||
 | 
					    return result.get(annotation);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public static Map<Class<? extends Annotation>, Iterable<ExtensionMetaData>> scan(
 | 
					  public static Map<Class<? extends Annotation>, Iterable<ExtensionMetaData>> scan(
 | 
				
			||||||
      JarFile jarFile, String pluginName,
 | 
					      JarFile jarFile, String pluginName,
 | 
				
			||||||
      Iterable<Class<? extends Annotation>> annotations)
 | 
					      Iterable<Class<? extends Annotation>> annotations)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,6 +77,10 @@ public class PluginLoader implements LifecycleListener {
 | 
				
			|||||||
  static final String PLUGIN_TMP_PREFIX = "plugin_";
 | 
					  static final String PLUGIN_TMP_PREFIX = "plugin_";
 | 
				
			||||||
  static final Logger log = LoggerFactory.getLogger(PluginLoader.class);
 | 
					  static final Logger log = LoggerFactory.getLogger(PluginLoader.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public static String getPluginName(File srcFile) throws IOException {
 | 
				
			||||||
 | 
					    return Objects.firstNonNull(getGerritPluginName(srcFile), nameOf(srcFile)).toLowerCase();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final File pluginsDir;
 | 
					  private final File pluginsDir;
 | 
				
			||||||
  private final File dataDir;
 | 
					  private final File dataDir;
 | 
				
			||||||
  private final File tmpDir;
 | 
					  private final File tmpDir;
 | 
				
			||||||
@@ -661,7 +665,7 @@ public class PluginLoader implements LifecycleListener {
 | 
				
			|||||||
  // If multiple plugin files provide the same plugin name, then only
 | 
					  // If multiple plugin files provide the same plugin name, then only
 | 
				
			||||||
  // the first plugin remains active and all other plugins with the same
 | 
					  // the first plugin remains active and all other plugins with the same
 | 
				
			||||||
  // name are disabled.
 | 
					  // name are disabled.
 | 
				
			||||||
  private static Multimap<String, File> prunePlugins(File pluginsDir) {
 | 
					  public static Multimap<String, File> prunePlugins(File pluginsDir) {
 | 
				
			||||||
    List<File> jars = scanJarsInPluginsDirectory(pluginsDir);
 | 
					    List<File> jars = scanJarsInPluginsDirectory(pluginsDir);
 | 
				
			||||||
    Multimap<String, File> map;
 | 
					    Multimap<String, File> map;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -757,8 +761,7 @@ public class PluginLoader implements LifecycleListener {
 | 
				
			|||||||
      throws IOException {
 | 
					      throws IOException {
 | 
				
			||||||
    Multimap<String, File> map = LinkedHashMultimap.create();
 | 
					    Multimap<String, File> map = LinkedHashMultimap.create();
 | 
				
			||||||
    for (File srcFile : plugins) {
 | 
					    for (File srcFile : plugins) {
 | 
				
			||||||
      map.put(Objects.firstNonNull(getGerritPluginName(srcFile),
 | 
					      map.put(getPluginName(srcFile), srcFile);
 | 
				
			||||||
          nameOf(srcFile)), srcFile);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return map;
 | 
					    return map;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2013 The Android Open Source Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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.google.gerrit.server.securestore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.annotations.ExtensionPoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@ExtensionPoint
 | 
				
			||||||
 | 
					public interface SecureStore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String get(String section, String subsection, String name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void set(String section, String subsection, String name, String value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void unset(String section, String subsection, String name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2014 The Android Open Source Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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.google.gerrit.server.securestore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.common.base.Objects;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.net.URL;
 | 
				
			||||||
 | 
					import java.net.URLClassLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SecureStoreData {
 | 
				
			||||||
 | 
					  public final File pluginFile;
 | 
				
			||||||
 | 
					  public final String storeName;
 | 
				
			||||||
 | 
					  public final String className;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public SecureStoreData(String pluginName, String className, File jarFile,
 | 
				
			||||||
 | 
					      String storeName) {
 | 
				
			||||||
 | 
					    this.className = className;
 | 
				
			||||||
 | 
					    this.pluginFile = jarFile;
 | 
				
			||||||
 | 
					    this.storeName = String.format("%s/%s", pluginName, storeName);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public String getStoreName() {
 | 
				
			||||||
 | 
					    return storeName;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public Class<? extends SecureStore> load() {
 | 
				
			||||||
 | 
					    return load(pluginFile);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
					  public Class<? extends SecureStore> load(File pluginFile) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      URL[] pluginJarUrls = new URL[] {pluginFile.toURI().toURL()};
 | 
				
			||||||
 | 
					      ClassLoader currentCL = Thread.currentThread().getContextClassLoader();
 | 
				
			||||||
 | 
					      final URLClassLoader newClassLoader =
 | 
				
			||||||
 | 
					          new URLClassLoader(pluginJarUrls, currentCL);
 | 
				
			||||||
 | 
					      Thread.currentThread().setContextClassLoader(newClassLoader);
 | 
				
			||||||
 | 
					      return (Class<? extends SecureStore>) newClassLoader.loadClass(className);
 | 
				
			||||||
 | 
					    } catch (Exception e) {
 | 
				
			||||||
 | 
					      throw new SecureStoreException(String.format(
 | 
				
			||||||
 | 
					          "Cannot load secure store implementation for %s", storeName), e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public String toString() {
 | 
				
			||||||
 | 
					    return Objects.toStringHelper(this).add("storeName", storeName)
 | 
				
			||||||
 | 
					        .add("className", className).add("file", pluginFile).toString();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public boolean equals(Object obj) {
 | 
				
			||||||
 | 
					    if (obj instanceof SecureStoreData) {
 | 
				
			||||||
 | 
					      SecureStoreData o = (SecureStoreData) obj;
 | 
				
			||||||
 | 
					      return storeName.equals(o.storeName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  public int hashCode() {
 | 
				
			||||||
 | 
					    return Objects.hashCode(storeName);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2013 The Android Open Source Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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.google.gerrit.server.securestore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SecureStoreException extends RuntimeException {
 | 
				
			||||||
 | 
					  private static final long serialVersionUID = 5581700510568485065L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SecureStoreException(String msg) {
 | 
				
			||||||
 | 
					    super(msg);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SecureStoreException(String msg, Exception e) {
 | 
				
			||||||
 | 
					    super(msg, e);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user