@Test public void testProperPoolId() throws ItemNotFoundException, RepositoryException, NoSuchAlgorithmException, UnsupportedEncodingException { SlingHttpServletRequest request = mock(SlingHttpServletRequest.class); HtmlResponse response = new HtmlResponse(); ResourceResolver resolver = mock(ResourceResolver.class); String poolId = "foobarbaz"; Resource resource = mock(Resource.class); // The tagnode Node tagNode = new MockNode("/path/to/tag"); tagNode.setProperty(SLING_RESOURCE_TYPE_PROPERTY, FilesConstants.RT_SAKAI_TAG); tagNode.setProperty(FilesConstants.SAKAI_TAG_NAME, "urban"); // The file we want to tag. Node fileNode = mock(Node.class); when(fileNode.getPath()).thenReturn("/path/to/file"); NodeType type = mock(NodeType.class); when(type.getName()).thenReturn("foo"); when(fileNode.getMixinNodeTypes()).thenReturn(new NodeType[] {type}); Property tagsProp = mock(Property.class); MockPropertyDefinition tagsPropDef = new MockPropertyDefinition(false); Value v = new MockValue("uuid-to-other-tag"); when(tagsProp.getDefinition()).thenReturn(tagsPropDef); when(tagsProp.getValue()).thenReturn(v); when(fileNode.getProperty(FilesConstants.SAKAI_TAGS)).thenReturn(tagsProp); when(fileNode.hasProperty(FilesConstants.SAKAI_TAGS)).thenReturn(true); // Stuff to check if this is a correct request when(session.getNode(CreateContentPoolServlet.hash(poolId))).thenReturn(tagNode); RequestParameter poolIdParam = mock(RequestParameter.class); when(resolver.adaptTo(Session.class)).thenReturn(session); when(resource.adaptTo(Node.class)).thenReturn(fileNode); when(poolIdParam.getString()).thenReturn(poolId); when(request.getResource()).thenReturn(resource); when(request.getResourceResolver()).thenReturn(resolver); when(request.getRequestParameter("key")).thenReturn(poolIdParam); when(request.getRemoteUser()).thenReturn("john"); // Actual tagging procedure Session adminSession = mock(Session.class); when(adminSession.getItem(fileNode.getPath())).thenReturn(fileNode); ValueFactory valueFactory = mock(ValueFactory.class); Value newValue = new MockValue("uuid-of-tag"); when(valueFactory.createValue(Mockito.anyString(), Mockito.anyInt())) .thenReturn(newValue) .thenReturn(newValue); when(adminSession.getValueFactory()).thenReturn(valueFactory).thenReturn(valueFactory); when(slingRepo.loginAdministrative(null)).thenReturn(adminSession); when(adminSession.hasPendingChanges()).thenReturn(true); operation.doRun(request, response, null); assertEquals(200, response.getStatusCode()); verify(adminSession).save(); verify(adminSession).logout(); }
@Test public void testAnonRequest() throws RepositoryException { SlingHttpServletRequest request = mock(SlingHttpServletRequest.class); when(request.getRemoteUser()).thenReturn(UserConstants.ANON_USERID); HtmlResponse response = new HtmlResponse(); operation.doRun(request, response, null); assertEquals(403, response.getStatusCode()); }
@Test public void testMissingResource() throws RepositoryException { // This shouldn't really happen, but hey! SlingHttpServletRequest request = mock(SlingHttpServletRequest.class); HtmlResponse response = new HtmlResponse(); ResourceResolver resolver = mock(ResourceResolver.class); when(resolver.adaptTo(Session.class)).thenReturn(session); Resource resource = mock(Resource.class); when(resource.adaptTo(Node.class)).thenReturn(null); when(request.getResource()).thenReturn(resource); when(request.getResourceResolver()).thenReturn(resolver); when(request.getRemoteUser()).thenReturn("john"); operation.doRun(request, response, null); assertEquals(400, response.getStatusCode()); }
@Test public void testMissingParams() throws RepositoryException { SlingHttpServletRequest request = mock(SlingHttpServletRequest.class); HtmlResponse response = new HtmlResponse(); ResourceResolver resolver = mock(ResourceResolver.class); when(resolver.adaptTo(Session.class)).thenReturn(session); Resource resource = mock(Resource.class); Node node = new MockNode("/bla/bla"); when(resource.adaptTo(Node.class)).thenReturn(node); when(request.getResource()).thenReturn(resource); when(request.getResourceResolver()).thenReturn(resolver); when(request.getRequestParameter("key")).thenReturn(null); when(request.getRemoteUser()).thenReturn("john"); operation.doRun(request, response, null); assertEquals(400, response.getStatusCode()); }
@Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { HtmlResponse htmlResponse = null; ResourceResolver adminResolver = null; Session adminSession = null; try { String email = request.getParameter(REQ_PRM_USERNAME); String password = request.getParameter(REQ_PRM_PASSWORD); String inviteKey = request.getParameter(REQ_PRM_INVITEKEY); String acceptStatus = request.getParameter(REQ_PRM_ACCEPT_STATUS); adminResolver = getAdminResolver(); adminSession = adminResolver.adaptTo(Session.class); InvitationToken invToken = ccInvitationService.getInvitationTokenByTokenKey(inviteKey, adminResolver); if (invToken != null && invToken.isValid() && inviteKey.equals(invToken.getKey())) { // Gets user account if user is already configured. Gets null // otherwise. Resource configResource = CCUtils.getAccountResourceByUserEmail(adminResolver, email); if (configResource == null) { // Create configuration if not // present. For first time login // encrypt the password if (!crypto.isProtected(password)) { password = crypto.protect(password); } AccessToken token = null; try { token = imsService.getAccessToken(email, password); } catch (Exception e) { log.error(e.getMessage(), e); htmlResponse = HtmlStatusResponseHelper.createStatusResponse(false, "Invalid Credentials"); } if (token != null) { // succesful login String configName = "invited_" + email; configName = configName.replace("@", "_at_").replaceAll("\\.", "_"); PageManager pageManager = pageManagerFactory.getPageManager(adminResolver); pageManager.create(CC_CONFIG_ROOT, configName, configName, CC_CONFIG_PAGE_TEMPLATE); Node configNode = adminSession.getNode(CC_CONFIG_ROOT + "/" + configName); Node contentNode = configNode.getNode("jcr:content"); contentNode.setProperty(CreativeCloudAccountConfig.PROPERTY_USERNAME, email); contentNode.setProperty("sling:resourceType", CreativeCloudAccountConfig.RESOURCE_TYPE); contentNode.setProperty( CreativeCloudAccountConfig.PROPERTY_ACCESS_TOKEN, token.getAccessToken()); contentNode.setProperty( CreativeCloudAccountConfig.PROPERTY_REFRESH_TOKEN, token.getRefreshToken()); contentNode.setProperty( CreativeCloudAccountConfig.PROPERTY_TOKEN_EXPIRES, token.getExpiresIn()); contentNode.setProperty(CreativeCloudAccountConfig.PROPERTY_PASSWORD, password); Node pollConfigNode = contentNode.addNode(CreativeCloudAccountConfig.NN_POLLCONFIG); pollConfigNode.setProperty( CreativeCloudAccountConfig.PROPERTY_INTERVAL, importer.getMinimumInterval()); pollConfigNode.setProperty(CreativeCloudAccountConfig.PROPERTY_ENABLED, true); configResource = adminResolver.getResource(contentNode.getPath()); ccConfigService.initAccount(configResource); } } else { // Sets the jcr content node as the config node configResource = configResource.getChild("jcr:content"); } if (acceptStatus != null && acceptStatus.equalsIgnoreCase("false")) { htmlResponse = HtmlStatusResponseHelper.createStatusResponse(true, "invitation declined"); } else { String[] paths = invToken.getPaths(); for (String path : paths) { // ccShareService.shareWithCCUser(configResource, // adminResolver.getResource(path)); // Asynchronous sharing Object job = new CCShareInBackground(factory, configResource.getPath(), path, ccShareService); String jobName = CCShareInBackground.class.getName() + "_" + UUID.randomUUID().toString().substring(0, 8); scheduler.fireJobAt(jobName, job, null, new Date()); } htmlResponse = HtmlStatusResponseHelper.createStatusResponse(true, "invitation accepted"); } ccInvitationService.acceptInvitation(email, inviteKey, adminResolver); adminSession.save(); } else { htmlResponse = HtmlStatusResponseHelper.createStatusResponse( false, "invitation expired or already accepted/declined"); } } catch (Exception e) { log.error(e.getMessage(), e); htmlResponse = HtmlStatusResponseHelper.createStatusResponse(false, e.getMessage()); htmlResponse.setError(e); } finally { if (adminSession != null) { adminSession.logout(); } if (adminResolver != null) { adminResolver.close(); } assert htmlResponse != null; htmlResponse.send(response, true); } }
/* * (non-Javadoc) * @see * org.apache.sling.jackrabbit.usermanager.post.AbstractAuthorizablePostServlet * #handleOperation(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.servlets.HtmlResponse, java.util.List) */ @Override protected void handleOperation( SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes) throws RepositoryException { // make sure user self-registration is enabled if (!selfRegistrationEnabled) { throw new RepositoryException( "Sorry, registration of new users is not currently enabled. Please try again later."); } Session session = request.getResourceResolver().adaptTo(Session.class); if (session == null) { throw new RepositoryException("JCR Session not found"); } // check that the submitted parameter values have valid values. String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); if (principalName == null) { throw new RepositoryException("User name was not submitted"); } String pwd = request.getParameter("pwd"); if (pwd == null) { throw new RepositoryException("Password was not submitted"); } String pwdConfirm = request.getParameter("pwdConfirm"); if (!pwd.equals(pwdConfirm)) { throw new RepositoryException("Password value does not match the confirmation password"); } Session selfRegSession = null; try { selfRegSession = getSession(); UserManager userManager = AccessControlUtil.getUserManager(selfRegSession); Authorizable authorizable = userManager.getAuthorizable(principalName); if (authorizable != null) { // user already exists! throw new RepositoryException( "A principal already exists with the requested name: " + principalName); } else { Map<String, RequestProperty> reqProperties = collectContent(request, response); User user = userManager.createUser(principalName, digestPassword(pwd)); String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + user.getID(); response.setPath(userPath); response.setLocation(externalizePath(request, userPath)); response.setParentLocation( externalizePath(request, AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PATH)); changes.add(Modification.onCreated(userPath)); // write content from form writeContent(selfRegSession, user, reqProperties, changes); if (selfRegSession.hasPendingChanges()) { selfRegSession.save(); } } } finally { ungetSession(selfRegSession); } }
/* * (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); } }