From 2c736095621d9ed8aea06e28664d80b545088308 Mon Sep 17 00:00:00 2001 From: mmsuo Date: Fri, 30 Oct 2020 13:34:40 +0800 Subject: [PATCH] add oauth2 Resource Owner Password Credentials Grant login method --- pom.xml | 2 +- src/main/java/org/gitlab/api/GitlabAPI.java | 293 +++++++++--------- .../gitlab/api/http/GitlabHTTPRequestor.java | 75 ++++- .../gitlab/api/models/GitlabAccessToken.java | 65 ++++ src/test/java/org/gitlab/api/GitlabAPIIT.java | 1 + 5 files changed, 278 insertions(+), 158 deletions(-) create mode 100644 src/main/java/org/gitlab/api/models/GitlabAccessToken.java diff --git a/pom.xml b/pom.xml index 902f0424..6e13ad98 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.10.5 + 2.5.3 commons-io diff --git a/src/main/java/org/gitlab/api/GitlabAPI.java b/src/main/java/org/gitlab/api/GitlabAPI.java index c0c88fa7..6622b360 100644 --- a/src/main/java/org/gitlab/api/GitlabAPI.java +++ b/src/main/java/org/gitlab/api/GitlabAPI.java @@ -97,6 +97,26 @@ public static GitlabAPI connect(String hostUrl, String apiToken, TokenType token return new GitlabAPI(hostUrl, apiToken, tokenType, method, apiNamespace); } + /** + * Use oauth 2 Resource Owner Password Credentials Grant type login + * + * @param hostUrl gitlab url + * @param username username + * @param password password + * @return GitlabAPI + * @throws IOException exception + */ + public static GitlabAPI oauth2Login(String hostUrl, String username, String password) throws IOException { + GitlabAPI api = new GitlabAPI(hostUrl, null, null, null, ""); + GitlabAccessToken accessToken = api.dispatch().method(POST) + .withHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + .with("grant_type", "password") + .with("username", username) + .with("password", password) + .to("/oauth/token", GitlabAccessToken.class); + return GitlabAPI.connect(hostUrl, accessToken.getAccessToken(), TokenType.ACCESS_TOKEN); + } + public GitlabAPI ignoreCertificateErrors(boolean ignoreCertificateErrors) { this.ignoreCertificateErrors = ignoreCertificateErrors; return this; @@ -253,7 +273,7 @@ public GitlabUser getUserViaSudo(String username) throws IOException { * @param can_create_group Can Create Group * @param skip_confirmation Skip Confirmation * @param external External - * @return A GitlabUser + * @return A GitlabUser * @throws IOException on gitlab api call error * @see http://doc.gitlab.com/ce/api/users.html */ @@ -400,8 +420,8 @@ public GitlabSSHKey createSSHKey(Integer targetUserId, String title, String key) /** * Create a new ssh key for the authenticated user. * - * @param title The title of the ssh key - * @param key The public key + * @param title The title of the ssh key + * @param key The public key * @return The new GitlabSSHKey * @throws IOException on gitlab api call error */ @@ -477,7 +497,6 @@ public GitlabGroup getGroupWithoutProjects(Integer groupId) throws IOException { * * @param path Path of the group * @return {@link GitlabGroup} object - * * @throws IOException on gitlab api call error */ public GitlabGroup getGroupWithoutProjects(String path) throws IOException { @@ -489,7 +508,6 @@ public GitlabGroup getGroupWithoutProjects(String path) throws IOException { * * @param path Path of the group * @return {@link GitlabGroup} object - * * @throws IOException on gitlab api call error */ public GitlabGroup getGroup(String path) throws IOException { @@ -499,16 +517,15 @@ public GitlabGroup getGroup(String path) throws IOException { /** * Get a group by path * - * @param path Path of the group + * @param path Path of the group * @param withProjects If true, include the projects * @return {@link GitlabGroup} object - * * @throws IOException on gitlab api call error */ public GitlabGroup getGroup(String path, boolean withProjects) throws IOException { String tailUrl = GitlabGroup.URL + "/" + URLEncoder.encode(path, "UTF-8"); Query query = new Query() - .append(PARAM_WITH_PROJECTS, "" + withProjects); + .append(PARAM_WITH_PROJECTS, "" + withProjects); return retrieve().to(tailUrl + query.toString(), GitlabGroup.class); } @@ -684,12 +701,11 @@ public GitlabGroup createGroup(String name, String path, String ldapCn, GitlabAc return dispatch().to(tailUrl, GitlabGroup.class); } - /** + /** * Creates a Group * - * @param group The gitlab Group object + * @param group The gitlab Group object * @param sudoUser The user to create the group on behalf of - * * @return The GitLab Group * @throws IOException on gitlab api call error */ @@ -717,7 +733,7 @@ public GitlabGroup createGroup(GitlabGroup group, GitlabUser sudoUser) throws IO /** * Updates a Group * - * @param group the group object + * @param group the group object * @param sudoUser The user to create the group on behalf of * @return The GitLab Group * @throws IOException on gitlab api call error @@ -1025,7 +1041,7 @@ public GitlabUpload uploadFile(GitlabProject project, File file) throws IOExcept /** * Get a project's pipeline * - * @param project the project + * @param project the project * @param pipeline the pipeline * @return The project pipeline */ @@ -1036,7 +1052,7 @@ public GitlabPipeline getProjectPipeline(GitlabProject project, GitlabPipeline p /** * Get a project's pipeline * - * @param projectId the project id + * @param projectId the project id * @param pipelineId the pipeline id * @return The project pipeline */ @@ -1110,8 +1126,9 @@ public List getProjectJobs(Integer projectId) { /** * Run pipeline for selected project and branch - * @param project project - * @param ref branch + * + * @param project project + * @param ref branch * @param variables pipeline variables * @return Created pipeline * @throws IOException @@ -1123,8 +1140,9 @@ public GitlabPipeline runPipeline(GitlabProject project, String ref, List * EE only. */ public GitlabMergeRequestApprovals setMergeRequestApprovals(GitlabMergeRequest mr, int count) throws IOException { String tailUrl = GitlabProject.URL + "/" + sanitizeProjectId(mr.getProjectId()) + GitlabMergeRequest.URL + "/" + mr.getIid() + GitlabMergeRequestApprovals.URL; return dispatch() - .with("approvals_required", count) - .to(tailUrl, GitlabMergeRequestApprovals.class); + .with("approvals_required", count) + .to(tailUrl, GitlabMergeRequestApprovals.class); } /** * Set the list of approvers. Important: Approvers and groups not * in the request will be removed - * + *

* EE only. */ public GitlabMergeRequestApprovals setMergeRequestApprovers(GitlabMergeRequest mr, @@ -1674,9 +1692,9 @@ public GitlabMergeRequestApprovals setMergeRequestApprovers(GitlabMergeRequest m String tailUrl = GitlabProject.URL + "/" + sanitizeProjectId(mr.getProjectId()) + GitlabMergeRequest.URL + "/" + mr.getIid() + GitlabMergeRequestApprovals.APPROVERS_URL; return put() - .with("approver_ids", userApproverIds) - .with("approver_group_ids", groupApproverIds) - .to(tailUrl, GitlabMergeRequestApprovals.class); + .with("approver_ids", userApproverIds) + .with("approver_group_ids", groupApproverIds) + .to(tailUrl, GitlabMergeRequestApprovals.class); } /** @@ -1720,21 +1738,21 @@ public GitlabMergeRequest getMergeRequestByIid(Serializable projectId, Integer m * @throws IOException on gitlab api call error */ public GitlabMergeRequest getMergeRequestChanges(Serializable projectId, - Integer mergeRequestIid) throws IOException { + Integer mergeRequestIid) throws IOException { String tailUrl = GitlabProject.URL + "/" + sanitizeProjectId(projectId) + GitlabMergeRequest.URL + "/" + mergeRequestIid + "/changes"; return retrieve().to(tailUrl, GitlabMergeRequest.class); } public GitlabMergeRequest getMergeRequest(Serializable projectId, - Integer mergeRequestIid) throws IOException { + Integer mergeRequestIid) throws IOException { String tailUrl = GitlabProject.URL + "/" + sanitizeProjectId(projectId) + GitlabMergeRequest.URL + "/" + mergeRequestIid; return retrieve().to(tailUrl, GitlabMergeRequest.class); } public GitlabMergeRequest getMergeRequest(GitlabProject project, - Integer mergeRequestIid) throws IOException { + Integer mergeRequestIid) throws IOException { return getMergeRequest(project.getId(), mergeRequestIid); } @@ -1826,7 +1844,7 @@ public GitlabMergeRequest acceptMergeRequest(Serializable projectId, Integer mer * @throws IOException on gitlab api call error */ public GitlabNote getNote(GitlabMergeRequest mergeRequest, - Integer noteId) throws IOException { + Integer noteId) throws IOException { String tailUrl = GitlabProject.URL + "/" + mergeRequest.getProjectId() + GitlabMergeRequest.URL + "/" + mergeRequest.getIid() + GitlabNote.URL + "/" + noteId; @@ -1857,12 +1875,11 @@ public List getAllNotes(GitlabMergeRequest mergeRequest) { * * @param mergeRequest to fetch the discussion from. * @param discussionId The id of the discussion. - * * @return The GitLab discussion identified by the given id. * @throws IOException on a GitLab api call error */ public GitlabDiscussion getDiscussion(GitlabMergeRequest mergeRequest, - int discussionId) throws IOException { + int discussionId) throws IOException { String tailUrl = GitlabProject.URL + "/" + mergeRequest.getProjectId() + GitlabMergeRequest.URL + "/" + mergeRequest.getIid() + GitlabDiscussion.URL + "/" + discussionId; @@ -1874,7 +1891,6 @@ public GitlabDiscussion getDiscussion(GitlabMergeRequest mergeRequest, * https://docs.gitlab.com/ce/api/discussions.html#list-project-merge-request-discussions * * @param mergeRequest to fetch the discussions from. - * * @return The discussions contained in the given merge request. * @throws IOException on a GitLab api call error */ @@ -1890,18 +1906,17 @@ public List getDiscussions(GitlabMergeRequest mergeRequest) th /** * Create a discussion just with the required arguments. * - * @param mergeRequest The merge request where the discussion is created. - * @param body The content of a discussion. - * @param positionBaseSha The base commit SHA in the source branch. - * @param positionStartSha The SHA referencing the commit in the target branch. - * @param positionHeadSha The SHA referencing the HEAD of this merge request. - * + * @param mergeRequest The merge request where the discussion is created. + * @param body The content of a discussion. + * @param positionBaseSha The base commit SHA in the source branch. + * @param positionStartSha The SHA referencing the commit in the target branch. + * @param positionHeadSha The SHA referencing the HEAD of this merge request. * @return The created discussion object. * @throws IOException on a GitLab api call error */ public GitlabDiscussion createDiscussion(GitlabMergeRequest mergeRequest, - String body, String positionBaseSha, String positionStartSha, - String positionHeadSha) throws IOException { + String body, String positionBaseSha, String positionStartSha, + String positionHeadSha) throws IOException { return createTextDiscussion(mergeRequest, body, null, positionBaseSha, positionStartSha, positionHeadSha, null, null, null, null); @@ -1911,24 +1926,23 @@ public GitlabDiscussion createDiscussion(GitlabMergeRequest mergeRequest, * Create a new discussion with position type text on the given merge request. * https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-discussion * - * @param mergeRequest The merge request where the discussion is created. - * @param body The content of a discussion. - * @param position The position when creating a diff note. (hash) - * @param positionBaseSha The base commit SHA in the source branch. - * @param positionStartSha The SHA referencing the commit in the target branch. - * @param positionHeadSha The SHA referencing the HEAD of this merge request. - * @param positionNewPath The file path after the change. - * @param positionNewLine The Line number after change - * @param positionOldPath The file path before the change. - * @param positionOldLine The Line number before change. - * + * @param mergeRequest The merge request where the discussion is created. + * @param body The content of a discussion. + * @param position The position when creating a diff note. (hash) + * @param positionBaseSha The base commit SHA in the source branch. + * @param positionStartSha The SHA referencing the commit in the target branch. + * @param positionHeadSha The SHA referencing the HEAD of this merge request. + * @param positionNewPath The file path after the change. + * @param positionNewLine The Line number after change + * @param positionOldPath The file path before the change. + * @param positionOldLine The Line number before change. * @return The created discussion object. * @throws IOException on a GitLab api call error */ public GitlabDiscussion createTextDiscussion(GitlabMergeRequest mergeRequest, - String body, String position, String positionBaseSha, String positionStartSha, - String positionHeadSha, String positionNewPath, Integer positionNewLine, - String positionOldPath, Integer positionOldLine) throws IOException { + String body, String position, String positionBaseSha, String positionStartSha, + String positionHeadSha, String positionNewPath, Integer positionNewLine, + String positionOldPath, Integer positionOldLine) throws IOException { checkRequiredCreateDiscussionArguments(body, positionBaseSha, positionStartSha, positionHeadSha); Query query = new Query() .append("body", body) @@ -1953,19 +1967,18 @@ public GitlabDiscussion createTextDiscussion(GitlabMergeRequest mergeRequest, * Create a new discussion with position type image on the given merge request. * https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-discussion * - * @param mergeRequest The merge request where the discussion is created. - * @param body The content of a discussion. - * @param position The position when creating a diff note. (hash) - * @param positionBaseSha The base commit SHA in the source branch. - * @param positionStartSha The SHA referencing the commit in the target branch. - * @param positionHeadSha The SHA referencing the HEAD of this merge request. - * @param positionNewPath The file path after the change. - * @param positionOldPath The file path before the change. - * @param positionWidth The width of the image. - * @param positionHeight The height of the image. - * @param positionX The X coordinate. - * @param positionY The Y coordinate. - * + * @param mergeRequest The merge request where the discussion is created. + * @param body The content of a discussion. + * @param position The position when creating a diff note. (hash) + * @param positionBaseSha The base commit SHA in the source branch. + * @param positionStartSha The SHA referencing the commit in the target branch. + * @param positionHeadSha The SHA referencing the HEAD of this merge request. + * @param positionNewPath The file path after the change. + * @param positionOldPath The file path before the change. + * @param positionWidth The width of the image. + * @param positionHeight The height of the image. + * @param positionX The X coordinate. + * @param positionY The Y coordinate. * @return The created discussion object. * @throws IOException on a GitLab api call error */ @@ -1975,7 +1988,7 @@ public GitlabDiscussion createImageDiscussion( String positionHeadSha, String positionNewPath, String positionOldPath, Integer positionWidth, Integer positionHeight, Integer positionX, Integer positionY - ) throws IOException { + ) throws IOException { checkRequiredCreateDiscussionArguments(body, positionBaseSha, positionStartSha, positionHeadSha); Query query = new Query() .append("body", body) @@ -2002,13 +2015,13 @@ public GitlabDiscussion createImageDiscussion( * Check if the required arguments to create a discussion are present and * contain values. * - * @param body The content of a discussion. - * @param positionBaseSha The base commit SHA in the source branch. - * @param positionStartSha The SHA referencing commit in target branch - * @param positionHeadSha The SHA referencing HEAD of this merge request + * @param body The content of a discussion. + * @param positionBaseSha The base commit SHA in the source branch. + * @param positionStartSha The SHA referencing commit in target branch + * @param positionHeadSha The SHA referencing HEAD of this merge request */ private void checkRequiredCreateDiscussionArguments(String body, - String positionBaseSha, String positionStartSha, String positionHeadSha) { + String positionBaseSha, String positionStartSha, String positionHeadSha) { if (body == null || body.isEmpty()) { throw new IllegalArgumentException("Missing required argument 'body'!"); } else if (positionBaseSha == null || positionBaseSha.isEmpty()) { @@ -2023,15 +2036,14 @@ private void checkRequiredCreateDiscussionArguments(String body, /** * Resolve or unresolve a whole discussion of a merge request. * - * @param mergeRequest The merge request of the discussion. - * @param discussionId The id of the discussion to resolve. - * @param resolved Resolve or unresolve the note. - * + * @param mergeRequest The merge request of the discussion. + * @param discussionId The id of the discussion to resolve. + * @param resolved Resolve or unresolve the note. * @return The discussion object. * @throws IOException on a GitLab api call error */ public GitlabDiscussion resolveDiscussion(GitlabMergeRequest mergeRequest, - int discussionId, boolean resolved) throws IOException { + int discussionId, boolean resolved) throws IOException { String tailUrl = GitlabProject.URL + "/" + mergeRequest.getProjectId() + GitlabMergeRequest.URL + "/" + mergeRequest.getIid() + GitlabDiscussion.URL + "/" + discussionId; @@ -2043,15 +2055,14 @@ public GitlabDiscussion resolveDiscussion(GitlabMergeRequest mergeRequest, /** * Add a note to existing merge request discussion. * - * @param mergeRequest The merge request of the discussion. - * @param discussionId The id of the discussion to add a note to. - * @param body The content of the discussion. - * + * @param mergeRequest The merge request of the discussion. + * @param discussionId The id of the discussion to add a note to. + * @param body The content of the discussion. * @return The added note object. * @throws IOException on a GitLab api call error */ public GitlabNote addDiscussionNote(GitlabMergeRequest mergeRequest, - int discussionId, String body) throws IOException { + int discussionId, String body) throws IOException { String tailUrl = GitlabProject.URL + "/" + mergeRequest.getProjectId() + GitlabMergeRequest.URL + "/" + mergeRequest.getIid() + GitlabDiscussion.URL + "/" + discussionId + @@ -2062,17 +2073,16 @@ public GitlabNote addDiscussionNote(GitlabMergeRequest mergeRequest, /** * Modify or resolve an existing discussion note of the given merge request. * - * @param mergeRequest The merge request of the discussion. - * @param discussionId The id of the discussion to modify. - * @param noteId The id of the discussion note. - * @param body The content of the discussion. - * @param resolved Resolve or unresolve the note. - * + * @param mergeRequest The merge request of the discussion. + * @param discussionId The id of the discussion to modify. + * @param noteId The id of the discussion note. + * @param body The content of the discussion. + * @param resolved Resolve or unresolve the note. * @return The modified note object. * @throws IOException on a GitLab api call error */ public GitlabNote modifyDiscussionNote(GitlabMergeRequest mergeRequest, int discussionId, - int noteId, String body, Boolean resolved) throws IOException { + int noteId, String body, Boolean resolved) throws IOException { boolean bodyHasValue = false; if (body != null && !body.isEmpty()) { bodyHasValue = true; @@ -2093,10 +2103,9 @@ public GitlabNote modifyDiscussionNote(GitlabMergeRequest mergeRequest, int disc /** * Delete a discussion note of a merge request. * - * @param mergeRequest The merge request of the discussion. - * @param discussionId The id of the discussion to resolve. - * @param noteId The id of a discussion note. - * + * @param mergeRequest The merge request of the discussion. + * @param discussionId The id of the discussion to resolve. + * @param noteId The id of a discussion note. * @return The deleted note object. * @throws IOException on a GitLab api call error */ @@ -2572,14 +2581,14 @@ public GitlabProjectHook addProjectHook(Serializable projectId, String url, bool public GitlabProjectHook addProjectHook(Serializable projectId, String url, GitlabProjectHook hook, String token) throws IOException { return this.addProjectHook(projectId, url, hook.getPushEvents(), hook.getIssueEvents(), hook.isMergeRequestsEvents(), - hook.isNoteEvents(), hook.isTagPushEvents(), hook.isSslVerificationEnabled(), hook.isJobEvents(), - hook.isPipelineEvents(), hook.isWikiPageEvents(), token); + hook.isNoteEvents(), hook.isTagPushEvents(), hook.isSslVerificationEnabled(), hook.isJobEvents(), + hook.isPipelineEvents(), hook.isWikiPageEvents(), token); } public GitlabProjectHook editProjectHook(GitlabProject project, String hookId, String url, - boolean pushEvents, boolean issuesEvents, boolean mergeRequestEvents, boolean noteEvents, - boolean tagPushEvents, boolean sslVerification, boolean jobEvents, boolean pipelineEvents, - boolean wikiPageEvents, String token) throws IOException { + boolean pushEvents, boolean issuesEvents, boolean mergeRequestEvents, boolean noteEvents, + boolean tagPushEvents, boolean sslVerification, boolean jobEvents, boolean pipelineEvents, + boolean wikiPageEvents, String token) throws IOException { Query query = new Query(); query.append("url", url); query.append("push_events", String.valueOf(pushEvents)); @@ -2598,9 +2607,9 @@ public GitlabProjectHook editProjectHook(GitlabProject project, String hookId, S public GitlabProjectHook editProjectHook(GitlabProject project, GitlabProjectHook projectHook, String token) throws IOException { return editProjectHook(project, projectHook.getId(), projectHook.getUrl(), projectHook.getPushEvents(), - projectHook.getIssueEvents(), projectHook.isMergeRequestsEvents(), projectHook.isNoteEvents(), - projectHook.isTagPushEvents(), projectHook.isSslVerificationEnabled(), projectHook.isJobEvents(), - projectHook.isWikiPageEvents(), projectHook.isPipelineEvents(), token); + projectHook.getIssueEvents(), projectHook.isMergeRequestsEvents(), projectHook.isNoteEvents(), + projectHook.isTagPushEvents(), projectHook.isSslVerificationEnabled(), projectHook.isJobEvents(), + projectHook.isWikiPageEvents(), projectHook.isPipelineEvents(), token); } public void deleteProjectHook(GitlabProjectHook hook) throws IOException { @@ -2743,7 +2752,6 @@ public void deleteNote(GitlabIssue issue, GitlabNote noteToDelete) throws IOExce * * @param projectId The id of the project for which the badges should be retrieved * @return The list of badges - * * @throws IOException on GitLab API call error */ public List getProjectBadges(Serializable projectId) throws IOException { @@ -2757,7 +2765,6 @@ public List getProjectBadges(Serializable projectId) throws IOExcep * @param projectId The id of the project for which the badge should be retrieved * @param badgeId The id of the badge that should be retrieved * @return The badge with a given id - * * @throws IOException on GitLab API call error */ public GitlabBadge getProjectBadge(Serializable projectId, Integer badgeId) throws IOException { @@ -2773,7 +2780,6 @@ public GitlabBadge getProjectBadge(Serializable projectId, Integer badgeId) thro * @param linkUrl The URL that the badge should link to * @param imageUrl The URL to the badge image * @return The created badge - * * @throws IOException on GitLab API call error */ public GitlabBadge addProjectBadge(Serializable projectId, String linkUrl, String imageUrl) throws IOException { @@ -2791,7 +2797,6 @@ public GitlabBadge addProjectBadge(Serializable projectId, String linkUrl, Strin * @param linkUrl The URL that the badge should link to * @param imageUrl The URL to the badge image * @return The updated badge - * * @throws IOException on GitLab API call error */ public GitlabBadge editProjectBadge(Serializable projectId, Integer badgeId, String linkUrl, String imageUrl) throws IOException { @@ -2821,7 +2826,6 @@ public void deleteProjectBadge(Serializable projectId, Integer badgeId) throws I * * @param groupId The id of the group for which the badges should be retrieved * @return The list of badges - * * @throws IOException on GitLab API call error */ public List getGroupBadges(Integer groupId) throws IOException { @@ -2835,7 +2839,6 @@ public List getGroupBadges(Integer groupId) throws IOException { * @param groupId The id of the group for which the badge should be retrieved * @param badgeId The id of the badge that should be retrieved * @return The badge with a given id - * * @throws IOException on GitLab API call error */ public GitlabBadge getGroupBadge(Integer groupId, Integer badgeId) throws IOException { @@ -2851,7 +2854,6 @@ public GitlabBadge getGroupBadge(Integer groupId, Integer badgeId) throws IOExce * @param linkUrl The URL that the badge should link to * @param imageUrl The URL to the badge image * @return The created badge - * * @throws IOException on GitLab API call error */ public GitlabBadge addGroupBadge(Integer groupId, String linkUrl, String imageUrl) throws IOException { @@ -2869,7 +2871,6 @@ public GitlabBadge addGroupBadge(Integer groupId, String linkUrl, String imageUr * @param linkUrl The URL that the badge should link to * @param imageUrl The URL to the badge image * @return The updated badge - * * @throws IOException on GitLab API call error */ public GitlabBadge editGroupBadge(Integer groupId, Integer badgeId, String linkUrl, String imageUrl) throws IOException { @@ -4153,12 +4154,12 @@ public GitlabRunner getRunnerDetail(int id) throws IOException { /** * Get events for a project. * - * @param action If not null, include only events of a particular action type + * @param action If not null, include only events of a particular action type * @param targetType If not null, include only events of a particular target type - * @param before If not null, include only events created before a particular date. - * @param after If not null, include only events created before a - * particular date. - * @param sortOrder If null, uses the server's default, which is "desc" + * @param before If not null, include only events created before a particular date. + * @param after If not null, include only events created before a + * particular date. + * @param sortOrder If null, uses the server's default, which is "desc" */ public List getEvents(GitlabProject project, GitlabEvent.ActionType action, @@ -4166,20 +4167,20 @@ public List getEvents(GitlabProject project, GitlabDate before, GitlabDate after, SortOrder sortOrder) - throws IOException { + throws IOException { return getEvents(project, action, targetType, before, - after, sortOrder, new Pagination()); + after, sortOrder, new Pagination()); } /** * Get events for a project. * - * @param action If not null, include only events of a particular action type + * @param action If not null, include only events of a particular action type * @param targetType If not null, include only events of a particular target type - * @param before If not null, include only events created before a particular date. - * @param after If not null, include only events created before a - * particular date. - * @param sortOrder If null, uses the server's default, which is "desc" + * @param before If not null, include only events created before a particular date. + * @param after If not null, include only events created before a + * particular date. + * @param sortOrder If null, uses the server's default, which is "desc" */ public List getEvents(GitlabProject project, GitlabEvent.ActionType action, @@ -4188,20 +4189,20 @@ public List getEvents(GitlabProject project, GitlabDate after, SortOrder sortOrder, Pagination pagination) - throws IOException { + throws IOException { return getProjectEvents(project.getId(), action, targetType, before, - after, sortOrder, pagination); + after, sortOrder, pagination); } /** * Get events for a project. * - * @param action If not null, include only events of a particular action type + * @param action If not null, include only events of a particular action type * @param targetType If not null, include only events of a particular target type - * @param before If not null, include only events created before a particular date. - * @param after If not null, include only events created before a - * particular date. - * @param sort If null, uses the server's default, which is "desc" + * @param before If not null, include only events created before a particular date. + * @param after If not null, include only events created before a + * particular date. + * @param sort If null, uses the server's default, which is "desc" */ public List getProjectEvents(Serializable projectId, GitlabEvent.ActionType action, @@ -4209,20 +4210,20 @@ public List getProjectEvents(Serializable projectId, GitlabDate before, GitlabDate after, SortOrder sort) - throws IOException { + throws IOException { return getProjectEvents(projectId, action, targetType, before, - after, sort, new Pagination()); + after, sort, new Pagination()); } /** * Get events for a project. * - * @param action If not null, include only events of a particular action type + * @param action If not null, include only events of a particular action type * @param targetType If not null, include only events of a particular target type - * @param before If not null, include only events created before a particular date. - * @param after If not null, include only events created before a - * particular date. - * @param sort If null, uses the server's default, which is "desc" + * @param before If not null, include only events created before a particular date. + * @param after If not null, include only events created before a + * particular date. + * @param sort If null, uses the server's default, which is "desc" */ public List getProjectEvents(Serializable projectId, GitlabEvent.ActionType action, @@ -4231,7 +4232,7 @@ public List getProjectEvents(Serializable projectId, GitlabDate after, SortOrder sort, Pagination pagination) - throws IOException { + throws IOException { final Query query = new Query(); query.appendIf("action", action); @@ -4245,10 +4246,10 @@ public List getProjectEvents(Serializable projectId, } StringBuilder tailUrl = new StringBuilder(GitlabProject.URL) - .append("/") - .append(sanitizeProjectId(projectId)) - .append(GitlabEvent.URL) - .append(query.toString()); + .append("/") + .append(sanitizeProjectId(projectId)) + .append(GitlabEvent.URL) + .append(query.toString()); return Arrays.asList(retrieve().method(GET).to(tailUrl.toString(), GitlabEvent[].class)); } diff --git a/src/main/java/org/gitlab/api/http/GitlabHTTPRequestor.java b/src/main/java/org/gitlab/api/http/GitlabHTTPRequestor.java index ebe80573..090587bf 100644 --- a/src/main/java/org/gitlab/api/http/GitlabHTTPRequestor.java +++ b/src/main/java/org/gitlab/api/http/GitlabHTTPRequestor.java @@ -16,6 +16,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import javax.net.ssl.*; @@ -43,6 +44,7 @@ public class GitlabHTTPRequestor { private final GitlabAPI root; private Method method = GET; // Default to GET requests + private Map headers = new HashMap<>(); private Map data = new HashMap<>(); private Map attachments = new HashMap<>(); @@ -86,8 +88,8 @@ public GitlabHTTPRequestor method(Method method) { * Sets the HTTP Form Post parameters for the request * Has a fluent api for method chaining * - * @param key Form parameter Key - * @param value Form parameter Value + * @param key Form parameter Key + * @param value Form parameter Value * @return this */ public GitlabHTTPRequestor with(String key, Object value) { @@ -96,13 +98,27 @@ public GitlabHTTPRequestor with(String key, Object value) { } return this; } - + + /** + * Sets the Http header + * + * @param key header name + * @param value header value + * @return this + */ + public GitlabHTTPRequestor withHeader(String key, String value) { + if (value != null && key != null) { + headers.put(key, value); + } + return this; + } + /** * Sets the HTTP Form Post parameters for the request * Has a fluent api for method chaining * - * @param key Form parameter Key - * @param file File data + * @param key Form parameter Key + * @param file File data * @return this */ public GitlabHTTPRequestor withAttachment(String key, File file) { @@ -132,13 +148,29 @@ public T to(String tailAPIUrl, Class type) throws IOException { * @throws java.io.IOException on gitlab api error */ public T to(String tailAPIUrl, Class type, T instance) throws IOException { + return doRequest(root.getAPIUrl(tailAPIUrl), type, instance); + } + + /** + * do connection + * + * @param url url connecting to + * @param type type of response to be deserialized + * @param instance The instance to update from the response + * @param The return type of the method + * @return An object of type T + * @throws IOException on gitlab api error + */ + private T doRequest(URL url, Class type, T instance) throws IOException { HttpURLConnection connection = null; try { - connection = setupConnection(root.getAPIUrl(tailAPIUrl)); + connection = setupConnection(url); + // add for oauth2 + writeHeader(connection); if (hasAttachments()) { submitAttachments(connection); } else if (hasOutput()) { - submitData(connection); + submitData(connection); } else if (PUT.equals(method)) { // PUT requires Content-Length: 0 even when there is no body (eg: API for protecting a branch) connection.setDoOutput(true); @@ -159,6 +191,13 @@ public T to(String tailAPIUrl, Class type, T instance) throws IOException } } + private void writeHeader(HttpURLConnection connection) { + for (Map.Entry header : headers.entrySet()) { + connection.setRequestProperty(header.getKey(), header.getValue()); + } + } + + public List getAll(final String tailUrl, final Class type) { List results = new ArrayList<>(); Iterator iterator = asIterator(tailUrl, type); @@ -301,17 +340,30 @@ private void submitAttachments(HttpURLConnection connection) throws IOException writer.append("--").append(boundary).append("--").append(CRLF).flush(); } } - + private void submitData(HttpURLConnection connection) throws IOException { connection.setDoOutput(true); + // add for oauth2 request + String contentType = headers.get("Content-Type"); + if ("application/x-www-form-urlencoded; charset=utf-8".equals(contentType)) { + String formData = parseFormData(data); + connection.getOutputStream().write(formData.getBytes()); + return; + } connection.setRequestProperty("Content-Type", "application/json"); GitlabAPI.MAPPER.writeValue(connection.getOutputStream(), data); } + private String parseFormData(Map data) { + List kv = data.entrySet().stream() + .map(d -> String.format("%s=%s", d.getKey(), d.getValue())).collect(Collectors.toList()); + return String.join("&", kv); + } + private boolean hasAttachments() { return !attachments.isEmpty(); } - + private boolean hasOutput() { return method.equals(POST) || method.equals(PUT) && !data.isEmpty(); } @@ -363,7 +415,7 @@ private T parse(HttpURLConnection connection, Class type, T instance) thr } reader = new InputStreamReader(wrapStream(connection, connection.getInputStream()), "UTF-8"); String json = IOUtils.toString(reader); - if (type != null && type == String.class) { + if (type == String.class) { return type.cast(json); } if (type != null && type != Void.class) { @@ -440,6 +492,7 @@ public void checkServerTrusted( HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Added per https://github.com/timols/java-gitlab-api/issues/44 HttpsURLConnection.setDefaultHostnameVerifier(nullVerifier); - } catch (Exception ignore) {} + } catch (Exception ignore) { + } } } diff --git a/src/main/java/org/gitlab/api/models/GitlabAccessToken.java b/src/main/java/org/gitlab/api/models/GitlabAccessToken.java new file mode 100644 index 00000000..666cb6d7 --- /dev/null +++ b/src/main/java/org/gitlab/api/models/GitlabAccessToken.java @@ -0,0 +1,65 @@ +package org.gitlab.api.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class GitlabAccessToken { + @JsonProperty("access_token") + private String accessToken; + @JsonProperty("token_type") + private String tokenType; + @JsonProperty("expires_in") + private long expiresIn; + @JsonProperty("refresh_token") + private String refreshToken; + private String scope; + @JsonProperty("created_at") + private Long created_at; + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public Long getCreated_at() { + return created_at; + } + + public void setCreated_at(Long created_at) { + this.created_at = created_at; + } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getTokenType() { + return tokenType; + } + + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } + + public long getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(long expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/src/test/java/org/gitlab/api/GitlabAPIIT.java b/src/test/java/org/gitlab/api/GitlabAPIIT.java index f8d2fc62..12f7e72c 100644 --- a/src/test/java/org/gitlab/api/GitlabAPIIT.java +++ b/src/test/java/org/gitlab/api/GitlabAPIIT.java @@ -5,6 +5,7 @@ import org.junit.Test; import java.io.FileNotFoundException; +import java.io.IOException; import java.net.URL; import java.util.List; import java.util.UUID;