diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java index 8a122cf3b5f7a1a559cc8ec5b470a3e852a09830..b25d989c073e670b7952752470e2ebd73ce30035 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java @@ -93,7 +93,6 @@ import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessResult; -import org.olat.restapi.security.RestSecurityHelper; import org.olat.restapi.support.ObjectFactory; import org.olat.restapi.support.vo.CourseConfigVO; import org.olat.restapi.support.vo.CourseVO; @@ -276,37 +275,33 @@ public class CourseWebService { @Path("file") @Produces({ "application/zip", MediaType.APPLICATION_OCTET_STREAM }) public Response getRepoFileById(@Context HttpServletRequest request) { - if(!isAuthor(request)) { - return Response.serverError().status(Status.UNAUTHORIZED).build(); - } - RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class); RepositoryEntry re = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); if (re == null) { return Response.serverError().status(Status.NOT_FOUND).build(); } - + RepositoryHandler typeToDownload = RepositoryHandlerFactory.getInstance().getRepositoryHandler(re); if (typeToDownload == null) { return Response.serverError().status(Status.NOT_FOUND).build(); } + + Identity identity = getIdentity(request); + boolean canDownload = re.getCanDownload() && typeToDownload.supportsDownload(); + if (isAdmin(request) || RepositoryManager.getInstance().isOwnerOfRepositoryEntry(identity, re)) { + canDownload = true; + } else if(!isAuthor(request)) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + if(!canDownload) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } OLATResource ores = OLATResourceManager.getInstance().findResourceable(re.getOlatResource()); if (ores == null) { return Response.serverError().status(Status.NOT_FOUND).build(); } - Identity identity = getIdentity(request); - boolean isAuthor = RestSecurityHelper.isAuthor(request); - boolean isOwner = RepositoryManager.getInstance().isOwnerOfRepositoryEntry(identity, re); - if (!(isAuthor | isOwner)) { - return Response.serverError().status(Status.UNAUTHORIZED).build(); - } - boolean canDownload = re.getCanDownload() && typeToDownload.supportsDownload(); - if (!canDownload) { - return Response.serverError().status(Status.NOT_ACCEPTABLE).build(); - } - boolean isAlreadyLocked = typeToDownload.isLocked(ores); LockResult lockResult = null; try { diff --git a/src/test/java/org/olat/restapi/CourseTest.java b/src/test/java/org/olat/restapi/CourseTest.java index b5f47ec8bf02ac80b2bb86474e502fbd0ba47a58..2bb9fb861a86d1cce1243f9d8b4572167ad0c7be 100644 --- a/src/test/java/org/olat/restapi/CourseTest.java +++ b/src/test/java/org/olat/restapi/CourseTest.java @@ -614,6 +614,62 @@ public class CourseTest extends OlatJerseyTestCase { Assert.assertEquals(0, repositoryEntry.getAccess()); } + @Test + public void exportCourse() + throws IOException, URISyntaxException { + Assert.assertTrue(conn.login("administrator", "openolat")); + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("course-owner"); + RepositoryEntry course = JunitTestHelper.deployBasicCourse(author); + dbInstance.closeSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses") + .path(course.getOlatResource().getResourceableId().toString()).path("file").build(); + HttpGet method = conn.createGet(request, "application/zip", true); + HttpResponse response = conn.execute(method); + + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + byte[] exportedFile = EntityUtils.toByteArray(response.getEntity()); + Assert.assertTrue(exportedFile.length > 1000); + } + + @Test + public void exportCourse_owner() + throws IOException, URISyntaxException { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("course-owner-2"); + RepositoryEntry course = JunitTestHelper.deployBasicCourse(author); + dbInstance.closeSession(); + + Assert.assertTrue(conn.login(author.getName(), "A6B7C8")); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses") + .path(course.getOlatResource().getResourceableId().toString()).path("file").build(); + HttpGet method = conn.createGet(request, "application/zip", true); + HttpResponse response = conn.execute(method); + + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + byte[] exportedFile = EntityUtils.toByteArray(response.getEntity()); + Assert.assertTrue(exportedFile.length > 1000); + } + + @Test + public void exportCourse_notOwner() + throws IOException, URISyntaxException { + Identity owner = JunitTestHelper.createAndPersistIdentityAsRndUser("course-owner-3"); + Identity otherUser = JunitTestHelper.createAndPersistIdentityAsRndUser("course-owner-4"); + RepositoryEntry course = JunitTestHelper.deployBasicCourse(owner); + dbInstance.closeSession(); + + Assert.assertTrue(conn.login(otherUser.getName(), "A6B7C8")); + + URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses") + .path(course.getOlatResource().getResourceableId().toString()).path("file").build(); + HttpGet method = conn.createGet(request, "application/zip", true); + HttpResponse response = conn.execute(method); + + Assert.assertEquals(401, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + } + protected List<UserVO> parseUserArray(InputStream body) { try { ObjectMapper mapper = new ObjectMapper(jsonFactory);