Skip to content
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
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@
<artifactId>aws-java-sdk-core</artifactId>
<version>1.12.129</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,12 @@ public boolean allowThrough(final HttpServletRequest pRequest) {
public boolean deleteUser(final User pAdmin, final User pTarget) {
return pAdmin.isAdmin();
}

public boolean allowReadSomeoneElseAnnos(final User pAnnoOwner, final User pRequester) {
if (pAnnoOwner.getId().equals(pRequester.getId())) {
return true;
} else {
return pRequester.isAdmin();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import uk.org.llgc.annotation.store.data.users.User;
import uk.org.llgc.annotation.store.adapters.StoreAdapter;
import uk.org.llgc.annotation.store.StoreConfig;
import uk.org.llgc.annotation.store.exceptions.PermissionDenied;
import uk.org.llgc.annotation.store.controllers.AuthorisationController;

import java.util.Base64;
import java.util.zip.Deflater;
Expand Down Expand Up @@ -59,26 +61,46 @@ public void init() {
_store = StoreConfig.getConfig().getStore();
}

public List<PageAnnoCount> listAnnoPages(final String pURI) {
Manifest tManifest = new Manifest();
tManifest.setURI(pURI);
protected User getCurrentUser() {
UserService tService = new UserService();
return tService.getUser();
}

try {
UserService tService = new UserService();
return _store.listAnnoPages(tManifest, tService.getUser());
} catch (IOException tExcpt) {
System.err.println("Failed to retrieve stats for " + pURI);
tExcpt.printStackTrace();
protected AuthorisationController getAuth() {
return new AuthorisationController();
}

protected User getCurrentUser(final HttpServletRequest pRequest) {
UserService tService = new UserService(pRequest);
return tService.getUser();
}

public List<PageAnnoCount> listAnnoPages(final String pURI) throws PermissionDenied {
return listAnnoPages(pURI, this.getCurrentUser());
}

public List<PageAnnoCount> listAnnoPages(final String pURI, final User pUser) throws PermissionDenied {
if (this.getAuth().allowReadSomeoneElseAnnos(pUser, this.getCurrentUser())) {
Manifest tManifest = new Manifest();
tManifest.setURI(pURI);

try {
return _store.listAnnoPages(tManifest, pUser);
} catch (IOException tExcpt) {
System.err.println("Failed to retrieve stats for " + pURI);
tExcpt.printStackTrace();
}
return new ArrayList<PageAnnoCount>();
} else {
throw new PermissionDenied("User " + this.getCurrentUser().getName() + "(" + this.getCurrentUser().getId() + ") cannot access " + pUser.getName() + "(" + pUser.getId() + ") annotations as user is not an admin");
}
return new ArrayList<PageAnnoCount>();
}

public Map<String,Integer> countAnnotations(final Manifest pManifest) {
UserService tService = new UserService();
return countAnnotations(pManifest, tService.getUser());
public Map<String,Integer> countAnnotations(final Manifest pManifest) throws PermissionDenied {
return countAnnotations(pManifest, this.getCurrentUser());
}

public Map<String,Integer> countAnnotations(final Manifest pManifest, final User pUser) {
public Map<String,Integer> countAnnotations(final Manifest pManifest, final User pUser) throws PermissionDenied {
String tKey = "stats_" + pManifest.getShortId();
HttpServletRequest tRequest = this.getRequest();
if (tRequest.getAttribute(tKey) != null) {
Expand All @@ -88,22 +110,17 @@ public Map<String,Integer> countAnnotations(final Manifest pManifest, final User
Map<String,Integer> tStats = new HashMap<String,Integer>();
tStats.put("canvas_count", 0);
tStats.put("total_annos", 0);
try {
List<PageAnnoCount> tCount = _store.listAnnoPages(pManifest, pUser);
tStats.put("canvas_count", tCount.size());
List<PageAnnoCount> tCount = this.listAnnoPages(pManifest.getURI(), pUser);
tStats.put("canvas_count", tCount.size());

int tTotalAnnos = 0;
for (PageAnnoCount tPageCount : tCount) {
tTotalAnnos += tPageCount.getCount();
}
tStats.put("total_annos", tTotalAnnos);
int tTotalAnnos = 0;
for (PageAnnoCount tPageCount : tCount) {
tTotalAnnos += tPageCount.getCount();
}
tStats.put("total_annos", tTotalAnnos);

if (tRequest.getAttribute(tKey) == null) {
tRequest.setAttribute(tKey, tStats);
}
} catch (IOException tExcpt) {
System.err.println("Failed to retrieve stats for " + pManifest.getURI());
tExcpt.printStackTrace();
if (tRequest.getAttribute(tKey) == null) {
tRequest.setAttribute(tKey, tStats);
}
return tStats;
}
Expand All @@ -119,8 +136,7 @@ protected HttpServletRequest getRequest() {

public Manifest getEnhancedManifest(final String pManifestURI) throws IOException {
Manifest tManifest = this.getManifestId(pManifestURI);
UserService tService = new UserService();
return this.getEnhancedManifest(tService.getUser(), tManifest, false);
return this.getEnhancedManifest(this.getCurrentUser(), tManifest, false);
}

public Manifest getEnhancedManifest(final User pUser, final Manifest pManifest, final boolean regenerate) throws IOException {
Expand Down Expand Up @@ -170,8 +186,7 @@ public List<PageAnnoCount> listAnnoPages(final Manifest pManifest) {
}
try {
//new PageAnnoCount(final Canvas pCanvas, final int pCount, final Manifest pManifest)
UserService tService = new UserService();
List<PageAnnoCount> tAnnosCount = _store.listAnnoPages(pManifest, tService.getUser());
List<PageAnnoCount> tAnnosCount = _store.listAnnoPages(pManifest, this.getCurrentUser());
List<PageAnnoCount> tFullCanvasList = new ArrayList<PageAnnoCount>();
for (Canvas tCanvas : pManifest.getCanvases()) {
PageAnnoCount tCanvasCount = new PageAnnoCount(tCanvas, 0, pManifest);
Expand Down Expand Up @@ -227,8 +242,7 @@ public List<Manifest> getManifests() {

public List<Manifest> getAnnoManifests() {
try {
UserService tService = new UserService();
return _store.getSkeletonManifests(tService.getUser());
return _store.getSkeletonManifests(this.getCurrentUser());
} catch (IOException tExcpt) {
return new ArrayList<Manifest>();
}
Expand All @@ -244,8 +258,7 @@ public Manifest getManifestFromCanvas(final String pCanvasURI) {
}

public AnnotationList getAnnotations(final String pCanvasURI) {
UserService tUserService = new UserService();
return this.getAnnotations(pCanvasURI, tUserService.getUser());
return this.getAnnotations(pCanvasURI, this.getCurrentUser());
}

public AnnotationList getAnnotations(final String pCanvasURI, final User pUser) {
Expand Down Expand Up @@ -304,9 +317,8 @@ public Manifest getManifestId(final String pURI) {
}

public List<Collection> getCollections(final HttpServletRequest pRequest) throws IOException {
UserService tService = new UserService(pRequest);
User tUser = tService.getUser();
String tKey = "get_collections_from_request_" + tService.getUser().getShortId();
User tUser = this.getCurrentUser(pRequest);
String tKey = "get_collections_from_request_" + tUser.getShortId();
if (this.isCached(tKey)) {
return (List<Collection>)this.getCacheObject(tKey);
}
Expand Down Expand Up @@ -352,8 +364,7 @@ public List<Collection> getCollections(final User pUser) throws IOException {

List<Collection> tCollections = new ArrayList<Collection>();

UserService tService = new UserService();
User tUser = tService.getUser();
User tUser = this.getCurrentUser();
if (tUser.isAdmin()) {
tCollections = _store.getCollections(pUser);

Expand All @@ -366,8 +377,7 @@ public List<Collection> getCollections(final User pUser) throws IOException {
public Collection getCollection(final String pID, final HttpServletRequest pRequest) throws IOException {
String tCollectionKey = "collection_";
if (pID == null || pID.length() == 0) {
UserService tService = new UserService(pRequest);
User tUser = tService.getUser();
User tUser = this.getCurrentUser(pRequest);

List<Collection> tCollections = this.getCollections(pRequest);
for (Collection tCollection : tCollections) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package uk.org.llgc.annotation.store.exceptions;

public class PermissionDenied extends Exception {
public PermissionDenied() {
super();
}

public PermissionDenied(final String pMessage) {
super(pMessage);
}
}


4 changes: 2 additions & 2 deletions src/main/webapp/admin/canvases.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<h1>Annotated Canvases for user: <h:outputText value="#{collUser.name}"/></h1>

<ul id="canvases" class="media-list">
<c:forEach items="#{storeService.listAnnoPages(param['manifest'])}" var="annoPage" varStatus="iterMetadata">
<c:forEach items="#{storeService.listAnnoPages(param['manifest'], collUser)}" var="annoPage" varStatus="iterMetadata">
<li class="manifestSummary #{className}" id="shortId">
<c:set var="short_id" value="#{annoPage.canvas.shortId}" />
<c:set var="isEmpty" value="#{annoPage.count == 0}" />
Expand Down Expand Up @@ -47,7 +47,7 @@
<div id="actionBar">
<span>
<c:if test="#{not isEmpty}">
<a class="actionLink" href="/annotations/#{collUser.shortId}/#{short_id}.json" target="_blank">Download annotations</a>
<a class="actionLink" href="/annotations/#{collUser.shortId}/#{short_id}.json" download="#{short_id}.json">Download annotations</a>
</c:if>
</span>
</div>
Expand Down
57 changes: 57 additions & 0 deletions src/test/java/uk/org/llgc/annotation/store/test/TestUsers.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
import uk.org.llgc.annotation.store.StoreConfig;
import uk.org.llgc.annotation.store.exceptions.IDConflictException;
import uk.org.llgc.annotation.store.exceptions.MalformedAnnotation;
import uk.org.llgc.annotation.store.exceptions.PermissionDenied;
import uk.org.llgc.annotation.store.data.Manifest;
import uk.org.llgc.annotation.store.data.Annotation;
import uk.org.llgc.annotation.store.data.AnnotationList;
import uk.org.llgc.annotation.store.data.SearchQuery;
import uk.org.llgc.annotation.store.data.Canvas;
import uk.org.llgc.annotation.store.data.PageAnnoCount;
import uk.org.llgc.annotation.store.data.users.User;
import uk.org.llgc.annotation.store.data.users.LocalUser;
import uk.org.llgc.annotation.store.controllers.AuthorisationController;
import uk.org.llgc.annotation.store.controllers.StoreService;
import uk.org.llgc.annotation.store.test.mocks.ControllerMocks;


import com.github.jsonldjava.utils.JsonUtils;

Expand Down Expand Up @@ -543,4 +548,56 @@ public void testDeleteUser() throws IOException, URISyntaxException {
assertNull("Found user but expected it to be deleted.", tFoundUser);
}

@Test
public void testAuthLevelListAnnos() throws IOException, IDConflictException, MalformedAnnotation, URISyntaxException, PermissionDenied {
// test listAnnoPages with non admin user but retrieving annos of someone else.
// Should be refused
User tUser = new User();
tUser.setId("http://example.com/user1");
tUser.setShortId("user1");
tUser.setName("Glen");
tUser.setEmail("glen@glen.com");
tUser.setAuthenticationMethod("test");
tUser.setAdmin(false);
tUser.setPicture("http://picture.net");
_store.saveUser(tUser);

Map<String, Object> tAnnotation = (Map<String,Object>)JsonUtils.fromInputStream(new FileInputStream(getClass().getResource("/jsonld/testManifestWithin.json").getFile()));
Annotation tAnno = new Annotation(tAnnotation);
tAnno.setCreator(tUser);

Annotation tStoredAnno = _store.addAnnotation(tAnno);

User tNormalUser = new User();
tNormalUser.setId("http://example.com/normal");
tNormalUser.setShortId("normal");
tNormalUser.setAuthenticationMethod("test");
tNormalUser.setAdmin(false);
_store.saveUser(tNormalUser);


StoreService storeService = ControllerMocks.getStoreServiceWithUser(tUser);
List<PageAnnoCount> tAnnos = storeService.listAnnoPages("http://example.com/manfiest/test/manifest.json", tUser);

assertEquals("With same user there should be 1 result. ", 1, tAnnos.size());

Exception exception = assertThrows(PermissionDenied.class, () -> {
final StoreService tNormalUserService = ControllerMocks.getStoreServiceWithUser(tNormalUser);
tNormalUserService.listAnnoPages("http://example.com/manfiest/test/manifest.json", tUser);
});

User tAdmin = new User();
tAdmin.setId("http://example.com/admin");
tAdmin.setShortId("admin");
tAdmin.setAuthenticationMethod("test");
tAdmin.setAdmin(true);
_store.saveUser(tAdmin);

storeService = ControllerMocks.getStoreServiceWithUser(tAdmin);
tAnnos = storeService.listAnnoPages("http://example.com/manfiest/test/manifest.json", tUser);

assertEquals("Admin should be able to see the 1 result. ", 1, tAnnos.size());

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package uk.org.llgc.annotation.store.test.mocks;

import uk.org.llgc.annotation.store.data.users.User;
import uk.org.llgc.annotation.store.controllers.StoreService;

public class ControllerMocks {

public static StoreService getStoreServiceWithUser(final User pUser) {
StoreService tService = new StoreService() {
public User getCurrentUser() {
return pUser;
}
};
tService.init();

return tService;
}
}
Loading