/** * Apply the 'search by role' filter to the lucene query string. * * @param parametersMap * @param filters */ protected void buildSearchByRoleQuery(Map<String, String> parametersMap, List<String> filters) { SearchableRole role = SearchableRole.valueOf(getSearchParam(parametersMap, REQUEST_PARAMETERS.role.toString())); String userid = getSearchParam(parametersMap, REQUEST_PARAMETERS.userid.toString()); AuthorizableManager authorizableManager = null; Session adminSession = null; try { adminSession = repository.loginAdministrative(); authorizableManager = adminSession.getAuthorizableManager(); Authorizable au = authorizableManager.findAuthorizable(userid); List<Authorizable> groups = AuthorizableUtil.getUserFacingGroups(au, authorizableManager); groups.add(au); List<String> groupStrs = new ArrayList<String>(groups.size()); for (Authorizable memberAuthz : groups) { groupStrs.add(ClientUtils.escapeQueryChars(memberAuthz.getId())); } filters.add(String.format(ROLE_TEMPLATE, role.toString(), JOINER_OR.join(groupStrs))); adminSession.logout(); } catch (ClientPoolException e) { throw new RuntimeException(e); } catch (StorageClientException e) { throw new RuntimeException(e); } catch (AccessDeniedException e) { throw new RuntimeException(e); } finally { SparseUtils.logoutQuietly(adminSession); } }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.solr.IndexingHandler#getDocuments(org.sakaiproject.nakamura.api.solr.RepositorySession, * org.osgi.service.event.Event) */ public Collection<SolrInputDocument> getDocuments( RepositorySession repositorySession, Event event) { String path = (String) event.getProperty(FIELD_PATH); logger.info("Indexing connections at path {}", path); List<SolrInputDocument> documents = Lists.newArrayList(); if (!StringUtils.isBlank(path)) { try { Session session = repositorySession.adaptTo(Session.class); ContentManager cm = session.getContentManager(); Content content = cm.get(path); int lastSlash = path.lastIndexOf('/'); String contactName = path.substring(lastSlash + 1); AuthorizableManager am = session.getAuthorizableManager(); Authorizable contactAuth = am.findAuthorizable(contactName); if (content != null && contactAuth != null) { SolrInputDocument doc = new SolrInputDocument(); for (Entry<String, String> prop : WHITELISTED_PROPS.entrySet()) { String key = prop.getKey(); Object value = content.getProperty(key); if (value != null) { doc.addField(WHITELISTED_PROPS.get(key), value); } } // flatten out the contact so we can search it Map<String, Object> contactProps = contactAuth.getSafeProperties(); if (contactAuth != null) { for (String prop : FLATTENED_PROPS) { Object value = contactProps.get(prop); if (value != null) { doc.addField(prop, value); } } } doc.addField(_DOC_SOURCE_OBJECT, content); documents.add(doc); } else { logger.warn( "Did not index {}: Content == {}; Contact Auth == {}", new Object[] {path, content, contactAuth}); } } catch (StorageClientException e) { logger.error(e.getMessage(), e); } catch (AccessDeniedException e) { logger.error(e.getMessage(), e); } } logger.debug("Got documents {} ", documents); return documents; }
public CreateContentPoolServletTest() throws ClientPoolException, StorageClientException, AccessDeniedException, ClassNotFoundException { MockitoAnnotations.initMocks(this); BaseMemoryRepository baseMemoryRepository = new BaseMemoryRepository(); repository = baseMemoryRepository.getRepository(); Session session = repository.loginAdministrative(); AuthorizableManager authorizableManager = session.getAuthorizableManager(); authorizableManager.createUser("ieb", "Ian Boston", "test", ImmutableMap.of("x", (Object) "y")); org.sakaiproject.nakamura.api.lite.authorizable.Authorizable authorizable = authorizableManager.findAuthorizable("ieb"); System.err.println("Got ieb as " + authorizable); session.logout(); }
private void writeProfileMap( javax.jcr.Session jcrSession, AuthorizableManager um, ExtendedJSONWriter writer, String user, boolean detailed) throws JSONException, AccessDeniedException, StorageClientException, RepositoryException { Authorizable au = um.findAuthorizable(user); if (au != null) { ValueMap profileMap; if (detailed) { profileMap = profileService.getProfileMap(au, jcrSession); } else { profileMap = new ValueMapDecorator(basicUserInfoService.getProperties(au)); } if (profileMap != null) { writer.valueMap(profileMap); } } else { writer.object(); writer.key("userid"); writer.value(user); writer.endObject(); } }
private Group getPeerGroupOf( Group group, AuthorizableManager authorizableManager, Map<String, Object> toSave) throws AccessDeniedException, StorageClientException { Group peerGroup = null; if (group.hasProperty(UserConstants.PROP_MANAGERS_GROUP)) { String managersGroupId = (String) group.getProperty(UserConstants.PROP_MANAGERS_GROUP); if (group.getId().equals(managersGroupId)) { return group; } peerGroup = (Group) toSave.get(managersGroupId); if (peerGroup == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} Not in toSave List loading Managers Group from store {} ", group.getId(), managersGroupId); } peerGroup = (Group) authorizableManager.findAuthorizable(managersGroupId); } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} got Managers Group from save list {} ", group.getId(), managersGroupId); } } } else if (group.hasProperty(UserConstants.PROP_MANAGED_GROUP)) { String managedGroupId = (String) group.getProperty(UserConstants.PROP_MANAGED_GROUP); if (group.getId().equals(managedGroupId)) { return group; } peerGroup = (Group) toSave.get(managedGroupId); if (peerGroup == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} Not in toSave List loading Managed Group from store {} ", group.getId(), managedGroupId); } peerGroup = (Group) authorizableManager.findAuthorizable(managedGroupId); } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} got Managed Group from save list {} ", group.getId(), managedGroupId); } } } return peerGroup; }
@POST @Path("{type:user|group}/{userid}") public Response doUpdateAuthorizable( @Context HttpServletRequest request, @Context HttpServletResponse response, @PathParam(value = "type") String authorizableType, @PathParam(value = "userid") String authorizableId) { try { AuthorizableManager authorizableManager = getAuthorizableManager(request, response); Authorizable authorizable = authorizableManager.findAuthorizable(authorizableId); Response checkType = checkType(authorizable, authorizableType); if (checkType != null) { return checkType; } // process the post request. AuthorizableHelper authorizableHelper = new AuthorizableHelper(authorizableManager); ModificationRequest modificationRequest = new ModificationRequest(); modificationRequest.processRequest(request); authorizableHelper.applyProperties(authorizable, modificationRequest); authorizableHelper.save(); final List<String> feedback = modificationRequest.getFeedback(); return Response.ok( new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { ResponseUtils.writeFeedback(feedback, output); } }) .type(MediaType.APPLICATION_JSON_TYPE.toString() + "; charset=utf-8") .lastModified(new Date()) .build(); } catch (StorageClientException e) { return ResponseUtils.getResponse( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } catch (AccessDeniedException e) { return ResponseUtils.getResponse(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); } catch (IOException e) { return ResponseUtils.getResponse( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } catch (FileUploadException e) { return ResponseUtils.getResponse( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.meservice.LiteAbstractMyGroupsServlet#getGroups(org.apache.jackrabbit.api.security.user.Authorizable, * org.apache.jackrabbit.api.security.user.UserManager) */ @Override protected TreeMap<String, Group> getGroups( Authorizable member, AuthorizableManager userManager, final SlingHttpServletRequest request) throws StorageClientException, AccessDeniedException { TreeMap<String, Group> groups = new TreeMap<String, Group>(); String[] principals = member.getPrincipals(); for (String principal : principals) { Authorizable group = userManager.findAuthorizable(principal); if (group == null || !(group instanceof Group) || group.getId().equals(Group.EVERYONE)) { // we don't want the "everyone" group in this feed continue; } if (group.getProperty(UserConstants.PROP_MANAGED_GROUP) != null) { // fetch the group that the manager group manages group = userManager.findAuthorizable( (String) group.getProperty(UserConstants.PROP_MANAGED_GROUP)); if (group == null || !(group instanceof Group) || group.getProperty("sakai:group-title") == null) { continue; } } if (isPseudoGroup((Group) group) && !isManagerGroup((Group) group, userManager)) { // The group we want is the child of the pseudo group group = userManager.findAuthorizable( (String) group.getProperty(UserConstants.PROP_PSEUDO_GROUP_PARENT)); } // KERN-1600 Group's without a title should only be system groups for things like // managing contacts. The UI requires a title. if (group.getProperty("sakai:group-title") != null) { final String category = stringRequestParameter(request, "category", null); if (category == null) { // no filtering groups.put(group.getId(), (Group) group); } else { // KERN-1865 category filter if (category.equals(group.getProperty("sakai:category"))) { groups.put(group.getId(), (Group) group); } } } } return groups; }
/** * Same as writeResults logic, but counts number of results iterated over. * * @param request * @param write * @param iterator * @return Set containing all unique paths processed. * @throws JSONException */ public Set<String> writeResultsInternal( SlingHttpServletRequest request, JSONWriter write, Iterator<Result> iterator) throws JSONException { final Set<String> uniquePaths = new HashSet<String>(); final Integer iDepth = (Integer) request.getAttribute("depth"); int depth = 0; if (iDepth != null) { depth = iDepth.intValue(); } try { javax.jcr.Session jcrSession = request.getResourceResolver().adaptTo(javax.jcr.Session.class); final Session session = StorageClientUtils.adaptToSession(jcrSession); while (iterator.hasNext()) { final Result result = iterator.next(); uniquePaths.add(result.getPath()); try { if ("authorizable".equals(result.getFirstValue("resourceType"))) { AuthorizableManager authManager = session.getAuthorizableManager(); Authorizable auth = authManager.findAuthorizable((String) result.getFirstValue("id")); if (auth != null) { write.object(); ValueMap map = profileService.getProfileMap(auth, jcrSession); ExtendedJSONWriter.writeValueMapInternals(write, map); write.endObject(); } } else { String contentPath = result.getPath(); final Content content = session.getContentManager().get(contentPath); if (content != null) { handleContent(content, session, write, depth); } else { LOGGER.debug("Found null content item while writing results [{}]", contentPath); } } } catch (AccessDeniedException e) { // do nothing } catch (RepositoryException e) { throw new JSONException(e); } } } catch (StorageClientException e) { throw new JSONException(e); } return uniquePaths; }
@Override protected TreeMap<String, Group> getGroups( Authorizable member, AuthorizableManager userManager, SlingHttpServletRequest request) throws StorageClientException, AccessDeniedException { TreeMap<String, Group> managedGroups = new TreeMap<String, Group>(); Iterator<Group> allGroupsIter = member.memberOf(userManager); for (String principal : member.getPrincipals()) { Group group = (Group) userManager.findAuthorizable(principal); if (group != null && !group.getId().equals(Group.EVERYONE)) { boolean isManager = false; if (isPseudoGroup(group) && isManagerGroup(group, userManager)) { // The group we want is the child of the pseudo group isManager = true; group = (Group) userManager.findAuthorizable( (String) group.getProperty(UserConstants.PROP_PSEUDO_GROUP_PARENT)); } else { for (String managerId : StorageClientUtils.nonNullStringArray( (String[]) group.getProperty(UserConstants.PROP_GROUP_MANAGERS))) { if (member.getId().equals(managerId)) { isManager = true; break; } } } if (isManager) { final String category = stringRequestParameter(request, "category", null); if (category == null) { // no filtering managedGroups.put(group.getId(), group); } else { // KERN-1865 category filter if (category.equals(group.getProperty("sakai:category"))) { managedGroups.put(group.getId(), group); } } } } } return managedGroups; }
@GET @Path("{type:user|group}/{userid}.{format}") public Response getUser( @Context HttpServletRequest request, @Context HttpServletResponse response, @PathParam(value = "type") String authorizableType, @PathParam(value = "userid") String authorizableId, @PathParam(value = "format") final String outputFormat) { try { AuthorizableManager authorizableManager = getAuthorizableManager(request, response); final Authorizable authorizable = authorizableManager.findAuthorizable(authorizableId); Response checkType = checkType(authorizable, authorizableType); if (checkType != null) { return checkType; } Date lastModified = new Date(); Long lm = (Long) authorizable.getProperty(Authorizable.LASTMODIFIED_FIELD); if (lm == null) { lm = (Long) authorizable.getProperty(Authorizable.CREATED_FIELD); } if (lm != null) { lastModified = new Date(lm); } return Response.ok( new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { ResponseUtils.writeTree(authorizable, outputFormat, output); } }) .type(MediaType.APPLICATION_JSON_TYPE.toString() + "; charset=utf-8") .lastModified(lastModified) .build(); } catch (StorageClientException e) { return ResponseUtils.getResponse( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } catch (AccessDeniedException e) { return ResponseUtils.getResponse(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); } }
/** * Process a query string to search using Solr. * * @param request * @param query * @param asAnon * @param rs * @return * @throws SolrSearchException */ private SolrSearchResultSet processSolrQuery( SlingHttpServletRequest request, Query query, boolean asAnon) throws StorageClientException, AccessDeniedException, SolrServerException { String queryString = query.getQueryString(); // apply readers restrictions. if (asAnon) { queryString = "(" + queryString + ") AND readers:" + User.ANON_USER; } else { Session session = StorageClientUtils.adaptToSession( request.getResourceResolver().adaptTo(javax.jcr.Session.class)); if (!User.ADMIN_USER.equals(session.getUserId())) { AuthorizableManager am = session.getAuthorizableManager(); Authorizable user = am.findAuthorizable(session.getUserId()); Set<String> readers = Sets.newHashSet(); for (Iterator<Group> gi = user.memberOf(am); gi.hasNext(); ) { readers.add(gi.next().getId()); } readers.add(session.getUserId()); queryString = "(" + queryString + ") AND readers:(" + StringUtils.join(readers, " OR ") + ")"; } } SolrQuery solrQuery = buildQuery(request, queryString, query.getOptions()); SolrServer solrServer = solrSearchService.getServer(); try { LOGGER.info("Performing Query {} ", URLDecoder.decode(solrQuery.toString(), "UTF-8")); } catch (UnsupportedEncodingException e) { } QueryResponse response = solrServer.query(solrQuery); SolrDocumentList resultList = response.getResults(); LOGGER.info("Got {} hits in {} ms", resultList.size(), response.getElapsedTime()); return new SolrSearchResultSetImpl(response); }
@Before public void setUp() throws Exception { provider = new MyRelatedGroupsPropertyProvider(searchServiceFactory); when(request.getRemoteUser()).thenReturn("user1"); when(repo.loginAdministrative()).thenReturn(session); when(session.getAuthorizableManager()).thenReturn(authMgr); when(authMgr.findAuthorizable("user1")).thenReturn(auth1); Group group1 = mock(Group.class); when(group1.getId()).thenReturn("group1"); when(group1.getProperty(GROUP_TITLE_PROPERTY)).thenReturn("Group 1 Test"); when(group1.getProperty("sakai:tag-uuid")).thenReturn(new String[] {"123-456"}); when(auth1.memberOf(authMgr)).thenReturn(Sets.newHashSet(group1).iterator()); when(searchServiceFactory.getSearchResultSet(eq(request), any(Query.class))).thenReturn(rs); }
/** * Retrieves the list of members. * * <p>{@inheritDoc} * * @see * org.apache.sling.api.servlets.SlingSafeMethodsServlet#doGet(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.SlingHttpServletResponse) */ @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { try { // Get hold of the actual file. Resource resource = request.getResource(); javax.jcr.Session jcrSession = request.getResourceResolver().adaptTo(javax.jcr.Session.class); Session session = resource.adaptTo(Session.class); AuthorizableManager am = session.getAuthorizableManager(); AccessControlManager acm = session.getAccessControlManager(); Content node = resource.adaptTo(Content.class); Authorizable thisUser = am.findAuthorizable(session.getUserId()); if (!acm.can(thisUser, Security.ZONE_CONTENT, resource.getPath(), Permissions.CAN_READ)) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } Map<String, Object> properties = node.getProperties(); String[] managers = (String[]) properties.get(POOLED_CONTENT_USER_MANAGER); String[] editors = (String[]) properties.get(POOLED_CONTENT_USER_EDITOR); String[] viewers = (String[]) properties.get(POOLED_CONTENT_USER_VIEWER); boolean detailed = false; boolean tidy = false; for (String selector : request.getRequestPathInfo().getSelectors()) { if ("detailed".equals(selector)) { detailed = true; } else if ("tidy".equals(selector)) { tidy = true; } } // Loop over the sets and output it. ExtendedJSONWriter writer = new ExtendedJSONWriter(response.getWriter()); writer.setTidy(tidy); writer.object(); writer.key("managers"); writer.array(); for (String manager : StorageClientUtils.nonNullStringArray(managers)) { try { writeProfileMap(jcrSession, am, writer, manager, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private manager [{}]", manager); } } writer.endArray(); writer.key("editors"); writer.array(); for (String editor : StorageClientUtils.nonNullStringArray(editors)) { try { writeProfileMap(jcrSession, am, writer, editor, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private editor [{}]", editor); } } writer.endArray(); writer.key("viewers"); writer.array(); for (String viewer : StorageClientUtils.nonNullStringArray(viewers)) { try { writeProfileMap(jcrSession, am, writer, viewer, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private viewer [{}]", viewer); } } writer.endArray(); writer.endObject(); } catch (JSONException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (StorageClientException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (AccessDeniedException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (RepositoryException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } }
/** * Manipulate the member list for this file. * * <p>{@inheritDoc} * * @see * org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.SlingHttpServletResponse) */ @SuppressWarnings("unchecked") @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { // fail if anonymous String remoteUser = request.getRemoteUser(); if (User.ANON_USER.equals(remoteUser)) { response.sendError(SC_FORBIDDEN, "Anonymous users cannot update content members."); return; } Session session = null; boolean releaseSession = false; try { Resource resource = request.getResource(); session = resource.adaptTo(Session.class); Content pooledContent = resource.adaptTo(Content.class); AccessControlManager accessControlManager = session.getAccessControlManager(); AuthorizableManager authorizableManager = session.getAuthorizableManager(); User thisUser = authorizableManager.getUser(); if (!accessControlManager.can( thisUser, Security.ZONE_CONTENT, pooledContent.getPath(), Permissions.CAN_READ)) { response.sendError(SC_FORBIDDEN, "Insufficient permission to read this content."); } Map<String, Object> properties = pooledContent.getProperties(); String[] managers = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_MANAGER)); String[] editors = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_EDITOR)); String[] viewers = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_VIEWER)); Set<String> managerSet = Sets.newHashSet(managers); Set<String> editorSet = Sets.newHashSet(editors); Set<String> viewerSet = Sets.newHashSet(viewers); List<String> removeViewers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":viewer@Delete"))); List<String> removeManagers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":manager@Delete"))); List<String> removeEditors = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":editor@Delete"))); List<String> addViewers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":viewer"))); List<String> addManagers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":manager"))); List<String> addEditors = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":editor"))); if (!accessControlManager.can( thisUser, Security.ZONE_CONTENT, pooledContent.getPath(), Permissions.CAN_WRITE)) { if (!addManagers.isEmpty()) { response.sendError(SC_FORBIDDEN, "Non-managers may not add managers to content."); return; } for (String name : removeManagers) { // asking to remove managers who don't exist is harmless if (managerSet.contains(name)) { response.sendError(SC_FORBIDDEN, "Non-managers may not remove managers from content."); return; } } if (addViewers.contains(User.ANON_USER) || addViewers.contains(Group.EVERYONE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not add 'anonymous' or 'everyone' as viewers."); return; } if (addEditors.contains(User.ANON_USER) || addEditors.contains(Group.EVERYONE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not add 'anonymous' or 'everyone' as editors."); return; } for (String name : removeViewers) { if (!thisUser.getId().equals(name)) { Authorizable viewer = authorizableManager.findAuthorizable(name); if (viewer != null && !accessControlManager.can( thisUser, Security.ZONE_AUTHORIZABLES, name, Permissions.CAN_WRITE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not remove any viewer other than themselves or a group which they manage."); } } } // the request has passed all the rules that govern non-manager users // so we'll grant an administrative session session = session.getRepository().loginAdministrative(); releaseSession = true; } List<AclModification> aclModifications = Lists.newArrayList(); for (String addManager : addManagers) { if ((addManager.length() > 0) && !managerSet.contains(addManager)) { managerSet.add(addManager); AclModification.addAcl(true, Permissions.CAN_MANAGE, addManager, aclModifications); } } for (String removeManager : removeManagers) { if ((removeManager.length() > 0) && managerSet.contains(removeManager)) { managerSet.remove(removeManager); AclModification.removeAcl(true, Permissions.CAN_MANAGE, removeManager, aclModifications); } } for (String addEditor : addEditors) { if ((addEditor.length() > 0) && !editorSet.contains(addEditor)) { editorSet.add(addEditor); AclModification.addAcl(true, PERMISSION_EDITOR, addEditor, aclModifications); } } for (String removeEditor : removeEditors) { if ((removeEditor.length() > 0) && editorSet.contains(removeEditor)) { editorSet.remove(removeEditor); AclModification.removeAcl(true, PERMISSION_EDITOR, removeEditor, aclModifications); } } for (String addViewer : addViewers) { if ((addViewer.length() > 0) && !viewerSet.contains(addViewer)) { viewerSet.add(addViewer); AclModification.addAcl(true, Permissions.CAN_READ, addViewer, aclModifications); } } for (String removeViewer : removeViewers) { removeViewer = removeViewer.trim(); if ((removeViewer.length() > 0) && viewerSet.contains(removeViewer)) { viewerSet.remove(removeViewer); if (!managerSet.contains(removeViewer)) { AclModification.removeAcl(true, Permissions.CAN_READ, removeViewer, aclModifications); } } } updateContentMembers(session, pooledContent, viewerSet, managerSet, editorSet); updateContentAccess(session, pooledContent, aclModifications); this.authorizableCountChanger.notify( UserConstants.CONTENT_ITEMS_PROP, addViewers, addEditors, addManagers, removeViewers, removeEditors, removeManagers); response.setStatus(SC_OK); } catch (StorageClientException e) { LOGGER.error(e.getMessage()); response.sendError( SC_INTERNAL_SERVER_ERROR, "StorageClientException: " + e.getLocalizedMessage()); } catch (AccessDeniedException e) { response.sendError( SC_FORBIDDEN, "Insufficient permission to update content members at " + request.getRequestURI()); } finally { if (session != null && releaseSession) { try { session.logout(); } catch (ClientPoolException e) { LOGGER.error(e.getMessage()); } } } }
private SolrInputDocument handleMessageIndexing(Map<String, Object> props) throws Exception { String messagePath = "a:user1/messagePath"; Content content = new Content(messagePath, props); Authorizable sender = mock(Authorizable.class); when(sender.getId()).thenReturn("sender"); when(sender.isGroup()).thenReturn(Boolean.FALSE); when(sender.getProperty(eq("firstName"))).thenReturn("test"); when(sender.getProperty(eq("lastName"))).thenReturn("user"); Authorizable user1 = mock(Authorizable.class); when(user1.getId()).thenReturn("user1"); when(user1.isGroup()).thenReturn(Boolean.FALSE); when(user1.getProperty(eq("firstName"))).thenReturn("user"); when(user1.getProperty(eq("lastName"))).thenReturn("one"); when(authorizableManager.findAuthorizable(anyString())).thenReturn(sender); when(repositorySession.adaptTo(Session.class)).thenReturn(session); when(session.getAuthorizableManager()).thenReturn(authorizableManager); when(session.getContentManager()).thenReturn(contentManager); when(contentManager.get(messagePath)).thenReturn(content); MessageIndexingHandler handler = new MessageIndexingHandler(); handler.dateParser = this.dateParser; Event event = new Event("topic", buildEventProperties(messagePath)); Collection<SolrInputDocument> documents = handler.getDocuments(repositorySession, event); assertNotNull(documents); assertTrue(!documents.isEmpty()); Iterator<SolrInputDocument> docIt = documents.iterator(); SolrInputDocument doc = docIt.next(); // test basic message properties assertEquals("test-messagestore", doc.getField("messagestore").getValue()); assertEquals("test-messagebox", doc.getField("messagebox").getValue()); assertEquals("test-type", doc.getField("type").getValue()); assertEquals("test-category", doc.getField("category").getValue()); assertEquals("test-from", doc.getField("from").getValue()); assertEquals("test-to", doc.getField("to").getValue()); assertEquals("test-read", doc.getField("read").getValue()); assertEquals("test-marker", doc.getField("marker").getValue()); assertEquals("test-sendstate", doc.getField("sendstate").getValue()); assertEquals("test-initialpost", doc.getField("initialpost").getValue()); assertEquals("test-title", doc.getField("title").getValue()); assertEquals("test-content", doc.getField("content").getValue()); // ensure unexpected value is skipped assertNull(doc.getField("notindexed")); // test sender name is set assertEquals("test", doc.getField("firstName").getValue()); assertEquals("user", doc.getField("lastName").getValue()); // an additional doc should have been added for authorizable searching: assertTrue(docIt.hasNext()); SolrInputDocument authDoc = docIt.next(); // test values set for user/group searching assertEquals("test-title", authDoc.getField("title").getValue()); assertEquals("test-content", authDoc.getField("content").getValue()); assertEquals("u", authDoc.getField("type").getValue()); assertEquals(content, authDoc.getField(IndexingHandler._DOC_SOURCE_OBJECT).getValue()); assertEquals("user1", authDoc.getField(IndexingHandler.FIELD_PATH).getValue()); assertEquals(messagePath + "-auth", authDoc.getField(IndexingHandler.FIELD_ID).getValue()); assertEquals("user1", authDoc.getField("returnpath").getValue()); assertTrue(!docIt.hasNext()); return doc; }
protected void updateGroupMembership( SlingHttpServletRequest request, Session session, Authorizable authorizable, String paramName, List<Modification> changes, Map<String, Object> toSave) throws AccessDeniedException, StorageClientException { if (authorizable instanceof Group) { Group group = ((Group) authorizable); String groupPath = LiteAuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getId(); boolean changed = false; AuthorizableManager authorizableManager = session.getAuthorizableManager(); // first remove any members posted as ":member@Delete" String[] membersToDelete = request.getParameterValues(paramName + SlingPostConstants.SUFFIX_DELETE); if (membersToDelete != null) { toSave.put(group.getId(), group); LOGGER.info("Members to delete {} ", membersToDelete); for (String member : membersToDelete) { String memberId = getAuthIdFromParameter(member); group.removeMember(memberId); changed = true; } } Joinable groupJoin = getJoinable(group); // second add any members posted as ":member" String[] membersToAdd = request.getParameterValues(paramName); if (membersToAdd != null) { LOGGER.info("Members to add {} ", membersToAdd); Group peerGroup = getPeerGroupOf(group, authorizableManager, toSave); List<Authorizable> membersToRemoveFromPeer = new ArrayList<Authorizable>(); for (String member : membersToAdd) { String memberId = getAuthIdFromParameter(member); Authorizable memberAuthorizable = (Authorizable) toSave.get(memberId); if (memberAuthorizable == null) { memberAuthorizable = authorizableManager.findAuthorizable(memberId); } if (memberAuthorizable != null) { if (!User.ADMIN_USER.equals(session.getUserId()) && !UserConstants.ANON_USERID.equals(session.getUserId()) && Joinable.yes.equals(groupJoin) && memberAuthorizable.getId().equals(session.getUserId())) { LOGGER.debug("Is Joinable {} {} ", groupJoin, session.getUserId()); // we can grab admin session since group allows all users to join Session adminSession = getSession(); try { AuthorizableManager adminAuthorizableManager = adminSession.getAuthorizableManager(); Group adminAuthGroup = (Group) adminAuthorizableManager.findAuthorizable(group.getId()); if (adminAuthGroup != null) { adminAuthGroup.addMember(memberAuthorizable.getId()); adminAuthorizableManager.updateAuthorizable(adminAuthGroup); changed = true; } } finally { ungetSession(adminSession); } } else { LOGGER.info( "Group {} is not Joinable: User {} adding {} ", new Object[] { group.getId(), session.getUserId(), memberAuthorizable.getId(), }); // group is restricted, so use the current user's authorization // to add the member to the group: group.addMember(memberAuthorizable.getId()); if (LOGGER.isInfoEnabled()) { LOGGER.info( "{} Membership now {} {} {}", new Object[] { group.getId(), Arrays.toString(group.getMembers()), Arrays.toString(group.getMembersAdded()), Arrays.toString(group.getMembersRemoved()) }); } toSave.put(group.getId(), group); Group gt = (Group) toSave.get(group.getId()); if (LOGGER.isInfoEnabled()) { LOGGER.info( "{} Membership now {} {} {}", new Object[] { group.getId(), Arrays.toString(gt.getMembers()), Arrays.toString(gt.getMembersAdded()), Arrays.toString(gt.getMembersRemoved()) }); } changed = true; } if (peerGroup != null && peerGroup.getId() != group.getId()) { Set<String> members = ImmutableSet.of(peerGroup.getMembers()); if (members.contains(memberAuthorizable.getId())) { membersToRemoveFromPeer.add(memberAuthorizable); } } } else { LOGGER.warn("member not found {} ", memberId); } } if ((peerGroup != null) && (membersToRemoveFromPeer.size() > 0)) { for (Authorizable member : membersToRemoveFromPeer) { if (LOGGER.isInfoEnabled()) { LOGGER.info("Removing Member {} from {} ", member.getId(), peerGroup.getId()); } peerGroup.removeMember(member.getId()); } toSave.put(peerGroup.getId(), peerGroup); if (LOGGER.isInfoEnabled()) { LOGGER.info( "{} Just Updated Peer Group Membership now {} {} {}", new Object[] { peerGroup.getId(), Arrays.toString(peerGroup.getMembers()), Arrays.toString(peerGroup.getMembersAdded()), Arrays.toString(peerGroup.getMembersRemoved()) }); } } } if (changed) { // add an entry to the changes list to record the membership // change changes.add(Modification.onModified(groupPath + "/members")); } } }
@SuppressWarnings("unchecked") public void onMessage(Message message) { log.debug("Receiving a message on {} : {}", SyncJMSMessageProducer.QUEUE_NAME, message); try { String topic = message.getJMSType(); String groupId = (String) message.getStringProperty("path"); String operation = "UNKNOWN"; // A group was DELETED if ("org/sakaiproject/nakamura/lite/authorizables/DELETE".equals(topic) && config.getDeletesEnabled()) { Map<String, Object> attributes = (Map<String, Object>) message.getObjectProperty(StoreListener.BEFORE_EVENT_PROPERTY); grouperManager.deleteGroup(groupId, attributes); operation = "DELETED"; } // A new group was ADDED or an existing group was UPDATED if ("org/sakaiproject/nakamura/lite/authorizables/ADDED".equals(topic) || "org/sakaiproject/nakamura/lite/authorizables/UPDATED".equals(topic)) { // These events should be under org/sakaiproject/nakamura/lite/authorizables/UPDATED // http://jira.sakaiproject.org/browse/KERN-1795 String membersAdded = (String) message.getStringProperty(GrouperEventUtils.MEMBERS_ADDED_PROP); if (membersAdded != null) { // membership adds can be attached to the same event for the group add. grouperManager.createGroup(groupId, config.getGroupTypes()); grouperManager.addMemberships( groupId, Arrays.asList(StringUtils.split(membersAdded, ","))); operation = "ADD_MEMBERS"; } String membersRemoved = (String) message.getStringProperty(GrouperEventUtils.MEMBERS_REMOVED_PROP); if (membersRemoved != null) { grouperManager.removeMemberships( groupId, Arrays.asList(StringUtils.split(membersRemoved, ","))); operation = "REMOVE_MEMBERS"; } if (membersAdded == null && membersRemoved == null) { org.sakaiproject.nakamura.api.lite.Session repositorySession = repository.loginAdministrative(); AuthorizableManager am = repositorySession.getAuthorizableManager(); Group group = (Group) am.findAuthorizable(groupId); repositorySession.logout(); if (groupId.startsWith(ContactsGrouperNameProviderImpl.CONTACTS_GROUPID_PREFIX)) { // TODO Why are we not getting added and removed properties on the Message grouperManager.createGroup(groupId, null); grouperManager.addMemberships(groupId, Arrays.asList(group.getMembers())); operation = "UPDATE CONTACTS"; } else { grouperManager.createGroup(groupId, config.getGroupTypes()); grouperManager.addMemberships(groupId, Arrays.asList(group.getMembers())); operation = "CREATE"; } } } // The message was processed successfully. No exceptions were thrown. // We acknowledge the message and its removed from the queue message.acknowledge(); // We got a message that we didn't know what to do with. if (operation.equals("UNKNOWN")) { log.error( "I don't know what to do with this topic: {}. Turn on debug logs to see the message.", topic); log.debug(message.toString()); } else { log.info("Successfully processed and acknowledged. {}, {}", operation, groupId); log.debug(message.toString()); } } catch (JMSException jmse) { log.error("JMSException while processing message.", jmse); } catch (Exception e) { log.error("Exception while processing message.", e); } }