mirror of https://github.com/apache/jclouds.git
Issue 191: added RSA PEM parsing to encryptionUtils
This commit is contained in:
parent
6d438fbbe1
commit
a9a0c53fb2
|
@ -24,6 +24,7 @@ import static org.easymock.classextension.EasyMock.replay;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -58,6 +59,8 @@ public class ParseObjectMetadataFromHeadersTest {
|
||||||
encryptionService = new JCEEncryptionService();
|
encryptionService = new JCEEncryptionService();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||||
|
@ -55,6 +56,8 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
encryptionService = new JCEEncryptionService();
|
encryptionService = new JCEEncryptionService();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,44 +74,47 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
|
||||||
CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0",
|
CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0",
|
||||||
"ferncam");
|
"ferncam");
|
||||||
ListBucketResponse expected = new ListBucketResponseImpl("adriancole.org.jclouds.aws.s3.amazons3testdelimiter",
|
ListBucketResponse expected = new ListBucketResponseImpl("adriancole.org.jclouds.aws.s3.amazons3testdelimiter",
|
||||||
ImmutableList
|
ImmutableList.of(
|
||||||
.of(
|
|
||||||
(ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService
|
(ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService
|
||||||
.iso8601DateParse("2009-05-07T18:27:08.000Z"), "\"c82e6a0025c31c5de5947fda62ac51ab\"",
|
.iso8601DateParse("2009-05-07T18:27:08.000Z"), "\"c82e6a0025c31c5de5947fda62ac51ab\"",
|
||||||
encryptionService.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner,
|
encryptionService.fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner,
|
||||||
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/1",
|
StorageClass.STANDARD),
|
||||||
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"),
|
(ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService
|
||||||
"\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService
|
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"944fab2c5a9a6bacf07db5e688310d7a\"",
|
||||||
.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner, StorageClass.STANDARD),
|
encryptionService.fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner,
|
||||||
|
StorageClass.STANDARD),
|
||||||
(ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService
|
(ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService
|
||||||
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"a227b8888045c8fd159fb495214000f0\"",
|
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"a227b8888045c8fd159fb495214000f0\"",
|
||||||
encryptionService.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner,
|
encryptionService.fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner,
|
||||||
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/3",
|
StorageClass.STANDARD),
|
||||||
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"),
|
(ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService
|
||||||
"\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService
|
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"c9caa76c3dec53e2a192608ce73eef03\"",
|
||||||
.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner, StorageClass.STANDARD),
|
encryptionService.fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner,
|
||||||
|
StorageClass.STANDARD),
|
||||||
(ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService
|
(ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService
|
||||||
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"1ce5d0dcc6154a647ea90c7bdf82a224\"",
|
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"1ce5d0dcc6154a647ea90c7bdf82a224\"",
|
||||||
encryptionService.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner,
|
encryptionService.fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner,
|
||||||
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/5",
|
StorageClass.STANDARD),
|
||||||
dateService.iso8601DateParse("2009-05-07T18:27:09.000Z"),
|
(ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService
|
||||||
"\"79433524d87462ee05708a8ef894ed55\"", encryptionService
|
.iso8601DateParse("2009-05-07T18:27:09.000Z"), "\"79433524d87462ee05708a8ef894ed55\"",
|
||||||
.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner, StorageClass.STANDARD),
|
encryptionService.fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner,
|
||||||
|
StorageClass.STANDARD),
|
||||||
(ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService
|
(ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService
|
||||||
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"dd00a060b28ddca8bc5a21a49e306f67\"",
|
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"dd00a060b28ddca8bc5a21a49e306f67\"",
|
||||||
encryptionService.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner,
|
encryptionService.fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner,
|
||||||
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/7",
|
StorageClass.STANDARD),
|
||||||
dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"),
|
(ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService
|
||||||
"\"8cd06eca6e819a927b07a285d750b100\"", encryptionService
|
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"8cd06eca6e819a927b07a285d750b100\"",
|
||||||
.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner, StorageClass.STANDARD),
|
encryptionService.fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner,
|
||||||
|
StorageClass.STANDARD),
|
||||||
(ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService
|
(ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService
|
||||||
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"174495094d0633b92cbe46603eee6bad\"",
|
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"174495094d0633b92cbe46603eee6bad\"",
|
||||||
encryptionService.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner,
|
encryptionService.fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner,
|
||||||
StorageClass.STANDARD), (ObjectMetadata) new BucketListObjectMetadata("apps/9",
|
StorageClass.STANDARD),
|
||||||
dateService.iso8601DateParse("2009-05-07T18:27:10.000Z"),
|
(ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService
|
||||||
"\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService
|
.iso8601DateParse("2009-05-07T18:27:10.000Z"), "\"cd8a19b26fea8a827276df0ad11c580d\"",
|
||||||
.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner, StorageClass.STANDARD)),
|
encryptionService.fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner,
|
||||||
"apps/", null, null, 1000, null, false, new TreeSet<String>());
|
StorageClass.STANDARD)), "apps/", null, null, 1000, null, false, new TreeSet<String>());
|
||||||
|
|
||||||
ListBucketResponse result = (ListBucketResponse) factory.create(injector.getInstance(ListBucketHandler.class))
|
ListBucketResponse result = (ListBucketResponse) factory.create(injector.getInstance(ListBucketHandler.class))
|
||||||
.parse(is);
|
.parse(is);
|
||||||
|
|
|
@ -24,15 +24,12 @@ import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import org.jclouds.aws.AWSResponseException;
|
import org.jclouds.aws.AWSResponseException;
|
||||||
import org.jclouds.aws.domain.Region;
|
import org.jclouds.aws.domain.Region;
|
||||||
import org.jclouds.aws.sqs.domain.Queue;
|
import org.jclouds.aws.sqs.domain.Queue;
|
||||||
import org.jclouds.encryption.EncryptionService;
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
@ -41,7 +38,6 @@ import org.testng.annotations.AfterTest;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
@ -59,15 +55,6 @@ public class SQSClientLiveTest {
|
||||||
|
|
||||||
private RestContext<SQSClient, SQSAsyncClient> context;
|
private RestContext<SQSClient, SQSAsyncClient> context;
|
||||||
|
|
||||||
protected volatile static EncryptionService encryptionService;
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
encryptionService = new JCEEncryptionService();
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
Throwables.propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Queue> queues = Sets.newHashSet();
|
private Set<Queue> queues = Sets.newHashSet();
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
|
@ -136,7 +123,7 @@ public class SQSClientLiveTest {
|
||||||
@Test(dependsOnMethods = "testCreateQueue")
|
@Test(dependsOnMethods = "testCreateQueue")
|
||||||
void testSendMessage() throws InterruptedException {
|
void testSendMessage() throws InterruptedException {
|
||||||
String message = "hardyharhar";
|
String message = "hardyharhar";
|
||||||
byte[] md5 = encryptionService.md5(Utils.toInputStream(message));
|
byte[] md5 = context.utils().encryption().md5(Utils.toInputStream(message));
|
||||||
for (Queue queue : queues) {
|
for (Queue queue : queues) {
|
||||||
assertEquals(client.sendMessage(queue, message), md5);
|
assertEquals(client.sendMessage(queue, message), md5);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.jclouds.blobstore.options.GetOptions.Builder.ifUnmodifiedSince
|
||||||
import static org.jclouds.blobstore.options.GetOptions.Builder.range;
|
import static org.jclouds.blobstore.options.GetOptions.Builder.range;
|
||||||
import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose;
|
import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose;
|
||||||
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
|
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
|
||||||
|
import static org.jclouds.concurrent.ConcurrentUtils.compose;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
@ -36,6 +37,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -49,7 +51,6 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.PageSet;
|
import org.jclouds.blobstore.domain.PageSet;
|
||||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||||
import org.jclouds.blobstore.domain.StorageType;
|
import org.jclouds.blobstore.domain.StorageType;
|
||||||
import static org.jclouds.concurrent.ConcurrentUtils.*;
|
|
||||||
import org.jclouds.encryption.EncryptionService;
|
import org.jclouds.encryption.EncryptionService;
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||||
import org.jclouds.http.BaseJettyTest;
|
import org.jclouds.http.BaseJettyTest;
|
||||||
|
@ -429,6 +430,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
encryptionService = new JCEEncryptionService();
|
encryptionService = new JCEEncryptionService();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNull
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
@ -40,8 +39,6 @@ import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||||
import org.jclouds.blobstore.domain.StorageType;
|
import org.jclouds.blobstore.domain.StorageType;
|
||||||
import org.jclouds.encryption.EncryptionService;
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.testng.ITestContext;
|
import org.testng.ITestContext;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
|
@ -62,8 +59,8 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple");
|
protected static final String TEST_STRING = String.format(XML_STRING_FORMAT, "apple");
|
||||||
|
|
||||||
protected Map<String, String> fiveStrings = ImmutableMap.of("one", String.format(XML_STRING_FORMAT, "apple"), "two",
|
protected Map<String, String> fiveStrings = ImmutableMap.of("one", String.format(XML_STRING_FORMAT, "apple"), "two",
|
||||||
String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four", String
|
String.format(XML_STRING_FORMAT, "bear"), "three", String.format(XML_STRING_FORMAT, "candy"), "four",
|
||||||
.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma"));
|
String.format(XML_STRING_FORMAT, "dogma"), "five", String.format(XML_STRING_FORMAT, "emma"));
|
||||||
|
|
||||||
protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1", String.format(XML_STRING_FORMAT,
|
protected Map<String, String> fiveStringsUnderPath = ImmutableMap.of("path/1", String.format(XML_STRING_FORMAT,
|
||||||
"apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3", String.format(XML_STRING_FORMAT,
|
"apple"), "path/2", String.format(XML_STRING_FORMAT, "bear"), "path/3", String.format(XML_STRING_FORMAT,
|
||||||
|
@ -81,18 +78,8 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
*/
|
*/
|
||||||
private volatile static BlockingQueue<String> containerNames = new ArrayBlockingQueue<String>(containerCount);
|
private volatile static BlockingQueue<String> containerNames = new ArrayBlockingQueue<String>(containerCount);
|
||||||
|
|
||||||
protected volatile static EncryptionService encryptionService;
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
encryptionService = new JCEEncryptionService();
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
Throwables.propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There are a lot of retries here mainly from experience running inside
|
* There are a lot of retries here mainly from experience running inside amazon EC2.
|
||||||
* amazon EC2.
|
|
||||||
*/
|
*/
|
||||||
@BeforeSuite
|
@BeforeSuite
|
||||||
public void setUpResourcesForAllThreads(ITestContext testContext) throws Exception {
|
public void setUpResourcesForAllThreads(ITestContext testContext) throws Exception {
|
||||||
|
@ -112,11 +99,10 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
protected ExecutorService exec;
|
protected ExecutorService exec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* we are doing this at a class level, as the context.getBlobStore() object
|
* we are doing this at a class level, as the context.getBlobStore() object is going to be shared
|
||||||
* is going to be shared for all methods in the class. We don't want to do
|
* for all methods in the class. We don't want to do this for group, as some test classes may
|
||||||
* this for group, as some test classes may want to have a different
|
* want to have a different implementation of context.getBlobStore(). For example, one class may
|
||||||
* implementation of context.getBlobStore(). For example, one class may want
|
* want non-blocking i/o and another class google appengine.
|
||||||
* non-blocking i/o and another class google appengine.
|
|
||||||
*/
|
*/
|
||||||
@BeforeClass(groups = { "integration", "live" })
|
@BeforeClass(groups = { "integration", "live" })
|
||||||
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
|
||||||
|
@ -209,9 +195,8 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
public static boolean SANITY_CHECK_RETURNED_BUCKET_NAME = false;
|
public static boolean SANITY_CHECK_RETURNED_BUCKET_NAME = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Due to eventual consistency, container commands may not return correctly
|
* Due to eventual consistency, container commands may not return correctly immediately. Hence,
|
||||||
* immediately. Hence, we will try up to the inconsistency window to see if
|
* we will try up to the inconsistency window to see if the assertion completes.
|
||||||
* the assertion completes.
|
|
||||||
*/
|
*/
|
||||||
protected static void assertConsistencyAware(BlobStoreContext context, Runnable assertion)
|
protected static void assertConsistencyAware(BlobStoreContext context, Runnable assertion)
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
|
@ -312,9 +297,9 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* requestor will create a container using the name returned from this. This
|
* requestor will create a container using the name returned from this. This method will take
|
||||||
* method will take care not to exceed the maximum containers permitted by a
|
* care not to exceed the maximum containers permitted by a provider by deleting an existing
|
||||||
* provider by deleting an existing container first.
|
* container first.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@ -326,13 +311,12 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
if (containerName != null) {
|
if (containerName != null) {
|
||||||
containerNames.add(containerName);
|
containerNames.add(containerName);
|
||||||
/*
|
/*
|
||||||
* Ensure that any returned container name actually exists on the
|
* Ensure that any returned container name actually exists on the server. Return of a
|
||||||
* server. Return of a non-existent container introduces subtle testing
|
* non-existent container introduces subtle testing bugs, where later unrelated tests will
|
||||||
* bugs, where later unrelated tests will fail.
|
* fail.
|
||||||
*
|
*
|
||||||
* NOTE: This sanity check should only be run for Stub-based
|
* NOTE: This sanity check should only be run for Stub-based Integration testing -- it will
|
||||||
* Integration testing -- it will *substantially* slow down tests on a
|
* *substantially* slow down tests on a real server over a network.
|
||||||
* real server over a network.
|
|
||||||
*/
|
*/
|
||||||
if (SANITY_CHECK_RETURNED_BUCKET_NAME) {
|
if (SANITY_CHECK_RETURNED_BUCKET_NAME) {
|
||||||
if (!Iterables.any(context.getBlobStore().list(), new Predicate<StorageMetadata>() {
|
if (!Iterables.any(context.getBlobStore().list(), new Predicate<StorageMetadata>() {
|
||||||
|
@ -347,8 +331,7 @@ public class BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* abandon old container name instead of waiting for the container to be
|
* abandon old container name instead of waiting for the container to be created.
|
||||||
* created.
|
|
||||||
*
|
*
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
// normalize the
|
// normalize the
|
||||||
// providers.
|
// providers.
|
||||||
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||||
object.getMetadata().setContentMD5(encryptionService.md5(toInputStream(TEST_STRING)));
|
object.getMetadata().setContentMD5(context.utils().encryption().md5(toInputStream(TEST_STRING)));
|
||||||
String containerName = getContainerName();
|
String containerName = getContainerName();
|
||||||
try {
|
try {
|
||||||
addBlobToContainer(containerName, object);
|
addBlobToContainer(containerName, object);
|
||||||
|
@ -93,7 +93,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
||||||
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
|
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
|
||||||
assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
|
assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
|
||||||
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
|
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
|
||||||
assertEquals(metadata.getContentMD5(), encryptionService.md5(toInputStream(TEST_STRING)));
|
assertEquals(metadata.getContentMD5(), context.utils().encryption().md5(toInputStream(TEST_STRING)));
|
||||||
} finally {
|
} finally {
|
||||||
returnContainer(containerName);
|
returnContainer(containerName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ import org.jclouds.chef.domain.Role;
|
||||||
import org.jclouds.chef.domain.Sandbox;
|
import org.jclouds.chef.domain.Sandbox;
|
||||||
import org.jclouds.chef.domain.UploadSandbox;
|
import org.jclouds.chef.domain.UploadSandbox;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
import org.jclouds.chef.functions.ParseKeyFromJson;
|
|
||||||
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
||||||
import org.jclouds.domain.JsonBall;
|
import org.jclouds.domain.JsonBall;
|
||||||
import org.jclouds.rest.annotations.BinderParam;
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
|
@ -148,16 +147,14 @@ public interface ChefAsyncClient {
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("clients")
|
@Path("clients")
|
||||||
@ResponseParser(ParseKeyFromJson.class)
|
ListenableFuture<Client> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
|
||||||
ListenableFuture<String> createClient(@BinderParam(BindClientnameToJsonPayload.class) String clientname);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ChefClient#generateKeyForClient
|
* @see ChefClient#generateKeyForClient
|
||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("clients/{clientname}")
|
@Path("clients/{clientname}")
|
||||||
@ResponseParser(ParseKeyFromJson.class)
|
ListenableFuture<Client> generateKeyForClient(
|
||||||
ListenableFuture<String> generateKeyForClient(
|
|
||||||
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
|
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -70,8 +70,7 @@ public interface ChefClient {
|
||||||
* FIXME Comment this
|
* FIXME Comment this
|
||||||
*
|
*
|
||||||
* @param md5s
|
* @param md5s
|
||||||
* raw md5s; uses {@code Bytes.asList()} and {@code
|
* raw md5s; uses {@code Bytes.asList()} and {@code Bytes.toByteArray()} as necessary
|
||||||
* Bytes.toByteArray()} as necessary
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
UploadSandbox getUploadSandboxForChecksums(Set<List<Byte>> md5s);
|
UploadSandbox getUploadSandboxForChecksums(Set<List<Byte>> md5s);
|
||||||
|
@ -85,8 +84,7 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if you do not have permission to see the
|
* "403 Forbidden" if you do not have permission to see the cookbook list.
|
||||||
* cookbook list.
|
|
||||||
*/
|
*/
|
||||||
Set<String> listCookbooks();
|
Set<String> listCookbooks();
|
||||||
|
|
||||||
|
@ -108,8 +106,7 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if you are not a recognized user.
|
* "401 Unauthorized" if you are not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if you do not have Delete rights on the
|
* "403 Forbidden" if you do not have Delete rights on the cookbook.
|
||||||
* cookbook.
|
|
||||||
*/
|
*/
|
||||||
CookbookVersion deleteCookbook(String cookbookName, String version);
|
CookbookVersion deleteCookbook(String cookbookName, String version);
|
||||||
|
|
||||||
|
@ -121,14 +118,13 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to view the
|
* "403 Forbidden" if the caller is not authorized to view the cookbook.
|
||||||
* cookbook.
|
|
||||||
*/
|
*/
|
||||||
Set<String> getVersionsOfCookbook(String cookbookName);
|
Set<String> getVersionsOfCookbook(String cookbookName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a description of the cookbook, with links to all of its component
|
* Returns a description of the cookbook, with links to all of its component parts, and the
|
||||||
* parts, and the metadata.
|
* metadata.
|
||||||
*
|
*
|
||||||
* @return the cookbook or null, if not found
|
* @return the cookbook or null, if not found
|
||||||
*
|
*
|
||||||
|
@ -136,31 +132,28 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to view the
|
* "403 Forbidden" if the caller is not authorized to view the cookbook.
|
||||||
* cookbook.
|
|
||||||
*/
|
*/
|
||||||
CookbookVersion getCookbook(String cookbookName, String version);
|
CookbookVersion getCookbook(String cookbookName, String version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a new client
|
* creates a new client
|
||||||
*
|
*
|
||||||
* @return the private key of the client. You can then use this client name
|
* @return the private key of the client. You can then use this client name and private key to
|
||||||
* and private key to access the Opscode API.
|
* access the Opscode API.
|
||||||
* @throws AuthorizationException
|
* @throws AuthorizationException
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to create a
|
* "403 Forbidden" if the caller is not authorized to create a client.
|
||||||
* client.
|
|
||||||
* @throws HttpResponseException
|
* @throws HttpResponseException
|
||||||
* "409 Conflict" if the client already exists
|
* "409 Conflict" if the client already exists
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
||||||
String createClient(String name);
|
Client createClient(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generate a new key-pair for this client, and return the new private key in
|
* generate a new key-pair for this client, and return the new private key in the response body.
|
||||||
* the response body.
|
|
||||||
*
|
*
|
||||||
* @return the new private key
|
* @return the new private key
|
||||||
*
|
*
|
||||||
|
@ -168,11 +161,10 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to modify the
|
* "403 Forbidden" if the caller is not authorized to modify the client.
|
||||||
* client.
|
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
||||||
String generateKeyForClient(String name);
|
Client generateKeyForClient(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of client names.
|
* @return list of client names.
|
||||||
|
@ -229,8 +221,7 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to create a
|
* "403 Forbidden" if the caller is not authorized to create a node.
|
||||||
* node.
|
|
||||||
* @throws HttpResponseException
|
* @throws HttpResponseException
|
||||||
* "409 Conflict" if the node already exists
|
* "409 Conflict" if the node already exists
|
||||||
*/
|
*/
|
||||||
|
@ -302,8 +293,7 @@ public interface ChefClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "401 Unauthorized" if the caller is not a recognized user.
|
* "401 Unauthorized" if the caller is not a recognized user.
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to create a
|
* "403 Forbidden" if the caller is not authorized to create a role.
|
||||||
* role.
|
|
||||||
* @throws HttpResponseException
|
* @throws HttpResponseException
|
||||||
* "409 Conflict" if the role already exists
|
* "409 Conflict" if the role already exists
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class BaseChefRestClientModule<S, A> extends RestClientModule<S, A> {
|
||||||
@Singleton
|
@Singleton
|
||||||
public PrivateKey provideKey(EncryptionService encryptionService, @Named(PROPERTY_CREDENTIAL) String pem)
|
public PrivateKey provideKey(EncryptionService encryptionService, @Named(PROPERTY_CREDENTIAL) String pem)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
return encryptionService.readPrivateKeyFromPEM(pem.getBytes("UTF-8"));
|
return encryptionService.privateKeyFromPEM(pem.getBytes("UTF-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,17 +18,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.config;
|
package org.jclouds.chef.config;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.chef.domain.DataBagItem;
|
import org.jclouds.chef.domain.DataBagItem;
|
||||||
|
import org.jclouds.encryption.EncryptionService;
|
||||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
|
@ -47,6 +54,87 @@ import com.google.inject.Provides;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ChefParserModule extends AbstractModule {
|
public class ChefParserModule extends AbstractModule {
|
||||||
|
@ImplementedBy(PrivateKeyAdapterImpl.class)
|
||||||
|
public static interface PrivateKeyAdapter extends JsonDeserializer<PrivateKey> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class PrivateKeyAdapterImpl implements PrivateKeyAdapter {
|
||||||
|
private final EncryptionService encryptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PrivateKeyAdapterImpl(EncryptionService encryptionService) {
|
||||||
|
this.encryptionService = encryptionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateKey deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
String keyText = json.getAsString().replaceAll("\\n", "\n");
|
||||||
|
try {
|
||||||
|
return encryptionService.privateKeyFromPEM(keyText.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ImplementedBy(PublicKeyAdapterImpl.class)
|
||||||
|
public static interface PublicKeyAdapter extends JsonDeserializer<PublicKey> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class PublicKeyAdapterImpl implements PublicKeyAdapter {
|
||||||
|
private final EncryptionService encryptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PublicKeyAdapterImpl(EncryptionService encryptionService) {
|
||||||
|
this.encryptionService = encryptionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PublicKey deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
String keyText = json.getAsString().replaceAll("\\n", "\n");
|
||||||
|
try {
|
||||||
|
return encryptionService.publicKeyFromPEM(keyText.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ImplementedBy(X509CertificateAdapterImpl.class)
|
||||||
|
public static interface X509CertificateAdapter extends JsonDeserializer<X509Certificate> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class X509CertificateAdapterImpl implements X509CertificateAdapter {
|
||||||
|
private final EncryptionService encryptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
X509CertificateAdapterImpl(EncryptionService encryptionService) {
|
||||||
|
this.encryptionService = encryptionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
String keyText = json.getAsString().replaceAll("\\n", "\n");
|
||||||
|
try {
|
||||||
|
return encryptionService.x509CertificateFromPEM(keyText.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ImplementedBy(DataBagItemAdapterImpl.class)
|
@ImplementedBy(DataBagItemAdapterImpl.class)
|
||||||
public static interface DataBagItemAdapter extends JsonSerializer<DataBagItem>, JsonDeserializer<DataBagItem> {
|
public static interface DataBagItemAdapter extends JsonSerializer<DataBagItem>, JsonDeserializer<DataBagItem> {
|
||||||
|
|
||||||
|
@ -75,8 +163,10 @@ public class ChefParserModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named(Constants.PROPERTY_GSON_ADAPTERS)
|
@Named(Constants.PROPERTY_GSON_ADAPTERS)
|
||||||
public Map<Type, Object> provideCustomAdapterBindings(DataBagItemAdapter adapter) {
|
public Map<Type, Object> provideCustomAdapterBindings(DataBagItemAdapter adapter, PrivateKeyAdapter privateAdapter,
|
||||||
return ImmutableMap.<Type, Object> of(DataBagItem.class, adapter);
|
PublicKeyAdapter publicAdapter, X509CertificateAdapter certAdapter) {
|
||||||
|
return ImmutableMap.<Type, Object> of(DataBagItem.class, adapter, PrivateKey.class, privateAdapter,
|
||||||
|
PublicKey.class, publicAdapter, X509Certificate.class, certAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.domain;
|
package org.jclouds.chef.domain;
|
||||||
|
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client object.
|
* Client object.
|
||||||
|
@ -30,7 +36,9 @@ package org.jclouds.chef.domain;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Client {
|
public class Client {
|
||||||
private String certificate;
|
private X509Certificate certificate;
|
||||||
|
@SerializedName("private_key")
|
||||||
|
private PrivateKey privateKey;
|
||||||
private String orgname;
|
private String orgname;
|
||||||
private String clientname;
|
private String clientname;
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -41,7 +49,11 @@ public class Client {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCertificate() {
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public X509Certificate getCertificate() {
|
||||||
return certificate;
|
return certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +76,7 @@ public class Client {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + validator
|
return "[name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + validator
|
||||||
+ ", certificate=" + certificate + "]";
|
+ ", certificate=" + certificate + ", privateKey=" + (privateKey != null) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,9 +85,10 @@ public class Client {
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
|
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
|
||||||
result = prime * result + ((clientname == null) ? 0 : clientname.hashCode());
|
result = prime * result + ((clientname == null) ? 0 : clientname.hashCode());
|
||||||
result = prime * result + (validator ? 1231 : 1237);
|
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
result = prime * result + ((orgname == null) ? 0 : orgname.hashCode());
|
result = prime * result + ((orgname == null) ? 0 : orgname.hashCode());
|
||||||
|
result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
|
||||||
|
result = prime * result + (validator ? 1231 : 1237);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +111,6 @@ public class Client {
|
||||||
return false;
|
return false;
|
||||||
} else if (!clientname.equals(other.clientname))
|
} else if (!clientname.equals(other.clientname))
|
||||||
return false;
|
return false;
|
||||||
if (validator != other.validator)
|
|
||||||
return false;
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
if (other.name != null)
|
if (other.name != null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -110,14 +121,24 @@ public class Client {
|
||||||
return false;
|
return false;
|
||||||
} else if (!orgname.equals(other.orgname))
|
} else if (!orgname.equals(other.orgname))
|
||||||
return false;
|
return false;
|
||||||
|
if (privateKey == null) {
|
||||||
|
if (other.privateKey != null)
|
||||||
|
return false;
|
||||||
|
} else if (!privateKey.equals(other.privateKey))
|
||||||
|
return false;
|
||||||
|
if (validator != other.validator)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Client(String certificate, String orgname, String clientname, String name, boolean isValidator) {
|
public Client(X509Certificate certificate, String orgname, String clientname, String name, boolean isValidator,
|
||||||
|
@Nullable PrivateKey privateKey) {
|
||||||
this.certificate = certificate;
|
this.certificate = certificate;
|
||||||
this.orgname = orgname;
|
this.orgname = orgname;
|
||||||
this.clientname = clientname;
|
this.clientname = clientname;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.validator = isValidator;
|
this.validator = isValidator;
|
||||||
|
this.privateKey = privateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.domain;
|
package org.jclouds.chef.domain;
|
||||||
|
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +34,8 @@ public class Organization implements Comparable<Organization> {
|
||||||
@SerializedName("org_type")
|
@SerializedName("org_type")
|
||||||
private String orgType;
|
private String orgType;
|
||||||
private String clientname;
|
private String clientname;
|
||||||
|
@SerializedName("private_key")
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
|
||||||
public Organization(String name) {
|
public Organization(String name) {
|
||||||
this();
|
this();
|
||||||
|
@ -80,6 +84,10 @@ public class Organization implements Comparable<Organization> {
|
||||||
this.clientname = clientname;
|
this.clientname = clientname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.domain;
|
package org.jclouds.chef.domain;
|
||||||
|
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +39,8 @@ public class User implements Comparable<User> {
|
||||||
private String displayName;
|
private String displayName;
|
||||||
private String email;
|
private String email;
|
||||||
private String password;
|
private String password;
|
||||||
|
@SerializedName("private_key")
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
|
||||||
public User(String username) {
|
public User(String username) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
|
@ -108,6 +112,10 @@ public class User implements Comparable<User> {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
|
@ -81,9 +81,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
Logger signatureLog = Logger.NULL;
|
Logger signatureLog = Logger.NULL;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SignedHeaderAuth(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String userId,
|
public SignedHeaderAuth(SignatureWire signatureWire, @Named(PROPERTY_IDENTITY) String userId, PrivateKey privateKey,
|
||||||
PrivateKey privateKey, @TimeStamp Provider<String> timeStampProvider,
|
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService, HttpUtils utils) {
|
||||||
EncryptionService encryptionService, HttpUtils utils) {
|
|
||||||
this.signatureWire = signatureWire;
|
this.signatureWire = signatureWire;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.privateKey = privateKey;
|
this.privateKey = privateKey;
|
||||||
|
@ -96,48 +95,41 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
public void filter(HttpRequest request) throws HttpException {
|
public void filter(HttpRequest request) throws HttpException {
|
||||||
|
|
||||||
String contentHash = hashBody(request.getPayload());
|
String contentHash = hashBody(request.getPayload());
|
||||||
request.getHeaders().replaceValues("X-Ops-Content-Hash",
|
request.getHeaders().replaceValues("X-Ops-Content-Hash", Collections.singletonList(contentHash));
|
||||||
Collections.singletonList(contentHash));
|
|
||||||
String timestamp = timeStampProvider.get();
|
String timestamp = timeStampProvider.get();
|
||||||
String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint()
|
String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint().getPath()), contentHash,
|
||||||
.getPath()), contentHash, timestamp);
|
timestamp);
|
||||||
request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId));
|
request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId));
|
||||||
request.getHeaders().replaceValues("X-Ops-Sign",
|
request.getHeaders().replaceValues("X-Ops-Sign", Collections.singletonList(SIGNING_DESCRIPTION));
|
||||||
Collections.singletonList(SIGNING_DESCRIPTION));
|
|
||||||
calculateAndReplaceAuthorizationHeaders(request, toSign);
|
calculateAndReplaceAuthorizationHeaders(request, toSign);
|
||||||
request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp));
|
request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp));
|
||||||
utils.logRequest(signatureLog, request, "<<");
|
utils.logRequest(signatureLog, request, "<<");
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign)
|
void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign) throws HttpException {
|
||||||
throws HttpException {
|
|
||||||
String signature = sign(toSign);
|
String signature = sign(toSign);
|
||||||
if (signatureWire.enabled())
|
if (signatureWire.enabled())
|
||||||
signatureWire.input(Utils.toInputStream(signature));
|
signatureWire.input(Utils.toInputStream(signature));
|
||||||
String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature),
|
String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String.class);
|
||||||
String.class);
|
|
||||||
for (int i = 0; i < signatureLines.length; i++) {
|
for (int i = 0; i < signatureLines.length; i++) {
|
||||||
request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1),
|
request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1),
|
||||||
Collections.singletonList(signatureLines[i]));
|
Collections.singletonList(signatureLines[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String createStringToSign(String request, String hashedPath, String contentHash,
|
public String createStringToSign(String request, String hashedPath, String contentHash, String timestamp) {
|
||||||
String timestamp) {
|
|
||||||
|
|
||||||
return new StringBuilder().append("Method:").append(request).append("\n").append(
|
return new StringBuilder().append("Method:").append(request).append("\n").append("Hashed Path:").append(
|
||||||
"Hashed Path:").append(hashedPath).append("\n").append("X-Ops-Content-Hash:")
|
hashedPath).append("\n").append("X-Ops-Content-Hash:").append(contentHash).append("\n").append(
|
||||||
.append(contentHash).append("\n").append("X-Ops-Timestamp:").append(timestamp)
|
"X-Ops-Timestamp:").append(timestamp).append("\n").append("X-Ops-UserId:").append(userId).toString();
|
||||||
.append("\n").append("X-Ops-UserId:").append(userId).toString();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String hashPath(String path) {
|
String hashPath(String path) {
|
||||||
try {
|
try {
|
||||||
return encryptionService.base64(encryptionService.sha1(Utils
|
return encryptionService.base64(encryptionService.sha1(Utils.toInputStream(canonicalPath(path))));
|
||||||
.toInputStream(canonicalPath(path))));
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Throwables.propagateIfPossible(e);
|
Throwables.propagateIfPossible(e);
|
||||||
throw new HttpException("error creating sigature for path: " + path, e);
|
throw new HttpException("error creating sigature for path: " + path, e);
|
||||||
|
@ -190,7 +182,7 @@ public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
|
|
||||||
public String sign(String toSign) {
|
public String sign(String toSign) {
|
||||||
try {
|
try {
|
||||||
byte[] encrypted = encryptionService.rsaSign(toSign, privateKey);
|
byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newStringPayload(toSign), privateKey);
|
||||||
return encryptionService.base64(encrypted);
|
return encryptionService.base64(encrypted);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new HttpException("error signing request", e);
|
throw new HttpException("error signing request", e);
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.jclouds.chef.functions;
|
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.http.functions.ReturnStringIf2xx;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class ParseKeyFromJson implements Function<HttpResponse, String> {
|
|
||||||
Pattern pattern = Pattern.compile(".*private_key\": *\"([^\"]+)\".*");
|
|
||||||
private final ReturnStringIf2xx returnStringIf200;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
ParseKeyFromJson(ReturnStringIf2xx returnStringIf200) {
|
|
||||||
this.returnStringIf200 = returnStringIf200;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String apply(HttpResponse response) {
|
|
||||||
String content = returnStringIf200.apply(response);
|
|
||||||
if (content == null)
|
|
||||||
return null;
|
|
||||||
return parse(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String parse(String in) {
|
|
||||||
Matcher matcher = pattern.matcher(in);
|
|
||||||
while (matcher.find()) {
|
|
||||||
return matcher.group(1).replaceAll("\\\\n", "\n");
|
|
||||||
}
|
|
||||||
assert false : String.format("pattern: %s didn't match %s", pattern, in);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,6 @@ import org.jclouds.chef.domain.Node;
|
||||||
import org.jclouds.chef.domain.Role;
|
import org.jclouds.chef.domain.Role;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuthTest;
|
import org.jclouds.chef.filters.SignedHeaderAuthTest;
|
||||||
import org.jclouds.chef.functions.ParseKeyFromJson;
|
|
||||||
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
||||||
import org.jclouds.date.TimeStamp;
|
import org.jclouds.date.TimeStamp;
|
||||||
import org.jclouds.encryption.EncryptionService;
|
import org.jclouds.encryption.EncryptionService;
|
||||||
|
@ -214,7 +213,7 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
|
||||||
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
|
||||||
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}", "application/json", false);
|
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\"}", "application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
|
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
@ -245,7 +244,7 @@ public class ChefAsyncClientTest extends RestClientTest<ChefAsyncClient> {
|
||||||
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
|
||||||
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\", \"private_key\": true}", "application/json", false);
|
assertPayloadEquals(httpRequest, "{\"clientname\":\"client\", \"private_key\": true}", "application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
|
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,9 @@ public class ChefClientLiveTest {
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateClient")
|
@Test(dependsOnMethods = "testCreateClient")
|
||||||
public void testGenerateKeyForClient() throws Exception {
|
public void testGenerateKeyForClient() throws Exception {
|
||||||
clientKey = validatorConnection.getApi().generateKeyForClient(PREFIX);
|
clientKey = validatorConnection.utils().encryption().toPem(
|
||||||
|
validatorConnection.getApi().generateKeyForClient(PREFIX).getPrivateKey());
|
||||||
|
|
||||||
assertNotNull(clientKey);
|
assertNotNull(clientKey);
|
||||||
clientConnection.close();
|
clientConnection.close();
|
||||||
clientConnection = createConnection(PREFIX, clientKey);
|
clientConnection = createConnection(PREFIX, clientKey);
|
||||||
|
@ -189,28 +191,30 @@ public class ChefClientLiveTest {
|
||||||
CookbookVersion cook = adminConnection.getApi().getCookbook(cookbook, version);
|
CookbookVersion cook = adminConnection.getApi().getCookbook(cookbook, version);
|
||||||
adminConnection.getApi().deleteCookbook(cookbook, version);
|
adminConnection.getApi().deleteCookbook(cookbook, version);
|
||||||
assert adminConnection.getApi().getCookbook(cookbook, version) == null : cookbook + version;
|
assert adminConnection.getApi().getCookbook(cookbook, version) == null : cookbook + version;
|
||||||
|
|
||||||
adminConnection.getApi().updateCookbook(cookbook, version, cook);
|
adminConnection.getApi().updateCookbook(cookbook, version, cook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListClients() throws Exception {
|
public void testListClients() throws Exception {
|
||||||
Set<String> clients = validatorConnection.getApi().listClients();
|
for (String client : validatorConnection.getApi().listClients())
|
||||||
assertNotNull(clients);
|
assertNotNull(validatorConnection.getApi().getClient(client));
|
||||||
assert clients.contains(validator) : "validator: " + validator + " not in: " + clients;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testListClients")
|
@Test(dependsOnMethods = "testListClients")
|
||||||
public void testCreateClient() throws Exception {
|
public void testCreateClient() throws Exception {
|
||||||
validatorConnection.getApi().deleteClient(PREFIX);
|
validatorConnection.getApi().deleteClient(PREFIX);
|
||||||
clientKey = validatorConnection.getApi().createClient(PREFIX);
|
|
||||||
assertNotNull(clientKey);
|
clientKey = validatorConnection.utils().encryption().toPem(
|
||||||
|
validatorConnection.getApi().createClient(PREFIX).getPrivateKey());
|
||||||
|
|
||||||
System.out.println(clientKey);
|
System.out.println(clientKey);
|
||||||
|
assertNotNull(clientKey);
|
||||||
clientConnection = createConnection(PREFIX, clientKey);
|
clientConnection = createConnection(PREFIX, clientKey);
|
||||||
clientConnection.getApi().clientExists(PREFIX);
|
clientConnection.getApi().clientExists(PREFIX);
|
||||||
Set<String> clients = adminConnection.getApi().listClients();
|
Set<String> clients = validatorConnection.getApi().listClients();
|
||||||
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
|
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
|
||||||
|
assertNotNull(validatorConnection.getApi().getClient(PREFIX));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateClient")
|
@Test(dependsOnMethods = "testCreateClient")
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
package org.jclouds.chef.functions;
|
package org.jclouds.chef.functions;
|
||||||
|
|
||||||
import static org.jclouds.io.Payloads.newStringPayload;
|
import static org.jclouds.io.Payloads.newInputStreamPayload;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import org.jclouds.chef.config.ChefParserModule;
|
import org.jclouds.chef.config.ChefParserModule;
|
||||||
import org.jclouds.chef.domain.Client;
|
import org.jclouds.chef.domain.Client;
|
||||||
|
import org.jclouds.encryption.EncryptionService;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.functions.ParseJson;
|
import org.jclouds.http.functions.ParseJson;
|
||||||
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -26,22 +30,35 @@ import com.google.inject.TypeLiteral;
|
||||||
@Test(groups = "unit", sequential = true, testName = "chef.ParseClientFromJsonTest")
|
@Test(groups = "unit", sequential = true, testName = "chef.ParseClientFromJsonTest")
|
||||||
public class ParseClientFromJsonTest {
|
public class ParseClientFromJsonTest {
|
||||||
|
|
||||||
|
private static final String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n";
|
||||||
|
private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n";
|
||||||
private ParseJson<Client> handler;
|
private ParseJson<Client> handler;
|
||||||
|
private EncryptionService encryptionService;
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
private X509Certificate certificate;
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
protected void setUpInjector() throws IOException {
|
protected void setUpInjector() throws IOException {
|
||||||
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule());
|
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule());
|
||||||
handler = injector.getInstance(Key.get(new TypeLiteral<ParseJson<Client>>() {
|
handler = injector.getInstance(Key.get(new TypeLiteral<ParseJson<Client>>() {
|
||||||
}));
|
}));
|
||||||
|
encryptionService = injector.getInstance(EncryptionService.class);
|
||||||
|
certificate = encryptionService.x509CertificateFromPEM(CERTIFICATE.getBytes("UTF-8"));
|
||||||
|
privateKey = encryptionService.privateKeyFromPEM(PRIVATE_KEY.getBytes("UTF-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
Client user = new Client("-----BEGIN CERTIFICATE-----dXQ==-----END CERTIFICATE-----", "jclouds",
|
Client user = new Client(certificate, "jclouds", "adriancole-jcloudstest", "adriancole-jcloudstest", false,
|
||||||
"adrian-jcloudstest", "adrian-jcloudstest", false);
|
privateKey);
|
||||||
|
|
||||||
String toParse = "{ \"certificate\":\"-----BEGIN CERTIFICATE-----dXQ==-----END CERTIFICATE-----\", \"orgname\":\"jclouds\", \"clientname\":\"adrian-jcloudstest\", \"name\": \"adrian-jcloudstest\",\"validator\": false }";
|
byte[] encrypted = encryptionService.rsaEncrypt(Payloads.newPayload("fooya"), user.getCertificate()
|
||||||
System.out.println(toParse);
|
.getPublicKey());
|
||||||
assertEquals(handler.apply(new HttpResponse(200, "ok", newStringPayload(toParse))), user);
|
|
||||||
|
assertEquals(encryptionService.rsaDecrypt(Payloads.newPayload(encrypted), user.getPrivateKey()), "fooya"
|
||||||
|
.getBytes());
|
||||||
|
|
||||||
|
assertEquals(handler.apply(new HttpResponse(200, "ok", newInputStreamPayload(ParseClientFromJsonTest.class
|
||||||
|
.getResourceAsStream("/client.json")))), user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
package org.jclouds.chef.functions;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.jclouds.chef.config.ChefParserModule;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.io.Payloads;
|
|
||||||
import org.jclouds.json.config.GsonModule;
|
|
||||||
import org.jclouds.util.Utils;
|
|
||||||
import org.testng.annotations.BeforeTest;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests behavior of {@code ParseKeyFromJson}
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", sequential = true, testName = "chef.ParseKeyFromJsonTest")
|
|
||||||
public class ParseKeyFromJsonTest {
|
|
||||||
|
|
||||||
private ParseKeyFromJson handler;
|
|
||||||
|
|
||||||
@BeforeTest
|
|
||||||
protected void setUpInjector() throws IOException {
|
|
||||||
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule());
|
|
||||||
handler = injector.getInstance(ParseKeyFromJson.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRegex() {
|
|
||||||
assertEquals(
|
|
||||||
handler
|
|
||||||
.apply(new HttpResponse(
|
|
||||||
200,
|
|
||||||
"ok",
|
|
||||||
Payloads
|
|
||||||
.newPayload(Utils
|
|
||||||
.toInputStream("{\n\"uri\": \"https://api.opscode.com/users/bobo\", \"private_key\": \"RSA_PRIVATE_KEY\",}")))),
|
|
||||||
"RSA_PRIVATE_KEY");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void test2() {
|
|
||||||
String key = handler.apply(new HttpResponse(200, "ok", Payloads.newPayload(ParseKeyFromJsonTest.class
|
|
||||||
.getResourceAsStream("/newclient.txt"))));
|
|
||||||
assert key.startsWith("-----BEGIN RSA PRIVATE KEY-----\n");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
{"orgname":"jclouds","certificate":"-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n","uri":"https://api.opscode.com/organizations/jclouds/clients/adriancole-jcloudstest","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n","clientname":"adriancole-jcloudstest","name":"adriancole-jcloudstest","validator":false}
|
|
@ -31,6 +31,7 @@ import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
@ -39,14 +40,13 @@ import org.jclouds.chef.ChefAsyncClient;
|
||||||
import org.jclouds.chef.ChefClient;
|
import org.jclouds.chef.ChefClient;
|
||||||
import org.jclouds.chef.ChefContext;
|
import org.jclouds.chef.ChefContext;
|
||||||
import org.jclouds.chef.ChefService;
|
import org.jclouds.chef.ChefService;
|
||||||
|
import org.jclouds.chef.domain.Client;
|
||||||
import org.jclouds.chef.reference.ChefConstants;
|
import org.jclouds.chef.reference.ChefConstants;
|
||||||
import org.jclouds.chef.servlet.functions.InitParamsToProperties;
|
import org.jclouds.chef.servlet.functions.InitParamsToProperties;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.logging.jdk.JDKLogger;
|
import org.jclouds.logging.jdk.JDKLogger;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to
|
* Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to
|
||||||
* {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to
|
* {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to
|
||||||
|
@ -121,7 +121,7 @@ public class ChefRegistrationListener implements ServletContextListener {
|
||||||
|
|
||||||
private ChefService createClientAndNode(ChefService validatorClient, String role, String id, Properties overrides) {
|
private ChefService createClientAndNode(ChefService validatorClient, String role, String id, Properties overrides) {
|
||||||
logger.trace("attempting to create client %s", id);
|
logger.trace("attempting to create client %s", id);
|
||||||
String clientKey = validatorClient.getContext().getApi().createClient(id);
|
Client client = validatorClient.getContext().getApi().createClient(id);
|
||||||
logger.debug("created client %s", id);
|
logger.debug("created client %s", id);
|
||||||
ChefService clientService = null;
|
ChefService clientService = null;
|
||||||
try {
|
try {
|
||||||
|
@ -129,7 +129,8 @@ public class ChefRegistrationListener implements ServletContextListener {
|
||||||
clientProperties.putAll(overrides);
|
clientProperties.putAll(overrides);
|
||||||
removeCredentials(clientProperties);
|
removeCredentials(clientProperties);
|
||||||
clientProperties.setProperty("chef.identity", id);
|
clientProperties.setProperty("chef.identity", id);
|
||||||
clientProperties.setProperty("chef.credential", clientKey);
|
clientProperties.setProperty("chef.credential", validatorClient.getContext().utils().encryption().toPem(
|
||||||
|
client.getPrivateKey()));
|
||||||
clientService = createService(clientProperties);
|
clientService = createService(clientProperties);
|
||||||
clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]"));
|
clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]"));
|
||||||
return clientService;
|
return clientService;
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
import org.jclouds.encryption.internal.JCEEncryptionService;
|
||||||
import org.jclouds.http.PayloadEnclosing;
|
import org.jclouds.http.PayloadEnclosing;
|
||||||
|
@ -46,7 +48,7 @@ public interface EncryptionService {
|
||||||
|
|
||||||
byte[] fromHex(String encoded);
|
byte[] fromHex(String encoded);
|
||||||
|
|
||||||
byte[] rsaSign(String toSign, Key privateKey);
|
byte[] rsaEncrypt(Payload payload, Key key);
|
||||||
|
|
||||||
byte[] hmacSha256(String toEncode, byte[] key);
|
byte[] hmacSha256(String toEncode, byte[] key);
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ public interface EncryptionService {
|
||||||
* <h2>Note</h2>
|
* <h2>Note</h2>
|
||||||
* <p/>
|
* <p/>
|
||||||
* If this is an InputStream, it will be converted to a byte array first.
|
* If this is an InputStream, it will be converted to a byte array first.
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
<T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing);
|
<T extends PayloadEnclosing> T generateMD5BufferingIfNotRepeatable(T payloadEnclosing);
|
||||||
|
@ -74,7 +77,7 @@ public interface EncryptionService {
|
||||||
|
|
||||||
MD5OutputStream md5OutputStream(OutputStream out);
|
MD5OutputStream md5OutputStream(OutputStream out);
|
||||||
|
|
||||||
PrivateKey readPrivateKeyFromPEM(byte [] pem);
|
PrivateKey privateKeyFromPEM(byte[] pem);
|
||||||
|
|
||||||
public static abstract class MD5OutputStream extends FilterOutputStream {
|
public static abstract class MD5OutputStream extends FilterOutputStream {
|
||||||
public MD5OutputStream(OutputStream out) {
|
public MD5OutputStream(OutputStream out) {
|
||||||
|
@ -84,4 +87,16 @@ public interface EncryptionService {
|
||||||
public abstract byte[] getMD5();
|
public abstract byte[] getMD5();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PublicKey publicKeyFromPEM(byte[] pem);
|
||||||
|
|
||||||
|
X509Certificate x509CertificateFromPEM(byte[] pem);
|
||||||
|
|
||||||
|
byte[] rsaDecrypt(Payload payload, Key key);
|
||||||
|
|
||||||
|
String toPem(X509Certificate cert);
|
||||||
|
|
||||||
|
String toPem(PublicKey key);
|
||||||
|
|
||||||
|
String toPem(PrivateKey key);
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,15 +20,33 @@ package org.jclouds.encryption.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static com.google.common.io.Closeables.closeQuietly;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.Key;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.cert.CertificateEncodingException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.spec.KeySpec;
|
import java.security.spec.KeySpec;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.ShortBufferException;
|
||||||
|
|
||||||
import net.oauth.signature.pem.PEMReader;
|
import net.oauth.signature.pem.PEMReader;
|
||||||
import net.oauth.signature.pem.PKCS1EncodedKeySpec;
|
import net.oauth.signature.pem.PKCS1EncodedKeySpec;
|
||||||
|
@ -55,9 +73,11 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
(byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
|
(byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
|
||||||
|
|
||||||
private final KeyFactory rsaKeyFactory;
|
private final KeyFactory rsaKeyFactory;
|
||||||
|
private final CertificateFactory certFactory;
|
||||||
|
|
||||||
public BaseEncryptionService(KeyFactory rsaKeyFactory) {
|
public BaseEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
|
||||||
this.rsaKeyFactory = rsaKeyFactory;
|
this.rsaKeyFactory = rsaKeyFactory;
|
||||||
|
this.certFactory = certFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,7 +138,7 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PrivateKey readPrivateKeyFromPEM(byte[] pem) {
|
public PrivateKey privateKeyFromPEM(byte[] pem) {
|
||||||
PEMReader reader;
|
PEMReader reader;
|
||||||
try {
|
try {
|
||||||
reader = new PEMReader(pem);
|
reader = new PEMReader(pem);
|
||||||
|
@ -131,7 +151,7 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
} else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) {
|
} else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) {
|
||||||
keySpec = new PKCS8EncodedKeySpec(bytes);
|
keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Invalid PEM file: Unknown marker " + "for private key " + reader.getBeginMarker());
|
throw new IOException("Invalid PEM file: Unknown marker for private key " + reader.getBeginMarker());
|
||||||
}
|
}
|
||||||
return rsaKeyFactory.generatePrivate(keySpec);
|
return rsaKeyFactory.generatePrivate(keySpec);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -139,4 +159,141 @@ public abstract class BaseEncryptionService implements EncryptionService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PublicKey publicKeyFromPEM(byte[] pem) {
|
||||||
|
PEMReader reader;
|
||||||
|
try {
|
||||||
|
reader = new PEMReader(pem);
|
||||||
|
|
||||||
|
byte[] bytes = reader.getDerBytes();
|
||||||
|
KeySpec keySpec;
|
||||||
|
|
||||||
|
if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) {
|
||||||
|
keySpec = new X509EncodedKeySpec(bytes);
|
||||||
|
} else {
|
||||||
|
throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker());
|
||||||
|
}
|
||||||
|
return rsaKeyFactory.generatePublic(keySpec);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public X509Certificate x509CertificateFromPEM(byte[] pem) {
|
||||||
|
PEMReader reader;
|
||||||
|
try {
|
||||||
|
reader = new PEMReader(pem);
|
||||||
|
|
||||||
|
byte[] bytes = reader.getDerBytes();
|
||||||
|
|
||||||
|
if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) {
|
||||||
|
return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes));
|
||||||
|
} else {
|
||||||
|
throw new IOException("Invalid PEM file: Unknown marker for public key " + reader.getBeginMarker());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] rsaEncrypt(Payload payload, Key key) {
|
||||||
|
// TODO convert this to BC code
|
||||||
|
Cipher cipher = null;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
return cipherPayload(cipher, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] rsaDecrypt(Payload payload, Key key) {
|
||||||
|
// TODO convert this to BC code
|
||||||
|
Cipher cipher = null;
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
return cipherPayload(cipher, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] cipherPayload(Cipher cipher, Payload payload) {
|
||||||
|
byte[] resBuf = new byte[cipher.getOutputSize(payload.getContentLength().intValue())];
|
||||||
|
byte[] buffer = new byte[BUF_SIZE];
|
||||||
|
long length = 0;
|
||||||
|
int numRead = -1;
|
||||||
|
InputStream plainBytes = payload.getInput();
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
numRead = plainBytes.read(buffer);
|
||||||
|
if (numRead > 0) {
|
||||||
|
length += numRead;
|
||||||
|
cipher.update(buffer, 0, numRead);
|
||||||
|
}
|
||||||
|
} while (numRead != -1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
propagate(e);
|
||||||
|
} finally {
|
||||||
|
closeQuietly(plainBytes);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int size = cipher.doFinal(resBuf, 0);
|
||||||
|
return Arrays.copyOfRange(resBuf, 0, size);
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (ShortBufferException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
assert false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toPem(X509Certificate cert) {
|
||||||
|
try {
|
||||||
|
return new StringBuilder("-----BEGIN CERTIFICATE-----\n").append(base64(cert.getEncoded())).append(
|
||||||
|
"\n-----END CERTIFICATE-----\n").toString();
|
||||||
|
} catch (CertificateEncodingException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toPem(PublicKey key) {
|
||||||
|
return new StringBuilder("-----BEGIN PUBLIC KEY-----\n").append(base64(key.getEncoded())).append(
|
||||||
|
"\n-----END PUBLIC KEY-----\n").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toPem(PrivateKey key) {
|
||||||
|
return new StringBuilder("-----BEGIN PRIVATE KEY-----\n").append(base64(key.getEncoded())).append(
|
||||||
|
"\n-----END PRIVATE KEY-----\n").toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.DigestOutputStream;
|
import java.security.DigestOutputStream;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
@ -44,12 +44,12 @@ import org.jclouds.io.payloads.ByteArrayPayload;
|
||||||
*/
|
*/
|
||||||
public class JCEEncryptionService extends BaseEncryptionService {
|
public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
|
|
||||||
public JCEEncryptionService(KeyFactory rsaKeyFactory) {
|
public JCEEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
|
||||||
super(rsaKeyFactory);
|
super(rsaKeyFactory, certFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCEEncryptionService() throws NoSuchAlgorithmException {
|
public JCEEncryptionService() throws NoSuchAlgorithmException, CertificateException {
|
||||||
super(KeyFactory.getInstance("RSA"));
|
this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,17 +199,4 @@ public class JCEEncryptionService extends BaseEncryptionService {
|
||||||
return digest.digest();
|
return digest.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] rsaSign(String toSign, Key key) {
|
|
||||||
Cipher cipher;
|
|
||||||
try {
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
||||||
return cipher.doFinal(toSign.getBytes());
|
|
||||||
} catch (Exception e) {
|
|
||||||
propagate(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import static org.jclouds.rest.RestContextFactory.createContextBuilder;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -39,7 +38,6 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import org.jclouds.encryption.EncryptionService;
|
import org.jclouds.encryption.EncryptionService;
|
||||||
import org.jclouds.encryption.internal.Base64;
|
import org.jclouds.encryption.internal.Base64;
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextBuilder;
|
import org.jclouds.rest.RestContextBuilder;
|
||||||
import org.jclouds.rest.RestContextFactory.ContextSpec;
|
import org.jclouds.rest.RestContextFactory.ContextSpec;
|
||||||
|
@ -124,13 +122,7 @@ public abstract class BaseJettyTest {
|
||||||
if (request.getContentLength() > 0) {
|
if (request.getContentLength() > 0) {
|
||||||
if (request.getHeader("Content-MD5") != null) {
|
if (request.getHeader("Content-MD5") != null) {
|
||||||
String expectedMd5 = request.getHeader("Content-MD5");
|
String expectedMd5 = request.getHeader("Content-MD5");
|
||||||
String realMd5FromRequest;
|
String realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream()));
|
||||||
try {
|
|
||||||
realMd5FromRequest = Base64.encodeBytes(new JCEEncryptionService()
|
|
||||||
.md5(request.getInputStream()));
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
boolean matched = expectedMd5.equals(realMd5FromRequest);
|
boolean matched = expectedMd5.equals(realMd5FromRequest);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
response.setContentType("text/xml");
|
response.setContentType("text/xml");
|
||||||
|
@ -152,8 +144,7 @@ public abstract class BaseJettyTest {
|
||||||
response.getWriter().println("test");
|
response.getWriter().println("test");
|
||||||
} else if (request.getMethod().equals("HEAD")) {
|
} else if (request.getMethod().equals("HEAD")) {
|
||||||
/*
|
/*
|
||||||
* NOTE: by HTML specification, HEAD response MUST NOT include a
|
* NOTE: by HTML specification, HEAD response MUST NOT include a body
|
||||||
* body
|
|
||||||
*/
|
*/
|
||||||
response.setContentType("text/xml");
|
response.setContentType("text/xml");
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
@ -186,12 +177,7 @@ public abstract class BaseJettyTest {
|
||||||
if (request.getHeader("Content-MD5") != null) {
|
if (request.getHeader("Content-MD5") != null) {
|
||||||
String expectedMd5 = request.getHeader("Content-MD5");
|
String expectedMd5 = request.getHeader("Content-MD5");
|
||||||
String realMd5FromRequest;
|
String realMd5FromRequest;
|
||||||
try {
|
realMd5FromRequest = Base64.encodeBytes(encryptionService.md5(request.getInputStream()));
|
||||||
realMd5FromRequest = Base64.encodeBytes(new JCEEncryptionService()
|
|
||||||
.md5(request.getInputStream()));
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
boolean matched = expectedMd5.equals(realMd5FromRequest);
|
boolean matched = expectedMd5.equals(realMd5FromRequest);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
response.setContentType("text/xml");
|
response.setContentType("text/xml");
|
||||||
|
@ -207,8 +193,7 @@ public abstract class BaseJettyTest {
|
||||||
}
|
}
|
||||||
} else if (request.getMethod().equals("HEAD")) {
|
} else if (request.getMethod().equals("HEAD")) {
|
||||||
/*
|
/*
|
||||||
* NOTE: by HTML specification, HEAD response MUST NOT include a
|
* NOTE: by HTML specification, HEAD response MUST NOT include a body
|
||||||
* body
|
|
||||||
*/
|
*/
|
||||||
response.setContentType("text/xml");
|
response.setContentType("text/xml");
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ public class BasicAuthenticationTest {
|
||||||
private static final String USER = "Aladdin";
|
private static final String USER = "Aladdin";
|
||||||
private static final String PASSWORD = "open sesame";
|
private static final String PASSWORD = "open sesame";
|
||||||
|
|
||||||
public void testAuth() throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
public void testAuth() throws UnsupportedEncodingException, NoSuchAlgorithmException, CertificateException {
|
||||||
BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService());
|
BasicAuthentication filter = new BasicAuthentication(USER, PASSWORD, new JCEEncryptionService());
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
HttpRequest request = new HttpRequest("GET", URI.create("http://localhost"));
|
||||||
filter.filter(request);
|
filter.filter(request);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -58,6 +59,9 @@ public class WireLiveTest {
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
encryptionService = null;
|
encryptionService = null;
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
encryptionService = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,872 @@
|
||||||
|
Provided by USConstitution.net
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
[Note: Repealed text is not noted in this version. Spelling errors have been
|
||||||
|
corrected in this version. For an uncorrected, annotated version of the
|
||||||
|
Constitution, visit http://www.usconstitution.net/const.html ]
|
||||||
|
|
||||||
|
We the People of the United States, in Order to form a more perfect Union,
|
||||||
|
establish Justice, insure domestic Tranquility, provide for the common
|
||||||
|
defence, promote the general Welfare, and secure the Blessings of Liberty to
|
||||||
|
ourselves and our Posterity, do ordain and establish this Constitution for the
|
||||||
|
United States of America.
|
||||||
|
|
||||||
|
Article 1.
|
||||||
|
|
||||||
|
Section 1
|
||||||
|
All legislative Powers herein granted shall be vested in a Congress of the
|
||||||
|
United States, which shall consist of a Senate and House of Representatives.
|
||||||
|
|
||||||
|
Section 2
|
||||||
|
The House of Representatives shall be composed of Members chosen every second
|
||||||
|
Year by the People of the several States, and the Electors in each State shall
|
||||||
|
have the Qualifications requisite for Electors of the most numerous Branch of
|
||||||
|
the State Legislature.
|
||||||
|
|
||||||
|
No Person shall be a Representative who shall not have attained to the Age of
|
||||||
|
twenty five Years, and been seven Years a Citizen of the United States, and who
|
||||||
|
shall not, when elected, be an Inhabitant of that State in which he shall be
|
||||||
|
chosen.
|
||||||
|
|
||||||
|
Representatives and direct Taxes shall be apportioned among the several States
|
||||||
|
which may be included within this Union, according to their respective Numbers,
|
||||||
|
which shall be determined by adding to the whole Number of free Persons,
|
||||||
|
including those bound to Service for a Term of Years, and excluding Indians not
|
||||||
|
taxed, three fifths of all other Persons.
|
||||||
|
|
||||||
|
The actual Enumeration shall be made within three Years after the first Meeting
|
||||||
|
of the Congress of the United States, and within every subsequent Term of ten
|
||||||
|
Years, in such Manner as they shall by Law direct. The Number of
|
||||||
|
Representatives shall not exceed one for every thirty Thousand, but each State
|
||||||
|
shall have at Least one Representative; and until such enumeration shall be
|
||||||
|
made, the State of New Hampshire shall be entitled to choose three,
|
||||||
|
Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut
|
||||||
|
five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland
|
||||||
|
six, Virginia ten, North Carolina five, South Carolina five and Georgia three.
|
||||||
|
|
||||||
|
When vacancies happen in the Representation from any State, the Executive
|
||||||
|
Authority thereof shall issue Writs of Election to fill such Vacancies.
|
||||||
|
|
||||||
|
The House of Representatives shall choose their Speaker and other Officers; and
|
||||||
|
shall have the sole Power of Impeachment.
|
||||||
|
|
||||||
|
Section 3
|
||||||
|
The Senate of the United States shall be composed of two Senators from each
|
||||||
|
State, chosen by the Legislature thereof, for six Years; and each Senator shall
|
||||||
|
have one Vote.
|
||||||
|
|
||||||
|
Immediately after they shall be assembled in Consequence of the first Election,
|
||||||
|
they shall be divided as equally as may be into three Classes. The Seats of the
|
||||||
|
Senators of the first Class shall be vacated at the Expiration of the second
|
||||||
|
Year, of the second Class at the Expiration of the fourth Year, and of the
|
||||||
|
third Class at the Expiration of the sixth Year, so that one third may be
|
||||||
|
chosen every second Year; and if Vacancies happen by Resignation, or otherwise,
|
||||||
|
during the Recess of the Legislature of any State, the Executive thereof may
|
||||||
|
make temporary Appointments until the next Meeting of the Legislature, which
|
||||||
|
shall then fill such Vacancies.
|
||||||
|
|
||||||
|
No person shall be a Senator who shall not have attained to the Age of thirty
|
||||||
|
Years, and been nine Years a Citizen of the United States, and who shall not,
|
||||||
|
when elected, be an Inhabitant of that State for which he shall be chosen.
|
||||||
|
|
||||||
|
The Vice President of the United States shall be President of the Senate, but
|
||||||
|
shall have no Vote, unless they be equally divided.
|
||||||
|
|
||||||
|
The Senate shall choose their other Officers, and also a President pro tempore,
|
||||||
|
in the absence of the Vice President, or when he shall exercise the Office of
|
||||||
|
President of the United States.
|
||||||
|
|
||||||
|
The Senate shall have the sole Power to try all Impeachments. When sitting for
|
||||||
|
that Purpose, they shall be on Oath or Affirmation. When the President of the
|
||||||
|
United States is tried, the Chief Justice shall preside: And no Person shall be
|
||||||
|
convicted without the Concurrence of two thirds of the Members present.
|
||||||
|
|
||||||
|
Judgment in Cases of Impeachment shall not extend further than to removal from
|
||||||
|
Office, and disqualification to hold and enjoy any Office of honor, Trust or
|
||||||
|
Profit under the United States: but the Party convicted shall nevertheless be
|
||||||
|
liable and subject to Indictment, Trial, Judgment and Punishment, according to
|
||||||
|
Law.
|
||||||
|
|
||||||
|
Section 4
|
||||||
|
The Times, Places and Manner of holding Elections for Senators and
|
||||||
|
Representatives, shall be prescribed in each State by the Legislature thereof;
|
||||||
|
but the Congress may at any time by Law make or alter such Regulations, except
|
||||||
|
as to the Place of Choosing Senators.
|
||||||
|
|
||||||
|
The Congress shall assemble at least once in every Year, and such Meeting shall
|
||||||
|
be on the first Monday in December, unless they shall by Law appoint a
|
||||||
|
different Day.
|
||||||
|
|
||||||
|
Section 5
|
||||||
|
Each House shall be the Judge of the Elections, Returns and Qualifications of
|
||||||
|
its own Members, and a Majority of each shall constitute a Quorum to do
|
||||||
|
Business; but a smaller number may adjourn from day to day, and may be
|
||||||
|
authorized to compel the Attendance of absent Members, in such Manner, and
|
||||||
|
under such Penalties as each House may provide.
|
||||||
|
|
||||||
|
Each House may determine the Rules of its Proceedings, punish its Members for
|
||||||
|
disorderly Behavior, and, with the Concurrence of two-thirds, expel a Member.
|
||||||
|
|
||||||
|
Each House shall keep a Journal of its Proceedings, and from time to time
|
||||||
|
publish the same, excepting such Parts as may in their Judgment require
|
||||||
|
Secrecy; and the Yeas and Nays of the Members of either House on any question
|
||||||
|
shall, at the Desire of one fifth of those Present, be entered on the Journal.
|
||||||
|
|
||||||
|
Neither House, during the Session of Congress, shall, without the Consent of
|
||||||
|
the other, adjourn for more than three days, nor to any other Place than that
|
||||||
|
in which the two Houses shall be sitting.
|
||||||
|
|
||||||
|
Section 6
|
||||||
|
The Senators and Representatives shall receive a Compensation for their
|
||||||
|
Services, to be ascertained by Law, and paid out of the Treasury of the United
|
||||||
|
States. They shall in all Cases, except Treason, Felony and Breach of the
|
||||||
|
Peace, be privileged from Arrest during their Attendance at the Session of
|
||||||
|
their respective Houses, and in going to and returning from the same; and for
|
||||||
|
any Speech or Debate in either House, they shall not be questioned in any other
|
||||||
|
Place.
|
||||||
|
|
||||||
|
No Senator or Representative shall, during the Time for which he was elected,
|
||||||
|
be appointed to any civil Office under the Authority of the United States which
|
||||||
|
shall have been created, or the Emoluments whereof shall have been increased
|
||||||
|
during such time; and no Person holding any Office under the United States,
|
||||||
|
shall be a Member of either House during his Continuance in Office.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7
|
||||||
|
All bills for raising Revenue shall originate in the House of Representatives;
|
||||||
|
but the Senate may propose or concur with Amendments as on other Bills.
|
||||||
|
|
||||||
|
Every Bill which shall have passed the House of Representatives and the Senate,
|
||||||
|
shall, before it become a Law, be presented to the President of the United
|
||||||
|
States; If he approve he shall sign it, but if not he shall return it, with his
|
||||||
|
Objections to that House in which it shall have originated, who shall enter the
|
||||||
|
Objections at large on their Journal, and proceed to reconsider it. If after
|
||||||
|
such Reconsideration two thirds of that House shall agree to pass the Bill, it
|
||||||
|
shall be sent, together with the Objections, to the other House, by which it
|
||||||
|
shall likewise be reconsidered, and if approved by two thirds of that House, it
|
||||||
|
shall become a Law. But in all such Cases the Votes of both Houses shall be
|
||||||
|
determined by Yeas and Nays, and the Names of the Persons voting for and
|
||||||
|
against the Bill shall be entered on the Journal of each House respectively. If
|
||||||
|
any Bill shall not be returned by the President within ten Days (Sundays
|
||||||
|
excepted) after it shall have been presented to him, the Same shall be a Law,
|
||||||
|
in like Manner as if he had signed it, unless the Congress by their Adjournment
|
||||||
|
prevent its Return, in which Case it shall not be a Law.
|
||||||
|
|
||||||
|
Every Order, Resolution, or Vote to which the Concurrence of the Senate and
|
||||||
|
House of Representatives may be necessary (except on a question of Adjournment)
|
||||||
|
shall be presented to the President of the United States; and before the Same
|
||||||
|
shall take Effect, shall be approved by him, or being disapproved by him, shall
|
||||||
|
be repassed by two thirds of the Senate and House of Representatives, according
|
||||||
|
to the Rules and Limitations prescribed in the Case of a Bill.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8
|
||||||
|
The Congress shall have Power To lay and collect Taxes, Duties, Imposts and
|
||||||
|
Excises, to pay the Debts and provide for the common Defence and general
|
||||||
|
Welfare of the United States; but all Duties, Imposts and Excises shall be
|
||||||
|
uniform throughout the United States;
|
||||||
|
|
||||||
|
To borrow money on the credit of the United States;
|
||||||
|
|
||||||
|
To regulate Commerce with foreign Nations, and among the several States, and
|
||||||
|
with the Indian Tribes;
|
||||||
|
|
||||||
|
To establish an uniform Rule of Naturalization, and uniform Laws on the subject
|
||||||
|
of Bankruptcies throughout the United States;
|
||||||
|
|
||||||
|
To coin Money, regulate the Value thereof, and of foreign Coin, and fix the
|
||||||
|
Standard of Weights and Measures;
|
||||||
|
|
||||||
|
To provide for the Punishment of counterfeiting the Securities and current Coin
|
||||||
|
of the United States;
|
||||||
|
|
||||||
|
To establish Post Offices and Post Roads;
|
||||||
|
|
||||||
|
To promote the Progress of Science and useful Arts, by securing for limited
|
||||||
|
Times to Authors and Inventors the exclusive Right to their respective Writings
|
||||||
|
and Discoveries;
|
||||||
|
|
||||||
|
To constitute Tribunals inferior to the supreme Court;
|
||||||
|
|
||||||
|
To define and punish Piracies and Felonies committed on the high Seas, and
|
||||||
|
Offenses against the Law of Nations;
|
||||||
|
|
||||||
|
To declare War, grant Letters of Marque and Reprisal, and make Rules concerning
|
||||||
|
Captures on Land and Water;
|
||||||
|
|
||||||
|
To raise and support Armies, but no Appropriation of Money to that Use shall be
|
||||||
|
for a longer Term than two Years;
|
||||||
|
|
||||||
|
To provide and maintain a Navy;
|
||||||
|
|
||||||
|
To make Rules for the Government and Regulation of the land and naval Forces;
|
||||||
|
|
||||||
|
To provide for calling forth the Militia to execute the Laws of the Union,
|
||||||
|
suppress Insurrections and repel Invasions;
|
||||||
|
|
||||||
|
To provide for organizing, arming, and disciplining the Militia, and for
|
||||||
|
governing such Part of them as may be employed in the Service of the United
|
||||||
|
States, reserving to the States respectively, the Appointment of the Officers,
|
||||||
|
and the Authority of training the Militia according to the discipline
|
||||||
|
prescribed by Congress;
|
||||||
|
|
||||||
|
To exercise exclusive Legislation in all Cases whatsoever, over such District
|
||||||
|
(not exceeding ten Miles square) as may, by Cession of particular States, and
|
||||||
|
the acceptance of Congress, become the Seat of the Government of the United
|
||||||
|
States, and to exercise like Authority over all Places purchased by the Consent
|
||||||
|
of the Legislature of the State in which the Same shall be, for the Erection of
|
||||||
|
Forts, Magazines, Arsenals, dock-Yards, and other needful Buildings; And
|
||||||
|
|
||||||
|
To make all Laws which shall be necessary and proper for carrying into
|
||||||
|
Execution the foregoing Powers, and all other Powers vested by this
|
||||||
|
Constitution in the Government of the United States, or in any Department or
|
||||||
|
Officer thereof.
|
||||||
|
|
||||||
|
Section 9
|
||||||
|
The Migration or Importation of such Persons as any of the States now existing
|
||||||
|
shall think proper to admit, shall not be prohibited by the Congress prior to
|
||||||
|
the Year one thousand eight hundred and eight, but a tax or duty may be imposed
|
||||||
|
on such Importation, not exceeding ten dollars for each Person.
|
||||||
|
|
||||||
|
The privilege of the Writ of Habeas Corpus shall not be suspended, unless when
|
||||||
|
in Cases of Rebellion or Invasion the public Safety may require it.
|
||||||
|
|
||||||
|
No Bill of Attainder or ex post facto Law shall be passed.
|
||||||
|
|
||||||
|
No capitation, or other direct, Tax shall be laid, unless in Proportion to the
|
||||||
|
Census or Enumeration herein before directed to be taken.
|
||||||
|
|
||||||
|
No Tax or Duty shall be laid on Articles exported from any State.
|
||||||
|
|
||||||
|
No Preference shall be given by any Regulation of Commerce or Revenue to the
|
||||||
|
Ports of one State over those of another: nor shall Vessels bound to, or from,
|
||||||
|
one State, be obliged to enter, clear, or pay Duties in another.
|
||||||
|
|
||||||
|
No Money shall be drawn from the Treasury, but in Consequence of Appropriations
|
||||||
|
made by Law; and a regular Statement and Account of the Receipts and
|
||||||
|
Expenditures of all public Money shall be published from time to time.
|
||||||
|
|
||||||
|
No Title of Nobility shall be granted by the United States: And no Person
|
||||||
|
holding any Office of Profit or Trust under them, shall, without the Consent of
|
||||||
|
the Congress, accept of any present, Emolument, Office, or Title, of any kind
|
||||||
|
whatever, from any King, Prince or foreign State.
|
||||||
|
|
||||||
|
Section 10
|
||||||
|
No State shall enter into any Treaty, Alliance, or Confederation; grant Letters
|
||||||
|
of Marque and Reprisal; coin Money; emit Bills of Credit; make any Thing but
|
||||||
|
gold and silver Coin a Tender in Payment of Debts; pass any Bill of Attainder,
|
||||||
|
ex post facto Law, or Law impairing the Obligation of Contracts, or grant any
|
||||||
|
Title of Nobility.
|
||||||
|
|
||||||
|
No State shall, without the Consent of the Congress, lay any Imposts or Duties
|
||||||
|
on Imports or Exports, except what may be absolutely necessary for executing
|
||||||
|
its inspection Laws: and the net Produce of all Duties and Imposts, laid by
|
||||||
|
any State on Imports or Exports, shall be for the Use of the Treasury of the
|
||||||
|
United States; and all such Laws shall be subject to the Revision and Control
|
||||||
|
of the Congress.
|
||||||
|
|
||||||
|
No State shall, without the Consent of Congress, lay any duty of Tonnage, keep
|
||||||
|
Troops, or Ships of War in time of Peace, enter into any Agreement or Compact
|
||||||
|
with another State, or with a foreign Power, or engage in War, unless actually
|
||||||
|
invaded, or in such imminent Danger as will not admit of delay.
|
||||||
|
|
||||||
|
Article 2.
|
||||||
|
|
||||||
|
Section 1
|
||||||
|
The executive Power shall be vested in a President of the United States of
|
||||||
|
America. He shall hold his Office during the Term of four Years, and, together
|
||||||
|
with the Vice-President chosen for the same Term, be elected, as follows:
|
||||||
|
|
||||||
|
Each State shall appoint, in such Manner as the Legislature thereof may direct,
|
||||||
|
a Number of Electors, equal to the whole Number of Senators and Representatives
|
||||||
|
to which the State may be entitled in the Congress: but no Senator or
|
||||||
|
Representative, or Person holding an Office of Trust or Profit under the United
|
||||||
|
States, shall be appointed an Elector.
|
||||||
|
|
||||||
|
The Electors shall meet in their respective States, and vote by Ballot for two
|
||||||
|
persons, of whom one at least shall not lie an Inhabitant of the same State
|
||||||
|
with themselves. And they shall make a List of all the Persons voted for, and
|
||||||
|
of the Number of Votes for each; which List they shall sign and certify, and
|
||||||
|
transmit sealed to the Seat of the Government of the United States, directed to
|
||||||
|
the President of the Senate. The President of the Senate shall, in the Presence
|
||||||
|
of the Senate and House of Representatives, open all the Certificates, and the
|
||||||
|
Votes shall then be counted. The Person having the greatest Number of Votes
|
||||||
|
shall be the President, if such Number be a Majority of the whole Number of
|
||||||
|
Electors appointed; and if there be more than one who have such Majority, and
|
||||||
|
have an equal Number of Votes, then the House of Representatives shall
|
||||||
|
immediately choose by Ballot one of them for President; and if no Person have a
|
||||||
|
Majority, then from the five highest on the List the said House shall in like
|
||||||
|
Manner choose the President. But in choosing the President, the Votes shall be
|
||||||
|
taken by States, the Representation from each State having one Vote; a quorum
|
||||||
|
for this Purpose shall consist of a Member or Members from two-thirds of the
|
||||||
|
States, and a Majority of all the States shall be necessary to a Choice. In
|
||||||
|
every Case, after the Choice of the President, the Person having the greatest
|
||||||
|
Number of Votes of the Electors shall be the Vice President. But if there
|
||||||
|
should remain two or more who have equal Votes, the Senate shall choose from
|
||||||
|
them by Ballot the Vice-President.
|
||||||
|
|
||||||
|
The Congress may determine the Time of choosing the Electors, and the Day on
|
||||||
|
which they shall give their Votes; which Day shall be the same throughout the
|
||||||
|
United States.
|
||||||
|
|
||||||
|
No person except a natural born Citizen, or a Citizen of the United States, at
|
||||||
|
the time of the Adoption of this Constitution, shall be eligible to the Office
|
||||||
|
of President; neither shall any Person be eligible to that Office who shall not
|
||||||
|
have attained to the Age of thirty-five Years, and been fourteen Years a
|
||||||
|
Resident within the United States.
|
||||||
|
|
||||||
|
In Case of the Removal of the President from Office, or of his Death,
|
||||||
|
Resignation, or Inability to discharge the Powers and Duties of the said
|
||||||
|
Office, the same shall devolve on the Vice President, and the Congress may by
|
||||||
|
Law provide for the Case of Removal, Death, Resignation or Inability, both of
|
||||||
|
the President and Vice President, declaring what Officer shall then act as
|
||||||
|
President, and such Officer shall act accordingly, until the Disability be
|
||||||
|
removed, or a President shall be elected.
|
||||||
|
|
||||||
|
The President shall, at stated Times, receive for his Services, a Compensation,
|
||||||
|
which shall neither be increased nor diminished during the Period for which he
|
||||||
|
shall have been elected, and he shall not receive within that Period any other
|
||||||
|
Emolument from the United States, or any of them.
|
||||||
|
|
||||||
|
Before he enter on the Execution of his Office, he shall take the following
|
||||||
|
Oath or Affirmation:
|
||||||
|
|
||||||
|
"I do solemnly swear (or affirm) that I will faithfully execute the Office of
|
||||||
|
President of the United States, and will to the best of my Ability, preserve,
|
||||||
|
protect and defend the Constitution of the United States."
|
||||||
|
|
||||||
|
Section 2
|
||||||
|
The President shall be Commander in Chief of the Army and Navy of the United
|
||||||
|
States, and of the Militia of the several States, when called into the actual
|
||||||
|
Service of the United States; he may require the Opinion, in writing, of the
|
||||||
|
principal Officer in each of the executive Departments, upon any subject
|
||||||
|
relating to the Duties of their respective Offices, and he shall have Power to
|
||||||
|
Grant Reprieves and Pardons for Offenses against the United States, except in
|
||||||
|
Cases of Impeachment.
|
||||||
|
|
||||||
|
He shall have Power, by and with the Advice and Consent of the Senate, to make
|
||||||
|
Treaties, provided two thirds of the Senators present concur; and he shall
|
||||||
|
nominate, and by and with the Advice and Consent of the Senate, shall appoint
|
||||||
|
Ambassadors, other public Ministers and Consuls, Judges of the supreme Court,
|
||||||
|
and all other Officers of the United States, whose Appointments are not herein
|
||||||
|
otherwise provided for, and which shall be established by Law: but the Congress
|
||||||
|
may by Law vest the Appointment of such inferior Officers, as they think
|
||||||
|
proper, in the President alone, in the Courts of Law, or in the Heads of
|
||||||
|
Departments.
|
||||||
|
|
||||||
|
The President shall have Power to fill up all Vacancies that may happen during
|
||||||
|
the Recess of the Senate, by granting Commissions which shall expire at the End
|
||||||
|
of their next Session.
|
||||||
|
|
||||||
|
Section 3
|
||||||
|
He shall from time to time give to the Congress Information of the State of the
|
||||||
|
Union, and recommend to their Consideration such Measures as he shall judge
|
||||||
|
necessary and expedient; he may, on extraordinary Occasions, convene both
|
||||||
|
Houses, or either of them, and in Case of Disagreement between them, with
|
||||||
|
Respect to the Time of Adjournment, he may adjourn them to such Time as he
|
||||||
|
shall think proper; he shall receive Ambassadors and other public Ministers; he
|
||||||
|
shall take Care that the Laws be faithfully executed, and shall Commission all
|
||||||
|
the Officers of the United States.
|
||||||
|
|
||||||
|
Section 4
|
||||||
|
The President, Vice President and all civil Officers of the United States,
|
||||||
|
shall be removed from Office on Impeachment for, and Conviction of, Treason,
|
||||||
|
Bribery, or other high Crimes and Misdemeanors.
|
||||||
|
|
||||||
|
Article 3.
|
||||||
|
|
||||||
|
Section 1
|
||||||
|
The judicial Power of the United States, shall be vested in one supreme Court,
|
||||||
|
and in such inferior Courts as the Congress may from time to time ordain and
|
||||||
|
establish. The Judges, both of the supreme and inferior Courts, shall hold
|
||||||
|
their Offices during good Behavior, and shall, at stated Times, receive for
|
||||||
|
their Services a Compensation which shall not be diminished during their
|
||||||
|
Continuance in Office.
|
||||||
|
|
||||||
|
Section 2
|
||||||
|
The judicial Power shall extend to all Cases, in Law and Equity, arising under
|
||||||
|
this Constitution, the Laws of the United States, and Treaties made, or which
|
||||||
|
shall be made, under their Authority; to all Cases affecting Ambassadors, other
|
||||||
|
public Ministers and Consuls; to all Cases of admiralty and maritime
|
||||||
|
Jurisdiction; to Controversies to which the United States shall be a Party; to
|
||||||
|
Controversies between two or more States; between a State and Citizens of
|
||||||
|
another State; between Citizens of different States; between Citizens of the
|
||||||
|
same State claiming Lands under Grants of different States, and between a
|
||||||
|
State, or the Citizens thereof, and foreign States, Citizens or Subjects.
|
||||||
|
|
||||||
|
In all Cases affecting Ambassadors, other public Ministers and Consuls, and
|
||||||
|
those in which a State shall be Party, the supreme Court shall have original
|
||||||
|
Jurisdiction. In all the other Cases before mentioned, the supreme Court shall
|
||||||
|
have appellate Jurisdiction, both as to Law and Fact, with such Exceptions, and
|
||||||
|
under such Regulations as the Congress shall make.
|
||||||
|
|
||||||
|
The Trial of all Crimes, except in Cases of Impeachment, shall be by Jury; and
|
||||||
|
such Trial shall be held in the State where the said Crimes shall have been
|
||||||
|
committed; but when not committed within any State, the Trial shall be at such
|
||||||
|
Place or Places as the Congress may by Law have directed.
|
||||||
|
|
||||||
|
Section 3
|
||||||
|
Treason against the United States, shall consist only in levying War against
|
||||||
|
them, or in adhering to their Enemies, giving them Aid and Comfort. No Person
|
||||||
|
shall be convicted of Treason unless on the Testimony of two Witnesses to the
|
||||||
|
same overt Act, or on Confession in open Court.
|
||||||
|
|
||||||
|
The Congress shall have power to declare the Punishment of Treason, but no
|
||||||
|
Attainder of Treason shall work Corruption of Blood, or Forfeiture except
|
||||||
|
during the Life of the Person attainted.
|
||||||
|
|
||||||
|
Article 4.
|
||||||
|
|
||||||
|
Section 1
|
||||||
|
Full Faith and Credit shall be given in each State to the public Acts, Records,
|
||||||
|
and judicial Proceedings of every other State. And the Congress may by general
|
||||||
|
Laws prescribe the Manner in which such Acts, Records and Proceedings shall be
|
||||||
|
proved, and the Effect thereof.
|
||||||
|
|
||||||
|
Section 2
|
||||||
|
The Citizens of each State shall be entitled to all Privileges and Immunities
|
||||||
|
of Citizens in the several States.
|
||||||
|
|
||||||
|
A Person charged in any State with Treason, Felony, or other Crime, who shall
|
||||||
|
flee from Justice, and be found in another State, shall on demand of the
|
||||||
|
executive Authority of the State from which he fled, be delivered up, to be
|
||||||
|
removed to the State having Jurisdiction of the Crime.
|
||||||
|
|
||||||
|
No Person held to Service or Labour in one State, under the Laws thereof,
|
||||||
|
escaping into another, shall, in Consequence of any Law or Regulation therein,
|
||||||
|
be discharged from such Service or Labour, But shall be delivered up on Claim
|
||||||
|
of the Party to whom such Service or Labour may be due.
|
||||||
|
|
||||||
|
Section 3
|
||||||
|
New States may be admitted by the Congress into this Union; but no new States
|
||||||
|
shall be formed or erected within the Jurisdiction of any other State; nor any
|
||||||
|
State be formed by the Junction of two or more States, or parts of States,
|
||||||
|
without the Consent of the Legislatures of the States concerned as well as of
|
||||||
|
the Congress.
|
||||||
|
|
||||||
|
The Congress shall have Power to dispose of and make all needful Rules and
|
||||||
|
Regulations respecting the Territory or other Property belonging to the United
|
||||||
|
States; and nothing in this Constitution shall be so construed as to Prejudice
|
||||||
|
any Claims of the United States, or of any particular State.
|
||||||
|
|
||||||
|
Section 4
|
||||||
|
The United States shall guarantee to every State in this Union a Republican
|
||||||
|
Form of Government, and shall protect each of them against Invasion; and on
|
||||||
|
Application of the Legislature, or of the Executive (when the Legislature
|
||||||
|
cannot be convened) against domestic Violence.
|
||||||
|
|
||||||
|
Article 5.
|
||||||
|
|
||||||
|
The Congress, whenever two thirds of both Houses shall deem it necessary, shall
|
||||||
|
propose Amendments to this Constitution, or, on the Application of the
|
||||||
|
Legislatures of two thirds of the several States, shall call a Convention for
|
||||||
|
proposing Amendments, which, in either Case, shall be valid to all Intents and
|
||||||
|
Purposes, as part of this Constitution, when ratified by the Legislatures of
|
||||||
|
three fourths of the several States, or by Conventions in three fourths
|
||||||
|
thereof, as the one or the other Mode of Ratification may be proposed by the
|
||||||
|
Congress; Provided that no Amendment which may be made prior to the Year One
|
||||||
|
thousand eight hundred and eight shall in any Manner affect the first and
|
||||||
|
fourth Clauses in the Ninth Section of the first Article; and that no State,
|
||||||
|
without its Consent, shall be deprived of its equal Suffrage in the Senate.
|
||||||
|
|
||||||
|
Article 6.
|
||||||
|
|
||||||
|
All Debts contracted and Engagements entered into, before the Adoption of this
|
||||||
|
Constitution, shall be as valid against the United States under this
|
||||||
|
Constitution, as under the Confederation.
|
||||||
|
|
||||||
|
This Constitution, and the Laws of the United States which shall be made in
|
||||||
|
Pursuance thereof; and all Treaties made, or which shall be made, under the
|
||||||
|
Authority of the United States, shall be the supreme Law of the Land; and the
|
||||||
|
Judges in every State shall be bound thereby, any Thing in the Constitution or
|
||||||
|
Laws of any State to the Contrary notwithstanding.
|
||||||
|
|
||||||
|
The Senators and Representatives before mentioned, and the Members of the
|
||||||
|
several State Legislatures, and all executive and judicial Officers, both of
|
||||||
|
the United States and of the several States, shall be bound by Oath or
|
||||||
|
Affirmation, to support this Constitution; but no religious Test shall ever be
|
||||||
|
required as a Qualification to any Office or public Trust under the United
|
||||||
|
States.
|
||||||
|
|
||||||
|
Article 7.
|
||||||
|
|
||||||
|
The Ratification of the Conventions of nine States, shall be sufficient for the
|
||||||
|
Establishment of this Constitution between the States so ratifying the Same.
|
||||||
|
|
||||||
|
Done in Convention by the Unanimous Consent of the States present the
|
||||||
|
Seventeenth Day of September in the Year of our Lord one thousand seven hundred
|
||||||
|
and Eighty seven and of the Independence of the United States of America the
|
||||||
|
Twelfth. In Witness whereof We have hereunto subscribed our Names.
|
||||||
|
|
||||||
|
George Washington - President and deputy from Virginia
|
||||||
|
|
||||||
|
New Hampshire - John Langdon, Nicholas Gilman
|
||||||
|
|
||||||
|
Massachusetts - Nathaniel Gorham, Rufus King
|
||||||
|
|
||||||
|
Connecticut - William Samuel Johnson, Roger Sherman
|
||||||
|
|
||||||
|
New York - Alexander Hamilton
|
||||||
|
|
||||||
|
New Jersey - William Livingston, David Brearley, William Paterson, Jonathan
|
||||||
|
Dayton
|
||||||
|
|
||||||
|
Pennsylvania - Benjamin Franklin, Thomas Mifflin, Robert Morris, George Clymer,
|
||||||
|
Thomas Fitzsimons, Jared Ingersoll, James Wilson, Gouvernour Morris
|
||||||
|
|
||||||
|
Delaware - George Read, Gunning Bedford Jr., John Dickinson, Richard Bassett,
|
||||||
|
Jacob Broom
|
||||||
|
|
||||||
|
Maryland - James McHenry, Daniel of St Thomas Jenifer, Daniel Carroll
|
||||||
|
|
||||||
|
Virginia - John Blair, James Madison Jr.
|
||||||
|
|
||||||
|
North Carolina - William Blount, Richard Dobbs Spaight, Hugh Williamson
|
||||||
|
|
||||||
|
South Carolina - John Rutledge, Charles Cotesworth Pinckney, Charles Pinckney,
|
||||||
|
Pierce Butler
|
||||||
|
|
||||||
|
Georgia - William Few, Abraham Baldwin
|
||||||
|
|
||||||
|
Attest: William Jackson, Secretary
|
||||||
|
|
||||||
|
|
||||||
|
Amendment 1
|
||||||
|
Congress shall make no law respecting an establishment of religion, or
|
||||||
|
prohibiting the free exercise thereof; or abridging the freedom of speech, or
|
||||||
|
of the press; or the right of the people peaceably to assemble, and to petition
|
||||||
|
the Government for a redress of grievances.
|
||||||
|
|
||||||
|
Amendment 2
|
||||||
|
A well regulated Militia, being necessary to the security of a free State, the
|
||||||
|
right of the people to keep and bear Arms, shall not be infringed.
|
||||||
|
|
||||||
|
Amendment 3
|
||||||
|
No Soldier shall, in time of peace be quartered in any house, without the
|
||||||
|
consent of the Owner, nor in time of war, but in a manner to be prescribed by
|
||||||
|
law.
|
||||||
|
|
||||||
|
Amendment 4
|
||||||
|
The right of the people to be secure in their persons, houses, papers, and
|
||||||
|
effects, against unreasonable searches and seizures, shall not be violated, and
|
||||||
|
no Warrants shall issue, but upon probable cause, supported by Oath or
|
||||||
|
affirmation, and particularly describing the place to be searched, and the
|
||||||
|
persons or things to be seized.
|
||||||
|
|
||||||
|
Amendment 5
|
||||||
|
No person shall be held to answer for a capital, or otherwise infamous crime,
|
||||||
|
unless on a presentment or indictment of a Grand Jury, except in cases arising
|
||||||
|
in the land or naval forces, or in the Militia, when in actual service in time
|
||||||
|
of War or public danger; nor shall any person be subject for the same offense
|
||||||
|
to be twice put in jeopardy of life or limb; nor shall be compelled in any
|
||||||
|
criminal case to be a witness against himself, nor be deprived of life,
|
||||||
|
liberty, or property, without due process of law; nor shall private property be
|
||||||
|
taken for public use, without just compensation.
|
||||||
|
|
||||||
|
Amendment 6
|
||||||
|
In all criminal prosecutions, the accused shall enjoy the right to a speedy and
|
||||||
|
public trial, by an impartial jury of the State and district wherein the crime
|
||||||
|
shall have been committed, which district shall have been previously
|
||||||
|
ascertained by law, and to be informed of the nature and cause of the
|
||||||
|
accusation; to be confronted with the witnesses against him; to have compulsory
|
||||||
|
process for obtaining witnesses in his favor, and to have the Assistance of
|
||||||
|
Counsel for his defence.
|
||||||
|
|
||||||
|
Amendment 7
|
||||||
|
In Suits at common law, where the value in controversy shall exceed twenty
|
||||||
|
dollars, the right of trial by jury shall be preserved, and no fact tried by a
|
||||||
|
jury, shall be otherwise re-examined in any Court of the United States, than
|
||||||
|
according to the rules of the common law.
|
||||||
|
|
||||||
|
Amendment 8
|
||||||
|
Excessive bail shall not be required, nor excessive fines imposed, nor cruel
|
||||||
|
and unusual punishments inflicted.
|
||||||
|
|
||||||
|
Amendment 9
|
||||||
|
The enumeration in the Constitution, of certain rights, shall not be construed
|
||||||
|
to deny or disparage others retained by the people.
|
||||||
|
|
||||||
|
Amendment 10
|
||||||
|
The powers not delegated to the United States by the Constitution, nor
|
||||||
|
prohibited by it to the States, are reserved to the States respectively, or to
|
||||||
|
the people.
|
||||||
|
|
||||||
|
Amendment 11
|
||||||
|
The Judicial power of the United States shall not be construed to extend to any
|
||||||
|
suit in law or equity, commenced or prosecuted against one of the United States
|
||||||
|
by Citizens of another State, or by Citizens or Subjects of any Foreign State.
|
||||||
|
|
||||||
|
Amendment 12
|
||||||
|
The Electors shall meet in their respective states, and vote by ballot for
|
||||||
|
President and Vice-President, one of whom, at least, shall not be an inhabitant
|
||||||
|
of the same state with themselves; they shall name in their ballots the person
|
||||||
|
voted for as President, and in distinct ballots the person voted for as
|
||||||
|
Vice-President, and they shall make distinct lists of all persons voted for as
|
||||||
|
President, and of all persons voted for as Vice-President and of the number of
|
||||||
|
votes for each, which lists they shall sign and certify, and transmit sealed to
|
||||||
|
the seat of the government of the United States, directed to the President of
|
||||||
|
the Senate;
|
||||||
|
|
||||||
|
The President of the Senate shall, in the presence of the Senate and House of
|
||||||
|
Representatives, open all the certificates and the votes shall then be counted;
|
||||||
|
|
||||||
|
The person having the greatest Number of votes for President, shall be the
|
||||||
|
President, if such number be a majority of the whole number of Electors
|
||||||
|
appointed; and if no person have such majority, then from the persons having
|
||||||
|
the highest numbers not exceeding three on the list of those voted for as
|
||||||
|
President, the House of Representatives shall choose immediately, by ballot,
|
||||||
|
the President. But in choosing the President, the votes shall be taken by
|
||||||
|
states, the representation from each state having one vote; a quorum for this
|
||||||
|
purpose shall consist of a member or members from two-thirds of the states, and
|
||||||
|
a majority of all the states shall be necessary to a choice. And if the House
|
||||||
|
of Representatives shall not choose a President whenever the right of choice
|
||||||
|
shall devolve upon them, before the fourth day of March next following, then
|
||||||
|
the Vice-President shall act as President, as in the case of the death or other
|
||||||
|
constitutional disability of the President.
|
||||||
|
|
||||||
|
The person having the greatest number of votes as Vice-President, shall be the
|
||||||
|
Vice-President, if such number be a majority of the whole number of Electors
|
||||||
|
appointed, and if no person have a majority, then from the two highest numbers
|
||||||
|
on the list, the Senate shall choose the Vice-President; a quorum for the
|
||||||
|
purpose shall consist of two-thirds of the whole number of Senators, and a
|
||||||
|
majority of the whole number shall be necessary to a choice. But no person
|
||||||
|
constitutionally ineligible to the office of President shall be eligible to
|
||||||
|
that of Vice-President of the United States.
|
||||||
|
|
||||||
|
Amendment 13
|
||||||
|
1. Neither slavery nor involuntary servitude, except as a punishment for crime
|
||||||
|
whereof the party shall have been duly convicted, shall exist within the United
|
||||||
|
States, or any place subject to their jurisdiction.
|
||||||
|
|
||||||
|
2. Congress shall have power to enforce this article by appropriate
|
||||||
|
legislation.
|
||||||
|
|
||||||
|
Amendment 14
|
||||||
|
1. All persons born or naturalized in the United States, and subject to the
|
||||||
|
jurisdiction thereof, are citizens of the United States and of the State
|
||||||
|
wherein they reside. No State shall make or enforce any law which shall abridge
|
||||||
|
the privileges or immunities of citizens of the United States; nor shall any
|
||||||
|
State deprive any person of life, liberty, or property, without due process of
|
||||||
|
law; nor deny to any person within its jurisdiction the equal protection of the
|
||||||
|
laws.
|
||||||
|
|
||||||
|
2. Representatives shall be apportioned among the several States according to
|
||||||
|
their respective numbers, counting the whole number of persons in each State,
|
||||||
|
excluding Indians not taxed. But when the right to vote at any election for the
|
||||||
|
choice of electors for President and Vice-President of the United States,
|
||||||
|
Representatives in Congress, the Executive and Judicial officers of a State, or
|
||||||
|
the members of the Legislature thereof, is denied to any of the male
|
||||||
|
inhabitants of such State, being twenty-one years of age, and citizens of the
|
||||||
|
United States, or in any way abridged, except for participation in rebellion,
|
||||||
|
or other crime, the basis of representation therein shall be reduced in the
|
||||||
|
proportion which the number of such male citizens shall bear to the whole
|
||||||
|
number of male citizens twenty-one years of age in such State.
|
||||||
|
|
||||||
|
3. No person shall be a Senator or Representative in Congress, or elector of
|
||||||
|
President and Vice-President, or hold any office, civil or military, under the
|
||||||
|
United States, or under any State, who, having previously taken an oath, as a
|
||||||
|
member of Congress, or as an officer of the United States, or as a member of
|
||||||
|
any State legislature, or as an executive or judicial officer of any State, to
|
||||||
|
support the Constitution of the United States, shall have engaged in
|
||||||
|
insurrection or rebellion against the same, or given aid or comfort to the
|
||||||
|
enemies thereof. But Congress may by a vote of two-thirds of each House, remove
|
||||||
|
such disability.
|
||||||
|
|
||||||
|
4. The validity of the public debt of the United States, authorized by law,
|
||||||
|
including debts incurred for payment of pensions and bounties for services in
|
||||||
|
suppressing insurrection or rebellion, shall not be questioned. But neither the
|
||||||
|
United States nor any State shall assume or pay any debt or obligation incurred
|
||||||
|
in aid of insurrection or rebellion against the United States, or any claim for
|
||||||
|
the loss or emancipation of any slave; but all such debts, obligations and
|
||||||
|
claims shall be held illegal and void.
|
||||||
|
|
||||||
|
5. The Congress shall have power to enforce, by appropriate legislation, the
|
||||||
|
provisions of this article.
|
||||||
|
|
||||||
|
Amendment 15
|
||||||
|
1. The right of citizens of the United States to vote shall not be denied or
|
||||||
|
abridged by the United States or by any State on account of race, color, or
|
||||||
|
previous condition of servitude.
|
||||||
|
|
||||||
|
2. The Congress shall have power to enforce this article by appropriate
|
||||||
|
legislation.
|
||||||
|
|
||||||
|
Amendment 16
|
||||||
|
The Congress shall have power to lay and collect taxes on incomes, from
|
||||||
|
whatever source derived, without apportionment among the several States, and
|
||||||
|
without regard to any census or enumeration.
|
||||||
|
|
||||||
|
Amendment 17
|
||||||
|
The Senate of the United States shall be composed of two Senators from each
|
||||||
|
State, elected by the people thereof, for six years; and each Senator shall
|
||||||
|
have one vote. The electors in each State shall have the qualifications
|
||||||
|
requisite for electors of the most numerous branch of the State legislatures.
|
||||||
|
|
||||||
|
When vacancies happen in the representation of any State in the Senate, the
|
||||||
|
executive authority of such State shall issue writs of election to fill such
|
||||||
|
vacancies: Provided, That the legislature of any State may empower the
|
||||||
|
executive thereof to make temporary appointments until the people fill the
|
||||||
|
vacancies by election as the legislature may direct.
|
||||||
|
|
||||||
|
This amendment shall not be so construed as to affect the election or term of
|
||||||
|
any Senator chosen before it becomes valid as part of the Constitution.
|
||||||
|
|
||||||
|
Amendment 18
|
||||||
|
1. After one year from the ratification of this article the manufacture, sale,
|
||||||
|
or transportation of intoxicating liquors within, the importation thereof into,
|
||||||
|
or the exportation thereof from the United States and all territory subject to
|
||||||
|
the jurisdiction thereof for beverage purposes is hereby prohibited.
|
||||||
|
|
||||||
|
2. The Congress and the several States shall have concurrent power to enforce
|
||||||
|
this article by appropriate legislation.
|
||||||
|
|
||||||
|
3. This article shall be inoperative unless it shall have been ratified as an
|
||||||
|
amendment to the Constitution by the legislatures of the several States, as
|
||||||
|
provided in the Constitution, within seven years from the date of the
|
||||||
|
submission hereof to the States by the Congress.
|
||||||
|
|
||||||
|
Amendment 19
|
||||||
|
The right of citizens of the United States to vote shall not be denied or
|
||||||
|
abridged by the United States or by any State on account of sex.
|
||||||
|
|
||||||
|
Congress shall have power to enforce this article by appropriate legislation.
|
||||||
|
|
||||||
|
Amendment 20
|
||||||
|
1. The terms of the President and Vice President shall end at noon on the 20th
|
||||||
|
day of January, and the terms of Senators and Representatives at noon on the 3d
|
||||||
|
day of January, of the years in which such terms would have ended if this
|
||||||
|
article had not been ratified; and the terms of their successors shall then
|
||||||
|
begin.
|
||||||
|
|
||||||
|
2. The Congress shall assemble at least once in every year, and such meeting
|
||||||
|
shall begin at noon on the 3d day of January, unless they shall by law appoint
|
||||||
|
a different day.
|
||||||
|
|
||||||
|
3. If, at the time fixed for the beginning of the term of the President, the
|
||||||
|
President elect shall have died, the Vice President elect shall become
|
||||||
|
President. If a President shall not have been chosen before the time fixed for
|
||||||
|
the beginning of his term, or if the President elect shall have failed to
|
||||||
|
qualify, then the Vice President elect shall act as President until a President
|
||||||
|
shall have qualified; and the Congress may by law provide for the case wherein
|
||||||
|
neither a President elect nor a Vice President elect shall have qualified,
|
||||||
|
declaring who shall then act as President, or the manner in which one who is to
|
||||||
|
act shall be selected, and such person shall act accordingly until a President
|
||||||
|
or Vice President shall have qualified.
|
||||||
|
|
||||||
|
4. The Congress may by law provide for the case of the death of any of the
|
||||||
|
persons from whom the House of Representatives may choose a President whenever
|
||||||
|
the right of choice shall have devolved upon them, and for the case of the
|
||||||
|
death of any of the persons from whom the Senate may choose a Vice President
|
||||||
|
whenever the right of choice shall have devolved upon them.
|
||||||
|
|
||||||
|
5. Sections 1 and 2 shall take effect on the 15th day of October following the
|
||||||
|
ratification of this article.
|
||||||
|
|
||||||
|
6. This article shall be inoperative unless it shall have been ratified as an
|
||||||
|
amendment to the Constitution by the legislatures of three-fourths of the
|
||||||
|
several States within seven years from the date of its submission.
|
||||||
|
|
||||||
|
Amendment 21
|
||||||
|
1. The eighteenth article of amendment to the Constitution of the United States
|
||||||
|
is hereby repealed.
|
||||||
|
|
||||||
|
2. The transportation or importation into any State, Territory, or possession
|
||||||
|
of the United States for delivery or use therein of intoxicating liquors, in
|
||||||
|
violation of the laws thereof, is hereby prohibited.
|
||||||
|
|
||||||
|
3. The article shall be inoperative unless it shall have been ratified as an
|
||||||
|
amendment to the Constitution by conventions in the several States, as provided
|
||||||
|
in the Constitution, within seven years from the date of the submission hereof
|
||||||
|
to the States by the Congress.
|
||||||
|
|
||||||
|
Amendment 22
|
||||||
|
1. No person shall be elected to the office of the President more than twice,
|
||||||
|
and no person who has held the office of President, or acted as President, for
|
||||||
|
more than two years of a term to which some other person was elected President
|
||||||
|
shall be elected to the office of the President more than once. But this
|
||||||
|
Article shall not apply to any person holding the office of President, when this
|
||||||
|
Article was proposed by the Congress, and shall not prevent any person who may
|
||||||
|
be holding the office of President, or acting as President, during the term
|
||||||
|
within which this Article becomes operative from holding the office of
|
||||||
|
President or acting as President during the remainder of such term.
|
||||||
|
|
||||||
|
2. This article shall be inoperative unless it shall have been ratified as an
|
||||||
|
amendment to the Constitution by the legislatures of three-fourths of the
|
||||||
|
several States within seven years from the date of its submission to the States
|
||||||
|
by the Congress.
|
||||||
|
|
||||||
|
Amendment 23
|
||||||
|
1. The District constituting the seat of Government of the United States shall
|
||||||
|
appoint in such manner as the Congress may direct: A number of electors of
|
||||||
|
President and Vice President equal to the whole number of Senators and
|
||||||
|
Representatives in Congress to which the District would be entitled if it were
|
||||||
|
a State, but in no event more than the least populous State; they shall be in
|
||||||
|
addition to those appointed by the States, but they shall be considered, for
|
||||||
|
the purposes of the election of President and Vice President, to be electors
|
||||||
|
appointed by a State; and they shall meet in the District and perform such
|
||||||
|
duties as provided by the twelfth article of amendment.
|
||||||
|
|
||||||
|
2. The Congress shall have power to enforce this article by appropriate
|
||||||
|
legislation.
|
||||||
|
|
||||||
|
Amendment 24
|
||||||
|
1. The right of citizens of the United States to vote in any primary or other
|
||||||
|
election for President or Vice President, for electors for President or
|
||||||
|
Vice President, or for Senator or Representative in Congress, shall not be
|
||||||
|
denied or abridged by the United States or any State by reason of failure to
|
||||||
|
pay any poll tax or other tax.
|
||||||
|
|
||||||
|
2. The Congress shall have power to enforce this article by appropriate
|
||||||
|
legislation.
|
||||||
|
|
||||||
|
Amendment 25
|
||||||
|
1. In case of the removal of the President from office or of his death or
|
||||||
|
resignation, the Vice President shall become President.
|
||||||
|
|
||||||
|
2. Whenever there is a vacancy in the office of the Vice President, the
|
||||||
|
President shall nominate a Vice President who shall take office upon
|
||||||
|
confirmation by a majority vote of both Houses of Congress.
|
||||||
|
|
||||||
|
3. Whenever the President transmits to the President pro tempore of the Senate
|
||||||
|
and the Speaker of the House of Representatives his written declaration that he
|
||||||
|
is unable to discharge the powers and duties of his office, and until he
|
||||||
|
transmits to them a written declaration to the contrary, such powers and duties
|
||||||
|
shall be discharged by the Vice President as Acting President.
|
||||||
|
|
||||||
|
4. Whenever the Vice President and a majority of either the principal officers
|
||||||
|
of the executive departments or of such other body as Congress may by law
|
||||||
|
provide, transmit to the President pro tempore of the Senate and the Speaker of
|
||||||
|
the House of Representatives their written declaration that the President is
|
||||||
|
unable to discharge the powers and duties of his office, the Vice President
|
||||||
|
shall immediately assume the powers and duties of the office as Acting
|
||||||
|
President.
|
||||||
|
|
||||||
|
Thereafter, when the President transmits to the President pro tempore of the
|
||||||
|
Senate and the Speaker of the House of Representatives his written declaration
|
||||||
|
that no inability exists, he shall resume the powers and duties of his office
|
||||||
|
unless the Vice President and a majority of either the principal officers of
|
||||||
|
the executive department or of such other body as Congress may by law provide,
|
||||||
|
transmit within four days to the President pro tempore of the Senate and the
|
||||||
|
Speaker of the House of Representatives their written declaration that the
|
||||||
|
President is unable to discharge the powers and duties of his office. Thereupon
|
||||||
|
Congress shall decide the issue, assembling within forty eight hours for that
|
||||||
|
purpose if not in session. If the Congress, within twenty one days after
|
||||||
|
receipt of the latter written declaration, or, if Congress is not in session,
|
||||||
|
within twenty one days after Congress is required to assemble, determines by
|
||||||
|
two thirds vote of both Houses that the President is unable to discharge the
|
||||||
|
powers and duties of his office, the Vice President shall continue to discharge
|
||||||
|
the same as Acting President; otherwise, the President shall resume the powers
|
||||||
|
and duties of his office.
|
||||||
|
|
||||||
|
Amendment 26
|
||||||
|
1. The right of citizens of the United States, who are eighteen years of age or
|
||||||
|
older, to vote shall not be denied or abridged by the United States or by any
|
||||||
|
State on account of age.
|
||||||
|
|
||||||
|
2. The Congress shall have power to enforce this article by appropriate
|
||||||
|
legislation.
|
||||||
|
|
||||||
|
Amendment 27
|
||||||
|
No law, varying the compensation for the services of the Senators and
|
||||||
|
Representatives, shall take effect, until an election of Representatives shall
|
||||||
|
have intervened.
|
|
@ -26,11 +26,11 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.bouncycastle.crypto.Digest;
|
import org.bouncycastle.crypto.Digest;
|
||||||
|
@ -50,12 +50,12 @@ import org.jclouds.io.payloads.ByteArrayPayload;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
public BouncyCastleEncryptionService(KeyFactory rsaKeyFactory) {
|
public BouncyCastleEncryptionService(KeyFactory rsaKeyFactory, CertificateFactory certFactory) {
|
||||||
super(rsaKeyFactory);
|
super(rsaKeyFactory, certFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BouncyCastleEncryptionService() throws NoSuchAlgorithmException {
|
public BouncyCastleEncryptionService() throws NoSuchAlgorithmException, CertificateException {
|
||||||
super(KeyFactory.getInstance("RSA"));
|
this(KeyFactory.getInstance("RSA"), CertificateFactory.getInstance("X.509"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -189,17 +189,4 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
|
||||||
return resBuf;
|
return resBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] rsaSign(String toSign, Key key) {
|
|
||||||
// TODO convert this to BC code
|
|
||||||
try {
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
||||||
return cipher.doFinal(toSign.getBytes());
|
|
||||||
} catch (Exception e) {
|
|
||||||
propagate(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.ws.rs.HttpMethod;
|
import javax.ws.rs.HttpMethod;
|
||||||
|
@ -60,6 +61,8 @@ public class ConvertToGaeRequestTest {
|
||||||
encryptionService = new JCEEncryptionService();
|
encryptionService = new JCEEncryptionService();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -59,6 +60,8 @@ public class ConvertToJcloudsResponseTest {
|
||||||
encryptionService = new JCEEncryptionService();
|
encryptionService = new JCEEncryptionService();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,14 +38,12 @@ import org.jclouds.chef.domain.Organization;
|
||||||
import org.jclouds.chef.domain.User;
|
import org.jclouds.chef.domain.User;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
import org.jclouds.chef.functions.OrganizationName;
|
import org.jclouds.chef.functions.OrganizationName;
|
||||||
import org.jclouds.chef.functions.ParseKeyFromJson;
|
|
||||||
import org.jclouds.chef.functions.Username;
|
import org.jclouds.chef.functions.Username;
|
||||||
import org.jclouds.rest.annotations.BinderParam;
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
import org.jclouds.rest.annotations.Delegate;
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
@ -74,9 +72,7 @@ public interface OpscodePlatformAsyncClient {
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/users")
|
@Path("/users")
|
||||||
@ResponseParser(ParseKeyFromJson.class)
|
ListenableFuture<User> createUser(@BinderParam(BindToJsonPayload.class) User user);
|
||||||
ListenableFuture<String> createUser(
|
|
||||||
@BinderParam(BindToJsonPayload.class) User user);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ChefClient#updateUser
|
* @see ChefClient#updateUser
|
||||||
|
@ -110,9 +106,7 @@ public interface OpscodePlatformAsyncClient {
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/organizations")
|
@Path("/organizations")
|
||||||
@ResponseParser(ParseKeyFromJson.class)
|
ListenableFuture<Organization> createOrg(@BinderParam(BindToJsonPayload.class) Organization org);
|
||||||
ListenableFuture<String> createOrg(
|
|
||||||
@BinderParam(BindToJsonPayload.class) Organization org);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ChefClient#updateOrg
|
* @see ChefClient#updateOrg
|
||||||
|
|
|
@ -64,7 +64,7 @@ public interface OpscodePlatformClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to create a user.
|
* "403 Forbidden" if the caller is not authorized to create a user.
|
||||||
*/
|
*/
|
||||||
String createUser(User user);
|
User createUser(User user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates an existing user. Note: you must have update rights on the user.
|
* updates an existing user. Note: you must have update rights on the user.
|
||||||
|
@ -109,7 +109,7 @@ public interface OpscodePlatformClient {
|
||||||
* <p/>
|
* <p/>
|
||||||
* "403 Forbidden" if the caller is not authorized to create a organization.
|
* "403 Forbidden" if the caller is not authorized to create a organization.
|
||||||
*/
|
*/
|
||||||
String createOrg(Organization organization);
|
Organization createOrg(Organization organization);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates an existing organization. Note: you must have update rights on the organization.
|
* updates an existing organization. Note: you must have update rights on the organization.
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.opscodeplatform;
|
package org.jclouds.opscodeplatform;
|
||||||
|
|
||||||
import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor;
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.jclouds.concurrent.ConcurrentUtils.sameThreadExecutor;
|
||||||
import static org.jclouds.rest.RestContextFactory.createContextBuilder;
|
import static org.jclouds.rest.RestContextFactory.createContextBuilder;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ import org.jclouds.chef.domain.Organization;
|
||||||
import org.jclouds.chef.domain.User;
|
import org.jclouds.chef.domain.User;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuthTest;
|
import org.jclouds.chef.filters.SignedHeaderAuthTest;
|
||||||
import org.jclouds.chef.functions.ParseKeyFromJson;
|
|
||||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.date.TimeStamp;
|
import org.jclouds.date.TimeStamp;
|
||||||
|
@ -111,18 +110,21 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
|
||||||
|
|
||||||
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
|
assertRequestLineEquals(httpRequest, "POST https://api.opscode.com/users HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(httpRequest, new StringBuilder("Accept: application/json").append("\n").append(
|
assertNonPayloadHeadersEqual(httpRequest, new StringBuilder("Accept: application/json").append("\n").append(
|
||||||
"X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n").append(
|
"X-Ops-Authorization-1: kfrkDpfgNU26k70R1vl1bEWk0Q0f9Fs/3kxOX7gHd7iNoJq03u7RrcrAOSgL").append("\n")
|
||||||
"X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append("\n").append(
|
.append("X-Ops-Authorization-2: ETj5JNeCk18BmFkHMAbCA9hXVo1T4rlHCpbuzAzFlFxUGAT4wj8UoO7V886X").append(
|
||||||
"X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append("\n").append(
|
"\n").append(
|
||||||
"X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append("\n").append(
|
"X-Ops-Authorization-3: Kf8DvihP6ElthCNuu1xuhN0B4GEmWC9+ut7UMLe0L2T34VzkbCtuInGbf42/").append(
|
||||||
"X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").append("\n").append(
|
"\n").append(
|
||||||
"X-Ops-Authorization-6: 2+BFLT5o6P6G0D+eCu3zSuaqEJRucPJPaDGWdKIMag==").append("\n").append(
|
"X-Ops-Authorization-4: G7iu94/xFOT1gN9cex4pNyTnRCHzob4JVU1usxt/2g5grN2SyYwRS5+4MNLN").append(
|
||||||
"X-Ops-Content-Hash: yLHOxvgIEtNw5UrZDxslOeMw1gw=").append("\n").append("X-Ops-Sign: version=1.0").append(
|
"\n").append(
|
||||||
"\n").append("X-Ops-Timestamp: timestamp").append("\n").append("X-Ops-Userid: user").append("\n")
|
"X-Ops-Authorization-5: WY/iLUPb/9dwtiIQsnUOXqDrs28zNswZulQW4AzYRd7MczJVKU4y4+4XRcB4").append(
|
||||||
.toString());
|
"\n").append("X-Ops-Authorization-6: 2+BFLT5o6P6G0D+eCu3zSuaqEJRucPJPaDGWdKIMag==")
|
||||||
|
.append("\n").append("X-Ops-Content-Hash: yLHOxvgIEtNw5UrZDxslOeMw1gw=").append("\n").append(
|
||||||
|
"X-Ops-Sign: version=1.0").append("\n").append("X-Ops-Timestamp: timestamp").append("\n")
|
||||||
|
.append("X-Ops-Userid: user").append("\n").toString());
|
||||||
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}", "application/json", false);
|
assertPayloadEquals(httpRequest, "{\"username\":\"myuser\"}", "application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
|
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
@ -188,7 +190,7 @@ public class OpscodePlatformAsyncClientTest extends RestClientTest<OpscodePlatfo
|
||||||
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
|
||||||
assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}", "application/json", false);
|
assertPayloadEquals(httpRequest, "{\"name\":\"myorganization\"}", "application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
|
assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
assertExceptionParserClassEquals(method, null);
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
|
|
@ -67,12 +67,11 @@ public class OpscodePlatformClientLiveTest {
|
||||||
String keyfile = System.getProperty("jclouds.test.credential");
|
String keyfile = System.getProperty("jclouds.test.credential");
|
||||||
if (keyfile == null || keyfile.equals(""))
|
if (keyfile == null || keyfile.equals(""))
|
||||||
keyfile = "/etc/chef/validation.pem";
|
keyfile = "/etc/chef/validation.pem";
|
||||||
validatorConnection = createConnection(orgname + "-validator", Files.toString(new File(
|
validatorConnection = createConnection(orgname + "-validator", Files.toString(new File(keyfile), Charsets.UTF_8));
|
||||||
keyfile), Charsets.UTF_8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestContext<OpscodePlatformClient, OpscodePlatformAsyncClient> createConnection(
|
private RestContext<OpscodePlatformClient, OpscodePlatformAsyncClient> createConnection(String identity, String key)
|
||||||
String identity, String key) throws IOException {
|
throws IOException {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
return new RestContextFactory().createContext("opscodeplatform", identity, key, ImmutableSet
|
return new RestContextFactory().createContext("opscodeplatform", identity, key, ImmutableSet
|
||||||
.<Module> of(new Log4JLoggingModule()), props);
|
.<Module> of(new Log4JLoggingModule()), props);
|
||||||
|
@ -88,7 +87,8 @@ public class OpscodePlatformClientLiveTest {
|
||||||
@Test(dependsOnMethods = "testListClientsInOrg")
|
@Test(dependsOnMethods = "testListClientsInOrg")
|
||||||
public void testCreateClientInOrg() throws Exception {
|
public void testCreateClientInOrg() throws Exception {
|
||||||
validatorConnection.getApi().getChefClientForOrg(orgname).deleteClient(PREFIX);
|
validatorConnection.getApi().getChefClientForOrg(orgname).deleteClient(PREFIX);
|
||||||
clientKey = validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX);
|
clientKey = validatorConnection.utils().encryption().toPem(
|
||||||
|
validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX).getPrivateKey());
|
||||||
assertNotNull(clientKey);
|
assertNotNull(clientKey);
|
||||||
System.out.println(clientKey);
|
System.out.println(clientKey);
|
||||||
clientConnection = createConnection(PREFIX, clientKey);
|
clientConnection = createConnection(PREFIX, clientKey);
|
||||||
|
@ -97,8 +97,8 @@ public class OpscodePlatformClientLiveTest {
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateClientInOrg")
|
@Test(dependsOnMethods = "testCreateClientInOrg")
|
||||||
public void testGenerateKeyForClientInOrg() throws Exception {
|
public void testGenerateKeyForClientInOrg() throws Exception {
|
||||||
clientKey = validatorConnection.getApi().getChefClientForOrg(orgname).generateKeyForClient(
|
clientKey = validatorConnection.utils().encryption().toPem(
|
||||||
PREFIX);
|
validatorConnection.getApi().getChefClientForOrg(orgname).createClient(PREFIX).getPrivateKey());
|
||||||
assertNotNull(clientKey);
|
assertNotNull(clientKey);
|
||||||
clientConnection.close();
|
clientConnection.close();
|
||||||
clientConnection = createConnection(PREFIX, clientKey);
|
clientConnection = createConnection(PREFIX, clientKey);
|
||||||
|
|
|
@ -27,7 +27,6 @@ import static org.testng.Assert.fail;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
@ -36,8 +35,6 @@ import java.util.concurrent.TimeoutException;
|
||||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||||
import org.jclouds.blobstore.domain.PageSet;
|
import org.jclouds.blobstore.domain.PageSet;
|
||||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||||
import org.jclouds.encryption.EncryptionService;
|
|
||||||
import org.jclouds.encryption.internal.JCEEncryptionService;
|
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.options.GetOptions;
|
import org.jclouds.http.options.GetOptions;
|
||||||
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
|
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
|
||||||
|
@ -52,7 +49,6 @@ import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
@ -64,15 +60,6 @@ import com.google.common.collect.Maps;
|
||||||
@Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest")
|
@Test(groups = "live", testName = "cloudfiles.CloudFilesClientLiveTest")
|
||||||
public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
|
|
||||||
protected volatile static EncryptionService encryptionService;
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
encryptionService = new JCEEncryptionService();
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
Throwables.propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloudFilesClient getApi() {
|
public CloudFilesClient getApi() {
|
||||||
return (CloudFilesClient) context.getProviderSpecificContext().getApi();
|
return (CloudFilesClient) context.getProviderSpecificContext().getApi();
|
||||||
}
|
}
|
||||||
|
@ -208,8 +195,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
|
|
||||||
// Test listing with options
|
// Test listing with options
|
||||||
response = getApi().listContainers(
|
response = getApi().listContainers(
|
||||||
ListContainerOptions.Builder.afterMarker(containerNames[0].substring(0, containerNames[0].length() - 1))
|
ListContainerOptions.Builder.afterMarker(
|
||||||
.maxResults(1));
|
containerNames[0].substring(0, containerNames[0].length() - 1)).maxResults(1));
|
||||||
assertEquals(response.size(), 1);
|
assertEquals(response.size(), 1);
|
||||||
assertEquals(Iterables.get(response, 0).getName(), containerNames[0]);
|
assertEquals(Iterables.get(response, 0).getName(), containerNames[0]);
|
||||||
|
|
||||||
|
@ -316,7 +303,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
byte[] md5 = object.getPayload().getContentMD5();
|
byte[] md5 = object.getPayload().getContentMD5();
|
||||||
String newEtag = getApi().putObject(containerName, object);
|
String newEtag = getApi().putObject(containerName, object);
|
||||||
assert newEtag != null;
|
assert newEtag != null;
|
||||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getPayload().getContentMD5()));
|
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
|
||||||
|
object.getPayload().getContentMD5()));
|
||||||
|
|
||||||
// Test HEAD of missing object
|
// Test HEAD of missing object
|
||||||
assert getApi().getObjectInfo(containerName, "non-existent-object") == null;
|
assert getApi().getObjectInfo(containerName, "non-existent-object") == null;
|
||||||
|
@ -332,8 +320,8 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// assertEquals(metadata.getBytes(), new Long(data.length()));
|
// assertEquals(metadata.getBytes(), new Long(data.length()));
|
||||||
// assertEquals(metadata.getContentType(), "text/plain");
|
// assertEquals(metadata.getContentType(), "text/plain");
|
||||||
|
|
||||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(metadata.getHash()));
|
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(metadata.getHash()));
|
||||||
assertEquals(metadata.getHash(), encryptionService.fromHex(newEtag));
|
assertEquals(metadata.getHash(), context.utils().encryption().fromHex(newEtag));
|
||||||
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
||||||
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
|
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
|
||||||
|
|
||||||
|
@ -352,8 +340,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// object.getMetadata().getName());
|
// object.getMetadata().getName());
|
||||||
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
|
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
|
||||||
assertEquals(getBlob.getInfo().getContentType(), "text/plain");
|
assertEquals(getBlob.getInfo().getContentType(), "text/plain");
|
||||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getInfo().getHash()));
|
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
|
||||||
assertEquals(encryptionService.fromHex(newEtag), getBlob.getInfo().getHash());
|
getBlob.getInfo().getHash()));
|
||||||
|
assertEquals(context.utils().encryption().fromHex(newEtag), getBlob.getInfo().getHash());
|
||||||
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
|
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
|
||||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
|
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
|
||||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
|
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
|
||||||
|
@ -362,7 +351,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// transit)
|
// transit)
|
||||||
String correctEtag = newEtag;
|
String correctEtag = newEtag;
|
||||||
String incorrectEtag = "0" + correctEtag.substring(1);
|
String incorrectEtag = "0" + correctEtag.substring(1);
|
||||||
object.getInfo().setHash(encryptionService.fromHex(incorrectEtag));
|
object.getInfo().setHash(context.utils().encryption().fromHex(incorrectEtag));
|
||||||
try {
|
try {
|
||||||
getApi().putObject(containerName, object);
|
getApi().putObject(containerName, object);
|
||||||
} catch (HttpResponseException e) {
|
} catch (HttpResponseException e) {
|
||||||
|
@ -375,13 +364,15 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
blob.getInfo().setName("chunked-object");
|
blob.getInfo().setName("chunked-object");
|
||||||
blob.setPayload(bais);
|
blob.setPayload(bais);
|
||||||
newEtag = getApi().putObject(containerName, blob);
|
newEtag = getApi().putObject(containerName, blob);
|
||||||
assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getInfo().getHash()));
|
assertEquals(context.utils().encryption().hex(md5), context.utils().encryption().hex(
|
||||||
|
getBlob.getInfo().getHash()));
|
||||||
|
|
||||||
// Test GET with options
|
// Test GET with options
|
||||||
// Non-matching ETag
|
// Non-matching ETag
|
||||||
try {
|
try {
|
||||||
getApi()
|
getApi()
|
||||||
.getObject(containerName, object.getInfo().getName(), GetOptions.Builder.ifETagDoesntMatch(newEtag));
|
.getObject(containerName, object.getInfo().getName(),
|
||||||
|
GetOptions.Builder.ifETagDoesntMatch(newEtag));
|
||||||
} catch (HttpResponseException e) {
|
} catch (HttpResponseException e) {
|
||||||
assertEquals(e.getResponse().getStatusCode(), 304);
|
assertEquals(e.getResponse().getStatusCode(), 304);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +380,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// Matching ETag
|
// Matching ETag
|
||||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
||||||
GetOptions.Builder.ifETagMatches(newEtag));
|
GetOptions.Builder.ifETagMatches(newEtag));
|
||||||
assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHex(newEtag));
|
assertEquals(getBlob.getInfo().getHash(), context.utils().encryption().fromHex(newEtag));
|
||||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
|
getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
|
||||||
assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8));
|
assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue