Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: GitHub connectors Set repositories to watch in a project - MEED-2300 - Meeds-io/MIPs#64 #82

Merged
merged 2 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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