Skip to content

Commit

Permalink
In the update method, if users don't have change permission, Metacat …
Browse files Browse the repository at this point in the history
…doesn't allow them to change the access rules.

See the ticket #1450
  • Loading branch information
taojing2002 committed Jan 11, 2021
1 parent e37c76b commit f06a388
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,17 @@ public Identifier update(Session session, Identifier pid, InputStream object,
D1AuthHelper authDel = new D1AuthHelper(request,pid,"1200","1310");
authDel.doUpdateAuth(session, existingSysMeta, Permission.WRITE, this.getCurrentNodeId());
allowed = true;
//only the users who have the the change_permission can change access rules
try {
authDel.doUpdateAuth(session, existingSysMeta, Permission.CHANGE_PERMISSION, this.getCurrentNodeId());
} catch(ServiceFailure e) {
throw new ServiceFailure("1310", "Can't determine if the client has the permission to update the object with id " + pid.getValue() + " since "+e.getDescription());
} catch(NotAuthorized e) {
//now the user doesn't have the change the permission. If the access rules in the new and old system metadata are the same, it is fine; otherwise, Metacat throws an exception
if (!D1NodeService.equals(sysmeta.getAccessPolicy(), existingSysMeta.getAccessPolicy())) {
throw new NotAuthorized("1200", "Can't update the object with id " + pid.getValue() + " since the user try to change the access rules without the change permission: " + e.getDescription());
}
}
} catch(ServiceFailure e) {
throw new ServiceFailure("1310", "Can't determine if the client has the permission to update the object with id "+pid.getValue()+" since "+e.getDescription());
} catch(NotAuthorized e) {
Expand Down
51 changes: 51 additions & 0 deletions test/edu/ucsb/nceas/metacat/dataone/MNodeServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,57 @@ public void testUpdate() {
} catch (InvalidRequest ee) {
//assertTrue(ee.getMessage().contains(newPid.getValue()));
}

//test update an object with new access rules
Subject write = new Subject();
write.setValue("Write");
Session writeSession = new Session();
writeSession.setSubject(write);
Subject change = new Subject();
change.setValue("Change");
Session changeSession = new Session();
changeSession.setSubject(change);

Identifier guid20 = new Identifier();
guid20.setValue("testUpdatewithAccessChange." + System.currentTimeMillis());
object = new ByteArrayInputStream("test".getBytes("UTF-8"));
sysmeta = createSystemMetadata(guid20, session.getSubject(), object);
AccessRule writeRule = new AccessRule();
writeRule.addSubject(write);
writeRule.addPermission(Permission.WRITE);
sysmeta.getAccessPolicy().addAllow(writeRule);
AccessRule changeRule = new AccessRule();
changeRule.addSubject(change);
changeRule.addPermission(Permission.CHANGE_PERMISSION);
sysmeta.getAccessPolicy().addAllow(changeRule);
MNodeService.getInstance(request).create(session, guid20, object, sysmeta);

//the write user fails to update the object since it modified the access rules of the original one
Identifier guid21 = new Identifier();
guid21.setValue("testUpdatewithAccessChange2." + System.currentTimeMillis());
object = new ByteArrayInputStream("test".getBytes("UTF-8"));
updatedSysMeta = createSystemMetadata(guid21, session.getSubject(), object);
try {
MNodeService.getInstance(request).update(writeSession, guid20, object, guid21, updatedSysMeta);
fail("The write-permission-only user can't change the access rules");
} catch (Exception ee) {
assertTrue( ee instanceof NotAuthorized);
}

//the write user can update the object without modifying access rules
object = new ByteArrayInputStream("test".getBytes("UTF-8"));
updatedSysMeta = createSystemMetadata(guid21, session.getSubject(), object);
updatedSysMeta.getAccessPolicy().addAllow(writeRule);
updatedSysMeta.getAccessPolicy().addAllow(changeRule);
MNodeService.getInstance(request).update(writeSession, guid20, object, guid21, updatedSysMeta);

//the change user can update the object even with the modified access rules
Identifier guid22 = new Identifier();
guid22.setValue("testUpdatewithAccessChange3." + System.currentTimeMillis());
object = new ByteArrayInputStream("test".getBytes("UTF-8"));
updatedSysMeta = createSystemMetadata(guid22, session.getSubject(), object);
MNodeService.getInstance(request).update(changeSession, guid21, object, guid22, updatedSysMeta);

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
fail("Unexpected error: " + e.getMessage());
Expand Down

0 comments on commit f06a388

Please sign in to comment.