diff --git a/src/main/java/org/radarbase/appserver/controller/RadarProjectController.java b/src/main/java/org/radarbase/appserver/controller/RadarProjectController.java index f51de00d..ba1e321f 100644 --- a/src/main/java/org/radarbase/appserver/controller/RadarProjectController.java +++ b/src/main/java/org/radarbase/appserver/controller/RadarProjectController.java @@ -129,27 +129,8 @@ public ResponseEntity addProject( public ResponseEntity updateProject( @Valid @PathParam("projectId") String projectId, @Valid @RequestBody ProjectDto projectDto, HttpServletRequest request) { - - if (authorization != null) { - RadarToken token = (RadarToken) request.getAttribute(AuthAspect.TOKEN_KEY); - if (authorization.hasPermission( - token, - AuthPermissions.UPDATE, - AuthEntities.SUBJECT, - PermissionOn.PROJECT, - projectDto.getProjectId(), - null, - null)) { - ProjectDto projectDto1 = this.projectService.updateProject(projectDto); - return ResponseEntity.ok(projectDto1); - } else { - throw new AuthorizationFailedException( - "The token does not have permission for the project " + projectDto.getProjectId()); - } - } else { ProjectDto projectDto1 = this.projectService.updateProject(projectDto); return ResponseEntity.ok(projectDto1); - } } @Authorized(permission = AuthPermissions.READ, entity = AuthEntities.PROJECT) diff --git a/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java b/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java index 980edd59..d111119b 100644 --- a/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java +++ b/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java @@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.context.request.WebRequest; +import radar.spring.auth.exception.AuthorizationFailedException; +import radar.spring.auth.exception.ResourceForbiddenException; import java.time.Instant; @@ -27,6 +29,15 @@ public final ResponseEntity handleUnhandledException(Exception ex, return new ResponseEntity<>(error, status); } + @ExceptionHandler(AuthorizationFailedException.class) + public final ResponseEntity handleAuthorizationFailedException(Exception ex, WebRequest request) throws Exception { + return handleEntityWithCause(ex, request); + } + + @ExceptionHandler(ResourceForbiddenException.class) + public final ResponseEntity handleResourceForbiddenException(Exception ex, WebRequest request) throws Exception { + return handleEntityWithCause(ex, request); + } @ExceptionHandler(InvalidProjectDetailsException.class) public final ResponseEntity handleInvalidProjectDetailsException(Exception ex, WebRequest request) throws Exception { diff --git a/src/main/java/org/radarbase/appserver/service/GithubClient.java b/src/main/java/org/radarbase/appserver/service/GithubClient.java index c9af99be..f502e259 100644 --- a/src/main/java/org/radarbase/appserver/service/GithubClient.java +++ b/src/main/java/org/radarbase/appserver/service/GithubClient.java @@ -67,7 +67,7 @@ public class GithubClient { public GithubClient( @Value("${security.github.client.timeout:10}") int httpTimeout, @Value("${security.github.client.token:}") String githubToken) { - this.authorizationHeader = githubToken != null ? "Bearer " + githubToken.trim() : ""; + this.authorizationHeader = githubToken.isEmpty() ? "" : "Bearer " + githubToken.trim(); this.httpTimeout = Duration.ofSeconds(httpTimeout); this.client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) @@ -76,31 +76,36 @@ public GithubClient( .build(); } - public String getGithubContent(String url) throws IOException, InterruptedException { + public String getGithubContent(String url, boolean authenticated) throws IOException, InterruptedException { log.debug("Fetching Github URL {}", url); - URI uri = URI.create(url); - HttpResponse response = makeRequest(uri); + HttpResponse response = makeRequest(getRequest(URI.create(url), authenticated)); if (response.statusCode() >= 200 && response.statusCode() < 300) { checkContentLengthHeader(response); - try (InputStream inputStream = response.body()) { byte[] bytes = inputStream.readNBytes(maxContentLength + 1); checkContentLength(bytes.length); return new String(bytes); } + } else if (response.statusCode() == 401 && authenticated) { + log.warn("Unauthorized access to Github content from URL {}, retrying..", url); + return getGithubContent(url, false); } else { log.error("Error getting Github content from URL {} : {}", url, response); throw new ResponseStatusException( HttpStatus.valueOf(response.statusCode()), "Github content could not be retrieved"); - } + } + } + + public String getGithubContent(String url) throws IOException, InterruptedException { + return getGithubContent(url, true); } - private HttpResponse makeRequest(URI uri) throws InterruptedException { + private HttpResponse makeRequest(HttpRequest request) throws InterruptedException { try { - return client.send(getRequest(uri), HttpResponse.BodyHandlers.ofInputStream()); + return client.send(request, HttpResponse.BodyHandlers.ofInputStream()); } catch (IOException ex) { - log.error("Failed to retrieve data from github {}: {}", uri, ex.toString()); + log.error("Failed to retrieve data from github {}: {}", request.uri(), ex.toString()); throw new ResponseStatusException(HttpStatus.BAD_GATEWAY, "Github responded with an error."); } } @@ -136,13 +141,14 @@ public URI getValidGithubUri(URI uri) throws IOException { } } - private HttpRequest getRequest(URI uri) throws IOException { + private HttpRequest getRequest(URI uri, boolean authenticated) throws IOException { URI validUri = this.getValidGithubUri(uri); HttpRequest.Builder request = HttpRequest.newBuilder(validUri) .header("Accept", GITHUB_API_ACCEPT_HEADER) .GET() .timeout(httpTimeout); - if (!authorizationHeader.isEmpty()) { + if (!this.authorizationHeader.isEmpty() && authenticated) { + log.info("Adding authorization header to request"); request.header("Authorization", authorizationHeader); } return request.build();