use of org.alfresco.rest.api.model.NodePermissions in project alfresco-remote-api by Alfresco.
the class NodesImpl method updateNodeImpl.
protected NodeRef updateNodeImpl(String nodeId, Node nodeInfo, Parameters parameters) {
final NodeRef nodeRef = validateOrLookupNode(nodeId, null);
QName nodeTypeQName = getNodeType(nodeRef);
validateCmObject(nodeTypeQName);
Map<QName, Serializable> props = new HashMap<>(0);
if (nodeInfo.getProperties() != null) {
props = mapToNodeProperties(nodeInfo.getProperties());
}
String name = nodeInfo.getName();
if ((name != null) && (!name.isEmpty())) {
// update node name if needed - note: if the name is different than existing then this is equivalent of a rename (within parent folder)
props.put(ContentModel.PROP_NAME, name);
}
NodePermissions nodePerms = nodeInfo.getPermissions();
if (nodePerms != null) {
// Cannot set inherited permissions, only direct (locally set) permissions can be set
if ((nodePerms.getInherited() != null) && (nodePerms.getInherited().size() > 0)) {
throw new InvalidArgumentException("Cannot set *inherited* permissions on this node");
}
// Check inherit from parent value and if it's changed set the new value
if (nodePerms.getIsInheritanceEnabled() != null) {
if (nodePerms.getIsInheritanceEnabled() != permissionService.getInheritParentPermissions(nodeRef)) {
permissionService.setInheritParentPermissions(nodeRef, nodePerms.getIsInheritanceEnabled());
}
}
// set direct permissions
if ((nodePerms.getLocallySet() != null)) {
// list of all directly set permissions
Set<AccessPermission> directPerms = new HashSet<>(5);
for (AccessPermission accessPerm : permissionService.getAllSetPermissions(nodeRef)) {
if (accessPerm.isSetDirectly()) {
directPerms.add(accessPerm);
}
}
// check if same permission is sent more than once
if (hasDuplicatePermissions(nodePerms.getLocallySet())) {
throw new InvalidArgumentException("Duplicate node permissions, there is more than one permission with the same authority and name!");
}
for (NodePermissions.NodePermission nodePerm : nodePerms.getLocallySet()) {
String permName = nodePerm.getName();
String authorityId = nodePerm.getAuthorityId();
AccessStatus accessStatus = AccessStatus.ALLOWED;
if (nodePerm.getAccessStatus() != null) {
accessStatus = AccessStatus.valueOf(nodePerm.getAccessStatus());
}
if (authorityId == null || authorityId.isEmpty()) {
throw new InvalidArgumentException("Authority Id is expected.");
}
if (permName == null || permName.isEmpty()) {
throw new InvalidArgumentException("Permission name is expected.");
}
if (((!authorityId.equals(PermissionService.ALL_AUTHORITIES) && (!authorityService.authorityExists(authorityId))))) {
throw new InvalidArgumentException("Cannot set permissions on this node - unknown authority: " + authorityId);
}
AccessPermission existing = null;
boolean addPerm = true;
boolean updatePerm = false;
// If the permission already exists but with different access status it will be updated
for (AccessPermission accessPerm : directPerms) {
if (accessPerm.getAuthority().equals(authorityId) && accessPerm.getPermission().equals(permName)) {
existing = accessPerm;
addPerm = false;
if (accessPerm.getAccessStatus() != accessStatus) {
updatePerm = true;
}
break;
}
}
if (existing != null) {
// ignore existing permissions
directPerms.remove(existing);
}
if (addPerm || updatePerm) {
try {
permissionService.setPermission(nodeRef, authorityId, permName, (accessStatus == AccessStatus.ALLOWED));
} catch (UnsupportedOperationException e) {
throw new InvalidArgumentException("Cannot set permissions on this node - unknown access level: " + permName);
}
}
}
// remove any remaining direct perms
for (AccessPermission accessPerm : directPerms) {
permissionService.deletePermission(nodeRef, accessPerm.getAuthority(), accessPerm.getPermission());
}
}
}
String nodeType = nodeInfo.getNodeType();
if ((nodeType != null) && (!nodeType.isEmpty())) {
// update node type - ensure that we are performing a specialise (we do not support generalise)
QName destNodeTypeQName = createQName(nodeType);
if ((!destNodeTypeQName.equals(nodeTypeQName)) && isSubClass(destNodeTypeQName, nodeTypeQName) && (!isSubClass(destNodeTypeQName, ContentModel.TYPE_SYSTEM_FOLDER))) {
nodeService.setType(nodeRef, destNodeTypeQName);
} else {
throw new InvalidArgumentException("Failed to change (specialise) node type - from " + nodeTypeQName + " to " + destNodeTypeQName);
}
}
NodeRef parentNodeRef = nodeInfo.getParentId();
if (parentNodeRef != null) {
NodeRef currentParentNodeRef = getParentNodeRef(nodeRef);
if (currentParentNodeRef == null) {
// implies root (Company Home) hence return 403 here
throw new PermissionDeniedException();
}
if (!currentParentNodeRef.equals(parentNodeRef)) {
// moveOrCopy(nodeRef, parentNodeRef, name, false); // not currently supported - client should use explicit POST /move operation instead
throw new InvalidArgumentException("Cannot update parentId of " + nodeId + " via PUT /nodes/{nodeId}. Please use explicit POST /nodes/{nodeId}/move operation instead");
}
}
List<String> aspectNames = nodeInfo.getAspectNames();
updateCustomAspects(nodeRef, aspectNames, EXCLUDED_ASPECTS);
if (props.size() > 0) {
validatePropValues(props);
try {
// update node properties - note: null will unset the specified property
nodeService.addProperties(nodeRef, props);
} catch (DuplicateChildNodeNameException dcne) {
throw new ConstraintViolatedException(dcne.getMessage());
}
}
return nodeRef;
}
use of org.alfresco.rest.api.model.NodePermissions in project alfresco-remote-api by Alfresco.
the class NodesImpl method getFolderOrDocument.
@Override
public Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> includeParam, Map<String, UserInfo> mapUserInfo) {
if (mapUserInfo == null) {
mapUserInfo = new HashMap<>(2);
}
if (includeParam == null) {
includeParam = Collections.emptyList();
}
Node node;
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
PathInfo pathInfo = null;
if (includeParam.contains(PARAM_INCLUDE_PATH)) {
ChildAssociationRef archivedParentAssoc = (ChildAssociationRef) properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
pathInfo = lookupPathInfo(nodeRef, archivedParentAssoc);
}
if (nodeTypeQName == null) {
nodeTypeQName = getNodeType(nodeRef);
}
if (parentNodeRef == null) {
parentNodeRef = getParentNodeRef(nodeRef);
}
Type type = getType(nodeTypeQName, nodeRef);
if (type == null) {
// not direct folder (or file) ...
// might be sub-type of cm:cmobject (or a cm:link pointing to cm:cmobject or possibly even another cm:link)
node = new Node(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
node.setIsFolder(false);
node.setIsFile(false);
} else if (type.equals(Type.DOCUMENT)) {
node = new Document(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
} else if (type.equals(Type.FOLDER)) {
node = new Folder(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
} else {
throw new RuntimeException("Unexpected - should not reach here: " + type);
}
if (includeParam.size() > 0) {
node.setProperties(mapFromNodeProperties(properties, includeParam, mapUserInfo, EXCLUDED_NS, EXCLUDED_PROPS));
}
Set<QName> aspects = null;
if (includeParam.contains(PARAM_INCLUDE_ASPECTNAMES)) {
aspects = nodeService.getAspects(nodeRef);
node.setAspectNames(mapFromNodeAspects(aspects, EXCLUDED_NS, EXCLUDED_ASPECTS));
}
if (includeParam.contains(PARAM_INCLUDE_ISLINK)) {
boolean isLink = isSubClass(nodeTypeQName, ContentModel.TYPE_LINK);
node.setIsLink(isLink);
}
if (includeParam.contains(PARAM_INCLUDE_ISLOCKED)) {
boolean isLocked = isLocked(nodeRef, aspects);
node.setIsLocked(isLocked);
}
if (includeParam.contains(PARAM_INCLUDE_ISFAVORITE)) {
boolean isFavorite = isFavorite(nodeRef);
node.setIsFavorite(isFavorite);
}
if (includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS)) {
// note: refactor when requirements change
Map<String, String> mapPermsToOps = new HashMap<>(3);
mapPermsToOps.put(PermissionService.DELETE, OP_DELETE);
mapPermsToOps.put(PermissionService.ADD_CHILDREN, OP_CREATE);
mapPermsToOps.put(PermissionService.WRITE, OP_UPDATE);
mapPermsToOps.put(PermissionService.CHANGE_PERMISSIONS, OP_UPDATE_PERMISSIONS);
List<String> allowableOperations = new ArrayList<>(3);
for (Entry<String, String> kv : mapPermsToOps.entrySet()) {
String perm = kv.getKey();
String op = kv.getValue();
if (perm.equals(PermissionService.ADD_CHILDREN) && Type.DOCUMENT.equals(type)) {
// special case: do not return "create" (as an allowable op) for file/content types - note: 'type' can be null
continue;
} else if (perm.equals(PermissionService.DELETE) && (isSpecialNode(nodeRef, nodeTypeQName))) {
// special case: do not return "delete" (as an allowable op) for specific system nodes
continue;
} else if (permissionService.hasPermission(nodeRef, perm) == AccessStatus.ALLOWED) {
allowableOperations.add(op);
}
}
node.setAllowableOperations((allowableOperations.size() > 0) ? allowableOperations : null);
}
if (includeParam.contains(PARAM_INCLUDE_PERMISSIONS)) {
Boolean inherit = permissionService.getInheritParentPermissions(nodeRef);
List<NodePermissions.NodePermission> inheritedPerms = new ArrayList<>(5);
List<NodePermissions.NodePermission> setDirectlyPerms = new ArrayList<>(5);
Set<String> settablePerms = null;
boolean allowRetrievePermission = true;
try {
for (AccessPermission accessPerm : permissionService.getAllSetPermissions(nodeRef)) {
NodePermissions.NodePermission nodePerm = new NodePermissions.NodePermission(accessPerm.getAuthority(), accessPerm.getPermission(), accessPerm.getAccessStatus().toString());
if (accessPerm.isSetDirectly()) {
setDirectlyPerms.add(nodePerm);
} else {
inheritedPerms.add(nodePerm);
}
}
settablePerms = permissionService.getSettablePermissions(nodeRef);
} catch (AccessDeniedException ade) {
// ignore - ie. denied access to retrieve permissions, eg. non-admin on root (Company Home)
allowRetrievePermission = false;
}
// returned only node info that he's allowed to see
if (allowRetrievePermission) {
NodePermissions nodePerms = new NodePermissions(inherit, inheritedPerms, setDirectlyPerms, settablePerms);
node.setPermissions(nodePerms);
}
}
if (includeParam.contains(PARAM_INCLUDE_ASSOCIATION)) {
// Ugh ... can we optimise this and return the actual assoc directly (via FileFolderService/GetChildrenCQ) ?
ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef);
// note: parentAssocRef.parentRef can be null for -root- node !
if ((parentAssocRef == null) || (parentAssocRef.getParentRef() == null) || (!parentAssocRef.getParentRef().equals(parentNodeRef))) {
List<ChildAssociationRef> parentAssocRefs = nodeService.getParentAssocs(nodeRef);
for (ChildAssociationRef pAssocRef : parentAssocRefs) {
if (pAssocRef.getParentRef().equals(parentNodeRef)) {
// for now, assume same parent/child cannot appear more than once (due to unique name)
parentAssocRef = pAssocRef;
break;
}
}
}
if (parentAssocRef != null) {
QName assocTypeQName = parentAssocRef.getTypeQName();
if ((assocTypeQName != null) && (!EXCLUDED_NS.contains(assocTypeQName.getNamespaceURI()))) {
AssocChild childAssoc = new AssocChild(assocTypeQName.toPrefixString(namespaceService), parentAssocRef.isPrimary());
node.setAssociation(childAssoc);
}
}
}
node.setNodeType(nodeTypeQName.toPrefixString(namespaceService));
node.setPath(pathInfo);
return node;
}
use of org.alfresco.rest.api.model.NodePermissions in project alfresco-remote-api by Alfresco.
the class NodeApiTest method testDownloadFileContentReadPermission.
/**
* Tests download of file/content - basic read permission
* <p>GET:</p>
* {@literal <host>:<port>/alfresco/api/-default-/public/alfresco/versions/1/nodes/<nodeId>/content}
*/
@Test
public void testDownloadFileContentReadPermission() throws Exception {
setRequestContext(user1);
String fileName = "quick-1.txt";
File file = getResourceFile(fileName);
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create().setFileData(new FileData(fileName, file));
MultiPartRequest reqBody = multiPartBuilder.build();
// Upload text content
HttpResponse response = post(getNodeChildrenUrl(Nodes.PATH_MY), reqBody.getBody(), null, reqBody.getContentType(), 201);
Document document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
String contentNodeId = document.getId();
// Download text content
response = getSingle(NodesEntityResource.class, contentNodeId + "/content", null, 200);
String textContent = response.getResponse();
assertEquals("The quick brown fox jumps over the lazy dog", textContent);
// Also test versions endpoint (1.0 in this case)
response = getSingle(NodesEntityResource.class, contentNodeId + "/versions/1.0/content", null, 200);
textContent = response.getResponse();
assertEquals("The quick brown fox jumps over the lazy dog", textContent);
// -ve test: user2 does not have read permission
setRequestContext(user2);
getSingle(NodesEntityResource.class, contentNodeId + "/content", null, 403);
getSingle(NodesEntityResource.class, contentNodeId + "/versions/1.0/content", null, 403);
// add Consumer (~ Read) permission
setRequestContext(user1);
Document dUpdate = new Document();
NodePermissions nodePermissions = new NodePermissions();
List<NodePermissions.NodePermission> locallySetPermissions = new ArrayList<>();
locallySetPermissions.add(new NodePermissions.NodePermission(user2, PermissionService.CONSUMER, AccessStatus.ALLOWED.toString()));
nodePermissions.setLocallySet(locallySetPermissions);
dUpdate.setPermissions(nodePermissions);
// update node
response = put(URL_NODES, contentNodeId, toJsonAsStringNonNull(dUpdate), null, 200);
setRequestContext(user2);
// Download text content
response = getSingle(NodesEntityResource.class, contentNodeId + "/content", null, 200);
textContent = response.getResponse();
assertEquals("The quick brown fox jumps over the lazy dog", textContent);
// Also test versions endpoint (1.0 in this case)
response = getSingle(NodesEntityResource.class, contentNodeId + "/versions/1.0/content", null, 200);
textContent = response.getResponse();
assertEquals("The quick brown fox jumps over the lazy dog", textContent);
}
use of org.alfresco.rest.api.model.NodePermissions in project alfresco-remote-api by Alfresco.
the class NodeApiTest method testUpdatePermissionsOnSpecialNodes.
/**
* Test update permissions on special nodes like
* 'Company Home', 'Sites', 'Shared', 'User Home', 'Data Dictionary'
*
* @throws Exception
*/
private void testUpdatePermissionsOnSpecialNodes() throws Exception {
NodePermissions nodePermissions = new NodePermissions();
List<NodePermissions.NodePermission> locallySetPermissions = new ArrayList<>();
locallySetPermissions.add(new NodePermissions.NodePermission(groupA, PermissionService.EDITOR, AccessStatus.ALLOWED.toString()));
nodePermissions.setLocallySet(locallySetPermissions);
// 'Company Home'
HttpResponse response = getSingle(NodesEntityResource.class, getRootNodeId(), null, 200);
Node node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
node.setPermissions(nodePermissions);
put(URL_NODES, node.getId(), toJsonAsStringNonNull(node), null, 403);
// 'Sites' folder
response = getSingle(NodesEntityResource.class, getSharedNodeId(), null, 200);
node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
node.setPermissions(nodePermissions);
put(URL_NODES, node.getId(), toJsonAsStringNonNull(node), null, 403);
// 'Data Dictionary' folder
response = getSingle(NodesEntityResource.class, getDataDictionaryNodeId(), null, 200);
node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
node.setPermissions(nodePermissions);
put(URL_NODES, node.getId(), toJsonAsStringNonNull(node), null, 403);
// 'Shared' folder
response = getSingle(NodesEntityResource.class, getSharedNodeId(), null, 200);
node = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
node.setPermissions(nodePermissions);
put(URL_NODES, node.getId(), toJsonAsStringNonNull(node), null, 403);
// 'User Home' folder
HttpResponse responseUserHome = getSingle(NodesEntityResource.class, getMyNodeId(), null, 200);
Node nodeUserHome = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
node.setPermissions(nodePermissions);
put(URL_NODES, node.getId(), toJsonAsStringNonNull(node), null, 403);
}
use of org.alfresco.rest.api.model.NodePermissions in project alfresco-remote-api by Alfresco.
the class NodeApiTest method testUpdatePermissionsSetFalseInheritFromParent.
/**
* Test set inherit from parent to false
*
* @throws Exception
*/
private void testUpdatePermissionsSetFalseInheritFromParent() throws Exception {
// create folder
String testFolderUrl = createFolder();
String dId = createDocument(testFolderUrl);
// create a new document in testFolder and set inherit to false
Document dUpdate = new Document();
NodePermissions nodePermissionsUpdate = new NodePermissions();
nodePermissionsUpdate.setIsInheritanceEnabled(false);
dUpdate.setPermissions(nodePermissionsUpdate);
HttpResponse response = put(URL_NODES, dId, toJsonAsStringNonNull(dUpdate), null, 200);
Document documentResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
Map params = new HashMap<>();
params.put("include", "permissions");
response = getSingle(NodesEntityResource.class, documentResp.getId(), params, 200);
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
assertFalse("Inheritance hasn't been disabled!", nodeResp.getPermissions().getIsInheritanceEnabled());
assertNull("Permissions were inherited from parent!", nodeResp.getPermissions().getInherited());
}
Aggregations