Skip to content

Commit 0ab14a6

Browse files
committed
Initial commit in support of System Hooks API (#117).
1 parent a9fb9b3 commit 0ab14a6

File tree

10 files changed

+846
-0
lines changed

10 files changed

+846
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
package org.gitlab4j.api;
3+
4+
import javax.servlet.http.HttpServletRequest;
5+
6+
/**
7+
* This class provides a base class handler for processing GitLab Web Hook and System Hook callouts.
8+
*/
9+
public abstract class HookManager {
10+
11+
private String secretToken;
12+
13+
/**
14+
* Create a HookManager to handle GitLab hook events.
15+
*/
16+
public HookManager() {
17+
this.secretToken = null;
18+
}
19+
20+
/**
21+
* Create a HookManager to handle GitLab hook events which will be verified
22+
* against the specified secretToken.
23+
*
24+
* @param secretToken the secret token to verify against
25+
*/
26+
public HookManager(String secretToken) {
27+
this.secretToken = secretToken;
28+
}
29+
30+
/**
31+
* Set the secret token that received hook events should be validated against.
32+
*
33+
* @param secretToken the secret token to verify against
34+
*/
35+
public void setSecretToken(String secretToken) {
36+
this.secretToken = secretToken;
37+
}
38+
39+
/**
40+
* Validate the provided secret token against the reference secret token. Returns true if
41+
* the secret token is valid or there is no reference secret token to validate against,
42+
* otherwise returns false.
43+
*
44+
* @param secretToken the token to validate
45+
* @return true if the secret token is valid or there is no reference secret token to validate against
46+
*/
47+
public boolean isValidSecretToken(String secretToken) {
48+
return (this.secretToken == null || this.secretToken.equals(secretToken) ? true : false);
49+
}
50+
51+
/**
52+
* Validate the provided secret token found in the HTTP header against the reference secret token.
53+
* Returns true if the secret token is valid or there is no reference secret token to validate
54+
* against, otherwise returns false.
55+
*
56+
* @param request the HTTP request to verify the secret token
57+
* @return true if the secret token is valid or there is no reference secret token to validate against
58+
*/
59+
public boolean isValidSecretToken(HttpServletRequest request) {
60+
61+
if (this.secretToken != null) {
62+
String secretToken = request.getHeader("X-Gitlab-Token");
63+
return (isValidSecretToken(secretToken));
64+
}
65+
66+
return (true);
67+
}
68+
69+
/**
70+
* Parses and verifies an Event instance from the HTTP request and
71+
* fires it off to the registered listeners.
72+
*
73+
* @param request the HttpServletRequest to read the Event instance from
74+
* @throws GitLabApiException if the parsed event is not supported
75+
*/
76+
public abstract void handleEvent(HttpServletRequest request) throws GitLabApiException;
77+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package org.gitlab4j.api;
2+
3+
import java.util.List;
4+
5+
import javax.ws.rs.core.GenericType;
6+
import javax.ws.rs.core.Response;
7+
8+
import org.gitlab4j.api.GitLabApi.ApiVersion;
9+
import org.gitlab4j.api.models.SystemHook;
10+
11+
/**
12+
* This class implements the client side API for the GitLab System Hooks Keys API calls.
13+
*/
14+
public class SystemHooksApi extends AbstractApi {
15+
16+
public SystemHooksApi(GitLabApi gitLabApi) {
17+
super(gitLabApi);
18+
}
19+
20+
/**
21+
* Get a list of all system hooks. This method requires admin access.
22+
* Only returns the first page. This method requires admin access.
23+
*
24+
* <code>GET /hooks</code>
25+
*
26+
* @return a list of SystemHookEvent
27+
* @throws GitLabApiException if any exception occurs
28+
*/
29+
public List<SystemHook> getSystemHooks() throws GitLabApiException {
30+
return (getSystemHooks(1, getDefaultPerPage()));
31+
}
32+
33+
/**
34+
* Get a list of all system hooks using the specified page and per page settings.
35+
* This method requires admin access.
36+
*
37+
* <code>GET /hooks</code>
38+
*
39+
* @param page the page to get
40+
* @param perPage the number of deploy keys per page
41+
* @return the list of SystemHookEvent in the specified range
42+
* @throws GitLabApiException if any exception occurs
43+
*/
44+
public List<SystemHook> getSystemHooks(int page, int perPage) throws GitLabApiException {
45+
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "hooks");
46+
return (response.readEntity(new GenericType<List<SystemHook>>() {}));
47+
}
48+
49+
/**
50+
* Get a Pager of all system hooks. This method requires admin access.
51+
*
52+
* <code>GET /hooks</code>
53+
*
54+
* @param itemsPerPage the number of SystemHookEvent instances that will be fetched per page
55+
* @return a Pager of SystemHookEvent
56+
* @throws GitLabApiException if any exception occurs
57+
*/
58+
public Pager<SystemHook> getSystemHooks(int itemsPerPage) throws GitLabApiException {
59+
return (new Pager<SystemHook>(this, SystemHook.class, itemsPerPage, null, "hooks"));
60+
}
61+
62+
/**
63+
* Add a new system hook. This method requires admin access.
64+
*
65+
* <code>POST /hooks</code>
66+
*
67+
* @param url the hook URL, required
68+
* @param token secret token to validate received payloads, optional
69+
* @param pushEvents when true, the hook will fire on push events, optional
70+
* @param tagPushEvents when true, the hook will fire on new tags being pushed, optional
71+
* @param enablSsslVerification do SSL verification when triggering the hook, optional
72+
* @return an SystemHookEvent instance with info on the added system hook
73+
* @throws GitLabApiException if any exception occurs
74+
*/
75+
public SystemHook addSystemHook(String url, String token, Boolean pushEvents,
76+
Boolean tagPushEvents, Boolean enablSsslVerification) throws GitLabApiException {
77+
78+
if (url == null) {
79+
throw new RuntimeException("url cannot be null");
80+
}
81+
82+
GitLabApiForm formData = new GitLabApiForm()
83+
.withParam("url", url, true)
84+
.withParam("token", token)
85+
.withParam("push_events", pushEvents)
86+
.withParam("tag_push_events", tagPushEvents)
87+
.withParam("enable_ssl_verification", enablSsslVerification);
88+
Response response = post(Response.Status.CREATED, formData, "hooks");
89+
return (response.readEntity(SystemHook.class));
90+
}
91+
92+
/**
93+
* Deletes a system hook. This method requires admin access.
94+
*
95+
* <code>DELETE /hooks/:hook_id</code>
96+
*
97+
* @param hook the SystemHook instance to delete
98+
* @throws GitLabApiException if any exception occurs
99+
*/
100+
public void deleteSystemHook(SystemHook hook) throws GitLabApiException {
101+
102+
if (hook == null) {
103+
throw new RuntimeException("hook cannot be null");
104+
}
105+
106+
deleteSystemHook(hook.getId());
107+
}
108+
109+
/**
110+
* Deletes a system hook. This method requires admin access.
111+
*
112+
* <code>DELETE /hooks/:hook_id</code>
113+
*
114+
* @param hookId the ID of the system hook to delete
115+
* @throws GitLabApiException if any exception occurs
116+
*/
117+
public void deleteSystemHook(Integer hookId) throws GitLabApiException {
118+
119+
if (hookId == null) {
120+
throw new RuntimeException("hookId cannot be null");
121+
}
122+
123+
Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT);
124+
delete(expectedStatus, null, "hooks", hookId);
125+
}
126+
127+
/**
128+
* Test a system hook. This method requires admin access.
129+
*
130+
* <code>GET /hooks/:hook_id</code>
131+
*
132+
* @param hook the SystemHookEvent instance to test
133+
* @throws GitLabApiException if any exception occurs
134+
*/
135+
public void testSystemHook(SystemHook hook) throws GitLabApiException {
136+
137+
if (hook == null) {
138+
throw new RuntimeException("hook cannot be null");
139+
}
140+
141+
testSystemHook(hook.getId());
142+
}
143+
144+
/**
145+
* Test a system hook. This method requires admin access.
146+
*
147+
* <code>GET /hooks/:hook_id</code>
148+
*
149+
* @param hookId the ID of the system hook to test
150+
* @throws GitLabApiException if any exception occurs
151+
*/
152+
public void testSystemHook(Integer hookId) throws GitLabApiException {
153+
154+
if (hookId == null) {
155+
throw new RuntimeException("hookId cannot be null");
156+
}
157+
158+
get(Response.Status.OK, null, "hooks", hookId);
159+
}
160+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package org.gitlab4j.api.systemhooks;
2+
3+
import java.util.Date;
4+
5+
import javax.xml.bind.annotation.XmlAccessType;
6+
import javax.xml.bind.annotation.XmlAccessorType;
7+
import javax.xml.bind.annotation.XmlRootElement;
8+
9+
import org.gitlab4j.api.models.Visibility;
10+
11+
@XmlRootElement
12+
@XmlAccessorType(XmlAccessType.FIELD)
13+
public class ProjectSystemHookEvent implements SystemHookEvent {
14+
15+
public static final String PROJECT_CREATE_EVENT = "project_create";
16+
public static final String PROJECT_DESTROY_EVENT = "project_destroy";
17+
public static final String PROJECT_RENAME_EVENT = "project_rename";
18+
public static final String PROJECT_TRANSFER_EVENT = "project_transfer";
19+
public static final String PROJECT_UPDATE_EVENT = "project_update";
20+
21+
private Date createdAt;
22+
private Date updatedAt;
23+
private String eventName;
24+
private String name;
25+
private String ownerEmail;
26+
private String ownerName;
27+
private String path;
28+
private Integer projectId;
29+
private String pathWithNamespace;
30+
private Visibility projectVisibility;
31+
private String oldPathWithNamespace;
32+
33+
public Date getCreatedAt() {
34+
return createdAt;
35+
}
36+
37+
public void setCreatedAt(Date createdAt) {
38+
this.createdAt = createdAt;
39+
}
40+
41+
public Date getUpdatedAt() {
42+
return updatedAt;
43+
}
44+
45+
public void setUpdatedAt(Date updatedAt) {
46+
this.updatedAt = updatedAt;
47+
}
48+
49+
public String getEventName() {
50+
return this.eventName;
51+
}
52+
53+
public void setEventName(String eventName) {
54+
this.eventName = eventName;
55+
}
56+
57+
public String getName() {
58+
return this.name;
59+
}
60+
61+
public void setName(String name) {
62+
this.name = name;
63+
}
64+
65+
public String getOwnerEmail() {
66+
return this.ownerEmail;
67+
}
68+
69+
public void setOwnerEmail(String ownerEmail) {
70+
this.ownerEmail = ownerEmail;
71+
}
72+
73+
public String getOwnerName() {
74+
return this.ownerName;
75+
}
76+
77+
public void setOwnerName(String ownerName) {
78+
this.ownerName = ownerName;
79+
}
80+
81+
public String getPath() {
82+
return this.path;
83+
}
84+
85+
public void setPath(String path) {
86+
this.path = path;
87+
}
88+
89+
public Integer getProjectId() {
90+
return this.projectId;
91+
}
92+
93+
public void setProjectId(Integer projectId) {
94+
this.projectId = projectId;
95+
}
96+
97+
public String getPathWithNamespace() {
98+
return pathWithNamespace;
99+
}
100+
101+
public void setPathWithNamespace(String pathWithNamespace) {
102+
this.pathWithNamespace = pathWithNamespace;
103+
}
104+
105+
public Visibility getProjectVisibility() {
106+
return projectVisibility;
107+
}
108+
109+
public void setProjectVisibility(Visibility projectVisibility) {
110+
this.projectVisibility = projectVisibility;
111+
}
112+
113+
public String getOldPathWithNamespace() {
114+
return oldPathWithNamespace;
115+
}
116+
117+
public void setOldPathWithNamespace(String oldPathWithNamespace) {
118+
this.oldPathWithNamespace = oldPathWithNamespace;
119+
}
120+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.gitlab4j.api.systemhooks;
2+
3+
import com.fasterxml.jackson.annotation.JsonSubTypes;
4+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
5+
6+
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
7+
include=JsonTypeInfo.As.PROPERTY,
8+
property="event_name")
9+
@JsonSubTypes({
10+
@JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_CREATE_EVENT),
11+
@JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_DESTROY_EVENT),
12+
@JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_RENAME_EVENT),
13+
@JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_TRANSFER_EVENT),
14+
@JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_UPDATE_EVENT),
15+
@JsonSubTypes.Type(value = TeamMemberSystemHookEvent.class, name = TeamMemberSystemHookEvent.NEW_TEAM_MEMBER_EVENT),
16+
@JsonSubTypes.Type(value = TeamMemberSystemHookEvent.class, name = TeamMemberSystemHookEvent.TEAM_MEMBER_REMOVED_EVENT)
17+
})
18+
public interface SystemHookEvent {
19+
public String getEventName();
20+
}

0 commit comments

Comments
 (0)