RepositoryBrowseResource extends ComponentSupport implements Resource { @GET public Response getHtml(@PathParam("repositoryName") final String repositoryName, @PathParam("repositoryPath") final String repositoryPath, @Context final UriInfo uriInfo) { log.debug("Get HTML directory listing for repository {} on path {}", repositoryName, repositoryPath); if (!uriInfo.getAbsolutePath().toString().endsWith("/")) { log.debug("Request does include a trailing slash, redirecting to include it"); return Response.seeOther(UriBuilder.fromUri(uriInfo.getAbsolutePath()).path("/").build()).build(); } Repository repository = repositoryManager.get(repositoryName); if (repository == null) { throw createNotFoundException(repositoryName, null); } List<String> pathSegments = new ArrayList<>(); if (!isRoot(repositoryPath)) { pathSegments = asList(repositoryPath.split("/")); } Iterable<BrowseNode> browseNodes = browseNodeQueryService.getByPath(repository, pathSegments, configuration.getMaxHtmlNodes()); final boolean permitted = securityHelper.allPermitted(new RepositoryViewPermission(repository, BROWSE)); final boolean hasChildren = browseNodes != null && !Iterables.isEmpty(browseNodes); final List<BrowseListItem> listItems = hasChildren ? browseNodeQueryService.toListItems(repository, browseNodes) : Collections.emptyList(); if (hasChildren || (isRoot(repositoryPath) && permitted)) { return Response .ok(templateHelper.render(template, initializeTemplateParameters(repositoryName, repositoryPath, listItems))) .build(); } throw createNotFoundException(repositoryName, permitted ? repositoryPath : null); } @Inject  RepositoryBrowseResource(
      final RepositoryManager repositoryManager,
      final BrowseNodeQueryService browseNodeQueryService,
      final BrowseNodeConfiguration configuration,
      final TemplateHelper templateHelper,
      final SecurityHelper securityHelper); @GET Response getHtml(@PathParam("repositoryName") final String repositoryName,
                          @PathParam("repositoryPath") final String repositoryPath,
                          @Context final UriInfo uriInfo); static final String RESOURCE_URI; }
@Test public void validateRootRequest() throws Exception { when(uriInfo.getAbsolutePath()).thenReturn(UriBuilder.fromPath(URL_PREFIX + "central/").build()); underTest.getHtml(REPOSITORY_NAME, "", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); assertThat(argument.getValue().get().get("requestPath"), is("/")); assertThat(((Collection<BrowseListItem>)argument.getValue().get().get("listItems")).size(), is(1)); assertThat(((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().getName(), is("org")); assertThat( ((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().getResourceUri(), is("org/")); assertThat( ((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().isCollection(), is(true)); }
@Test public void validateNonRootRequest() throws Exception { when(uriInfo.getAbsolutePath()).thenReturn(UriBuilder.fromPath(URL_PREFIX + "central/org/").build()); underTest.getHtml(REPOSITORY_NAME, "org/", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); assertThat(argument.getValue().get().get("requestPath"), is("/org/")); assertThat(((Collection<BrowseListItem>)argument.getValue().get().get("listItems")).size(), is(1)); assertThat(((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().getName(), is("sonatype")); assertThat( ((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().getResourceUri(), is("sonatype/")); assertThat( ((Collection<BrowseListItem>) argument.getValue().get().get("listItems")).iterator().next().isCollection(), is(true)); }
@Test public void validateRootRequestWithoutTrailingSlash() throws Exception { when(uriInfo.getAbsolutePath()).thenReturn( UriBuilder.fromPath(URL_PREFIX + "central").build()); Response response = underTest.getHtml(REPOSITORY_NAME, "", uriInfo); assertThat(response.getStatus(), is(303)); assertThat(response.getHeaders().get("location").get(0).toString(), is(URL_PREFIX + "central/")); }
@Test public void validateNonRootRequestWithoutTrailingSlash() throws Exception { when(uriInfo.getAbsolutePath()).thenReturn( UriBuilder.fromPath(URL_PREFIX + "central/org").build()); Response response = underTest.getHtml(REPOSITORY_NAME, "org", uriInfo); assertThat(response.getStatus(), is(303)); assertThat(response.getHeaders().get("location").get(0).toString(), is(URL_PREFIX + "central/org/")); }
@Test public void validatePathNotFoundRequest() throws Exception { expectedException.expect(WebApplicationException.class); expectedException.expectMessage("Path not found"); underTest.getHtml(REPOSITORY_NAME, "missing", uriInfo); }
@Test public void validatePathNotFoundRequestNotAuthorized() throws Exception { when(securityHelper.allPermitted(any())).thenReturn(false); expectedException.expect(WebApplicationException.class); expectedException.expectMessage("Repository not found"); underTest.getHtml(REPOSITORY_NAME, "missing", uriInfo); }
@Test public void validateRepositoryNotFoundRequest() throws Exception { expectedException.expect(WebApplicationException.class); expectedException.expectMessage("Repository not found"); underTest.getHtml("missing", "org", uriInfo); }
@Test public void validateRepositoryNotAuthorizedRequest() throws Exception { when(browseNodeQueryService.getByPath(repository, Collections.singletonList("org"), configuration.getMaxHtmlNodes())) .thenReturn(Collections.emptyList()); when(securityHelper.allPermitted(any())).thenReturn(false); expectedException.expect(WebApplicationException.class); expectedException.expectMessage("Repository not found"); underTest.getHtml(REPOSITORY_NAME, "org", uriInfo); }
@Test public void validateRepositoryWithNoBrowseNodesRequest() throws Exception { when(browseNodeQueryService.getByPath(repository, Collections.emptyList(), configuration.getMaxHtmlNodes())) .thenReturn(Collections.emptyList()); underTest.getHtml(REPOSITORY_NAME, "", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); assertThat(((Collection<BrowseListItem>)argument.getValue().get().get("listItems")).size(), is(0)); }
@Test public void validateRepositoryWithNoBrowseNodesRequest_nullResponseFromGetChildrenByPath() throws Exception { when(browseNodeQueryService.getByPath(repository, Collections.emptyList(), configuration.getMaxHtmlNodes())) .thenReturn(null); underTest.getHtml(REPOSITORY_NAME, "", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); assertThat(((Collection<BrowseListItem>)argument.getValue().get().get("listItems")).size(), is(0)); }
@Test public void validateAssetFoldersAreTreatedLikeFolders() { BrowseNode folderAsset = browseNode("folderAsset", mock(EntityId.class), false); when(browseNodeQueryService.getByPath(repository, Collections.emptyList(), configuration.getMaxHtmlNodes())) .thenReturn(asList(folderAsset)); BrowseListItem folderListItem = mock(BrowseListItem.class); when(folderListItem.getName()).thenReturn("folderAsset"); when(folderListItem.getResourceUri()).thenReturn("folderAsset/"); when(folderListItem.isCollection()).thenReturn(true); when(browseNodeQueryService.toListItems(repository, asList(folderAsset))) .thenReturn(Collections.singletonList(folderListItem)); underTest.getHtml(REPOSITORY_NAME, "", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); List<BrowseListItem> listItems = (List<BrowseListItem>) argument.getValue().get().get("listItems"); assertThat(listItems.size(), is(1)); assertThat(listItems.get(0).getName(), is("folderAsset")); assertThat(listItems.get(0).getResourceUri(), is("folderAsset/")); assertThat(listItems.get(0).isCollection(), is(true)); }
@Test public void validateAssetUriIsUrlEscapedToPreventXss() { BrowseNode browseNode = browseNode("<img src=\"foo\">"); when(browseNodeQueryService.getByPath(repository, Collections.emptyList(), configuration.getMaxHtmlNodes())) .thenReturn(asList(browseNode)); BrowseListItem listItem = mock(BrowseListItem.class); when(listItem.getName()).thenReturn("<img src=\"foo\">"); when(listItem.getResourceUri()).thenReturn("%3Cimg%20src%3D%22foo%22%3E/"); when(browseNodeQueryService.toListItems(repository, asList(browseNode))) .thenReturn(Collections.singletonList(listItem)); underTest.getHtml(REPOSITORY_NAME, "", uriInfo); ArgumentCaptor<TemplateParameters> argument = ArgumentCaptor.forClass(TemplateParameters.class); verify(templateHelper).render(any(), argument.capture()); List<BrowseListItem> listItems = (List<BrowseListItem>) argument.getValue().get().get("listItems"); assertThat(listItems.size(), is(1)); assertThat(listItems.get(0).getName(), is("<img src=\"foo\">")); assertThat(listItems.get(0).getResourceUri(), is("%3Cimg%20src%3D%22foo%22%3E/")); }