public void setUserRoles( Session session, final ITenant theTenant, final String userName, final String[] roles) throws RepositoryException, NotFoundException { if (hasAdminRole(getUserRoles(theTenant, userName)) && (roles.length == 0)) { throw new RepositoryException( Messages.getInstance() .getString("AbstractJcrBackedUserRoleDao.ERROR_0005_LAST_ADMIN_USER", userName)); } Set<String> roleSet = new HashSet<String>(); if (roles != null) { roleSet.addAll(Arrays.asList(roles)); } roleSet.add(authenticatedRoleName); User jackrabbitUser = getJackrabbitUser(theTenant, userName, session); if ((jackrabbitUser == null) || !TenantUtils.isAccessibleTenant( theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID()) : theTenant)) { throw new NotFoundException( Messages.getInstance() .getString("AbstractJcrBackedUserRoleDao.ERROR_0003_USER_NOT_FOUND")); } HashMap<String, Group> currentlyAssignedGroups = new HashMap<String, Group>(); Iterator<Group> currentGroups = jackrabbitUser.memberOf(); while (currentGroups.hasNext()) { Group currentGroup = currentGroups.next(); currentlyAssignedGroups.put(currentGroup.getID(), currentGroup); } HashMap<String, Group> finalCollectionOfAssignedGroups = new HashMap<String, Group>(); ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(userName, true) : theTenant; for (String role : roleSet) { Group jackrabbitGroup = getJackrabbitGroup(tenant, role, session); if (jackrabbitGroup != null) { finalCollectionOfAssignedGroups.put( tenantedRoleNameUtils.getPrincipleId(tenant, role), jackrabbitGroup); } } ArrayList<String> groupsToRemove = new ArrayList<String>(currentlyAssignedGroups.keySet()); groupsToRemove.removeAll(finalCollectionOfAssignedGroups.keySet()); ArrayList<String> groupsToAdd = new ArrayList<String>(finalCollectionOfAssignedGroups.keySet()); groupsToAdd.removeAll(currentlyAssignedGroups.keySet()); for (String groupId : groupsToRemove) { currentlyAssignedGroups.get(groupId).removeMember(jackrabbitUser); } for (String groupId : groupsToAdd) { finalCollectionOfAssignedGroups.get(groupId).addMember(jackrabbitUser); } // Purge the UserDetails cache purgeUserFromCache(userName); }
@Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { String paramUser = request.getParameter(SiteService.SiteEvent.USER); logger.info("Request to add user " + paramUser); String paramGroup = ""; try { Node requestedNode = request.getResource().adaptTo(Node.class); Value[] authorizables = requestedNode.getProperty("sakai:authorizables").getValues(); paramGroup = authorizables[1].getString(); request.setAttribute(JoinRequestConstants.PARAM_SITENODE, requestedNode); Session session = slingRepository.loginAdministrative(null); UserManager userManager = AccessControlUtil.getUserManager(session); Authorizable userAuth = userManager.getAuthorizable(paramUser); Group groupAuth = (Group) userManager.getAuthorizable(paramGroup); if (siteJoinIsAuthorized(request)) { groupAuth.addMember(userAuth); logger.info(paramUser + " added as member of group " + paramGroup); } else { response.sendError(403, "Not authorized to add member to site."); } if (session.hasPendingChanges()) { session.save(); } } catch (Exception e) { response.sendError(500, e.getMessage()); } }
/** * KERN-1026 changed the results of this to be the authz's that are members of the managers group * associated to a group rather than the group managers associated to the group. * * <p><del>Get the managers for a group. These should be stored in the {@link * UserConstants#PROP_GROUP_MANAGERS}.</del> * * @param request * @param group * @param writer * @throws RepositoryException * @throws JSONException */ protected TreeMap<String, Authorizable> getManagers( SlingHttpServletRequest request, Group group, Comparator<String> comparator) throws RepositoryException, JSONException { TreeMap<String, Authorizable> map = new TreeMap<String, Authorizable>(comparator); // KERN-949 will probably change this. // note above was made before this was changed to retrieving members of the managers // group and may not apply. Session session = request.getResourceResolver().adaptTo(Session.class); UserManager um = AccessControlUtil.getUserManager(session); Value[] managersGroup = group.getProperty(UserConstants.PROP_MANAGERS_GROUP); if (managersGroup != null && managersGroup.length == 1) { String mgrGroupName = managersGroup[0].getString(); Group mgrGroup = (Group) um.getAuthorizable(mgrGroupName); Iterator<Authorizable> members = mgrGroup.getMembers(); while (members.hasNext()) { Authorizable member = members.next(); String prinName = member.getPrincipal().getName(); Authorizable mau = um.getAuthorizable(prinName); String name = getName(mau); map.put(name, mau); } } return map; }
public IPentahoRole getRole(Session session, final ITenant tenant, final String name) throws RepositoryException { Group jackrabbitGroup = getJackrabbitGroup(tenant, name, session); return jackrabbitGroup != null && TenantUtils.isAccessibleTenant( tenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()) : tenant) ? convertToPentahoRole(jackrabbitGroup) : null; }
public void deleteRole(Session session, final IPentahoRole role) throws NotFoundException, RepositoryException { if (canDeleteRole(session, role)) { Group jackrabbitGroup = getJackrabbitGroup(role.getTenant(), role.getName(), session); if (jackrabbitGroup != null && TenantUtils.isAccessibleTenant( tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()))) { jackrabbitGroup.remove(); } else { throw new NotFoundException(""); // $NON-NLS-1$ } } else { throw new RepositoryException( Messages.getInstance() .getString("AbstractJcrBackedUserRoleDao.ERROR_0007_ATTEMPTED_SYSTEM_ROLE_DELETE")); } }
@Override protected TreeMap<String, Group> getGroups(Authorizable member, UserManager userManager) throws RepositoryException { TreeMap<String, Group> managedGroups = new TreeMap<String, Group>(); Iterator<Group> allGroupsIter = member.memberOf(); while (allGroupsIter.hasNext()) { Group group = allGroupsIter.next(); if (group.hasProperty(UserConstants.PROP_MANAGED_GROUP)) { Value[] values = group.getProperty(UserConstants.PROP_MANAGED_GROUP); if ((values != null) && (values.length == 1)) { String managedGroupId = values[0].getString(); Group managedGroup = (Group) userManager.getAuthorizable(managedGroupId); managedGroups.put(managedGroupId, managedGroup); } } } return managedGroups; }
private IPentahoRole convertToPentahoRole(Group jackrabbitGroup) throws RepositoryException { IPentahoRole role = null; Value[] propertyValues = null; String description = null; try { propertyValues = jackrabbitGroup.getProperty("description"); // $NON-NLS-1$ description = propertyValues.length > 0 ? propertyValues[0].getString() : null; } catch (Exception ex) { } role = new PentahoRole( tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()), tenantedRoleNameUtils.getPrincipleName(jackrabbitGroup.getID()), description); return role; }
public List<IPentahoUser> getRoleMembers( Session session, final ITenant theTenant, final String roleName) throws RepositoryException { List<IPentahoUser> users = new ArrayList<IPentahoUser>(); Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session); if ((jackrabbitGroup != null) && TenantUtils.isAccessibleTenant( theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()) : theTenant)) { Iterator<Authorizable> authorizables = jackrabbitGroup.getMembers(); while (authorizables.hasNext()) { Authorizable authorizable = authorizables.next(); if (authorizable instanceof User) { users.add(convertToPentahoUser((User) authorizable)); } } } return users; }
public void setRoleDescription( Session session, final ITenant theTenant, final String roleName, final String description) throws NotFoundException, RepositoryException { Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session); if (jackrabbitGroup != null && TenantUtils.isAccessibleTenant( theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()) : theTenant)) { if (description == null) { jackrabbitGroup.removeProperty("description"); // $NON-NLS-1$ } else { jackrabbitGroup.setProperty( "description", session.getValueFactory().createValue(description)); // $NON-NLS-1$ } } else { throw new NotFoundException( Messages.getInstance() .getString("AbstractJcrBackedUserRoleDao.ERROR_0002_ROLE_NOT_FOUND")); } }
@Test public void testGetEmailAddrs_Group() throws Exception { // mock group and users String groupPath = "/home/users/g/group"; List<Authorizable> groupMembers = new ArrayList<Authorizable>(); Authorizable user1 = mock(Authorizable.class); Authorizable user2 = mock(Authorizable.class); when(user1.hasProperty(PN_EMAIL)).thenReturn(true); when(user1.getProperty(PN_EMAIL)) .thenReturn(new MockValue[] {new MockValue("*****@*****.**")}); when(user2.hasProperty(PN_EMAIL)).thenReturn(true); when(user2.getProperty(PN_EMAIL)) .thenReturn(new MockValue[] {new MockValue("*****@*****.**")}); groupMembers.add(user1); groupMembers.add(user2); ResourceResolver resolver = mock(ResourceResolver.class); Resource groupRes = mock(Resource.class); Authorizable groupAuth = mock(Authorizable.class); Group userGroup = mock(Group.class); when(resolver.getResource(groupPath)).thenReturn(groupRes); when(groupRes.adaptTo(Authorizable.class)).thenReturn(groupAuth); when(groupAuth.isGroup()).thenReturn(true); when(groupRes.adaptTo(Group.class)).thenReturn(userGroup); when(userGroup.getMembers()).thenReturn(groupMembers.iterator()); String[] emails = SendTemplatedEmailUtils.getEmailAddrsFromUserPath(resolver, groupPath); assertEquals(2, emails.length); assertEquals("*****@*****.**", emails[0]); assertEquals("*****@*****.**", emails[1]); }
/** * @param request * @param group * @param writer * @throws RepositoryException * @throws JSONException */ protected TreeMap<String, Authorizable> getMembers( SlingHttpServletRequest request, Group group, Comparator<String> comparator) throws RepositoryException, JSONException { TreeMap<String, Authorizable> map = new TreeMap<String, Authorizable>(comparator); // Only the direct members are required. // If we would do group.getMembers() that would also retrieve all the indirect ones. Iterator<Authorizable> members = group.getDeclaredMembers(); while (members.hasNext()) { Authorizable member = members.next(); String name = getName(member); map.put(name, member); } return map; }
public void setRoleMembers( Session session, final ITenant theTenant, final String roleName, final String[] memberUserNames) throws RepositoryException, NotFoundException { List<IPentahoUser> currentRoleMembers = getRoleMembers(session, theTenant, roleName); if (tenantAdminRoleName.equals(roleName) && (currentRoleMembers != null && currentRoleMembers.size() > 0) && memberUserNames.length == 0) { throw new RepositoryException( Messages.getInstance() .getString( "AbstractJcrBackedUserRoleDao.ERROR_0001_LAST_ADMIN_ROLE", tenantAdminRoleName)); } Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session); if ((jackrabbitGroup == null) || !TenantUtils.isAccessibleTenant( theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()) : theTenant)) { throw new NotFoundException( Messages.getInstance() .getString("AbstractJcrBackedUserRoleDao.ERROR_0002_ROLE_NOT_FOUND")); } HashMap<String, User> currentlyAssignedUsers = new HashMap<String, User>(); Iterator<Authorizable> currentMembers = jackrabbitGroup.getMembers(); while (currentMembers.hasNext()) { Authorizable member = currentMembers.next(); if (member instanceof User) { currentlyAssignedUsers.put(member.getID(), (User) member); } } HashMap<String, User> finalCollectionOfAssignedUsers = new HashMap<String, User>(); if (memberUserNames != null) { ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(roleName, false) : theTenant; for (String user : memberUserNames) { User jackrabbitUser = getJackrabbitUser(tenant, user, session); if (jackrabbitUser != null) { finalCollectionOfAssignedUsers.put( tenantedRoleNameUtils.getPrincipleId(tenant, user), jackrabbitUser); } } } ArrayList<String> usersToRemove = new ArrayList<String>(currentlyAssignedUsers.keySet()); usersToRemove.removeAll(finalCollectionOfAssignedUsers.keySet()); ArrayList<String> usersToAdd = new ArrayList<String>(finalCollectionOfAssignedUsers.keySet()); usersToAdd.removeAll(currentlyAssignedUsers.keySet()); for (String userId : usersToRemove) { jackrabbitGroup.removeMember(currentlyAssignedUsers.get(userId)); } for (String userId : usersToAdd) { jackrabbitGroup.addMember(finalCollectionOfAssignedUsers.get(userId)); // Purge the UserDetails cache purgeUserFromCache(userId); } }
/* * (non-Javadoc) * * @seeorg.apache.sling.jackrabbit.usermanager.post.AbstractAuthorizablePostServlet# * handleOperation(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.servlets.HtmlResponse, java.util.List) */ @Override @edu.umd.cs.findbugs.annotations.SuppressWarnings( justification = "If there is an exception, the user is certainly not admin", value = {"REC_CATCH_EXCEPTION"}) protected void handleOperation( SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes) throws RepositoryException { // KERN-432 dont allow anon users to access create group. if (SecurityConstants.ANONYMOUS_ID.equals(request.getRemoteUser())) { response.setStatus(403, "AccessDenied"); } // check that the submitted parameter values have valid values. final String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); if (principalName == null) { throw new RepositoryException("Group name was not submitted"); } NameSanitizer san = new NameSanitizer(principalName, false); san.validate(); // check for allow create Group boolean allowCreateGroup = false; User currentUser = null; try { Session currentSession = request.getResourceResolver().adaptTo(Session.class); UserManager um = AccessControlUtil.getUserManager(currentSession); currentUser = (User) um.getAuthorizable(currentSession.getUserID()); if (currentUser.isAdmin()) { LOGGER.debug("User is an admin "); allowCreateGroup = true; } else { LOGGER.debug("Checking for membership of one of {} ", Arrays.toString(authorizedGroups)); PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(currentSession); PrincipalIterator pi = principalManager.getGroupMembership( principalManager.getPrincipal(currentSession.getUserID())); Set<String> groups = new HashSet<String>(); for (; pi.hasNext(); ) { groups.add(pi.nextPrincipal().getName()); } for (String groupName : authorizedGroups) { if (groups.contains(groupName)) { allowCreateGroup = true; break; } // TODO: move this nasty hack into the PrincipalManager dynamic groups need to // be in the principal manager for this to work. if ("authenticated".equals(groupName) && !SecurityConstants.ADMIN_ID.equals(currentUser.getID())) { allowCreateGroup = true; break; } // just check via the user manager for dynamic resolution. Group group = (Group) um.getAuthorizable(groupName); LOGGER.debug("Checking for group {} {} ", groupName, group); if (group != null && group.isMember(currentUser)) { allowCreateGroup = true; LOGGER.debug("User is a member of {} {} ", groupName, group); break; } } } } catch (Exception ex) { LOGGER.warn( "Failed to determin if the user is an admin, assuming not. Cause: " + ex.getMessage()); allowCreateGroup = false; } if (!allowCreateGroup) { LOGGER.debug("User is not allowed to create groups "); response.setStatus(HttpServletResponse.SC_FORBIDDEN, "User is not allowed to create groups"); return; } Session session = getSession(); try { UserManager userManager = AccessControlUtil.getUserManager(session); Authorizable authorizable = userManager.getAuthorizable(principalName); if (authorizable != null) { // principal already exists! throw new RepositoryException( "A principal already exists with the requested name: " + principalName); } else { Group group = userManager.createGroup( new Principal() { public String getName() { return principalName; } }); String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getID(); Map<String, RequestProperty> reqProperties = collectContent(request, response, groupPath); response.setPath(groupPath); response.setLocation(externalizePath(request, groupPath)); response.setParentLocation( externalizePath(request, AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH)); changes.add(Modification.onCreated(groupPath)); // It is not allowed to touch the rep:group-managers property directly. String key = SYSTEM_USER_MANAGER_GROUP_PREFIX + principalName + "/"; reqProperties.remove(key + PROP_GROUP_MANAGERS); reqProperties.remove(key + PROP_GROUP_VIEWERS); // write content from form writeContent(session, group, reqProperties, changes); // update the group memberships, although this uses session from the request, it // only // does so for finding authorizables, so its ok that we are using an admin session // here. updateGroupMembership(request, group, changes); updateOwnership(request, group, new String[] {currentUser.getID()}, changes); sakaiAuthorizableService.postprocess(group, session); // Launch an OSGi event for creating a group. try { Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(UserConstants.EVENT_PROP_USERID, principalName); EventUtils.sendOsgiEvent(properties, UserConstants.TOPIC_GROUP_CREATED, eventAdmin); } catch (Exception e) { // Trap all exception so we don't disrupt the normal behaviour. LOGGER.error("Failed to launch an OSGi event for creating a user.", e); } } } catch (RepositoryException re) { throw new RepositoryException("Failed to create new group.", re); } finally { ungetSession(session); } }