diff --git a/src/main/java/org/gitlab4j/api/HookManager.java b/src/main/java/org/gitlab4j/api/HookManager.java new file mode 100644 index 0000000000000000000000000000000000000000..3e16df2059c0cfa25ab2f45eb8fe15b3e6dde20b --- /dev/null +++ b/src/main/java/org/gitlab4j/api/HookManager.java @@ -0,0 +1,77 @@ + +package org.gitlab4j.api; + +import javax.servlet.http.HttpServletRequest; + +/** + * This class provides a base class handler for processing GitLab Web Hook and System Hook callouts. + */ +public abstract class HookManager { + + private String secretToken; + + /** + * Create a HookManager to handle GitLab hook events. + */ + public HookManager() { + this.secretToken = null; + } + + /** + * Create a HookManager to handle GitLab hook events which will be verified + * against the specified secretToken. + * + * @param secretToken the secret token to verify against + */ + public HookManager(String secretToken) { + this.secretToken = secretToken; + } + + /** + * Set the secret token that received hook events should be validated against. + * + * @param secretToken the secret token to verify against + */ + public void setSecretToken(String secretToken) { + this.secretToken = secretToken; + } + + /** + * Validate the provided secret token against the reference secret token. Returns true if + * the secret token is valid or there is no reference secret token to validate against, + * otherwise returns false. + * + * @param secretToken the token to validate + * @return true if the secret token is valid or there is no reference secret token to validate against + */ + public boolean isValidSecretToken(String secretToken) { + return (this.secretToken == null || this.secretToken.equals(secretToken) ? true : false); + } + + /** + * Validate the provided secret token found in the HTTP header against the reference secret token. + * Returns true if the secret token is valid or there is no reference secret token to validate + * against, otherwise returns false. + * + * @param request the HTTP request to verify the secret token + * @return true if the secret token is valid or there is no reference secret token to validate against + */ + public boolean isValidSecretToken(HttpServletRequest request) { + + if (this.secretToken != null) { + String secretToken = request.getHeader("X-Gitlab-Token"); + return (isValidSecretToken(secretToken)); + } + + return (true); + } + + /** + * Parses and verifies an Event instance from the HTTP request and + * fires it off to the registered listeners. + * + * @param request the HttpServletRequest to read the Event instance from + * @throws GitLabApiException if the parsed event is not supported + */ + public abstract void handleEvent(HttpServletRequest request) throws GitLabApiException; +} \ No newline at end of file diff --git a/src/main/java/org/gitlab4j/api/SystemHooksApi.java b/src/main/java/org/gitlab4j/api/SystemHooksApi.java new file mode 100644 index 0000000000000000000000000000000000000000..b665e66e4e72dd44831854a1ab206abf92d931f2 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/SystemHooksApi.java @@ -0,0 +1,160 @@ +package org.gitlab4j.api; + +import java.util.List; + +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.Response; + +import org.gitlab4j.api.GitLabApi.ApiVersion; +import org.gitlab4j.api.models.SystemHook; + +/** + * This class implements the client side API for the GitLab System Hooks Keys API calls. + */ +public class SystemHooksApi extends AbstractApi { + + public SystemHooksApi(GitLabApi gitLabApi) { + super(gitLabApi); + } + + /** + * Get a list of all system hooks. This method requires admin access. + * Only returns the first page. This method requires admin access. + * + * GET /hooks + * + * @return a list of SystemHookEvent + * @throws GitLabApiException if any exception occurs + */ + public List getSystemHooks() throws GitLabApiException { + return (getSystemHooks(1, getDefaultPerPage())); + } + + /** + * Get a list of all system hooks using the specified page and per page settings. + * This method requires admin access. + * + * GET /hooks + * + * @param page the page to get + * @param perPage the number of deploy keys per page + * @return the list of SystemHookEvent in the specified range + * @throws GitLabApiException if any exception occurs + */ + public List getSystemHooks(int page, int perPage) throws GitLabApiException { + Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "hooks"); + return (response.readEntity(new GenericType>() {})); + } + + /** + * Get a Pager of all system hooks. This method requires admin access. + * + * GET /hooks + * + * @param itemsPerPage the number of SystemHookEvent instances that will be fetched per page + * @return a Pager of SystemHookEvent + * @throws GitLabApiException if any exception occurs + */ + public Pager getSystemHooks(int itemsPerPage) throws GitLabApiException { + return (new Pager(this, SystemHook.class, itemsPerPage, null, "hooks")); + } + + /** + * Add a new system hook. This method requires admin access. + * + * POST /hooks + * + * @param url the hook URL, required + * @param token secret token to validate received payloads, optional + * @param pushEvents when true, the hook will fire on push events, optional + * @param tagPushEvents when true, the hook will fire on new tags being pushed, optional + * @param enablSsslVerification do SSL verification when triggering the hook, optional + * @return an SystemHookEvent instance with info on the added system hook + * @throws GitLabApiException if any exception occurs + */ + public SystemHook addSystemHook(String url, String token, Boolean pushEvents, + Boolean tagPushEvents, Boolean enablSsslVerification) throws GitLabApiException { + + if (url == null) { + throw new RuntimeException("url cannot be null"); + } + + GitLabApiForm formData = new GitLabApiForm() + .withParam("url", url, true) + .withParam("token", token) + .withParam("push_events", pushEvents) + .withParam("tag_push_events", tagPushEvents) + .withParam("enable_ssl_verification", enablSsslVerification); + Response response = post(Response.Status.CREATED, formData, "hooks"); + return (response.readEntity(SystemHook.class)); + } + + /** + * Deletes a system hook. This method requires admin access. + * + * DELETE /hooks/:hook_id + * + * @param hook the SystemHook instance to delete + * @throws GitLabApiException if any exception occurs + */ + public void deleteSystemHook(SystemHook hook) throws GitLabApiException { + + if (hook == null) { + throw new RuntimeException("hook cannot be null"); + } + + deleteSystemHook(hook.getId()); + } + + /** + * Deletes a system hook. This method requires admin access. + * + * DELETE /hooks/:hook_id + * + * @param hookId the ID of the system hook to delete + * @throws GitLabApiException if any exception occurs + */ + public void deleteSystemHook(Integer hookId) throws GitLabApiException { + + if (hookId == null) { + throw new RuntimeException("hookId cannot be null"); + } + + Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); + delete(expectedStatus, null, "hooks", hookId); + } + + /** + * Test a system hook. This method requires admin access. + * + * GET /hooks/:hook_id + * + * @param hook the SystemHookEvent instance to test + * @throws GitLabApiException if any exception occurs + */ + public void testSystemHook(SystemHook hook) throws GitLabApiException { + + if (hook == null) { + throw new RuntimeException("hook cannot be null"); + } + + testSystemHook(hook.getId()); + } + + /** + * Test a system hook. This method requires admin access. + * + * GET /hooks/:hook_id + * + * @param hookId the ID of the system hook to test + * @throws GitLabApiException if any exception occurs + */ + public void testSystemHook(Integer hookId) throws GitLabApiException { + + if (hookId == null) { + throw new RuntimeException("hookId cannot be null"); + } + + get(Response.Status.OK, null, "hooks", hookId); + } +} diff --git a/src/main/java/org/gitlab4j/api/systemhooks/ProjectSystemHookEvent.java b/src/main/java/org/gitlab4j/api/systemhooks/ProjectSystemHookEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..39ba57f2348aff65ac3eedf0ffcc957a40d4d527 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/systemhooks/ProjectSystemHookEvent.java @@ -0,0 +1,120 @@ +package org.gitlab4j.api.systemhooks; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.gitlab4j.api.models.Visibility; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ProjectSystemHookEvent implements SystemHookEvent { + + public static final String PROJECT_CREATE_EVENT = "project_create"; + public static final String PROJECT_DESTROY_EVENT = "project_destroy"; + public static final String PROJECT_RENAME_EVENT = "project_rename"; + public static final String PROJECT_TRANSFER_EVENT = "project_transfer"; + public static final String PROJECT_UPDATE_EVENT = "project_update"; + + private Date createdAt; + private Date updatedAt; + private String eventName; + private String name; + private String ownerEmail; + private String ownerName; + private String path; + private Integer projectId; + private String pathWithNamespace; + private Visibility projectVisibility; + private String oldPathWithNamespace; + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public String getEventName() { + return this.eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOwnerEmail() { + return this.ownerEmail; + } + + public void setOwnerEmail(String ownerEmail) { + this.ownerEmail = ownerEmail; + } + + public String getOwnerName() { + return this.ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } + + public Integer getProjectId() { + return this.projectId; + } + + public void setProjectId(Integer projectId) { + this.projectId = projectId; + } + + public String getPathWithNamespace() { + return pathWithNamespace; + } + + public void setPathWithNamespace(String pathWithNamespace) { + this.pathWithNamespace = pathWithNamespace; + } + + public Visibility getProjectVisibility() { + return projectVisibility; + } + + public void setProjectVisibility(Visibility projectVisibility) { + this.projectVisibility = projectVisibility; + } + + public String getOldPathWithNamespace() { + return oldPathWithNamespace; + } + + public void setOldPathWithNamespace(String oldPathWithNamespace) { + this.oldPathWithNamespace = oldPathWithNamespace; + } +} diff --git a/src/main/java/org/gitlab4j/api/systemhooks/SystemHookEvent.java b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..c17454d88deee49f02fa7ab574e652a65bfb67fa --- /dev/null +++ b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookEvent.java @@ -0,0 +1,20 @@ +package org.gitlab4j.api.systemhooks; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, + include=JsonTypeInfo.As.PROPERTY, + property="event_name") +@JsonSubTypes({ + @JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_CREATE_EVENT), + @JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_DESTROY_EVENT), + @JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_RENAME_EVENT), + @JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_TRANSFER_EVENT), + @JsonSubTypes.Type(value = ProjectSystemHookEvent.class, name = ProjectSystemHookEvent.PROJECT_UPDATE_EVENT), + @JsonSubTypes.Type(value = TeamMemberSystemHookEvent.class, name = TeamMemberSystemHookEvent.NEW_TEAM_MEMBER_EVENT), + @JsonSubTypes.Type(value = TeamMemberSystemHookEvent.class, name = TeamMemberSystemHookEvent.TEAM_MEMBER_REMOVED_EVENT) +}) +public interface SystemHookEvent { + public String getEventName(); +} diff --git a/src/main/java/org/gitlab4j/api/systemhooks/SystemHookListener.java b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookListener.java new file mode 100644 index 0000000000000000000000000000000000000000..5c9a0181cf2580a475a5250b4fc0f1639d0fb204 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookListener.java @@ -0,0 +1,23 @@ + +package org.gitlab4j.api.systemhooks; + +/** + * This class defines an event listener for the event fired when + * a System Hook notification has been received from a GitLab server. + */ +public interface SystemHookListener extends java.util.EventListener { + + /** + * This method is called when a System Hook prject event has been received. + * + * @param event the ProjectSystemHookEvent instance + */ + public void onProjectEvent(ProjectSystemHookEvent event); + + /** + * This method is called when a System Hook team member event has been received. + * + * @param event the TeamMemberSystemHookEvent instance containing info on the team member event + */ + public void onTeamMemberEvent(TeamMemberSystemHookEvent event); +} diff --git a/src/main/java/org/gitlab4j/api/systemhooks/SystemHookManager.java b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookManager.java new file mode 100644 index 0000000000000000000000000000000000000000..fde49c1081687e0f4ed8f66631f3254243ad6931 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/systemhooks/SystemHookManager.java @@ -0,0 +1,174 @@ + +package org.gitlab4j.api.systemhooks; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; + +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.HookManager; +import org.gitlab4j.api.utils.HttpRequestUtils; +import org.gitlab4j.api.utils.JacksonJson; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +/** + * This class provides a handler for processing GitLab System Hook callouts. + */ +public class SystemHookManager extends HookManager { + + public static final String SYSTEM_HOOK_EVENT = "System Hook"; + + private final static Logger LOG = Logger.getLogger(SystemHookManager.class.getName()); + private final JacksonJson jacksonJson = new JacksonJson(); + + // Collection of objects listening for System Hook events. + private final List systemHookListeners = new CopyOnWriteArrayList(); + + /** + * Create a HookManager to handle GitLab system hook events. + */ + public SystemHookManager() { + super(); + } + + /** + * Create a HookManager to handle GitLab system hook events which will be verified + * against the specified secretToken. + * + * @param secretToken the secret token to verify against + */ + public SystemHookManager(String secretToken) { + super(secretToken); + } + + /** + * Parses and verifies an SystemHookEvent instance from the HTTP request and + * fires it off to the registered listeners. + * + * @param request the HttpServletRequest to read the Event instance from + * @throws GitLabApiException if the parsed event is not supported + */ + public void handleEvent(HttpServletRequest request) throws GitLabApiException { + + if (!isValidSecretToken(request)) { + String message = "X-Gitlab-Token mismatch!"; + LOG.warning(message); + throw new GitLabApiException(message); + } + + String eventName = request.getHeader("X-Gitlab-Event"); + LOG.info("handleEvent: X-Gitlab-Event=" + eventName); + if (!SYSTEM_HOOK_EVENT.equals(eventName)) { + String message = "Unsupported X-Gitlab-Event, event Name=" + eventName; + LOG.warning(message); + throw new GitLabApiException(message); + } + + String errorMessage = null; + try { + + SystemHookEvent event; + if (LOG.isLoggable(Level.FINE)) { + LOG.fine(HttpRequestUtils.getShortRequestDump("System Hook", true, request)); + String postData = HttpRequestUtils.getPostDataAsString(request); + LOG.fine("Raw POST data:\n" + postData); + event = jacksonJson.unmarshal(SystemHookEvent.class, postData); + LOG.fine(event.getEventName() + "\n" + jacksonJson.marshal(event) + "\n"); + } else { + InputStreamReader reader = new InputStreamReader(request.getInputStream()); + event = jacksonJson.unmarshal(SystemHookEvent.class, reader); + } + + fireEvent(event); + + } catch (JsonParseException jpe) { + errorMessage = jpe.getMessage(); + LOG.warning("Error parsing JSON data, error=" + errorMessage); + } catch (JsonMappingException jme) { + errorMessage = jme.getMessage(); + LOG.warning("Error mapping JSON data, error=" + errorMessage); + } catch (IOException ioe) { + errorMessage = ioe.getMessage(); + LOG.warning("Error reading JSON data, error=" + errorMessage); + } catch (Exception e) { + errorMessage = e.getMessage(); + LOG.warning("Unexpected error reading JSON data, error=" + errorMessage); + } + + if (errorMessage != null) + throw new GitLabApiException(errorMessage); + } + + /** + * Verifies the provided Event and fires it off to the registered listeners. + * + * @param event the Event instance to handle + * @throws GitLabApiException if the event is not supported + */ + public void handleEvent(SystemHookEvent event) throws GitLabApiException { + + LOG.info("handleEvent: object_kind=" + event.getEventName()); + fireEvent(event); + } + + /** + * Adds a System Hook event listener. + * + * @param listener the SystemHookListener to add + */ + public void addListener(SystemHookListener listener) { + + if (!systemHookListeners.contains(listener)) { + systemHookListeners.add(listener); + } + } + + /** + * Removes a System Hook event listener. + * + * @param listener the SystemHookListener to remove + */ + public void removeListener(SystemHookListener listener) { + systemHookListeners.remove(listener); + } + + /** + * Fire the event to the registered listeners. + * + * @param event the SystemHookEvent instance to fire to the registered event listeners + * @throws GitLabApiException if the event is not supported + */ + public void fireEvent(SystemHookEvent event) throws GitLabApiException { + + if (event instanceof ProjectSystemHookEvent) { + fireProjectEvent((ProjectSystemHookEvent) event); + } else if (event instanceof TeamMemberSystemHookEvent) { + fireTeamMemberEvent((TeamMemberSystemHookEvent) event); + } else { + String message = "Unsupported event, event_named=" + event.getEventName(); + LOG.warning(message); + throw new GitLabApiException(message); + } + } + + protected void fireProjectEvent(ProjectSystemHookEvent event) { + + for (SystemHookListener listener : systemHookListeners) { + listener.onProjectEvent(event); + } + } + + protected void fireTeamMemberEvent(TeamMemberSystemHookEvent event) { + + for (SystemHookListener listener : systemHookListeners) { + listener.onTeamMemberEvent(event); + } + } +} diff --git a/src/main/java/org/gitlab4j/api/systemhooks/TeamMemberSystemHookEvent.java b/src/main/java/org/gitlab4j/api/systemhooks/TeamMemberSystemHookEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..b9602c33b705498524b94ef46e90a0836511ba9e --- /dev/null +++ b/src/main/java/org/gitlab4j/api/systemhooks/TeamMemberSystemHookEvent.java @@ -0,0 +1,143 @@ +package org.gitlab4j.api.systemhooks; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.gitlab4j.api.models.Visibility; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class TeamMemberSystemHookEvent implements SystemHookEvent { + + public static final String NEW_TEAM_MEMBER_EVENT = "user_add_to_team"; + public static final String TEAM_MEMBER_REMOVED_EVENT = "user_remove_from_team"; + + private Date createdAt; + private Date updatedAt; + private String eventName; + private String projectAccess; + private String projectName; + private String projectPath; + private Integer projectId; + private String projectPathWithNamespace; + private String userEmail; + private String userName; + private String userUsername; + private Integer userId; + private Visibility projectVisibility; + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public String getEventName() { + return this.eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getProjectAccess() { + return projectAccess; + } + + public void setProjectAccess(String projectAccess) { + this.projectAccess = projectAccess; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getProjectPath() { + return projectPath; + } + + public void setProjectPath(String projectPath) { + this.projectPath = projectPath; + } + + public Integer getProjectId() { + return projectId; + } + + public void setProjectId(Integer projectId) { + this.projectId = projectId; + } + + public String getProjectPathWithNamespace() { + return projectPathWithNamespace; + } + + public void setProjectPathWithNamespace(String projectPathWithNamespace) { + this.projectPathWithNamespace = projectPathWithNamespace; + } + + public String getUserEmail() { + return userEmail; + } + + public void setUserEmail(String userEmail) { + this.userEmail = userEmail; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getUserUsername() { + return userUsername; + } + + public void setUserUsername(String userUsername) { + this.userUsername = userUsername; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Visibility getProjectVisibility() { + return projectVisibility; + } + + public void setProjectVisibility(Visibility projectVisibility) { + this.projectVisibility = projectVisibility; + } + + public static String getNewTeamMemberEvent() { + return NEW_TEAM_MEMBER_EVENT; + } + + public static String getTeamMemberRemovedEvent() { + return TEAM_MEMBER_REMOVED_EVENT; + } +} diff --git a/src/test/java/org/gitlab4j/api/TestSystemHooksApi.java b/src/test/java/org/gitlab4j/api/TestSystemHooksApi.java new file mode 100644 index 0000000000000000000000000000000000000000..8c56c3bb32c9d1bd5ebddb9422db640940f9c8bc --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestSystemHooksApi.java @@ -0,0 +1,102 @@ +package org.gitlab4j.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import java.util.List; + +import org.gitlab4j.api.GitLabApi.ApiVersion; +import org.gitlab4j.api.models.SystemHook; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** +* In order for these tests to run you must set the following properties in test-gitlab4j.properties + * + * TEST_HOOK_URL + * TEST_HOST_URL + * TEST_PRIVATE_TOKEN + * + * If any of the above are NULL, all tests in this class will be skipped. + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestSystemHooksApi { + + // The following needs to be set to your test repository + private static final String TEST_HOST_URL; + private static final String TEST_HOOK_URL; + private static final String TEST_PRIVATE_TOKEN; + static { + TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL"); + TEST_HOOK_URL = TestUtils.getProperty("TEST_HOOK_URL"); + TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN"); + } + + private static final String TEST_SECRET_TOKEN = "123456abcd"; + + private static GitLabApi gitLabApi; + + public TestSystemHooksApi() { + super(); + } + + @BeforeClass + public static void setup() { + + String problems = ""; + if (TEST_HOOK_URL == null || TEST_HOOK_URL.trim().length() == 0) { + problems += "TEST_HOOK_URL cannot be empty\n"; + } + + if (TEST_HOST_URL == null || TEST_HOST_URL.trim().length() == 0) { + problems += "TEST_HOST_URL cannot be empty\n"; + } + + if (TEST_PRIVATE_TOKEN == null || TEST_PRIVATE_TOKEN.trim().length() == 0) { + problems += "TEST_PRIVATE_TOKEN cannot be empty\n"; + } + + if (problems.isEmpty()) { + gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN); + } else { + System.err.print(problems); + } + } + + @Before + public void beforeMethod() { + assumeTrue(gitLabApi != null); + } + + @Test + public void testAddSystemHook() throws GitLabApiException { + + SystemHook hook = gitLabApi.getSystemHooksApi().addSystemHook(TEST_HOOK_URL, TEST_SECRET_TOKEN, true, false, true); + assertNotNull(hook); + assertEquals(TEST_HOOK_URL, hook.getUrl()); + assertTrue(hook.getPushEvents()); + assertFalse(hook.getTagPushEvents()); + assertTrue(hook.getEnableSslVerification()); + + gitLabApi.getSystemHooksApi().deleteSystemHook(hook); + } + + @Test + public void testGerSystemHooks() throws GitLabApiException { + + SystemHook hook = gitLabApi.getSystemHooksApi().addSystemHook(TEST_HOOK_URL, TEST_SECRET_TOKEN, true, false, true); + assertNotNull(hook); + + List hooks = gitLabApi.getSystemHooksApi().getSystemHooks(); + assertNotNull(hooks); + assertFalse(hooks.isEmpty()); + + gitLabApi.getSystemHooksApi().deleteSystemHook(hook); + } +} diff --git a/src/test/resources/org/gitlab4j/api/project-system-hook-event.json b/src/test/resources/org/gitlab4j/api/project-system-hook-event.json new file mode 100644 index 0000000000000000000000000000000000000000..64c918d47284345bbdb5f4156f93c0d8ab4d5c57 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/project-system-hook-event.json @@ -0,0 +1,12 @@ +{ + "created_at": "2012-07-21T07:30:54Z", + "updated_at": "2012-07-21T07:38:22Z", + "event_name": "project_create", + "name": "StoreCloud", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", + "path": "storecloud", + "path_with_namespace": "jsmith/storecloud", + "project_id": 74, + "project_visibility": "private" +} \ No newline at end of file diff --git a/src/test/resources/org/gitlab4j/api/team-member-system-hook-event.json b/src/test/resources/org/gitlab4j/api/team-member-system-hook-event.json new file mode 100644 index 0000000000000000000000000000000000000000..fdebf50a5e4f739d24686d04cb4a51e2bb2f0ef1 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/team-member-system-hook-event.json @@ -0,0 +1,15 @@ +{ + "created_at": "2012-07-21T07:30:56Z", + "updated_at": "2012-07-21T07:38:22Z", + "event_name": "user_add_to_team", + "project_access": "Master", + "project_id": 74, + "project_name": "StoreCloud", + "project_path": "storecloud", + "project_path_with_namespace": "jsmith/storecloud", + "user_email": "johnsmith@gmail.com", + "user_name": "John Smith", + "user_username": "johnsmith", + "user_id": 41, + "project_visibility": "private" +} \ No newline at end of file