Skip to content

Commit 44b2d5a

Browse files
authored
Only show thumbnails if user has viewAccessCopies permissions (#1630)
* Only show thumbnails if user has viewAccessCopies permissions * Simplify thumbnail permissions check * Fix thumbnail IT tests * Let the client handle displaying a thumbnail or not * Update test permission
1 parent d822e02 commit 44b2d5a

File tree

10 files changed

+43
-45
lines changed

10 files changed

+43
-45
lines changed

auth-api/src/main/java/edu/unc/lib/boxc/auth/api/services/DatastreamPermissionUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ public class DatastreamPermissionUtil {
3030
DS_PERMISSION_MAP.put(DatastreamType.ORIGINAL_FILE, Permission.viewOriginal);
3131
DS_PERMISSION_MAP.put(DatastreamType.TECHNICAL_METADATA, Permission.viewHidden);
3232
DS_PERMISSION_MAP.put(DatastreamType.TECHNICAL_METADATA_HISTORY, Permission.viewHidden);
33-
DS_PERMISSION_MAP.put(DatastreamType.THUMBNAIL_SMALL, Permission.viewMetadata);
34-
DS_PERMISSION_MAP.put(DatastreamType.THUMBNAIL_LARGE, Permission.viewMetadata);
33+
DS_PERMISSION_MAP.put(DatastreamType.THUMBNAIL_SMALL, Permission.viewAccessCopies);
34+
DS_PERMISSION_MAP.put(DatastreamType.THUMBNAIL_LARGE, Permission.viewAccessCopies);
3535
}
3636

3737
private DatastreamPermissionUtil() {

static/js/vue-cdr-access/src/components/full_record/fileList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export default {
135135
render: (data, type, row) => {
136136
let img;
137137
138-
if ('thumbnail_url' in row) {
138+
if ('thumbnail_url' in row && this.hasPermission(row,'viewAccessCopies')) {
139139
const thumbnail_title = this.$t('full_record.thumbnail_title', { title: row.title })
140140
img = `<img class="data-thumb" loading="lazy" src="${row.thumbnail_url}"` +
141141
` alt="${thumbnail_title}">`;

static/js/vue-cdr-access/src/components/full_record/thumbnail.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export default {
105105
},
106106
107107
src() {
108-
if (this.objectData.thumbnail_url !== undefined) {
108+
if (this.objectData.thumbnail_url !== undefined && this.hasPermission(this.objectData, 'viewAccessCopies')) {
109109
return this.objectData.thumbnail_url;
110110
}
111111

static/js/vue-cdr-access/tests/unit/thumbnail.spec.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,21 @@ describe('thumbnail.vue', () => {
128128
});
129129
});
130130

131-
it('displays a thumbnail, if present', () => {
131+
it('displays a thumbnail, if present and user has viewAccessCopies permissions', () => {
132132
expect(wrapper.find('.thumbnail .thumbnail-viewer').exists()).toBe(true);
133+
expect(wrapper.find('i.placeholder').exists()).toBe(false);
133134
expect(wrapper.find('a').attributes('class'))
134135
.toEqual('thumbnail thumbnail-size-large has_tooltip')
135136
});
136137

138+
it('does not display a thumbnail if user does not have viewAccessCopies permissions', async () => {
139+
let updatedRecordData = cloneDeep(recordData);
140+
updatedRecordData.briefObject.permissions = ['viewMetadata'];
141+
await wrapper.setProps({ thumbnailData: updatedRecordData });
142+
expect(wrapper.find('i.placeholder').exists()).toBe(true);
143+
expect(wrapper.find('.thumbnail .thumbnail-viewer').exists()).toBe(false);
144+
});
145+
137146
it('displays a placeholder, if no thumbnail', async () => {
138147
let updatedRecordData = cloneDeep(recordData);
139148
updatedRecordData.briefObject.thumbnail_url = undefined;

web-common/src/main/java/edu/unc/lib/boxc/web/common/services/AccessCopiesService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public String getThumbnailId(ContentObjectRecord contentObjectRecord, AccessGrou
136136
log.debug("Found thumbnail object directly assigned to object {}", thumbId);
137137
return thumbId;
138138
}
139+
139140
// Don't need to check any further if object isn't a work or doesn't contain files with thumbnails
140141
if (!ResourceType.Work.name().equals(contentObjectRecord.getResourceType())
141142
|| contentObjectRecord.getFileFormatCategory() == null

web-common/src/main/java/edu/unc/lib/boxc/web/common/services/PermissionsHelper.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,6 @@ public boolean hasOriginalAccess(AccessGroupSet principals, ContentObjectRecord
4848
return hasDatastreamAccess(principals, ORIGINAL_FILE, metadata);
4949
}
5050

51-
/**
52-
* Returns true if the principals can access thumbnails belonging to
53-
* the requested object, if present.
54-
*
55-
* @param principals
56-
* @param metadata
57-
* @return
58-
*/
59-
public boolean hasThumbnailAccess(AccessGroupSet principals, ContentObjectRecord metadata) {
60-
return hasDatastreamAccess(principals, THUMBNAIL_SMALL, metadata);
61-
}
62-
6351
/**
6452
* Returns true if the principals can access the image preview belonging to
6553
* the requested object, if present.
@@ -75,7 +63,7 @@ public boolean hasImagePreviewAccess(AccessGroupSet principals, ContentObjectRec
7563
/**
7664
* Returns true if the principals can access the MODS description belonging to
7765
* the requested object, if present.
78-
*
66+
*
7967
* @param metadata
8068
* @return
8169
*/
@@ -93,7 +81,7 @@ public boolean hasDescriptionAccess(AccessGroupSet principals, ContentObjectReco
9381
* @return
9482
*/
9583
public boolean hasDatastreamAccess(AccessGroupSet principals, DatastreamType datastream,
96-
ContentObjectRecord metadata) {
84+
ContentObjectRecord metadata) {
9785
notNull(principals, "Requires agent principals");
9886
notNull(datastream, "Requires datastream type");
9987
notNull(metadata, "Requires metadata object");
@@ -168,4 +156,4 @@ public AccessControlService getAccessControlService() {
168156
public void setAccessControlService(AccessControlService accessControlService) {
169157
this.accessControlService = accessControlService;
170158
}
171-
}
159+
}

web-common/src/test/java/edu/unc/lib/boxc/web/common/services/AccessCopiesServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,4 @@ private void hasPermissions(ContentObjectSolrRecord contentObject, boolean hasAc
371371
private void populateResultList(ContentObjectRecord... objects) {
372372
when(searchResultResponse.getResultList()).thenReturn(Arrays.asList(objects));
373373
}
374-
}
374+
}

web-common/src/test/java/edu/unc/lib/boxc/web/common/services/PermissionsHelperTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,4 @@ public void testDoesNotHaveEnhancedIfLoggedIn() {
162162
private void assignPermission(Permission permission, boolean value) {
163163
when(accessControlService.hasAccess(any(PID.class), eq(principals), eq(permission))).thenReturn(value);
164164
}
165-
}
165+
}

web-services-app/src/test/java/edu/unc/lib/boxc/web/services/rest/DatastreamRestControllerIT.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package edu.unc.lib.boxc.web.services.rest;
22

3+
import static edu.unc.lib.boxc.auth.api.Permission.viewAccessCopies;
34
import static edu.unc.lib.boxc.auth.api.Permission.viewHidden;
4-
import static edu.unc.lib.boxc.auth.api.Permission.viewMetadata;
55
import static edu.unc.lib.boxc.model.api.DatastreamType.MD_EVENTS;
66
import static edu.unc.lib.boxc.model.api.DatastreamType.TECHNICAL_METADATA;
77
import static edu.unc.lib.boxc.model.api.DatastreamType.THUMBNAIL_SMALL;
@@ -66,10 +66,10 @@
6666
@ExtendWith(SpringExtension.class)
6767
@WebAppConfiguration
6868
@ContextHierarchy({
69-
@ContextConfiguration("/spring-test/test-fedora-container.xml"),
70-
@ContextConfiguration("/spring-test/cdr-client-container.xml"),
71-
@ContextConfiguration("/spring-test/solr-indexing-context.xml"),
72-
@ContextConfiguration("/datastream-content-it-servlet.xml")
69+
@ContextConfiguration("/spring-test/test-fedora-container.xml"),
70+
@ContextConfiguration("/spring-test/cdr-client-container.xml"),
71+
@ContextConfiguration("/spring-test/solr-indexing-context.xml"),
72+
@ContextConfiguration("/datastream-content-it-servlet.xml")
7373
})
7474
public class DatastreamRestControllerIT extends AbstractAPIIT {
7575

@@ -225,7 +225,7 @@ public void testGetThumbnailNoPermission() throws Exception {
225225
createDerivative(id, THUMBNAIL_SMALL, BINARY_CONTENT.getBytes());
226226

227227
doThrow(new AccessRestrictionException()).when(accessControlService)
228-
.assertHasAccess(anyString(), eq(filePid), any(AccessGroupSetImpl.class), eq(viewMetadata));
228+
.assertHasAccess(anyString(), eq(filePid), any(AccessGroupSetImpl.class), eq(viewAccessCopies));
229229

230230
MvcResult result = mvc.perform(get("/thumb/" + filePid.getId()))
231231
.andExpect(status().isForbidden())
@@ -277,9 +277,9 @@ public void testGetEventLog() throws Exception {
277277

278278
FolderObject folderObj = repositoryObjectFactory.createFolderObject(folderPid, null);
279279
premisLoggerFactory.createPremisLogger(folderObj)
280-
.buildEvent(Premis.Creation)
281-
.addAuthorizingAgent(AgentPids.forPerson("some_user"))
282-
.writeAndClose();
280+
.buildEvent(Premis.Creation)
281+
.addAuthorizingAgent(AgentPids.forPerson("some_user"))
282+
.writeAndClose();
283283

284284
MvcResult result = mvc.perform(get("/file/" + id + "/" + MD_EVENTS.getId()))
285285
.andExpect(status().is2xxSuccessful())
@@ -321,9 +321,9 @@ public void testGetEventLogNoPermissions() throws Exception {
321321

322322
FolderObject folderObj = repositoryObjectFactory.createFolderObject(folderPid, null);
323323
premisLoggerFactory.createPremisLogger(folderObj)
324-
.buildEvent(Premis.Creation)
325-
.addAuthorizingAgent(AgentPids.forPerson("some_user"))
326-
.writeAndClose();
324+
.buildEvent(Premis.Creation)
325+
.addAuthorizingAgent(AgentPids.forPerson("some_user"))
326+
.writeAndClose();
327327

328328
doThrow(new AccessRestrictionException()).when(accessControlService)
329329
.assertHasAccess(anyString(), eq(folderPid), any(AccessGroupSetImpl.class), eq(viewHidden));
@@ -347,4 +347,4 @@ private File createDerivative(String id, DatastreamType dsType, byte[] content)
347347

348348
return derivFile;
349349
}
350-
}
350+
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

33
<beans xmlns="http://www.springframework.org/schema/beans"
4-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xmlns:mvc="http://www.springframework.org/schema/mvc"
6-
xmlns:context="http://www.springframework.org/schema/context"
7-
xsi:schemaLocation="
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:mvc="http://www.springframework.org/schema/mvc"
6+
xmlns:context="http://www.springframework.org/schema/context"
7+
xsi:schemaLocation="
88
http://www.springframework.org/schema/beans
99
http://www.springframework.org/schema/beans/spring-beans.xsd
1010
http://www.springframework.org/schema/context
1111
http://www.springframework.org/schema/context/spring-context-3.0.xsd
1212
http://www.springframework.org/schema/mvc
1313
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
14-
14+
1515
<mvc:annotation-driven/>
1616

1717
<context:component-scan resource-pattern="**/DatastreamController*" base-package="edu.unc.lib.boxc.web.services.rest"/>
18-
18+
1919
<bean id="fedoraContentService" class="edu.unc.lib.boxc.web.common.services.FedoraContentService">
2020
<property name="accessControlService" ref="aclService" />
2121
<property name="repositoryObjectLoader" ref="repositoryObjectLoader" />
2222
</bean>
23-
23+
2424
<bean id="derivativeContentService" class="edu.unc.lib.boxc.web.common.services.DerivativeContentService">
2525
<property name="accessControlService" ref="aclService" />
2626
</bean>
27-
27+
2828
<bean id="aclService" class="org.mockito.Mockito" factory-method="mock">
2929
<constructor-arg value="edu.unc.lib.boxc.auth.fcrepo.services.AccessControlServiceImpl" />
3030
</bean>
31-
31+
3232
<bean id="analyticsTracker" class="org.mockito.Mockito" factory-method="mock">
3333
<constructor-arg value="edu.unc.lib.boxc.web.common.utils.AnalyticsTrackerUtil" />
3434
</bean>
@@ -41,4 +41,4 @@
4141
<property name="globalPermissionEvaluator" ref="globalPermissionEvaluator" />
4242
<property name="solrSearchService" ref="solrSearchService" />
4343
</bean>
44-
</beans>
44+
</beans>

0 commit comments

Comments
 (0)