/** * Reset any permissions that have been set on the node. * * <p>All permissions will be deleted and the node set to inherit permissions. * * @param node node */ public void resetAllPermissions(ScriptNode node) { final NodeRef nodeRef = node.getNodeRef(); // ensure the user has permission to Change Permissions final PermissionService permissionService = serviceRegistry.getPermissionService(); if (permissionService .hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) .equals(AccessStatus.ALLOWED)) { AuthenticationUtil.runAs( new RunAsWork<Void>() { public Void doWork() throws Exception { // Ensure node isn't inheriting permissions from an ancestor before deleting if (!permissionService.getInheritParentPermissions(nodeRef)) { permissionService.deletePermissions(nodeRef); permissionService.setInheritParentPermissions(nodeRef, true); } return null; } }, AuthenticationUtil.SYSTEM_USER_NAME); } else { throw new AlfrescoRuntimeException( "You do not have the authority to update permissions on this node."); } }
/** * Helper to encapsulate the test for whether the currently authenticated user can write to the * preferences objects for the given username and person node reference. * * @param userName Username owner of the preferences object for modification test * @param personNodeRef Non-null person representing the given username * @return true if they are allowed to write to the user preferences, false otherwise */ private boolean userCanWritePreferences(final String userName, final NodeRef personNodeRef) { final String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser(); return (userName.equals(currentUserName) || personService .getUserIdentifier(userName) .equals(personService.getUserIdentifier(currentUserName)) || authenticationContext.isSystemUserName(currentUserName) || permissionService.hasPermission(personNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED); }
/** * Apply a set of permissions to the node. * * @param node node * @param permissions permissions */ public void setPermissions(final ScriptNode node, final Object permissions) { final NodeRef nodeRef = node.getNodeRef(); if (permissions != null && permissions instanceof ScriptableObject) { final PermissionService permissionService = this.serviceRegistry.getPermissionService(); // ensure the user has permission to Change Permissions if (permissionService .hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS) .equals(AccessStatus.ALLOWED)) { AuthenticationUtil.runAs( new RunAsWork<Void>() { public Void doWork() throws Exception { if (!permissionService.getInheritParentPermissions(nodeRef)) { // remove existing permissions permissionService.deletePermissions(nodeRef); } // Assign the correct permissions ScriptableObject scriptable = (ScriptableObject) permissions; Object[] propIds = scriptable.getIds(); for (int i = 0; i < propIds.length; i++) { // Work on each key in turn Object propId = propIds[i]; // Only interested in keys that are formed of Strings if (propId instanceof String) { // Get the value out for the specified key - it must be String final String key = (String) propId; final Object value = scriptable.get(key, scriptable); if (value instanceof String) { // Set the permission on the node permissionService.setPermission(nodeRef, key, (String) value, true); } } } // always add the site managers group with SiteManager permission String managers = siteService.getSiteRoleGroup(getShortName(), SiteModel.SITE_MANAGER); permissionService.setPermission(nodeRef, managers, SiteModel.SITE_MANAGER, true); // now turn off inherit to finalize our permission changes permissionService.setInheritParentPermissions(nodeRef, false); return null; } }, AuthenticationUtil.SYSTEM_USER_NAME); } } else { // No permissions passed-in this.resetAllPermissions(node); } }
/** * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) */ public boolean evaluate(final Node node) { // is the authenticated user permitted to execute the regenerate renditions action // against at least one web project boolean isUserAllowed = false; final FacesContext fc = FacesContext.getCurrentInstance(); final ServiceRegistry services = Repository.getServiceRegistry(fc); final PermissionService permissionService = services.getPermissionService(); final WebProjectService webProjectService = services.getWebProjectService(); final NavigationBean navigator = (NavigationBean) FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME); // check that the authenticated user has CONTENT MANAGER permissions for at least one web // project // this will ensure that the action appears only if the user is able to regenerate renditions // for at least one web project List<WebProjectInfo> wpInfos = webProjectService.listWebProjects(); for (WebProjectInfo wpInfo : wpInfos) { if (permissionService.hasPermission( wpInfo.getNodeRef(), PermissionService.WCM_CONTENT_MANAGER) == AccessStatus.ALLOWED) { isUserAllowed = true; break; } } // TODO improve how we determine whether the form supports the ability to regenerate renditions // or not // get the path to the current name - compare each path element with the Web Forms folder name final Path path = navigator.getCurrentNode().getNodePath(); boolean isWebFormsPath = false; Iterator<Path.Element> itr = path.iterator(); while (itr.hasNext()) { Path.Element element = (Path.Element) itr.next(); String pathElement = element.getPrefixedString(services.getNamespaceService()); if (Application.getWebContentFormsFolderName(fc).equals(pathElement)) { isWebFormsPath = true; break; } } return (node.hasAspect(WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE) || isWebFormsPath) && isUserAllowed; }
/* * Extract favourite nodes of the given type from the comma-separated list in "nodes". */ private Map<PersonFavouriteKey, PersonFavourite> extractFavouriteNodes( String userName, Type type, String nodes) { PrefKeys prefKeys = getPrefKeys(type); Map<PersonFavouriteKey, PersonFavourite> favouriteNodes = new HashMap<PersonFavouriteKey, PersonFavourite>(); StringTokenizer st = new StringTokenizer(nodes, ","); while (st.hasMoreTokens()) { String nodeRefStr = st.nextToken(); nodeRefStr = nodeRefStr.trim(); if (!NodeRef.isNodeRef((String) nodeRefStr)) { continue; } NodeRef nodeRef = new NodeRef((String) nodeRefStr); if (!nodeService.exists(nodeRef)) { continue; } if (permissionService.hasPermission(nodeRef, PermissionService.READ_PROPERTIES) == AccessStatus.DENIED) { continue; } // get createdAt for this favourited node // use ISO8601 StringBuilder builder = new StringBuilder(prefKeys.getAlfrescoPrefKey()); builder.append(nodeRef.toString()); builder.append(".createdAt"); String prefKey = builder.toString(); String createdAtStr = (String) preferenceService.getPreference(userName, prefKey); Date createdAt = (createdAtStr != null ? ISO8601DateFormat.parse(createdAtStr) : null); String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); PersonFavourite personFavourite = new PersonFavourite(userName, nodeRef, type, name, createdAt); PersonFavouriteKey key = personFavourite.getKey(); favouriteNodes.put(key, personFavourite); } return favouriteNodes; }
/** * Helper method to extract file info from a specific node. * * <p>This method goes direct to the repo for all information and no data is cached here. * * @param nodeRef the node * @param readOnly, should the file be shown as "read only", regardless of its permissions? * @param lockedFilesAsOffline should a locked file be marked as offline * @return Returns the file information pertinent to the node * @throws FileNotFoundException if the path refers to a non-existent file */ private ContentFileInfo getFileInformationImpl( NodeRef nodeRef, boolean readOnly, boolean lockedFilesAsOffline) throws FileNotFoundException { // get the file info org.alfresco.service.cmr.model.FileInfo fileFolderInfo = fileFolderService.getFileInfo(nodeRef); // retrieve required properties and create new JLAN file info ContentFileInfo fileInfo = new ContentFileInfo(nodeRef); // Set the file id from the node's DBID long id = DefaultTypeConverter.INSTANCE.convert( Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID)); fileInfo.setFileId((int) (id & 0xFFFFFFFFL)); // unset all attribute flags int fileAttributes = 0; fileInfo.setFileAttributes(fileAttributes); if (fileFolderInfo.isFolder()) { // add directory attribute fileAttributes |= FileAttribute.Directory; fileInfo.setFileAttributes(fileAttributes); fileInfo.setFileType(FileType.Directory); } else { Map<QName, Serializable> nodeProperties = fileFolderInfo.getProperties(); // Get the file size from the content ContentData contentData = (ContentData) nodeProperties.get(ContentModel.PROP_CONTENT); long size = 0L; if (contentData != null) { size = contentData.getSize(); } fileInfo.setSize(size); // Set the allocation size by rounding up the size to a 512 byte block boundary if (size > 0) { fileInfo.setAllocationSize((size + 512L) & 0xFFFFFFFFFFFFFE00L); } // Check whether the file is locked if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE)) { LockType lockType = lockService.getLockType(nodeRef); int attr = fileInfo.getFileAttributes(); if (lockType != null) { switch (lockType) { case NODE_LOCK: if ((attr & FileAttribute.ReadOnly) == 0) attr += FileAttribute.ReadOnly; break; case WRITE_LOCK: LockStatus lockStatus = lockService.getLockStatus(nodeRef); if (lockStatus == LockStatus.LOCK_OWNER) { } else { if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; } if (lockedFilesAsOffline) { attr += FileAttribute.NTOffline; } } break; case READ_ONLY_LOCK: if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; } if (lockedFilesAsOffline) { attr += FileAttribute.NTOffline; } break; } fileInfo.setFileAttributes(attr); } } // Check if it is a link node if (fileFolderInfo.isLink()) { fileInfo.setLinkNodeRef(fileFolderInfo.getLinkNodeRef()); } } // created Date createdDate = fileFolderInfo.getCreatedDate(); if (createdDate != null) { long created = DefaultTypeConverter.INSTANCE.longValue(createdDate); fileInfo.setCreationDateTime(created); } // modified Date modifiedDate = fileFolderInfo.getModifiedDate(); if (modifiedDate != null) { long modified = DefaultTypeConverter.INSTANCE.longValue(modifiedDate); fileInfo.setModifyDateTime(modified); fileInfo.setAccessDateTime(modified); fileInfo.setChangeDateTime(modified); } // name String name = fileFolderInfo.getName(); if (name != null) { fileInfo.setFileName(name); // Check for file names that should be hidden if (hiddenAspect.getVisibility(Client.cifs, fileInfo.getNodeRef()) == Visibility.HiddenAttribute) { // Add the hidden file attribute int attr = fileInfo.getFileAttributes(); if ((attr & FileAttribute.Hidden) == 0) { attr += FileAttribute.Hidden; fileInfo.setFileAttributes(attr); } } } // Read/write access if (!fileFolderInfo.isFolder() || isReadOnlyFlagOnFolders) { boolean deniedPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED; if (readOnly || deniedPermission) { int attr = fileInfo.getFileAttributes(); if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; fileInfo.setFileAttributes(attr); } } } // Set the normal file attribute if no other attributes are set if (fileInfo.getFileAttributes() == 0) fileInfo.setFileAttributes(FileAttribute.NTNormal); // Debug if (logger.isDebugEnabled()) { logger.debug("Fetched file info: \n" + " info: " + fileInfo); } // Return the file information return fileInfo; }
@Override public PagingResults<PersonFavourite> getPagedFavourites( String userName, Set<Type> types, List<Pair<FavouritesService.SortFields, Boolean>> sortProps, PagingRequest pagingRequest) { // Get the user node reference final NodeRef personNodeRef = personService.getPerson(userName); if (personNodeRef == null) { throw new AlfrescoRuntimeException( "Can not get preferences for " + userName + " because he/she does not exist."); } boolean includeFiles = types.contains(Type.FILE); boolean includeFolders = types.contains(Type.FOLDER); boolean includeSites = types.contains(Type.SITE); String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser(); if (authenticationContext.isSystemUserName(currentUserName) == true || permissionService.hasPermission(personNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED || userName.equals(currentUserName) == true) { // we may have more than one favourite that is considered the same w.r.t. the PersonFavourite // comparator final Map<PersonFavouriteKey, PersonFavourite> sortedFavouriteNodes = new TreeMap<PersonFavouriteKey, PersonFavourite>(getComparator(sortProps)); PrefKeys sitePrefKeys = getPrefKeys(Type.SITE); PrefKeys documentsPrefKeys = getPrefKeys(Type.FILE); PrefKeys foldersPrefKeys = getPrefKeys(Type.FOLDER); Map<String, Serializable> preferences = preferenceService.getPreferences(userName); for (String key : preferences.keySet()) { if (includeFiles && key.startsWith(documentsPrefKeys.sharePrefKey)) { String nodes = (String) preferences.get(key); if (nodes != null) { sortedFavouriteNodes.putAll(extractFavouriteNodes(userName, Type.FILE, nodes)); } } else if (includeFolders && key.startsWith(foldersPrefKeys.sharePrefKey)) { String nodes = (String) preferences.get(key); if (nodes != null) { sortedFavouriteNodes.putAll(extractFavouriteNodes(userName, Type.FOLDER, nodes)); } } else if (includeSites && key.startsWith(sitePrefKeys.getSharePrefKey()) && !key.endsWith(".createdAt")) { // key is either of the form org.alfresco.share.sites.favourites.<siteId>.favourited or // org.alfresco.share.sites.favourites.<siteId> extractFavouriteSite(userName, Type.SITE, sortedFavouriteNodes, preferences, key); } } int totalSize = sortedFavouriteNodes.size(); final PageDetails pageDetails = PageDetails.getPageDetails(pagingRequest, totalSize); final List<PersonFavourite> page = new ArrayList<PersonFavourite>(pageDetails.getPageSize()); Iterator<PersonFavourite> it = sortedFavouriteNodes.values().iterator(); for (int counter = 0; counter < pageDetails.getEnd() && it.hasNext(); counter++) { PersonFavourite favouriteNode = it.next(); if (counter < pageDetails.getSkipCount()) { continue; } if (counter > pageDetails.getEnd() - 1) { break; } page.add(favouriteNode); } return new PagingResults<PersonFavourite>() { @Override public List<PersonFavourite> getPage() { return page; } @Override public boolean hasMoreItems() { return pageDetails.hasMoreItems(); } @Override public Pair<Integer, Integer> getTotalResultCount() { Integer total = Integer.valueOf(sortedFavouriteNodes.size()); return new Pair<Integer, Integer>(total, total); } @Override public String getQueryExecutionId() { return null; } }; } else { // The current user does not have sufficient permissions to update the preferences for this // user throw new AccessDeniedException( "The current user " + currentUserName + " does not have sufficient permissions to get the favourites of the user " + userName); } }
/** Test for MNT-11725 */ public void testDowngradePermissions() throws Exception { NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); NodeRef folderRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.ALFRESCO_URI, "testFolder"), ContentModel.TYPE_FOLDER) .getChildRef(); permissionService.setPermission(folderRef, USER_ONE, PermissionService.COORDINATOR, true); permissionService.setInheritParentPermissions(folderRef, false); authenticationComponent.setCurrentUser(USER_ONE); // JSON fromat // {"permissions": // [{"authority":"userA", // "role":"Consumer"}, // {"authority":"userA", // "role":"Coordinator", // "remove":true}], // "isInherited":true} /* negative test, we are first deleting the coordinator role and then try to add consumer */ JSONObject changePermission = new JSONObject(); JSONArray permissions = new JSONArray(); // First delete permission, then add JSONObject addPermission = new JSONObject(); addPermission.put("authority", USER_ONE); addPermission.put("role", PermissionService.CONSUMER); JSONObject removePermission = new JSONObject(); removePermission.put("authority", USER_ONE); removePermission.put("role", PermissionService.COORDINATOR); removePermission.put("remove", "true"); permissions.put(removePermission); permissions.put(addPermission); changePermission.put("permissions", permissions); changePermission.put("isInherited", "true"); sendRequest( new PostRequest( URL_DOCLIB_PERMISSIONS + "/" + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol() + "/" + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier() + "/" + folderRef.getId(), changePermission.toString(), "application/json"), Status.STATUS_INTERNAL_SERVER_ERROR); /* positive test */ changePermission = new JSONObject(); permissions = new JSONArray(); // First add permission, then delete addPermission = new JSONObject(); addPermission.put("authority", USER_ONE); addPermission.put("role", PermissionService.CONSUMER); removePermission = new JSONObject(); removePermission.put("authority", USER_ONE); removePermission.put("role", PermissionService.COORDINATOR); removePermission.put("remove", "true"); permissions.put(addPermission); permissions.put(removePermission); changePermission.put("permissions", permissions); changePermission.put("isInherited", "true"); sendRequest( new PostRequest( URL_DOCLIB_PERMISSIONS + "/" + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol() + "/" + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier() + "/" + folderRef.getId(), changePermission.toString(), "application/json"), Status.STATUS_OK); AccessStatus accessStatus = permissionService.hasPermission(folderRef, PermissionService.CONSUMER); assertTrue("The permission was not set correctly", accessStatus == AccessStatus.ALLOWED); this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); nodeService.deleteNode(folderRef); }