incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jvazq...@apache.org
Subject svn commit: r756191 [1/2] - in /incubator/sling/trunk: bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/
Date Thu, 19 Mar 2009 20:53:25 GMT
Author: jvazquez
Date: Thu Mar 19 20:53:24 2009
New Revision: 756191

URL: http://svn.apache.org/viewvc?rev=756191&view=rev
Log:
SLING-875: New Bundle for a ResourceProvider and Sling Post Operations for interacting with the jackrabbit UserManager 
https://issues.apache.org/jira/browse/SLING-875

Added:
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizablePostServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractGroupPostServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractUserPostServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangeUserPasswordServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateGroupServlet.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateUserServlet.java
Removed:
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizableOperation.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangePasswordOperation.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupOperation.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserOperation.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableOperation.java
    incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateAuthorizableOperation.java
Modified:
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/AbstractUserManagerTest.java
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateGroupTest.java
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateUserTest.java
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/RemoveAuthorizablesTest.java
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateGroupTest.java
    incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizablePostServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizablePostServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizablePostServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractAuthorizablePostServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,717 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.api.wrappers.SlingRequestPaths;
+import org.apache.sling.commons.osgi.OsgiUtil;
+import org.apache.sling.jackrabbit.usermanager.post.impl.DateParser;
+import org.apache.sling.jackrabbit.usermanager.post.impl.RequestProperty;
+import org.apache.sling.jackrabbit.usermanager.resource.AuthorizableResourceProvider;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for all the POST servlets for the UserManager operations 
+ */
+public abstract class AbstractAuthorizablePostServlet extends SlingAllMethodsServlet {
+	private static final long serialVersionUID = -5918670409789895333L;
+
+	/**
+     * default log
+     */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * @scr.property values.0="EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
+     *               values.1="yyyy-MM-dd'T'HH:mm:ss.SSSZ"
+     *               values.2="yyyy-MM-dd'T'HH:mm:ss" values.3="yyyy-MM-dd"
+     *               values.4="dd.MM.yyyy HH:mm:ss" values.5="dd.MM.yyyy"
+     */
+    private static final String PROP_DATE_FORMAT = "servlet.post.dateFormats";
+	
+	private DateParser dateParser;
+	
+    // ---------- SCR Integration ----------------------------------------------
+
+    protected void activate(ComponentContext context) {
+        Dictionary<?, ?> props = context.getProperties();
+
+        dateParser = new DateParser();
+        String[] dateFormats = OsgiUtil.toStringArray(props.get(PROP_DATE_FORMAT));
+        for (String dateFormat : dateFormats) {
+            dateParser.register(dateFormat);
+        }
+    }
+
+    protected void deactivate(ComponentContext context) {
+        dateParser = null;
+    }
+	
+    
+	/* (non-Javadoc)
+	 * @see org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.SlingHttpServletResponse)
+	 */
+	@Override
+	protected void doPost(SlingHttpServletRequest request,
+			SlingHttpServletResponse httpResponse) throws ServletException,
+			IOException {
+        // prepare the response
+        HtmlResponse htmlResponse = new HtmlResponse();
+        htmlResponse.setReferer(request.getHeader("referer"));
+
+        // calculate the paths
+        String path = getItemPath(request);
+        htmlResponse.setPath(path);
+
+        // location
+        htmlResponse.setLocation(externalizePath(request, path));
+
+        // parent location
+        path = ResourceUtil.getParent(path);
+        if (path != null) {
+        	htmlResponse.setParentLocation(externalizePath(request, path));
+        }
+
+        Session session = request.getResourceResolver().adaptTo(Session.class);
+
+        final List<Modification> changes = new ArrayList<Modification>();
+        
+        try {
+            handleOperation(request, htmlResponse, changes);
+            
+            //TODO: maybe handle SlingAuthorizablePostProcessor handlers here
+            
+            // set changes on html response
+            for(Modification change : changes) {
+                switch ( change.getType() ) {
+                    case MODIFY : htmlResponse.onModified(change.getSource()); break;
+                    case DELETE : htmlResponse.onDeleted(change.getSource()); break;
+                    case MOVE :   htmlResponse.onMoved(change.getSource(), change.getDestination()); break;
+                    case COPY :   htmlResponse.onCopied(change.getSource(), change.getDestination()); break;
+                    case CREATE : htmlResponse.onCreated(change.getSource()); break;
+                    case ORDER : htmlResponse.onChange("ordered", change.getSource(), change.getDestination()); break;
+                }
+            }
+            
+            if (session.hasPendingChanges()) {
+                session.save();
+            }
+        } catch (ResourceNotFoundException rnfe) {
+            htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND,
+                rnfe.getMessage());
+        } catch (Throwable throwable) {
+            log.debug("Exception while handling POST "
+                + request.getResource().getPath() + " with "
+                + getClass().getName(), throwable);
+            htmlResponse.setError(throwable);
+        } finally {
+            try {
+                if (session.hasPendingChanges()) {
+                    session.refresh(false);
+                }
+            } catch (RepositoryException e) {
+                log.warn("RepositoryException in finally block: {}",
+                    e.getMessage(), e);
+            }
+        }
+        
+        // check for redirect URL if processing succeeded
+        if (htmlResponse.isSuccessful()) {
+            String redirect = getRedirectUrl(request, htmlResponse);
+            if (redirect != null) {
+                httpResponse.sendRedirect(redirect);
+                return;
+            }
+        }
+
+        // create a html response and send if unsuccessful or no redirect
+        htmlResponse.send(httpResponse, isSetStatus(request));
+	}
+
+	/**
+	 * Extending Servlet should implement this operation to do the work
+	 * 
+	 * @param request the sling http request to process
+	 * @param htmlResponse the response 
+	 * @param changes 
+	 */
+	abstract protected void handleOperation(SlingHttpServletRequest request,
+			HtmlResponse htmlResponse, List<Modification> changes) throws RepositoryException;
+	
+	
+    /**
+     * compute redirect URL (SLING-126)
+     *
+     * @param ctx the post processor
+     * @return the redirect location or <code>null</code>
+     */
+    protected String getRedirectUrl(HttpServletRequest request, HtmlResponse ctx) {
+        // redirect param has priority (but see below, magic star)
+        String result = request.getParameter(SlingPostConstants.RP_REDIRECT_TO);
+        if (result != null && ctx.getPath() != null) {
+
+            // redirect to created/modified Resource
+            int star = result.indexOf('*');
+            if (star >= 0) {
+                StringBuffer buf = new StringBuffer();
+
+                // anything before the star
+                if (star > 0) {
+                    buf.append(result.substring(0, star));
+                }
+
+                // append the name of the manipulated node
+                buf.append(ResourceUtil.getName(ctx.getPath()));
+
+                // anything after the star
+                if (star < result.length() - 1) {
+                    buf.append(result.substring(star + 1));
+                }
+
+                // use the created path as the redirect result
+                result = buf.toString();
+
+            } else if (result.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
+                // if the redirect has a trailing slash, append modified node
+                // name
+                result = result.concat(ResourceUtil.getName(ctx.getPath()));
+            }
+
+            if (log.isDebugEnabled()) {
+                log.debug("Will redirect to " + result);
+            }
+        }
+        return result;
+    }
+
+    protected boolean isSetStatus(SlingHttpServletRequest request) {
+        String statusParam = request.getParameter(SlingPostConstants.RP_STATUS);
+        if (statusParam == null) {
+            log.debug(
+                "getStatusMode: Parameter {} not set, assuming standard status code",
+                SlingPostConstants.RP_STATUS);
+            return true;
+        }
+
+        if (SlingPostConstants.STATUS_VALUE_BROWSER.equals(statusParam)) {
+            log.debug(
+                "getStatusMode: Parameter {} asks for user-friendly status code",
+                SlingPostConstants.RP_STATUS);
+            return false;
+        }
+
+        if (SlingPostConstants.STATUS_VALUE_STANDARD.equals(statusParam)) {
+            log.debug(
+                "getStatusMode: Parameter {} asks for standard status code",
+                SlingPostConstants.RP_STATUS);
+            return true;
+        }
+
+        log.debug(
+            "getStatusMode: Parameter {} set to unknown value {}, assuming standard status code",
+            SlingPostConstants.RP_STATUS);
+        return true;
+    }
+	
+    
+    
+    // ------ The methods below are based on the private methods from the ModifyOperation class -----
+    
+    /**
+     * Collects the properties that form the content to be written back to the
+     * repository. 
+     * 
+     * NOTE: In the returned map, the key is the property name not a path.
+     *
+     * @throws RepositoryException if a repository error occurs
+     * @throws ServletException if an internal error occurs
+     */
+    protected Map<String, RequestProperty> collectContent(
+            SlingHttpServletRequest request, HtmlResponse response) {
+
+        boolean requireItemPrefix = requireItemPathPrefix(request);
+
+        // walk the request parameters and collect the properties
+        Map<String, RequestProperty> reqProperties = new HashMap<String, RequestProperty>();
+        for (Map.Entry<String, RequestParameter[]> e : request.getRequestParameterMap().entrySet()) {
+            final String paramName = e.getKey();
+
+            // do not store parameters with names starting with sling:post
+            if (paramName.startsWith(SlingPostConstants.RP_PREFIX)) {
+                continue;
+            }
+            // SLING-298: skip form encoding parameter
+            if (paramName.equals("_charset_")) {
+                continue;
+            }
+            // skip parameters that do not start with the save prefix
+            if (requireItemPrefix && !hasItemPathPrefix(paramName)) {
+                continue;
+            }
+
+            // ensure the paramName is an absolute property name
+            String propPath;
+            if (paramName.startsWith("./")) {
+            	propPath = paramName.substring(2);
+            } else {
+            	propPath = paramName;
+            }
+            if (propPath.indexOf('/') != -1) {
+            	//only one path segment is valid here, so this paramter can't be used.
+            	continue; //skip it.
+            }
+
+            // @TypeHint example
+            // <input type="text" name="./age" />
+            // <input type="hidden" name="./age@TypeHint" value="long" />
+            // causes the setProperty using the 'long' property type
+            if (propPath.endsWith(SlingPostConstants.TYPE_HINT_SUFFIX)) {
+                RequestProperty prop = getOrCreateRequestProperty(
+                    reqProperties, propPath,
+                    SlingPostConstants.TYPE_HINT_SUFFIX);
+
+                final RequestParameter[] rp = e.getValue();
+                if (rp.length > 0) {
+                    prop.setTypeHintValue(rp[0].getString());
+                }
+
+                continue;
+            }
+
+            // @DefaultValue
+            if (propPath.endsWith(SlingPostConstants.DEFAULT_VALUE_SUFFIX)) {
+                RequestProperty prop = getOrCreateRequestProperty(
+                    reqProperties, propPath,
+                    SlingPostConstants.DEFAULT_VALUE_SUFFIX);
+
+                prop.setDefaultValues(e.getValue());
+
+                continue;
+            }
+
+            // SLING-130: VALUE_FROM_SUFFIX means take the value of this
+            // property from a different field
+            // @ValueFrom example:
+            // <input name="./Text@ValueFrom" type="hidden" value="fulltext" />
+            // causes the JCR Text property to be set to the value of the
+            // fulltext form field.
+            if (propPath.endsWith(SlingPostConstants.VALUE_FROM_SUFFIX)) {
+                RequestProperty prop = getOrCreateRequestProperty(
+                    reqProperties, propPath,
+                    SlingPostConstants.VALUE_FROM_SUFFIX);
+
+                // @ValueFrom params must have exactly one value, else ignored
+                if (e.getValue().length == 1) {
+                    String refName = e.getValue()[0].getString();
+                    RequestParameter[] refValues = request.getRequestParameters(refName);
+                    if (refValues != null) {
+                        prop.setValues(refValues);
+                    }
+                }
+
+                continue;
+            }
+
+            // SLING-458: Allow Removal of properties prior to update
+            // @Delete example:
+            // <input name="./Text@Delete" type="hidden" />
+            // causes the JCR Text property to be deleted before update
+            if (propPath.endsWith(SlingPostConstants.SUFFIX_DELETE)) {
+                RequestProperty prop = getOrCreateRequestProperty(
+                    reqProperties, propPath, SlingPostConstants.SUFFIX_DELETE);
+
+                prop.setDelete(true);
+
+                continue;
+            }
+
+            // SLING-455: @MoveFrom means moving content to another location
+            // @MoveFrom example:
+            // <input name="./Text@MoveFrom" type="hidden" value="/tmp/path" />
+            // causes the JCR Text property to be set by moving the /tmp/path
+            // property to Text.
+            if (propPath.endsWith(SlingPostConstants.SUFFIX_MOVE_FROM)) {
+            	//don't support @MoveFrom here
+                continue;
+            }
+
+            // SLING-455: @CopyFrom means moving content to another location
+            // @CopyFrom example:
+            // <input name="./Text@CopyFrom" type="hidden" value="/tmp/path" />
+            // causes the JCR Text property to be set by copying the /tmp/path
+            // property to Text.
+            if (propPath.endsWith(SlingPostConstants.SUFFIX_COPY_FROM)) {
+            	//don't support @CopyFrom here
+                continue;
+            }
+
+            // plain property, create from values
+            RequestProperty prop = getOrCreateRequestProperty(reqProperties,
+                propPath, null);
+            prop.setValues(e.getValue());
+        }
+
+        return reqProperties;
+    }
+	
+	
+    /**
+     * Returns the request property for the given property path. If such a
+     * request property does not exist yet it is created and stored in the
+     * <code>props</code>.
+     *
+     * @param props The map of already seen request properties.
+     * @param paramName The absolute path of the property including the
+     *            <code>suffix</code> to be looked up.
+     * @param suffix The (optional) suffix to remove from the
+     *            <code>paramName</code> before looking it up.
+     * @return The {@link RequestProperty} for the <code>paramName</code>.
+     */
+    private RequestProperty getOrCreateRequestProperty(
+            Map<String, RequestProperty> props, String paramName, String suffix) {
+        if (suffix != null && paramName.endsWith(suffix)) {
+            paramName = paramName.substring(0, paramName.length()
+                - suffix.length());
+        }
+
+        RequestProperty prop = props.get(paramName);
+        if (prop == null) {
+            prop = new RequestProperty(paramName);
+            props.put(paramName, prop);
+        }
+
+        return prop;
+    }
+    
+    
+    /**
+     * Removes all properties listed as {@link RequestProperty#isDelete()} from
+     * the authorizable.
+     *
+     * @param authorizable The <code>org.apache.jackrabbit.api.security.user.Authorizable</code> 
+     * 				that should have properties deleted.
+     * @param reqProperties The map of request properties to check for
+     *            properties to be removed.
+     * @param response The <code>HtmlResponse</code> to be updated with
+     *            information on deleted properties.
+     * @throws RepositoryException Is thrown if an error occurrs checking or
+     *             removing properties.
+     */
+    protected void processDeletes(Authorizable resource, 
+            Map<String, RequestProperty> reqProperties,
+            List<Modification> changes) throws RepositoryException {
+
+        for (RequestProperty property : reqProperties.values()) {
+            if (property.isDelete()) {
+            	if (resource.hasProperty(property.getName())) {
+            		resource.removeProperty(property.getName());
+                    changes.add(Modification.onDeleted(property.getPath()));
+            	}
+            }
+        }
+    }
+
+    
+    /**
+     * Writes back the content
+     *
+     * @throws RepositoryException if a repository error occurs
+     * @throws ServletException if an internal error occurs
+     */
+    protected void writeContent(Session session, Authorizable authorizable,
+            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            throws RepositoryException {
+
+        for (RequestProperty prop : reqProperties.values()) {
+            if (prop.hasValues()) {
+                // skip jcr special properties
+                if (prop.getName().equals("jcr:primaryType")
+                    || prop.getName().equals("jcr:mixinTypes")) {
+                    continue;
+                }
+                if (authorizable.isGroup()) {
+                    if (prop.getName().equals("groupId")) {
+                    	//skip these
+                    	continue;
+                	}                	
+                } else {
+                    if (prop.getName().equals("userId") ||
+                    		prop.getName().equals("pwd") ||
+                    		prop.getName().equals("pwdConfirm")) {
+                    	//skip these
+                    	continue;
+                    }
+                }
+                if (prop.isFileUpload()) {
+                	//don't handle files for user properties for now.
+                	continue;
+                    //uploadHandler.setFile(parent, prop, changes);
+                } else {
+                	setPropertyAsIs(session, authorizable, prop, changes);
+                }
+            }
+        }
+    }
+    
+    /**
+     * set property without processing, except for type hints
+     *
+     * @param parent the parent node
+     * @param prop the request property
+     * @throws RepositoryException if a repository error occurs.
+     */
+    private void setPropertyAsIs(Session session, Authorizable parent, RequestProperty prop, List<Modification> changes)
+            throws RepositoryException {
+
+    	String parentPath;
+    	if (parent.isGroup()) {
+    		parentPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + parent.getID();
+    	} else {
+    		parentPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + parent.getID();
+    	}
+
+
+        // no explicit typehint
+        int type = PropertyType.UNDEFINED;
+        if (prop.getTypeHint() != null) {
+            try {
+                type = PropertyType.valueFromName(prop.getTypeHint());
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        String[] values = prop.getStringValues();
+		if (values == null) {
+            // remove property
+	        boolean removedProp = removePropertyIfExists(parent, prop.getName());
+	        if (removedProp) {
+	            changes.add(Modification.onDeleted(
+	            		parentPath + "/" + prop.getName()
+	            ));
+	        }
+        } else if (values.length == 0) {
+            // do not create new prop here, but clear existing
+            if (parent.hasProperty(prop.getName())) {
+            	Value val = session.getValueFactory().createValue("");
+            	parent.setProperty(prop.getName(), val);
+                changes.add(Modification.onModified(
+                	parentPath + "/" + prop.getName()
+                ));
+            }
+        } else if (values.length == 1) {
+            boolean removedProp = removePropertyIfExists(parent, prop.getName());
+            // if the provided value is the empty string, we don't have to do anything.
+            if ( values[0].length() == 0 ) {
+                if ( removedProp ) {
+                    changes.add(Modification.onDeleted(parentPath + "/" + prop.getName()));
+                }
+            } else {
+                // modify property
+                if (type == PropertyType.DATE) {
+                    // try conversion
+                    Calendar c = dateParser.parse(values[0]);
+                    if (c != null) {
+                        if ( prop.hasMultiValueTypeHint() ) {
+                            final Value[] array = new Value[1];
+                            array[0] = session.getValueFactory().createValue(c);
+                            parent.setProperty(prop.getName(), array);
+                            changes.add(Modification.onModified(
+                                parentPath + "/" + prop.getName()
+                            ));
+                        } else {
+                        	Value cVal = session.getValueFactory().createValue(c);
+                        	parent.setProperty(prop.getName(), cVal);
+                            changes.add(Modification.onModified(
+                                    parentPath + "/" + prop.getName()
+                                ));
+                        }
+                        return;
+                    }
+                    // fall back to default behaviour
+                }
+                if ( type == PropertyType.UNDEFINED ) {
+                	Value val = session.getValueFactory().createValue(values[0], PropertyType.STRING);
+                	parent.setProperty(prop.getName(), val);
+                } else {
+                    if ( prop.hasMultiValueTypeHint() ) {
+                        final Value[] array = new Value[1];
+                        array[0] = session.getValueFactory().createValue(values[0], type);
+                        parent.setProperty(prop.getName(), array);
+                    } else {
+                    	Value val = session.getValueFactory().createValue(values[0], type);
+                        parent.setProperty(prop.getName(), val);
+                    }
+                }
+                changes.add(Modification.onModified(parentPath + "/" + prop.getName()));
+            }
+        } else {
+            removePropertyIfExists(parent, prop.getName());
+            if (type == PropertyType.DATE) {
+                // try conversion
+                ValueFactory valFac = session.getValueFactory();
+                Value[] c = dateParser.parse(values, valFac);
+                if (c != null) {
+                	parent.setProperty(prop.getName(), c);
+                    changes.add(Modification.onModified(
+                    		parentPath + "/" + prop.getName()
+                    ));
+                    return;
+                }
+                // fall back to default behaviour
+            }
+
+            Value [] vals = new Value[values.length];
+            if ( type == PropertyType.UNDEFINED ) {
+            	for(int i=0; i < values.length; i++) {
+            		vals[i] = session.getValueFactory().createValue(values[i]);
+            	}
+            } else {
+            	for(int i=0; i < values.length; i++) {
+            		vals[i] = session.getValueFactory().createValue(values[i], type);
+            	}
+            }
+        	parent.setProperty(prop.getName(), vals);
+            changes.add(Modification.onModified(parentPath + "/" + prop.getName()));
+        }
+    
+    }
+
+    /**
+     * Removes the property with the given name from the parent resource if it
+     * exists.
+     *
+     * @param parent the parent resource
+     * @param name the name of the property to remove
+     * @return path of the property that was removed or <code>null</code> if
+     *         it was not removed
+     * @throws RepositoryException if a repository error occurs.
+     */
+	private boolean removePropertyIfExists(Authorizable resource, String name) throws RepositoryException {
+    	if (resource.getProperty(name) != null) {
+    		resource.removeProperty(name);
+    		return true;
+    	}
+    	return false;
+	}
+
+	
+	// ------ These methods were copied from AbstractSlingPostOperation ------
+
+    /**
+     * Returns the path of the resource of the request as the item path.
+     * <p>
+     * This method may be overwritten by extension if the operation has
+     * different requirements on path processing.
+     */
+    protected String getItemPath(SlingHttpServletRequest request) {
+        return request.getResource().getPath();
+    }
+
+    /**
+     * Returns an external form of the given path prepending the context path
+     * and appending a display extension.
+     *
+     * @param path the path to externalize
+     * @return the url
+     */
+    protected final String externalizePath(SlingHttpServletRequest request,
+            String path) {
+        StringBuffer ret = new StringBuffer();
+        ret.append(SlingRequestPaths.getContextPath(request));
+        ret.append(request.getResourceResolver().map(path));
+
+        // append optional extension
+        String ext = request.getParameter(SlingPostConstants.RP_DISPLAY_EXTENSION);
+        if (ext != null && ext.length() > 0) {
+            if (ext.charAt(0) != '.') {
+                ret.append('.');
+            }
+            ret.append(ext);
+        }
+
+        return ret.toString();
+    }
+	
+    /**
+     * Returns <code>true</code> if the <code>name</code> starts with either
+     * of the prefixes
+     * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>},
+     * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_PARENT <code>../</code>}
+     * and {@link SlingPostConstants#ITEM_PREFIX_ABSOLUTE <code>/</code>}.
+     */
+    protected boolean hasItemPathPrefix(String name) {
+        return name.startsWith(SlingPostConstants.ITEM_PREFIX_ABSOLUTE)
+            || name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT)
+            || name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_PARENT);
+    }
+    
+    /**
+     * Returns true if any of the request parameters starts with
+     * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>}.
+     * In this case only parameters starting with either of the prefixes
+     * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_CURRENT <code>./</code>},
+     * {@link SlingPostConstants#ITEM_PREFIX_RELATIVE_PARENT <code>../</code>}
+     * and {@link SlingPostConstants#ITEM_PREFIX_ABSOLUTE <code>/</code>} are
+     * considered as providing content to be stored. Otherwise all parameters
+     * not starting with the command prefix <code>:</code> are considered as
+     * parameters to be stored.
+     */
+    protected final boolean requireItemPathPrefix(
+            SlingHttpServletRequest request) {
+
+        boolean requirePrefix = false;
+
+        Enumeration<?> names = request.getParameterNames();
+        while (names.hasMoreElements() && !requirePrefix) {
+            String name = (String) names.nextElement();
+            requirePrefix = name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT);
+        }
+
+        return requirePrefix;
+    }
+    
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractGroupPostServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractGroupPostServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractGroupPostServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractGroupPostServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.jackrabbit.usermanager.resource.AuthorizableResourceProvider;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+
+/**
+ * Base class for servlets manipulating groups
+ */
+public abstract class AbstractGroupPostServlet extends AbstractAuthorizablePostServlet {
+	private static final long serialVersionUID = 1159063041816944076L;
+
+	/**
+     * Update the group membership based on the ":member" request
+     * parameters.  If the ":member" value ends with @Delete it is removed
+     * from the group membership, otherwise it is added to the group membership.
+     * 
+     * @param request
+     * @param authorizable
+     * @throws RepositoryException
+     */
+	protected void updateGroupMembership(SlingHttpServletRequest request,
+			Authorizable authorizable, List<Modification> changes) throws RepositoryException {
+		if (authorizable.isGroup()) {
+			Group group = ((Group)authorizable);
+    		String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getID(); 
+
+	    	ResourceResolver resolver = request.getResourceResolver();
+	    	Resource baseResource = request.getResource();
+	    	boolean changed = false;
+
+	    	//first remove any members posted as ":member@Delete"
+	    	String[] membersToDelete = request.getParameterValues(SlingPostConstants.RP_PREFIX + "member" + SlingPostConstants.SUFFIX_DELETE);
+	    	if (membersToDelete != null) {
+				for (String member : membersToDelete) {
+	                Resource res = resolver.getResource(baseResource, member);
+	                if (res != null) {
+	                	Authorizable memberAuthorizable = res.adaptTo(Authorizable.class);
+	                	if (memberAuthorizable != null) {
+	                		group.removeMember(memberAuthorizable);
+	                		changed = true;
+	                	}
+	                }
+					
+				}
+	    	}
+	    	
+	    	//second add any members posted as ":member"
+	    	String[] membersToAdd = request.getParameterValues(SlingPostConstants.RP_PREFIX + "member");
+	    	if (membersToAdd != null) {
+				for (String member : membersToAdd) {
+	                Resource res = resolver.getResource(baseResource, member);
+	                if (res != null) {
+	                	Authorizable memberAuthorizable = res.adaptTo(Authorizable.class);
+	                	if (memberAuthorizable != null) {
+	                		group.addMember(memberAuthorizable);
+	                		changed = true;
+	                	}
+	                }
+				}
+	    	}
+
+	    	if (changed) {
+        		//add an entry to the changes list to record the membership change
+        		changes.add(Modification.onModified(groupPath + "/members"));
+	    	}
+		}
+	}
+	
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractUserPostServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractUserPostServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractUserPostServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/AbstractUserPostServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Dictionary;
+
+import org.apache.jackrabbit.util.Text;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Base class for servlets manipulating users
+ */
+public abstract class AbstractUserPostServlet extends AbstractAuthorizablePostServlet {
+	private static final long serialVersionUID = -8401210711297654453L;
+
+	/**
+     * To be used for the encryption. E.g. for passwords in
+     * {@link javax.jcr.SimpleCredentials#getPassword()}  SimpleCredentials} 
+     * @scr.property valueRef="DEFAULT_PASSWORD_DIGEST_ALGORITHM"
+     */
+    private static final String PROP_PASSWORD_DIGEST_ALGORITHM = "password.digest.algorithm";
+    private static final String DEFAULT_PASSWORD_DIGEST_ALGORITHM = "sha1";
+    private String passwordDigestAlgoritm = null;
+
+    // ---------- SCR Integration ----------------------------------------------
+
+    protected void activate(ComponentContext context) {
+        super.activate(context);
+        
+        Dictionary<?, ?> props = context.getProperties();
+
+        Object propValue = props.get(PROP_PASSWORD_DIGEST_ALGORITHM);
+        if (propValue instanceof String) {
+        	passwordDigestAlgoritm = (String)propValue;
+        } else {
+        	passwordDigestAlgoritm = DEFAULT_PASSWORD_DIGEST_ALGORITHM;
+        }
+    }
+
+    protected void deactivate(ComponentContext context) {
+        super.deactivate(context);
+        passwordDigestAlgoritm = null;
+    }
+    
+    /**
+     * Digest the given password using the configured digest algorithm
+     * 
+     * @param pwd the value to digest
+     * @return the digested value
+     * @throws IllegalArgumentException
+     */
+    protected String digestPassword(String pwd) throws IllegalArgumentException {
+        try {
+            StringBuffer password = new StringBuffer();
+            password.append("{").append(passwordDigestAlgoritm).append("}");
+            password.append(Text.digest(passwordDigestAlgoritm, pwd.getBytes("UTF-8")));
+            return password.toString();
+        } catch (NoSuchAlgorithmException e) {
+            throw new IllegalArgumentException(e.toString());
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+    
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangeUserPasswordServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangeUserPasswordServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangeUserPasswordServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/ChangeUserPasswordServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.servlets.post.Modification;
+
+/**
+ * Sling Post Operation implementation for updating the password of a user in the 
+ * jackrabbit UserManager.
+ * 
+ * @scr.component metatype="no" immediate="true"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" value="sling/user"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="changePassword" 
+ */
+public class ChangeUserPasswordServlet extends AbstractUserPostServlet {
+	private static final long serialVersionUID = 1923614318474654502L;
+
+	/* (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 htmlResponse, List<Modification> changes)
+			throws RepositoryException {
+		Authorizable authorizable = null;
+		Resource resource = request.getResource();
+		if (resource != null) {
+			authorizable = resource.adaptTo(Authorizable.class);
+		}
+		
+		//check that the user was located.
+		if (authorizable == null || authorizable.isGroup()) {
+			throw new ResourceNotFoundException("User to update could not be determined.");
+		}
+
+		if ("anonymous".equals(authorizable.getID())) {
+			throw new RepositoryException("Can not change the password of the anonymous user.");
+		}
+
+		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 oldPwd = request.getParameter("oldPwd");
+		if (oldPwd == null || oldPwd.length() == 0) {
+			throw new RepositoryException("Old Password was not submitted");
+		}
+		String newPwd = request.getParameter("newPwd");
+		if (newPwd == null || newPwd.length() == 0) {
+			throw new RepositoryException("New Password was not submitted");
+		}
+		String newPwdConfirm = request.getParameter("newPwdConfirm");
+		if (!newPwd.equals(newPwdConfirm)) {
+			throw new RepositoryException("New Password does not match the confirmation password");
+		}
+		
+		try {
+			String digestedOldPwd = digestPassword(oldPwd);
+			Value[] pwdProperty = ((User)authorizable).getProperty("rep:password");
+			if (pwdProperty != null && pwdProperty.length > 0) {
+				String repPasswordValue = pwdProperty[0].getString();
+				if (!digestedOldPwd.equals(repPasswordValue)) {
+					//submitted oldPwd value is not correct.
+					throw new RepositoryException("Old Password does not match");
+				}
+			}
+				
+			((User)authorizable).changePassword(digestPassword(newPwd));
+			
+            changes.add(Modification.onModified(
+                	resource.getPath() + "/rep:password"
+                ));
+		} catch (RepositoryException re) {
+			throw new RepositoryException("Failed to change user password.", re);
+		}
+	}
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateGroupServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.jackrabbit.usermanager.post.impl.RequestProperty;
+import org.apache.sling.jackrabbit.usermanager.resource.AuthorizableResourceProvider;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+
+/**
+ * Sling Post Servlet implementation for creating a group in the jackrabbit
+ * UserManager.
+ * 
+ * @scr.component immediate="true" 
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" value="sling/groups"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="create" 
+ */
+public class CreateGroupServlet extends AbstractGroupPostServlet {
+	private static final long serialVersionUID = -1084915263933901466L;
+
+	/* (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 {
+		
+		//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");
+		}
+
+		Session session = request.getResourceResolver().adaptTo(Session.class);
+		if (session == null) {
+			throw new RepositoryException("JCR Session not found");
+		}
+
+		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 {
+				Map<String, RequestProperty> reqProperties = collectContent(request, response);
+
+				Group group = userManager.createGroup(new Principal() {
+					public String getName() {
+						return principalName;
+					}
+				});
+
+				String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getID();
+				response.setPath(groupPath);
+				response.setLocation(externalizePath(request, groupPath));
+				response.setParentLocation(externalizePath(request, AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH));
+				changes.add(Modification.onCreated(groupPath));
+				
+		        // write content from form
+		        writeContent(session, group, reqProperties, changes);
+		        
+		        //update the group memberships
+		        updateGroupMembership(request, group, changes);
+			}
+		} catch (RepositoryException re) {
+			throw new RepositoryException("Failed to create new group.", re);
+		}
+	}
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/CreateUserServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.jackrabbit.usermanager.post.impl.RequestProperty;
+import org.apache.sling.jackrabbit.usermanager.resource.AuthorizableResourceProvider;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Sling Post Servlet implementation for creating a user in the jackrabbit
+ * UserManager.
+ * 
+ * @scr.component immediate="true" label="%createUser.post.operation.name"
+ *                description="%createUser.post.operation.description"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" value="sling/users"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="create" 
+ */
+public class CreateUserServlet extends AbstractUserPostServlet {
+	private static final long serialVersionUID = 6871481922737658675L;
+
+	/**
+     * default log
+     */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /** @scr.property label="%self.registration.enabled.name" 
+     * 					description="%self.registration.enabled.description" 
+     * 					valueRef="DEFAULT_SELF_REGISTRATION_ENABLED" 
+     */
+    private static final String PROP_SELF_REGISTRATION_ENABLED = "self.registration.enabled";
+    private static final Boolean DEFAULT_SELF_REGISTRATION_ENABLED = Boolean.TRUE;
+
+    private Boolean selfRegistrationEnabled = DEFAULT_SELF_REGISTRATION_ENABLED;
+
+    /**
+     * The JCR Repository we access to resolve resources
+     *
+     * @scr.reference
+     */
+    private SlingRepository repository;
+
+    /** Returns the JCR repository used by this service. */
+    protected SlingRepository getRepository() {
+        return repository;
+    }
+
+    /**
+     * Returns an administrative session to the default workspace.
+     */
+    private Session getSession() throws RepositoryException {
+        return getRepository().loginAdministrative(null);
+    }
+
+    /**
+     * Return the administrative session and close it.
+     */
+    private void ungetSession(final Session session) {
+        if ( session != null ) {
+            try {
+                session.logout();
+            } catch (Throwable t) {
+                log.error("Unable to log out of session: " + t.getMessage(), t);
+            }
+        }
+    }
+
+    // ---------- SCR integration ---------------------------------------------
+
+    /**
+     * Activates this component.
+     *
+     * @param componentContext The OSGi <code>ComponentContext</code> of this
+     *      component.
+     */
+    protected void activate(ComponentContext componentContext) {
+    	super.activate(componentContext);
+        Dictionary<?, ?> props = componentContext.getProperties();
+        Object propValue = props.get(PROP_SELF_REGISTRATION_ENABLED);
+        if (propValue instanceof String) {
+        	selfRegistrationEnabled = Boolean.parseBoolean((String)propValue);
+        } else {
+        	selfRegistrationEnabled = DEFAULT_SELF_REGISTRATION_ENABLED;
+        }
+    }
+
+    
+
+	/* (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);
+		}
+	}
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/DeleteAuthorizableServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.SlingPostConstants;
+
+/**
+ * Sling Post Operation implementation for deleting one or more users and/or groups from the 
+ * jackrabbit UserManager.
+ * 
+ * @scr.component metatype="no" immediate="true"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" values.0="sling/user" values.1="sling/group" values.2="sling/userManager"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="delete" 
+ */
+public class DeleteAuthorizableServlet extends AbstractAuthorizablePostServlet {
+	private static final long serialVersionUID = 5874621724096106496L;
+
+	/* (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 htmlResponse, List<Modification> changes)
+			throws RepositoryException {
+
+        Iterator<Resource> res = getApplyToResources(request);
+        if (res == null) {
+            Resource resource = request.getResource();
+            Authorizable item = resource.adaptTo(Authorizable.class);
+            if (item == null) {
+  	            String msg = "Missing source " + resource.getPath() + " for delete";
+  	            htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND, msg);
+               	throw new ResourceNotFoundException(msg);
+            }
+
+            item.remove();
+            changes.add(Modification.onDeleted(resource.getPath()));
+        } else {
+            while (res.hasNext()) {
+                Resource resource = res.next();
+                Authorizable item = resource.adaptTo(Authorizable.class);
+                if (item != null) {
+                    item.remove();
+                    changes.add(Modification.onDeleted(resource.getPath()));
+                }
+            }
+        }
+	}
+	
+	
+    /**
+     * Returns an iterator on <code>Resource</code> instances addressed in the
+     * {@link SlingPostConstants#RP_APPLY_TO} request parameter. If the request
+     * parameter is not set, <code>null</code> is returned. If the parameter
+     * is set with valid resources an empty iterator is returned. Any resources
+     * addressed in the {@link SlingPostConstants#RP_APPLY_TO} parameter is
+     * ignored.
+     *
+     * @param request The <code>SlingHttpServletRequest</code> object used to
+     *            get the {@link SlingPostConstants#RP_APPLY_TO} parameter.
+     * @return The iterator of resources listed in the parameter or
+     *         <code>null</code> if the parameter is not set in the request.
+     */
+    protected Iterator<Resource> getApplyToResources(
+            SlingHttpServletRequest request) {
+
+        String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO);
+        if (applyTo == null) {
+            return null;
+        }
+
+        return new ApplyToIterator(request, applyTo);
+    }
+
+    private static class ApplyToIterator implements Iterator<Resource> {
+
+        private final ResourceResolver resolver;
+        private final Resource baseResource;
+        private final String[] paths;
+
+        private int pathIndex;
+
+        private Resource nextResource;
+
+        ApplyToIterator(SlingHttpServletRequest request, String[] paths) {
+            this.resolver = request.getResourceResolver();
+            this.baseResource = request.getResource();
+            this.paths = paths;
+            this.pathIndex = 0;
+
+            nextResource = seek();
+        }
+
+        public boolean hasNext() {
+            return nextResource != null;
+        }
+
+        public Resource next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+
+            Resource result = nextResource;
+            nextResource = seek();
+
+            return result;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        private Resource seek() {
+            while (pathIndex < paths.length) {
+                String path = paths[pathIndex];
+                pathIndex++;
+
+                Resource res = resolver.getResource(baseResource, path);
+                if (res != null) {
+                    return res;
+                }
+            }
+
+            // no more elements in the array
+            return null;
+        }
+    }
+	
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateGroupServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateGroupServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateGroupServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateGroupServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.jackrabbit.usermanager.post.impl.RequestProperty;
+import org.apache.sling.servlets.post.Modification;
+
+/**
+ * Sling Post Operation implementation for updating a group in the 
+ * jackrabbit UserManager.
+ * 
+ * @scr.component metatype="no" immediate="true"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" values="sling/group"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="update" 
+ */
+public class UpdateGroupServlet extends AbstractGroupPostServlet {
+	private static final long serialVersionUID = -8292054361992488797L;
+
+	/* (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 htmlResponse, List<Modification> changes)
+			throws RepositoryException {
+		Authorizable authorizable = null;
+		Resource resource = request.getResource();
+		if (resource != null) {
+			authorizable = resource.adaptTo(Authorizable.class);
+		}
+		
+		//check that the group was located.
+		if (authorizable == null) {
+			throw new ResourceNotFoundException("Group to update could not be determined");
+		}
+
+		Session session = request.getResourceResolver().adaptTo(Session.class);
+		if (session == null) {
+			throw new RepositoryException("JCR Session not found");
+		}
+
+		Map<String, RequestProperty> reqProperties = collectContent(request, htmlResponse);
+		try {
+	        // cleanup any old content (@Delete parameters)
+	        processDeletes(authorizable, reqProperties, changes);
+				
+	        // write content from form
+	        writeContent(session, authorizable, reqProperties, changes);
+	        
+	        //update the group memberships
+			if (authorizable.isGroup()) {
+		        updateGroupMembership(request, authorizable, changes);
+			}
+		} catch (RepositoryException re) {
+			throw new RepositoryException("Failed to update group.", re);
+		}
+	}
+}

Added: incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateUserServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateUserServlet.java?rev=756191&view=auto
==============================================================================
--- incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateUserServlet.java (added)
+++ incubator/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/post/UpdateUserServlet.java Thu Mar 19 20:53:24 2009
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.jackrabbit.usermanager.post;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.jackrabbit.usermanager.post.impl.RequestProperty;
+import org.apache.sling.servlets.post.Modification;
+
+/**
+ * Sling Post Operation implementation for updating a user in the 
+ * jackrabbit UserManager.
+ * 
+ * @scr.component metatype="no" immediate="true"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="sling.servlet.resourceTypes" value="sling/user"
+ * @scr.property name="sling.servlet.methods" value="POST" 
+ * @scr.property name="sling.servlet.selectors" value="update" 
+ */
+public class UpdateUserServlet extends AbstractUserPostServlet {
+	private static final long serialVersionUID = 5874621724096106496L;
+
+	/* (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 htmlResponse, List<Modification> changes)
+			throws RepositoryException {
+		Authorizable authorizable = null;
+		Resource resource = request.getResource();
+		if (resource != null) {
+			authorizable = resource.adaptTo(Authorizable.class);
+		}
+		
+		//check that the group was located.
+		if (authorizable == null) {
+			throw new ResourceNotFoundException("User to update could not be determined");
+		}
+
+		Session session = request.getResourceResolver().adaptTo(Session.class);
+		if (session == null) {
+			throw new RepositoryException("JCR Session not found");
+		}
+
+		Map<String, RequestProperty> reqProperties = collectContent(request, htmlResponse);
+		try {
+	        // cleanup any old content (@Delete parameters)
+	        processDeletes(authorizable, reqProperties, changes);
+				
+	        // write content from form
+	        writeContent(session, authorizable, reqProperties, changes);
+
+		} catch (RepositoryException re) {
+			throw new RepositoryException("Failed to update user.", re);
+		}
+	}
+}

Modified: incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/AbstractUserManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/AbstractUserManagerTest.java?rev=756191&r1=756190&r2=756191&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/AbstractUserManagerTest.java (original)
+++ incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/AbstractUserManagerTest.java Thu Mar 19 20:53:24 2009
@@ -55,6 +55,7 @@
         URL baseUrl = new URL(HTTP_BASE_URL);
         AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);
         post.setDoAuthentication(true);
+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);
         try {
 			httpClient.getState().setCredentials(authScope, creds);
 	        
@@ -70,7 +71,7 @@
 	            assertEquals(assertMessage, expectedStatusCode, status);
 	        }
         } finally {
-        	httpClient.getState().setCredentials(authScope, null);
+        	httpClient.getState().setCredentials(authScope, oldCredentials);
         }
     }
 
@@ -81,6 +82,7 @@
         AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);
         GetMethod getMethod = new GetMethod(urlString);
         getMethod.setDoAuthentication(true);
+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);
     	try {
 			httpClient.getState().setCredentials(authScope, creds);
 
@@ -91,7 +93,7 @@
                 assertEquals(assertMessage, expectedStatusCode, status);
             }
     	} finally {
-        	httpClient.getState().setCredentials(authScope, null);
+        	httpClient.getState().setCredentials(authScope, oldCredentials);
     	}
     }
 
@@ -106,6 +108,7 @@
         URL baseUrl = new URL(HTTP_BASE_URL);
         AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);
         get.setDoAuthentication(true);
+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);
     	try {
 			httpClient.getState().setCredentials(authScope, creds);
 			
@@ -146,7 +149,7 @@
 	        return content.toString();
 			
     	} finally {
-        	httpClient.getState().setCredentials(authScope, null);
+        	httpClient.getState().setCredentials(authScope, oldCredentials);
     	}
     }
     
@@ -154,11 +157,10 @@
     protected static int counter = 1;
     
 	protected String createTestUser() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
 		String testUserId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", testUserId));
 		postParams.add(new NameValuePair("pwd", "testPwd"));
 		postParams.add(new NameValuePair("pwdConfirm", "testPwd"));
@@ -168,11 +170,10 @@
 	}
     
 	protected String createTestGroup() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/group/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";
 
 		String testGroupId = "testGroup" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createGroup"));
 		postParams.add(new NameValuePair(":name", testGroupId));
 		
 		//success would be a redirect to the welcome page of the webapp

Modified: incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateGroupTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateGroupTest.java?rev=756191&r1=756190&r2=756191&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateGroupTest.java (original)
+++ incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateGroupTest.java Thu Mar 19 20:53:24 2009
@@ -39,9 +39,8 @@
 	protected void tearDown() throws Exception {
 		if (testGroupId != null) {
 			//remove the test group if it exists.
-			String postUrl = HTTP_BASE_URL + "/system/userManager/group/" + testGroupId;
+			String postUrl = HTTP_BASE_URL + "/system/userManager/group/" + testGroupId + ".delete.html";
 			List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-			postParams.add(new NameValuePair(":operation", "deleteAuthorizable"));
 			assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
 		}
 
@@ -49,11 +48,10 @@
 	}
 
 	public void testCreateGroup() throws IOException, JSONException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/group/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";
 
 		testGroupId = "testGroup" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createGroup"));
 		postParams.add(new NameValuePair(":name", testGroupId));
 		assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
 		
@@ -67,19 +65,17 @@
 	}
 
 	public void testCreateGroupMissingGroupId() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/group/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";
 
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createGroup"));
 		assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
 	}
 
 	public void testCreateGroupAlreadyExists() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/group/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";
 
 		testGroupId = "testGroup" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createGroup"));
 		postParams.add(new NameValuePair(":name", testGroupId));
 		assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
 		
@@ -88,11 +84,10 @@
 	}
 	
 	public void testCreateGroupWithExtraProperties() throws IOException, JSONException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/group/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";
 
 		testGroupId = "testGroup" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createGroup"));
 		postParams.add(new NameValuePair(":name", testGroupId));
 		postParams.add(new NameValuePair("displayName", "My Test Group"));
 		postParams.add(new NameValuePair("url", "http://www.apache.org"));

Modified: incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateUserTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateUserTest.java?rev=756191&r1=756190&r2=756191&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateUserTest.java (original)
+++ incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/CreateUserTest.java Thu Mar 19 20:53:24 2009
@@ -39,17 +39,15 @@
 	protected void tearDown() throws Exception {
 		if (testUserId != null) {
 			//remove the test user if it exists.
-			String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId;
+			String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".delete.html";
 			List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-			postParams.add(new NameValuePair(":operation", "deleteAuthorizable"));
 			assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
 		}
 		super.tearDown();
 	}
 
 	/*
-		<form action="/system/userManager/createUser.html" method="POST">
-			<input type="hidden" name=":operation" value="creteUser" />
+		<form action="/system/userManager/user.create.html" method="POST">
 		   <div>Name: <input type="text" name=":name" value="testUser" /></div>
 		   <div>Password: <input type="text" name="pwd" value="testUser" /></div>
 		   <div>Password Confirm: <input type="text" name="pwdConfirm" value="testUser" /></div>
@@ -57,11 +55,10 @@
 		</form>
 	 */
 	public void testCreateUser() throws IOException, JSONException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
         
 		testUserId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", testUserId));
 		postParams.add(new NameValuePair("pwd", "testPwd"));
 		postParams.add(new NameValuePair("pwdConfirm", "testPwd"));
@@ -77,33 +74,29 @@
 		assertFalse(jsonObj.has(":name"));
 		assertFalse(jsonObj.has("pwd"));
 		assertFalse(jsonObj.has("pwdConfirm"));
-		assertFalse(jsonObj.has(":operation"));
 	}
 
 	public void testCreateUserMissingUserId() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		assertPostStatus(postUrl, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
 	}
 
 	public void testCreateUserMissingPwd() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
         String userId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", userId));
 		assertPostStatus(postUrl, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
 	}
 
 	public void testCreateUserWrongConfirmPwd() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
         String userId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", userId));
 		postParams.add(new NameValuePair("pwd", "testPwd"));
 		postParams.add(new NameValuePair("pwdConfirm", "testPwd2"));
@@ -111,11 +104,10 @@
 	}
 
 	public void testCreateUserUserAlreadyExists() throws IOException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
 		testUserId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", testUserId));
 		postParams.add(new NameValuePair("pwd", "testPwd"));
 		postParams.add(new NameValuePair("pwdConfirm", "testPwd"));
@@ -126,8 +118,7 @@
 	}
 	
 	/*
-	<form action="/system/userManager/createUser.html" method="POST">
-	    <input type="hidden" name=":operation" value="creteUser" />
+	<form action="/system/userManager/user.create.html" method="POST">
 	   <div>Name: <input type="text" name=":name" value="testUser" /></div>
 	   <div>Password: <input type="text" name="pwd" value="testUser" /></div>
 	   <div>Password Confirm: <input type="text" name="pwdConfirm" value="testUser" /></div>
@@ -137,11 +128,10 @@
 	</form>
 	*/
 	public void testCreateUserWithExtraProperties() throws IOException, JSONException {
-        String postUrl = HTTP_BASE_URL + "/system/userManager/user/";
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";
 
 		testUserId = "testUser" + (counter++);
 		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
-		postParams.add(new NameValuePair(":operation", "createUser"));
 		postParams.add(new NameValuePair(":name", testUserId));
 		postParams.add(new NameValuePair("pwd", "testPwd"));
 		postParams.add(new NameValuePair("pwdConfirm", "testPwd"));
@@ -161,6 +151,5 @@
 		assertFalse(jsonObj.has(":name"));
 		assertFalse(jsonObj.has("pwd"));
 		assertFalse(jsonObj.has("pwdConfirm"));
-		assertFalse(jsonObj.has(":operation"));
 	}		
 }



Mime
View raw message