Skip to content

Commit

Permalink
Adding release webhook configuration to global configuration (#208)
Browse files Browse the repository at this point in the history
* Adding release webhook configuration to global configuration

* Fixed casing in the url
  • Loading branch information
kasubram committed Sep 9, 2018
1 parent fd9e944 commit a8e3dd6
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 18 deletions.
28 changes: 18 additions & 10 deletions tfs/src/main/java/hudson/plugins/tfs/JenkinsEventNotifier.java
Expand Up @@ -60,7 +60,7 @@ public static void sendJobCompletionEvent(final JSONObject payload) {
final JobCompletionEventArgs args = new JobCompletionEventArgs(
connectionParameters.getConnectionKey(),
jsonPayload,
getPayloadSignature(connectionParameters, jsonPayload));
getPayloadSignature(connectionParameters.getConnectionSignature(), jsonPayload));
client.sendJobCompletionEvent(args);
} catch (final Exception e) {
log.warning("ERROR: sendJobCompletionEvent: (collection=" + c.getCollectionUrl() + ") " + e.getMessage());
Expand Down Expand Up @@ -154,6 +154,23 @@ public static String getApiJson(final String url) {
}
}

/**
* Calculates the payload hash.
* @param secret
* @param payload
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws UnsupportedEncodingException
*/
public static String getPayloadSignature(final String secret, final String payload)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
final SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(ENCODING), "HmacSHA1");
final Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return toHexString(mac.doFinal(payload.getBytes(ENCODING)));
}

private static String urlCombine(final String url, final String... parts) {
final StringBuilder sb = new StringBuilder();
if (url != null) {
Expand All @@ -170,15 +187,6 @@ private static String urlCombine(final String url, final String... parts) {
return sb.toString();
}

private static String getPayloadSignature(final ConnectionParameters connectionParameters, final String payload)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
final String key = connectionParameters.getConnectionSignature();
final SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(ENCODING), "HmacSHA1");
final Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return toHexString(mac.doFinal(payload.getBytes(ENCODING)));
}

private static String toHexString(final byte[] bytes) {
final Formatter formatter = new Formatter();
for (final byte b : bytes) {
Expand Down
12 changes: 12 additions & 0 deletions tfs/src/main/java/hudson/plugins/tfs/TeamEventsEndpoint.java
Expand Up @@ -12,6 +12,7 @@
import hudson.plugins.tfs.model.GitPushEvent;
import hudson.plugins.tfs.model.PingHookEvent;
import hudson.plugins.tfs.model.servicehooks.Event;
import hudson.plugins.tfs.rm.ConnectReleaseWebHookEvent;
import hudson.plugins.tfs.telemetry.TelemetryHelper;
import hudson.plugins.tfs.util.EndpointHelper;
import hudson.plugins.tfs.util.MediaType;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class TeamEventsEndpoint implements UnprotectedRootAction {
eventMap.put("gitPullRequestMerged", new GitPullRequestMergedEvent.Factory());
eventMap.put("gitPush", new GitPushEvent.Factory());
eventMap.put("connect", new ConnectHookEvent.Factory());
eventMap.put("rmWebhook", new ConnectReleaseWebHookEvent.Factory());
HOOK_EVENT_FACTORIES_BY_NAME = Collections.unmodifiableMap(eventMap);
}

Expand Down Expand Up @@ -225,6 +227,16 @@ public void doConnect(
dispatch(request, response, body);
}

@RequirePOST
public void doRmwebhook(
final StaplerRequest request,
final StaplerResponse response,
@StringBodyParameter @Nonnull final String body) {
// Send telemetry
TelemetryHelper.sendEvent("team-events-rmwebhook", new TelemetryHelper.PropertyMapBuilder().build());
dispatch(request, response, body);
}

public static <T extends Trigger> T findTrigger(final Job<?, ?> job, final Class<T> tClass) {
if (job instanceof ParameterizedJobMixIn.ParameterizedJob) {
final ParameterizedJobMixIn.ParameterizedJob pJob = (ParameterizedJobMixIn.ParameterizedJob) job;
Expand Down
15 changes: 14 additions & 1 deletion tfs/src/main/java/hudson/plugins/tfs/TeamPluginGlobalConfig.java
Expand Up @@ -6,6 +6,7 @@
import hudson.plugins.tfs.model.DomainUserAccountMapper;
import hudson.plugins.tfs.model.UserAccountMapper;
import hudson.plugins.tfs.model.UserAccountMapperDescriptor;
import hudson.plugins.tfs.rm.ReleaseWebHook;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
Expand All @@ -27,7 +28,8 @@ public class TeamPluginGlobalConfig extends GlobalConfiguration {
public static final TeamPluginGlobalConfig DEFAULT_CONFIG = new TeamPluginGlobalConfig(false);

private List<TeamCollectionConfiguration> collectionConfigurations = new ArrayList<TeamCollectionConfiguration>();

private List<ReleaseWebHook> releaseWebHookConfigurations = new ArrayList<ReleaseWebHook>();

private boolean configFolderPerNode;
private boolean enableTeamPushTriggerForAllJobs;
private boolean enableTeamStatusForAllJobs;
Expand Down Expand Up @@ -64,6 +66,14 @@ public List<TeamCollectionConfiguration> getCollectionConfigurations() {
public void setCollectionConfigurations(final List<TeamCollectionConfiguration> collectionConfigurations) {
this.collectionConfigurations = collectionConfigurations;
}

public List<ReleaseWebHook> getReleaseWebHookConfigurations() {
return this.releaseWebHookConfigurations;
}

public void setReleaseWebHookConfigurations(final List<ReleaseWebHook> releaseWebHookConfigurations) {
this.releaseWebHookConfigurations = releaseWebHookConfigurations;
}

public boolean isConfigFolderPerNode() {
return configFolderPerNode;
Expand Down Expand Up @@ -108,6 +118,9 @@ public List<UserAccountMapperDescriptor> getUserAccountMapperDescriptors() {
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
try {
req.bindJSON(this, json);

// stapler oddity, empty lists are not set on bean by "req.bindJSON(this, json)"
this.releaseWebHookConfigurations = req.bindJSONToList(ReleaseWebHook.class, json.get("releaseWebHookConfigurations"));
}
catch (final Exception e) {
final String message = "Configuration error: " + e.getMessage();
Expand Down
@@ -1,7 +1,10 @@
package hudson.plugins.tfs.rm;

import hudson.plugins.tfs.JenkinsEventNotifier;
import hudson.plugins.tfs.TeamPluginGlobalConfig;
import java.util.ArrayList;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
Expand All @@ -22,8 +25,7 @@ public static List<ReleaseWebHook> getReleaseWebHookConfigurations() {
throw new InternalError("Cannot load TFS global configuration");
}

//return config.getReleaseWebHookConfigurations();
return new ArrayList<ReleaseWebHook>();
return config.getReleaseWebHookConfigurations();
}

/**
Expand All @@ -36,7 +38,7 @@ public static void saveReleaseWebHookConfigurations(final List<ReleaseWebHook> r
throw new InternalError("Cannot load TFS global configuration");
}

//config.setReleaseWebHookConfigurations(releaseWebHooks);
config.setReleaseWebHookConfigurations(releaseWebHooks);
config.save();
}

Expand All @@ -46,8 +48,7 @@ public static void saveReleaseWebHookConfigurations(final List<ReleaseWebHook> r
* @param payload
* @return
*/
public static String getPayloadSignature(final String secret, final String payload) {
//JenkinsEventNotifier.getPayloadSignature(secret payload);
return null;
public static String getPayloadSignature(final String secret, final String payload) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
return JenkinsEventNotifier.getPayloadSignature(secret, payload);
}
}
Expand Up @@ -33,4 +33,9 @@ f.section(title: descriptor.displayName) {
f.checkbox (default: false)
}
}
f.entry(title: _("Release WebHooks"),
field: "releaseWebHookConfigurations") {

f.repeatableProperty(field: "releaseWebHookConfigurations")
}
}
@@ -0,0 +1,3 @@
<div>
Adds a Release Webhook. Project can refer to this Webhook in its post build action. When a build completes it will send the event payload to the payload url mentioned.
</div>

0 comments on commit a8e3dd6

Please sign in to comment.