Skip to content

Commit

Permalink
Merge branch 'master' into user-scoped-credentials-extension
Browse files Browse the repository at this point in the history
  • Loading branch information
jvz committed Aug 1, 2019
2 parents a25f413 + 742afde commit f3efa56
Show file tree
Hide file tree
Showing 30 changed files with 143 additions and 68 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Truths which we believe to be self-evident (adapted from [TextSecure's](https://
1. "hungarian"-style notation is banned (i.e. instance variable names preceded by an 'm', etc)
2. If the field is `static final` then it shall be named in `ALL_CAPS_WITH_UNDERSCORES`.
3. Start variable names with a lowercase letter and use camelCase rather than under_scores.
4. Spelling and abreviations: If the word is widely used in the JVM runtime, stick with the spelling/abreviation in the JVM runtime, e.g. `color` over `colour`, `sync` over `synch`, `async` over `asynch`, etc.
4. Spelling and abbreviations: If the word is widely used in the JVM runtime, stick with the spelling/abbreviation in the JVM runtime, e.g. `color` over `colour`, `sync` over `synch`, `async` over `asynch`, etc.
5. It is acceptable to use `i`, `j`, `k` for loop indices and iterators. If you need more than three, you are likely doing something wrong and as such you shall either use full descriptive names or refactor.
6. It is acceptable to use `e` for the exception in a `try...catch` block.
7. You shall never use `l` (i.e. lower case `L`) as a variable name.
Expand Down Expand Up @@ -136,7 +136,7 @@ To the greatest extent possible, please wrap lines to ensure that they do not ex
+ Indent case statements in switch
- Wrapping
+ Change all the `Never` values to `If Long`
+ Select the checkbox for Wrap After Assignement Operators
+ Select the checkbox for Wrap After Assignment Operators
* IntelliJ, by and large the IDE defaults are acceptable with the following changes:
- Wrapping and Braces
+ Change `Do not wrap` to `Wrap if long`
Expand Down
2 changes: 1 addition & 1 deletion docs/consumer.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ Do not make any assumptions about the format of a `IdCredentials.getId()` other

.Historical evolution of the API
****
Prior to the introduction of the `StandardCredentials` interface, the assuption was that each credentials type would have its own unique identifier, e.g. a `UsernamePasswordCredentials` would have the username, etc.
Prior to the introduction of the `StandardCredentials` interface, the assumption was that each credentials type would have its own unique identifier, e.g. a `UsernamePasswordCredentials` would have the username, etc.
This breaks down because the same username may have different passwords for different services, hence the introduction of a separate ID.
Expand Down
6 changes: 3 additions & 3 deletions docs/user.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ The expected response is:
HTTP/200::
Success.

.Example of removing the `testing` credentilas domain from the `/example-folder` folder
.Example of removing the `testing` credentials domain from the `/example-folder` folder
[source,bash]
----
$ curl -X DELETE https://jenkins.example.com/job/example-folder/credentials/store/folder/\
Expand Down Expand Up @@ -921,7 +921,7 @@ The expected responses are:
HTTP/200::
Success, the credentials has been created.
HTTP/409::
Failure, a credentiasl with that id already exists.
Failure, a credentials with that id already exists.
HTTP/50x::
Could not parse the supplied domain XML body.

Expand Down Expand Up @@ -1005,7 +1005,7 @@ The expected response is:
HTTP/200::
Success.

.Example of removing the `deploy-key` credentials instance from the `testing` credentilas domain in the `/example-folder` folder
.Example of removing the `deploy-key` credentials instance from the `testing` credentials domain in the `/example-folder` folder
[source,bash]
----
$ curl -X DELETE https://jenkins.example.com/job/example-folder/credentials/store/folder/\
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>3.43</version>
<version>3.47</version>
<relativePath />
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,15 @@ public static <C extends Credentials> List<C> trackAll(@NonNull Node node, C...
public static <C extends Credentials> List<C> trackAll(@NonNull Node node, @NonNull List<C> credentials) {
long timestamp = System.currentTimeMillis();
String nodeName = node.getNodeName();
// Create a list of all current node names. The credential will only be
// fingerprinted if it is one of these.
// TODO (JENKINS-51694): This breaks tracking for cloud agents. We should
// track those agents against the cloud instead of the node itself.
Set<String> jenkinsNodeNames = new HashSet<>();
// TODO: Switch to Jenkins.get() once 2.98+ is the baseline
for (Node n: Jenkins.getActiveInstance().getNodes()) {
jenkinsNodeNames.add(n.getNodeName());
}
for (Credentials c : credentials) {
if (c != null) {
try {
Expand All @@ -1530,14 +1539,23 @@ public static <C extends Credentials> List<C> trackAll(@NonNull Node node, @NonN
long start = timestamp;
for (Iterator<FingerprintFacet> iterator = facets.iterator(); iterator.hasNext(); ) {
FingerprintFacet f = iterator.next();
if (f instanceof NodeCredentialsFingerprintFacet && StringUtils
.equals(nodeName, ((NodeCredentialsFingerprintFacet) f).getNodeName())) {
start = Math.min(start, f.getTimestamp());
iterator.remove();
// For all the node-tracking credentials, check to see if we can remove
// older instances of these credential fingerprints, or from nodes which no longer exist
if (f instanceof NodeCredentialsFingerprintFacet) {
// Remove older instances
if (StringUtils.equals(nodeName, ((NodeCredentialsFingerprintFacet) f).getNodeName())) {
start = Math.min(start, f.getTimestamp());
iterator.remove();
// Remove unneeded instances
} else if (!jenkinsNodeNames.contains(((NodeCredentialsFingerprintFacet) f).getNodeName())) {
iterator.remove();
}
}
}
// add in the new one
facets.add(new NodeCredentialsFingerprintFacet(node, fingerprint, start, timestamp));
// add in the new one if it is a valid current node
if (jenkinsNodeNames.contains(node.getNodeName())) {
facets.add(new NodeCredentialsFingerprintFacet(node, fingerprint, start, timestamp));
}
} finally {
change.commit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ public String getDisplayName() {
public abstract ModelObject getContext(String token);

/**
* Returns a human readable descripton of the type of context objects that this resolver resolves.
* @return a human readable descripton of the type of context objects that this resolver resolves.
* Returns a human readable description of the type of context objects that this resolver resolves.
* @return a human readable description of the type of context objects that this resolver resolves.
* @throws AbstractMethodError if somebody compiled against pre-2.1.1 implementations. Use
* {@link CredentialsSelectHelper.ContextResolver#displayName(CredentialsSelectHelper.ContextResolver)}
* if you would prefer not to have to catch them.
Expand All @@ -787,10 +787,10 @@ public String getDisplayName() {
public abstract String getDisplayName();

/**
* Returns a human readable descripton of the type of context objects that the specified resolver resolves.
* Returns a human readable description of the type of context objects that the specified resolver resolves.
*
* @param resolver the context resolver to get the display name of.
* @return a human readable descripton of the type of context objects that the specified resolver resolves.
* @return a human readable description of the type of context objects that the specified resolver resolves.
* @since 2.1.1
*/
public static String displayName(ContextResolver resolver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Some credential types can store some of the credential details in a file outside of Jenkins. Taking a snapshot
* of the credential ensures that all the details are captured within the credential. For example
* {@link com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl} can use different keystores implementations
* to hold the certificiate. Calling {@link #snapshot(Credentials)} resolve the actual source into
* to hold the certificate. Calling {@link #snapshot(Credentials)} resolve the actual source into
* a source like {@link com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl.UploadedKeyStoreSource}
* which is self contained.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
import org.kohsuke.accmod.restrictions.NoExternalUse;

/**
* An analogue of {@link Secret} to be used for efficient storage of {@link byte[]}. The serialized form will embed the
* An analogue of {@link Secret} to be used for efficient storage of {@code byte[]}. The serialized form will embed the
* salt and padding so no two invocations of {@link #getEncryptedData()} will return the same result, but all will
* decrypt to the same {@link #getPlainData()}. XStream serialization and Stapler form-binding will assume that
* the {@link #toString()} representation is used (i.e. the Base64 encoded secret bytes wrapped with <code>{</code>
Expand Down Expand Up @@ -121,7 +121,7 @@ private SecretBytes(boolean encrypted, @NonNull byte[] value) {
}

/**
* Returns the raw unencrypted data. The caller is responsible for zeroing out the returned {@link byte[]} after
* Returns the raw unencrypted data. The caller is responsible for zeroing out the returned {@code byte[]} after
* use.
*
* @return the raw unencrypted data.
Expand Down Expand Up @@ -240,7 +240,7 @@ public static byte[] getPlainData(@CheckForNull SecretBytes s) {
* <p>
* Useful for recovering a value from a form field.
* If the supplied bytes are known to be unencrypted then the caller is responsible for zeroing out the supplied
* {@link byte[]} afterwards.
* {@code byte[]} afterwards.
*
* @param data the data to wrap or decrypt.
* @return never null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ private UserCredentialsProperty getInstance() {
UserCredentialsProperty property = user.getProperty(UserCredentialsProperty.class);
if (property == null) {
synchronized (emptyProperties) {
// need to recheck as UserCredentialsProperty#save() may have added while we awaited the lock
// need to recheck as UserCredentialsProperty#save() may have added while we waited for the lock
property = user.getProperty(UserCredentialsProperty.class);
if (property == null) {
property = emptyProperties.get(user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.jenkins.ui.icon.IconSpec;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
Expand All @@ -73,6 +75,12 @@ public class ViewCredentialsAction implements Action, IconSpec, AccessControlled
*/
public static final Permission VIEW = CredentialsProvider.VIEW;

/**
* Expose {@link CredentialsProvider#MANAGE_DOMAINS} for Jelly.
*/
@Restricted(NoExternalUse.class)
public static final Permission MANAGE_DOMAINS = CredentialsProvider.MANAGE_DOMAINS;

/**
* The context in which this {@link ViewCredentialsAction} was created.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public AbstractIdCredentialsListBoxModel<T, C> withAll(@NonNull Iterator<? exten
}

/**
* Adds the matching subset of suppled credentials to the model.
* Adds the matching subset of supplied credentials to the model.
*
* @param matcher the matcher.
* @param credentials the superset of credentials.
Expand All @@ -242,7 +242,7 @@ public AbstractIdCredentialsListBoxModel<T, C> withMatching(@NonNull Credentials
}

/**
* Adds the matching subset of suppled credentials to the model.
* Adds the matching subset of supplied credentials to the model.
*
* @param matcher the matcher.
* @param credentials the superset of credentials.
Expand All @@ -260,7 +260,7 @@ public AbstractIdCredentialsListBoxModel<T, C> withMatching(@NonNull Credentials
}

/**
* Adds the matching subset of suppled credentials to the model.
* Adds the matching subset of supplied credentials to the model.
*
* @param matcher the matcher.
* @param credentials the superset of credentials.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ public String getIconClassName() {
public static abstract class KeyStoreSource extends AbstractDescribableImpl<KeyStoreSource> {

/**
* Returns the {@link byte[]} content of the {@link KeyStore}.
* Returns the {@code byte[]} content of the {@link KeyStore}.
*
* @return the {@link byte[]} content of the {@link KeyStore}.
* @return the {@code byte[]} content of the {@link KeyStore}.
*/
@NonNull
public abstract byte[] getKeyStoreBytes();
Expand Down Expand Up @@ -287,7 +287,7 @@ protected KeyStoreSourceDescriptor(Class<? extends KeyStoreSource> clazz) {
* Helper method that performs form validation on a {@link KeyStore}.
*
* @param type the type of keystore to instantiate, see {@link KeyStore#getInstance(String)}.
* @param keystoreBytes the {@link byte[]} content of the {@link KeyStore}.
* @param keystoreBytes the {@code byte[]} content of the {@link KeyStore}.
* @param password the password to use when loading the {@link KeyStore} and recovering the key from the
* {@link KeyStore}.
* @return the validation results.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div>
Defines a credentials parameter, which you can use during a build.
<p style="font-weight: bold; padding: 5px; background: darkred; color: white; text-align: center">
<i>For security reasons</i>, the credential is <i>NOT</i> directly exposed, the UUID of the credential is exposed.
<i>For security reasons</i>, the credential is <i>NOT</i> directly exposed, the ID of the credential is exposed.
</p>
However, the selected credential is available through variable substitution in some other parts of the configuration.
The string value will be the UUID of the credential. A supporting plugin can thus use the UUID to retrieve
The string value will be the ID of the credential. A supporting plugin can thus use the ID to retrieve
the selected credential and expose it to the build in an appropriate way.
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:f="/lib/form" xmlns:l="/lib/layout">
<j:local>
<j:scope>
<j:set var="it" value="${it.store}"/>
<!-- TODO revert to dropdownDescriptorSelector when baseline is 1.645+ which supports `capture` attribute -->
<j:set var="descriptor" value="${it.credentialDescriptor}"/>
Expand All @@ -43,5 +43,5 @@
</f:dropdownListBlock>
</j:forEach>
</f:dropdownList>
</j:local>
</j:scope>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
usageTrackingImperfect=Note: usage tracking requires the cooperation of plugins and consequently may not track every usage
usageTrackingImperfect=Note: usage tracking requires the cooperation of plugins and consequently may not track every use.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<l:main-panel>
<j:set var="descriptor" value="${it.descriptor}"/>
<j:set var="instance" value="${it}"/>
<j:local>
<j:scope>
<j:set var="it" value="${it.store}"/>
<f:form action="updateSubmit" method="POST" name="update">
<j:set var="instance" value="${instance.credentials}" />
Expand All @@ -47,7 +47,7 @@
<f:submit value="${%Save}"/>
</f:bottomButtonBar>
</f:form>
</j:local>
</j:scope>
<script>
// TODO remove this JENKINS-24662 workaround when baseline core has fix for root cause
window.setTimeout(function(){layoutUpdateCallback.call();}, 1000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
</f:rowSet>
</j:when>
<j:otherwise>
<j:local>
<j:scope>
<j:set var="it" value="${it.store}"/>
<!-- TODO revert to dropdownDescriptorSelector when baseline is 1.645+ which supports `capture` attribute -->
<f:dropdownList name="credentials" title="${%Kind}" help="${descriptor.getHelpFile('credentials')}">
Expand All @@ -64,7 +64,7 @@
</j:forEach>
</f:dropdownList>
<!--f:dropdownDescriptorSelector field="credentials" title="${%Kind}" lazy="it"/-->
</j:local>
</j:scope>
</j:otherwise>
</j:choose>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<j:if test="${action.domainsModifiable}">
<l:task icon="plugin/credentials/images/24x24/new-domain.png" title="${%Add domain}"
href="newDomain"
permission="${it.MANAGE_DOMAINS}"/>
permission="${action.MANAGE_DOMAINS}"/>
</j:if>
</l:task>
</j:forEach>
Expand Down

0 comments on commit f3efa56

Please sign in to comment.