From b3ce8870d8d60c5211ea2fdc3b18ae49b9a43c20 Mon Sep 17 00:00:00 2001 From: Azmi Touil Date: Fri, 15 Sep 2023 17:00:44 +0200 Subject: [PATCH 1/2] feat: Improve URL for connectors - MEED-2408 - Meeds-io/MIPs#64 This PR will add github connector URLs --- .../github/rest/HooksManagementRest.java | 28 +++++++++++++++++++ .../github/services/WebhookService.java | 26 +++++++++++++++-- .../services/impl/WebhookServiceImpl.java | 19 +++++++++++++ .../components/GithubAdminConnectorItem.vue | 28 ++++++++++++++++++- .../js/GithubConnectorService.js | 13 +++++++++ 5 files changed, 110 insertions(+), 4 deletions(-) diff --git a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/rest/HooksManagementRest.java b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/rest/HooksManagementRest.java index 97b916a7..207daade 100644 --- a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/rest/HooksManagementRest.java +++ b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/rest/HooksManagementRest.java @@ -88,6 +88,34 @@ public Response getWebHooks(@QueryParam("offset") int offset, } } + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{webHookId}") + @RolesAllowed("users") + @Operation(summary = "Retrieves a webHook by its technical identifier", method = "GET") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Request fulfilled"), + @ApiResponse(responseCode = "401", description = "Unauthorized operation"), + @ApiResponse(responseCode = "400", description = "Invalid query input"), + @ApiResponse(responseCode = "404", description = "Not found"), + @ApiResponse(responseCode = "500", description = "Internal server error"), }) + public Response getWebHookById(@Parameter(description = "WebHook technical identifier", required = true) @PathParam("webHookId") long webHookId) { + if (webHookId == 0) { + return Response.status(Response.Status.BAD_REQUEST).entity("WebHook Id must be not null").build(); + } + String currentUser = getCurrentUser(); + try { + WebHook webHook = webhookService.getWebhookId(webHookId, currentUser); + return Response.ok(WebHookBuilder.toRestEntity(webhookService, githubConsumerService, webHook)).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (IllegalAccessException e) { + return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); + } catch (ObjectNotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); + } + } + @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @RolesAllowed("users") diff --git a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/WebhookService.java b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/WebhookService.java index 108b89ed..deba055d 100644 --- a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/WebhookService.java +++ b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/WebhookService.java @@ -37,6 +37,25 @@ public interface WebhookService { */ List getWebhooks(String currentUser, int offset, int limit, boolean forceUpdate) throws IllegalAccessException; + /** + * Retrieves a webHook identified by its technical identifier. + * + * @param webhookId WebHook technical identifier + * @return found {@link WebHook} + */ + WebHook getWebhookId(long webhookId); + + /** + * Retrieves a webHook identified by its technical identifier accessed by a user + * + * @param webhookId WebHook technical identifier + * @param username user name attempting to access connector webhook + * @return found {@link WebHook} + * @throws IllegalAccessException when user is not authorized to access webhook + * @throws ObjectNotFoundException webhook not found + */ + WebHook getWebhookId(long webhookId, String username) throws IllegalAccessException, ObjectNotFoundException; + /** * Get available github hooks using offset and limit. * @@ -197,8 +216,9 @@ int countOrganizationRepos(long organizationRemoteId, String currentUser) throws * @throws IllegalAccessException when user is not authorized enables/disables * organization event */ - void setEventEnabledForOrganization(long eventId, long organizationId, boolean enabled, String currentUser) throws IllegalAccessException, - ObjectNotFoundException; - + void setEventEnabledForOrganization(long eventId, + long organizationId, + boolean enabled, + String currentUser) throws IllegalAccessException, ObjectNotFoundException; } diff --git a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/impl/WebhookServiceImpl.java b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/impl/WebhookServiceImpl.java index 3b2acbcf..568ef1d1 100644 --- a/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/impl/WebhookServiceImpl.java +++ b/gamification-github-services/src/main/java/org/exoplatform/gamification/github/services/impl/WebhookServiceImpl.java @@ -82,6 +82,25 @@ public List getWebhooks(String currentUser, int offset, int limit, bool return getWebhooks(offset, limit, forceUpdate); } + public WebHook getWebhookId(long webhookId, String username) throws IllegalAccessException, ObjectNotFoundException { + if (!Utils.isRewardingManager(username)) { + throw new IllegalAccessException(AUTHORIZED_TO_ACCESS_GIT_HUB_HOOKS); + } + WebHook webHook = getWebhookId(webhookId); + if (webHook == null) { + throw new ObjectNotFoundException("Webhook doesn't exist"); + } + return webHook; + } + + @Override + public WebHook getWebhookId(long webhookId) { + if (webhookId <= 0) { + throw new IllegalArgumentException("Webhook id is mandatory"); + } + return webHookStorage.getWebHookById(webhookId); + } + public List getWebhooks(int offset, int limit, boolean forceUpdate) { if (forceUpdate) { forceUpdateWebhooks(); diff --git a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue index d24df181..d796e752 100644 --- a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue +++ b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue @@ -163,7 +163,8 @@ export default { editing: false, displayHookDetail: false, selectedHook: null, - webhooks: [] + webhooks: [], + githubConnectorLinkBasePath: '/portal/g/:platform:rewarding/gamificationConnectorsAdministration#github', }; }, computed: { @@ -182,6 +183,15 @@ export default { return this.connectionSettingStored && !this.enabled && this.webhooksLength > 0; }, }, + watch: { + displayHookDetail() { + if (this.displayHookDetail && this.selectedHook?.id) { + window.history.replaceState('gamification connectors', this.$t('gamification.connectors.label.connectors'), `${this.githubConnectorLinkBasePath}-${this.selectedHook?.id}`); + } else { + window.history.replaceState('gamification connectors', this.$t('gamification.connectors.label.connectors'), `${this.githubConnectorLinkBasePath}-configuration`); + } + }, + }, created() { this.$root.$on('github-hook-detail', this.openHookDetail); if (!this.apiKey && !this.secretKey && !this.redirectUrl) { @@ -196,6 +206,14 @@ export default { this.redirectUrl = redirectUrl; this.saveConnectorSetting(this.enabled); }); + const fragment = document.location.hash.substring(1); + const match = fragment.match(/github-(\d+)/); + if (match) { + const hookId = match[1]; + if (hookId) { + this.openHookDetailById(hookId); + } + } }, methods: { saveConnectorSetting(status) { @@ -237,6 +255,14 @@ export default { webhooksUpdated(webhooks){ this.webhooks = webhooks; }, + openHookDetailById(id) { + this.$githubConnectorService.getGithubWebHookById(id) + .then(hook => { + if (hook?.id) { + this.openHookDetail(hook); + } + }); + }, } }; \ No newline at end of file diff --git a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/js/GithubConnectorService.js b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/js/GithubConnectorService.js index 0f742184..c3c0decc 100644 --- a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/js/GithubConnectorService.js +++ b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/js/GithubConnectorService.js @@ -28,6 +28,19 @@ export function getGithubWebHooks(offset, limit) { }); } +export function getGithubWebHookById(hookId) { + return fetch(`${eXo.env.portal.context}/${eXo.env.portal.rest}/gamification/connectors/github/hooks/${hookId}`, { + method: 'GET', + credentials: 'include', + }).then((resp) => { + if (resp?.ok) { + return resp.json(); + } else { + throw new Error('Error when getting github webhook'); + } + }); +} + export function saveGithubWebHook(organizationName, accessToken) { const formData = new FormData(); formData.append('organizationName', organizationName); From 29cb4154d0ed7f8d33a9261e2e854ccfcd31fea3 Mon Sep 17 00:00:00 2001 From: Azmi Touil Date: Fri, 15 Sep 2023 17:12:37 +0200 Subject: [PATCH 2/2] Fix Sonar issue --- .../components/GithubAdminConnectorItem.vue | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue index d796e752..848b9878 100644 --- a/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue +++ b/gamification-github-webapp/src/main/webapp/vue-app/githubAdminConnectorExtension/components/GithubAdminConnectorItem.vue @@ -207,12 +207,10 @@ export default { this.saveConnectorSetting(this.enabled); }); const fragment = document.location.hash.substring(1); - const match = fragment.match(/github-(\d+)/); - if (match) { - const hookId = match[1]; - if (hookId) { - this.openHookDetailById(hookId); - } + const match = fragment.split('-'); + const hookId = Number(match[1]); + if (hookId) { + this.openHookDetailById(hookId); } }, methods: {