33import static org .hamcrest .MatcherAssert .assertThat ;
44import static org .hamcrest .Matchers .containsString ;
55import static org .hamcrest .Matchers .equalTo ;
6+ import static org .hamcrest .Matchers .greaterThan ;
67import static org .hamcrest .Matchers .hasSize ;
8+ import static org .hamcrest .Matchers .instanceOf ;
79import static org .hamcrest .Matchers .not ;
10+ import static org .hamcrest .Matchers .notNullValue ;
811
912import com .cloudbees .jenkins .plugins .sshcredentials .impl .BasicSSHUserPrivateKey ;
1013import com .cloudbees .jenkins .plugins .sshcredentials .impl .BasicSSHUserPrivateKey .DirectEntryPrivateKeySource ;
1114import com .cloudbees .plugins .credentials .CredentialsProvider ;
1215import com .cloudbees .plugins .credentials .common .CertificateCredentials ;
1316import com .cloudbees .plugins .credentials .common .UsernamePasswordCredentials ;
17+ import com .cloudbees .plugins .credentials .impl .CertificateCredentialsImpl ;
18+ import com .cloudbees .plugins .credentials .impl .CertificateCredentialsImpl .UploadedKeyStoreSource ;
1419import hudson .security .ACL ;
1520import io .jenkins .plugins .casc .impl .configurators .DataBoundConfigurator ;
1621import io .jenkins .plugins .casc .misc .ConfiguredWithCode ;
1722import io .jenkins .plugins .casc .misc .JenkinsConfiguredWithCodeRule ;
1823import io .jenkins .plugins .casc .model .CNode ;
24+ import java .net .URL ;
25+ import java .nio .file .Files ;
26+ import java .nio .file .Paths ;
27+ import java .security .KeyStore ;
28+ import java .security .cert .X509Certificate ;
29+ import java .util .Base64 ;
1930import java .util .Collections ;
31+ import java .util .Enumeration ;
2032import java .util .List ;
2133import java .util .logging .Level ;
2234import java .util .logging .LogRecord ;
@@ -41,7 +53,8 @@ public class SystemCredentialsTest {
4153 public RuleChain chain = RuleChain .outerRule (new EnvironmentVariables ()
4254 .set ("SUDO_PASSWORD" , "1234" )
4355 .set ("SSH_PRIVATE_KEY" , "s3cr3t" )
44- .set ("SSH_KEY_PASSWORD" , "ABCD" ))
56+ .set ("SSH_KEY_PASSWORD" , "123456" )
57+ .set ("CERTIFICATE_BASE64" , getBase64Keystore ()))
4558 .around (log )
4659 .around (new JenkinsConfiguredWithCodeRule ());
4760
@@ -63,16 +76,42 @@ public void configure_system_credentials() throws Exception {
6376
6477 List <CertificateCredentials > certs = CredentialsProvider .lookupCredentials (
6578 CertificateCredentials .class , jenkins , ACL .SYSTEM , Collections .emptyList ());
66- assertThat (certs , hasSize (0 ));
67- // TODO: add test for uploaded certificate
68- // assertThat(certs.get(0).getPassword().getPlainText(), equalTo("ABCD"));
79+ assertThat (certs , hasSize (1 ));
80+
81+ CertificateCredentialsImpl certImpl = (CertificateCredentialsImpl ) certs .get (0 );
82+ assertThat (certImpl .getId (), equalTo ("uploaded_certificate" ));
83+ assertThat (certImpl .getPassword ().getPlainText (), equalTo ("123456" ));
84+ assertThat (certImpl .getKeyStoreSource (), notNullValue ());
85+ assertThat (certImpl .getKeyStoreSource (), instanceOf (UploadedKeyStoreSource .class ));
86+ assertThat (certImpl .getKeyStore (), notNullValue ());
87+ assertThat (certImpl .getKeyStore ().size (), greaterThan (0 ));
88+
89+ UploadedKeyStoreSource keyStoreSource = (UploadedKeyStoreSource ) certImpl .getKeyStoreSource ();
90+ assertThat (keyStoreSource .getUploadedKeystore (), notNullValue ());
91+
92+ byte [] expectedBytes = getRawKeystoreBytes ();
93+ byte [] actualBytes = keyStoreSource .getUploadedKeystore ().getPlainData ();
94+ assertThat ("The bytes in Jenkins should be identical to the source file" , actualBytes , equalTo (expectedBytes ));
95+
96+ KeyStore keyStore = certImpl .getKeyStore ();
97+ Enumeration <String > aliases = keyStore .aliases ();
98+ assertThat ("Keystore should not be empty" , aliases .hasMoreElements (), equalTo (true ));
99+
100+ String alias = aliases .nextElement ();
101+ X509Certificate certificate = (X509Certificate ) keyStore .getCertificate (alias );
102+ assertThat (certificate , notNullValue ());
103+
104+ String subject = certificate .getSubjectX500Principal ().getName ();
105+ assertThat (subject , containsString ("CN=Test" ));
106+
107+ assertThat (certificate .getType (), equalTo ("X.509" ));
69108
70109 List <BasicSSHUserPrivateKey > sshPrivateKeys = CredentialsProvider .lookupCredentials (
71110 BasicSSHUserPrivateKey .class , jenkins , ACL .SYSTEM , Collections .emptyList ());
72111 assertThat (sshPrivateKeys , hasSize (1 ));
73112
74113 final BasicSSHUserPrivateKey ssh_with_passphrase = sshPrivateKeys .get (0 );
75- assertThat (ssh_with_passphrase .getPassphrase ().getPlainText (), equalTo ("ABCD " ));
114+ assertThat (ssh_with_passphrase .getPassphrase ().getPlainText (), equalTo ("123456 " ));
76115
77116 final DirectEntryPrivateKeySource source =
78117 (DirectEntryPrivateKeySource ) ssh_with_passphrase .getPrivateKeySource ();
@@ -81,7 +120,23 @@ public void configure_system_credentials() throws Exception {
81120 // credentials should not appear in plain text in log
82121 for (LogRecord logRecord : log .getRecords ()) {
83122 assertThat (logRecord .getMessage (), not (containsString ("1234" )));
84- assertThat (logRecord .getMessage (), not (containsString ("ABCD" )));
123+ assertThat (logRecord .getMessage (), not (containsString ("123456" )));
124+ }
125+ }
126+
127+ private static String getBase64Keystore () {
128+ return Base64 .getEncoder ().encodeToString (getRawKeystoreBytes ());
129+ }
130+
131+ private static byte [] getRawKeystoreBytes () {
132+ try {
133+ URL res = SystemCredentialsTest .class .getResource ("test.p12" );
134+ if (res == null ) {
135+ throw new IllegalStateException ("Cannot find test.p12 on classpath" );
136+ }
137+ return Files .readAllBytes (Paths .get (res .toURI ()));
138+ } catch (Exception e ) {
139+ throw new RuntimeException ("Failed to read test.p12 from classpath" , e );
85140 }
86141 }
87142}
0 commit comments