Add documentation for SecureStore

Provides javadoc and documentation for SecureStore.

Change-Id: I24a5565dc7d38b506a77459aa13fccd606f0e408
Signed-off-by: Dariusz Luksza <dariusz@luksza.org>
This commit is contained in:
Dariusz Luksza
2014-09-10 11:14:19 +02:00
parent 8f33a51706
commit ebab92aabd
4 changed files with 145 additions and 0 deletions

View File

@@ -1731,6 +1731,34 @@ MyType(@PluginData java.io.File myDir) {
}
----
[[secure-store]]
== SecureStore
SecureStore allows to change the way Gerrit stores sensitive data like
passwords.
In order to replace the default SecureStore (no-op) implementation,
a class that extends `com.google.gerrit.server.securestore.SecureStore`
needs to be provided (with dependencies) in a separate jar file. Then
link:pgm-SwitchSecureStore.html[SwitchSecureStore] must be run to
switch implementations.
The SecureStore implementation is instantiated using a Guice injector
which binds the `File` annotated with the `@SitePath` annotation.
This means that a SecureStore implementation class can get access to
the `site_path` like in the following example:
[source,java]
----
@Inject
MySecureStore(@SitePath java.io.File sitePath) {
// your code
}
----
No Guice bindings or modules are required. Gerrit will automatically
discover and bind the implementation.
[[download-commands]]
== Download Commands

View File

@@ -0,0 +1,39 @@
= SwitchSecureStore
== NAME
SwitchSecureStore - Changes the currently used SecureStore implementation
== SYNOPSIS
--
'java' -jar gerrit.war 'SwitchSecureStore' [<OPTIONS>]
--
== DESCRIPTION
Changes the SecureStore implementation used by Gerrit. It migrates all data
stored in the old implementation, removes the old implementation jar file
from `$site_path/lib` and puts the new one there. As a final step
the link:config-gerrit.html#gerrit.secureStoreClass[gerrit.secureStoreClass]
property of `gerrit.config` will be updated.
All dependencies not provided by Gerrit should be put the in `$site_path/lib`
directory manually, before running the `SwitchSecureStore` program.
After this operation there is no automatic way back the to standard Gerrit no-op
secure store implementation, however there is a manual procedure:
* stop Gerrit,
* remove SecureStore jar file from `$site_path/lib`,
* put plain text passwords into `$site_path/etc/secure.conf` file,
* start Gerrit.
== OPTIONS
--new-secure-store-lib::
Path to jar file with new SecureStore implementation. Jar dependencies must be
put in `$site_path/lib` directory.
GERRIT
------
Part of link:index.html[Gerrit Code Review]
SEARCHBOX
---------

View File

@@ -24,6 +24,9 @@ link:pgm-prolog-shell.html[prolog-shell]::
link:pgm-reindex.html[reindex]::
Rebuild the secondary index.
link:pgm-SwitchSecureStore.html[SwitchSecureStore]::
Change used SecureStore implementation.
link:pgm-rulec.html[rulec]::
Compile project-specific Prolog rules to JARs.

View File

@@ -18,12 +18,38 @@ import com.google.common.collect.Lists;
import java.util.List;
/**
* Abstract class for providing new SecureStore implementation for Gerrit.
*
* SecureStore is responsible for storing sensitive data like passwords in a
* secure manner.
*
* It is implementator's responsibility to encrypt and store values.
*
* To deploy new SecureStore one needs to provide a jar file with explicitly one
* class that extends {@code SecureStore} and put it in Gerrit server. Then run:
*
* `java -jar gerrit.war SwitchSecureStore -d $gerrit_site --new-secure-store-lib
* $path_to_new_secure_store.jar`
*
* on stopped Gerrit instance.
*/
public abstract class SecureStore {
/**
* Describes {@link SecureStore} entry
*/
public static class EntryKey {
public final String name;
public final String section;
public final String subsection;
/**
* Creates EntryKey.
*
* @param section
* @param subsection
* @param name
*/
public EntryKey(String section, String subsection, String name) {
this.name = name;
this.section = section;
@@ -31,6 +57,15 @@ public abstract class SecureStore {
}
}
/**
* Extract decrypted value of stored property from SecureStore or {@code null}
* when property was not found.
*
* @param section
* @param subsection
* @param name
* @return decrypted String value or {@code null} if not found
*/
public final String get(String section, String subsection, String name) {
String[] values = getList(section, subsection, name);
if (values != null && values.length > 0) {
@@ -39,15 +74,55 @@ public abstract class SecureStore {
return null;
}
/**
* Extract list of values from SecureStore and decrypt every value in that
* list or {@code null} when property was not found.
*
* @param section
* @param subsection
* @param name
* @return decrypted list of string values or {@code null}
*/
public abstract String[] getList(String section, String subsection, String name);
/**
* Store single value in SecureStore.
*
* This method is responsible for encrypting value and storing it.
*
* @param section
* @param subsection
* @param name
* @param value plain text value
*/
public final void set(String section, String subsection, String name, String value) {
setList(section, subsection, name, Lists.newArrayList(value));
}
/**
* Store list of values in SecureStore.
*
* This method is responsible for encrypting all values in the list and storing them.
*
* @param section
* @param subsection
* @param name
* @param values list of plain text values
*/
public abstract void setList(String section, String subsection, String name, List<String> values);
/**
* Remove value for given {@code section}, {@code subsection} and {@code name}
* from SecureStore.
*
* @param section
* @param subsection
* @param name
*/
public abstract void unset(String section, String subsection, String name);
/**
* @return list of stored entries.
*/
public abstract Iterable<EntryKey> list();
}