Skip to content

Commit

Permalink
feat: GitHub connectors Set repositories to watch in a project - MEED…
Browse files Browse the repository at this point in the history
…-2300 - Meeds-io/MIPs#64 (#82)

Allow rewarding users to enable/disable organization repositories from watch
  • Loading branch information
AzmiTouil authored and exo-swf committed Aug 28, 2023
1 parent bdcffb4 commit 7459228
Show file tree
Hide file tree
Showing 17 changed files with 833 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2023 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.exoplatform.gamification.github.model;

import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString(callSuper = true)
public class RemoteRepository {

private long id;

private String name;

private String description;

private boolean enabled;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ public GithubWebHookRest(WebhookService webhookService, GithubTriggerService git
public Response githubEvent(// NOSONAR
@HeaderParam("x-github-event") String event,
@HeaderParam("x-hub-signature") String signature,
String obj) {
String payload) {

if (!webhookService.verifyWebhookSecret(obj, signature)) {
if (!webhookService.verifyWebhookSecret(payload, signature)) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
if (!webhookService.isWebHookRepositoryEnabled(payload)) {
return Response.noContent().build();
}
try {
githubTriggerService.handleTrigger(obj, event);
githubTriggerService.handleTrigger(payload, event);
return Response.ok().build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@

import org.exoplatform.commons.ObjectAlreadyExistsException;
import org.exoplatform.commons.exception.ObjectNotFoundException;
import org.exoplatform.gamification.github.model.RemoteRepository;
import org.exoplatform.gamification.github.model.WebHook;
import org.exoplatform.gamification.github.rest.builder.WebHookBuilder;
import org.exoplatform.gamification.github.rest.model.RepositoryList;
import org.exoplatform.gamification.github.rest.model.WebHookList;
import org.exoplatform.gamification.github.rest.model.WebHookRestEntity;
import org.exoplatform.gamification.github.services.WebhookService;
Expand All @@ -45,6 +47,8 @@
@Path("/gamification/connectors/github/hooks")
public class HooksManagementRest implements ResourceContainer {

public static final String GITHUB_HOOK_NOT_FOUND = "The GitHub hook doesn't exit";

private final WebhookService webhookService;

public HooksManagementRest(WebhookService webhookService) {
Expand Down Expand Up @@ -134,7 +138,7 @@ public Response updateWebHookAccessToken(@Parameter(description = "webHook id",
} catch (IllegalAccessException e) {
return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build();
} catch (ObjectNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity("The GitHub hook doesn't exit").build();
return Response.status(Response.Status.NOT_FOUND).entity(GITHUB_HOOK_NOT_FOUND).build();
}
}

Expand All @@ -158,7 +162,81 @@ public Response deleteWebhookHook(@Parameter(description = "GitHub organization
} catch (IllegalAccessException e) {
return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
} catch (ObjectNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity("The GitHub hook doesn't exit").build();
return Response.status(Response.Status.NOT_FOUND).entity(GITHUB_HOOK_NOT_FOUND).build();
}
}

@GET
@Path("{organizationId}/repos")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("users")
@Operation(summary = "Retrieves the list GitHub organization repositories", method = "GET")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Request fulfilled"),
@ApiResponse(responseCode = "401", description = "Unauthorized operation"), })
public Response getWebHookRepos(@Parameter(description = "GitHub organization id", required = true) @PathParam("organizationId") long organizationId,
@QueryParam("offset") int offset,
@Parameter(description = "Query results limit", required = true) @QueryParam("limit") int limit,
@Parameter(description = "Repositories total size") @Schema(defaultValue = "false") @QueryParam("returnSize") boolean returnSize) {

String currentUser = getCurrentUser();
List<RemoteRepository> remoteRepositories;
try {
RepositoryList repositoryList = new RepositoryList();
remoteRepositories = webhookService.retrieveOrganizationRepos(organizationId, currentUser, offset, limit);
if (returnSize) {
int size = webhookService.countOrganizationRepos(organizationId, currentUser);
repositoryList.setSize(size);
}
repositoryList.setRemoteRepositories(remoteRepositories);
repositoryList.setOffset(offset);
repositoryList.setLimit(limit);
return Response.ok(repositoryList).build();
} catch (IllegalAccessException e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
} catch (ObjectNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity(GITHUB_HOOK_NOT_FOUND).build();
}
}

@Path("repo/status")
@POST
@RolesAllowed("users")
@Operation(summary = "enables/disables webhook repository.", description = "enables/disables webhook repository", method = "POST")
@ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Request fulfilled"),
@ApiResponse(responseCode = "400", description = "Bad request"),
@ApiResponse(responseCode = "401", description = "Unauthorized operation"),
@ApiResponse(responseCode = "500", description = "Internal server error"), })
public Response updateWebHookRepoStatus(@Parameter(description = "GitHub organization remote Id", required = true) @FormParam("organizationId") long organizationId,
@Parameter(description = "Organization repository remote Id", required = true) @FormParam("repositoryId") long repositoryId,
@Parameter(description = "Organization repository status enabled/disabled. possible values: true for enabled, else false", required = true) @FormParam("enabled") boolean enabled) {

String currentUser = getCurrentUser();
try {
webhookService.setWebHookRepositoryEnabled(organizationId, repositoryId, enabled, currentUser);
return Response.noContent().build();
} catch (IllegalAccessException e) {
return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
}
}

@Path("watchScope/status")
@POST
@RolesAllowed("users")
@Operation(summary = "Limit webhook watch scope or not", description = "Limit webhook watch scope or not", method = "POST")
@ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Request fulfilled"),
@ApiResponse(responseCode = "400", description = "Bad request"),
@ApiResponse(responseCode = "401", description = "Unauthorized operation"),
@ApiResponse(responseCode = "500", description = "Internal server error"), })
public Response updateWebHookWatchScope(@Parameter(description = "GitHub organization remote Id", required = true) @FormParam("organizationId") long organizationId,
@Parameter(description = "webhook watch scope limited status enabled/disabled. possible values: true for enabled, else false", required = true) @FormParam("enabled") boolean enabled) {

String currentUser = getCurrentUser();
try {
webhookService.setWebHookWatchLimitEnabled(organizationId, enabled, currentUser);
return Response.noContent().build();
} catch (IllegalAccessException e) {
return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public static WebHookRestEntity toRestEntity(WebhookService webhookService, WebH
remoteOrganization.getName(),
remoteOrganization.getTitle(),
remoteOrganization.getDescription(),
remoteOrganization.getAvatarUrl());
remoteOrganization.getAvatarUrl(),
webhookService.isWebHookWatchLimitEnabled(webHook.getOrganizationId()));
}

public static List<WebHookRestEntity> toRestEntities(WebhookService webhookService, Collection<WebHook> webHooks) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2023 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.exoplatform.gamification.github.rest.model;

import java.util.List;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.exoplatform.gamification.github.model.RemoteRepository;

@NoArgsConstructor
@Getter
@Setter
public class RepositoryList {

private List<RemoteRepository> remoteRepositories;

private int offset;

private int limit;

private int size;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2023 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.exoplatform.gamification.github.rest.model;

import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class RepositoryRestEntity {

private long id;

private String title;

private String description;

private boolean enabled;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class WebHookRestEntity {

private String avatarUrl;

private boolean watchScopeLimited;

public WebHookRestEntity(long id, // NOSONAR
long webhookId,
long organizationId,
Expand All @@ -62,7 +64,8 @@ public WebHookRestEntity(long id, // NOSONAR
String name,
String title,
String description,
String avatarUrl) {
String avatarUrl,
boolean watchScopeLimited) {

this.id = id;
this.webhookId = webhookId;
Expand All @@ -77,5 +80,6 @@ public WebHookRestEntity(long id, // NOSONAR
this.title = title;
this.description = description;
this.avatarUrl = avatarUrl;
this.watchScopeLimited = watchScopeLimited;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.exoplatform.commons.ObjectAlreadyExistsException;
import org.exoplatform.commons.exception.ObjectNotFoundException;
import org.exoplatform.gamification.github.model.RemoteOrganization;
import org.exoplatform.gamification.github.model.RemoteRepository;
import org.exoplatform.gamification.github.model.WebHook;

import java.util.List;
Expand Down Expand Up @@ -110,6 +111,82 @@ void updateWebHookAccessToken(long webHookId, String accessToken, String current
*/
boolean verifyWebhookSecret(String payload, String signature);

/**
* Check if webhook repository is enabled
*
* @param payload payload The raw payload of the webhook request.
* @return true if the intended repository is enabled, else false.
*/
boolean isWebHookRepositoryEnabled(String payload);

/**
* Check if webhook repository is enabled
*
* @param organizationRemoteId gitHub organization remote Id
* @param repositoryRemoteId gitHub repository remote Id
* @return true if the intended repository is enabled, else false.
*/
boolean isWebHookRepositoryEnabled(long organizationRemoteId, long repositoryRemoteId);

/**
* enables/disables repository
*
* @param organizationRemoteId gitHub organization remote Id
* @param repositoryRemoteId gitHub repository remote Id
* @param enabled true to enabled, else false
* @param currentUser user name attempting to enables/disables repository.
*/
void setWebHookRepositoryEnabled(long organizationRemoteId,
long repositoryRemoteId,
boolean enabled,
String currentUser) throws IllegalAccessException;

/**
* Check if webhook watch limit is enabled
*
* @param organizationRemoteId gitHub organization remote Id
* @return true if webHook watch limit is enabled, else false.
*/
boolean isWebHookWatchLimitEnabled(long organizationRemoteId);

/**
* Limit webhook watch scope or not
*
* @param organizationRemoteId gitHub organization remote Id
* @param enabled true to enabled, else false
* @param currentUser user name attempting to enables/disables webHook watch
* limit.
*/
void setWebHookWatchLimitEnabled(long organizationRemoteId, boolean enabled, String currentUser) throws IllegalAccessException;

/**
* Retrieve available github organization repositories.
*
* @param organizationRemoteId gitHub organization remote Id
* @param currentUser user name attempting to access remote organization
* repositories
* @throws IllegalAccessException when user is not authorized to access remote
* organization repositories
* @return {@link List} of {@link RemoteRepository}
*/
List<RemoteRepository> retrieveOrganizationRepos(long organizationRemoteId,
String currentUser,
int page,
int perPage) throws IllegalAccessException, ObjectNotFoundException;

/**
* Count available github organization repositories.
*
* @param organizationRemoteId gitHub organization remote Id
* @param currentUser user name attempting to access remote organization
* repositories
* @throws IllegalAccessException when user is not authorized to access remote
* organization repositories
* @return Repositories count
*/
int countOrganizationRepos(long organizationRemoteId, String currentUser) throws IllegalAccessException,
ObjectNotFoundException;

/**
* create gamification history
*
Expand All @@ -119,4 +196,5 @@ void updateWebHookAccessToken(long webHookId, String accessToken, String current
* @param object Object link
*/
void createGamificationHistory(String ruleTitle, String senderId, String receiverId, String object);

}
Loading

0 comments on commit 7459228

Please sign in to comment.