You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2011/05/06 05:17:52 UTC

svn commit: r1100034 - in /sling/trunk: bundles/jcr/jackrabbit-usermanager/ bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/ bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/user...

Author: enorman
Date: Fri May  6 03:17:47 2011
New Revision: 1100034

URL: http://svn.apache.org/viewvc?rev=1100034&view=rev
Log:
SLING-2072 Add support for disabling users

Modified:
    sling/trunk/bundles/jcr/jackrabbit-usermanager/pom.xml
    sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java
    sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java
    sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java
    sling/trunk/samples/usermanager-ui/src/main/resources/SLING-INF/i18n/resources.json
    sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.css
    sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css
    sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.js
    sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js
    sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp

Modified: sling/trunk/bundles/jcr/jackrabbit-usermanager/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-usermanager/pom.xml?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-usermanager/pom.xml (original)
+++ sling/trunk/bundles/jcr/jackrabbit-usermanager/pom.xml Fri May  6 03:17:47 2011
@@ -95,7 +95,7 @@
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
             <artifactId>jackrabbit-api</artifactId>
-            <version>2.0.0</version>
+            <version>2.2.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>

Modified: sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java Fri May  6 03:17:47 2011
@@ -243,15 +243,6 @@ public class AuthorizablePrivilegesInfoI
 						return true;
 					}
 				}
-				
-				//check if the user is a member of the 'User administrator' group
-				Authorizable userAdmin = userManager.getAuthorizable(this.userAdminGroupName);
-				if (userAdmin instanceof Group) {
-					boolean isMember = ((Group)userAdmin).isMember(currentUser);
-					if (isMember) {
-						return true;
-					}
-				}
 			}
 		} catch (RepositoryException e) {
 			log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), groupId);

Modified: sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java Fri May  6 03:17:47 2011
@@ -22,14 +22,14 @@ 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.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.impl.helper.RequestProperty;
 import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider;
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.impl.helper.RequestProperty;
 
 /**
  * <p>
@@ -91,10 +91,10 @@ public class UpdateUserServlet extends A
     protected void handleOperation(SlingHttpServletRequest request,
             HtmlResponse htmlResponse, List<Modification> changes)
             throws RepositoryException {
-        Authorizable authorizable = null;
+        User authorizable = null;
         Resource resource = request.getResource();
         if (resource != null) {
-            authorizable = resource.adaptTo(Authorizable.class);
+            authorizable = resource.adaptTo(User.class);
         }
 
         // check that the group was located.
@@ -119,7 +119,21 @@ public class UpdateUserServlet extends A
 
             // write content from form
             writeContent(session, authorizable, reqProperties, changes);
-
+            
+            //SLING-2072 set the user as enabled or disabled if the request
+            // has supplied the relev
+            String disabledParam = request.getParameter(":disabled");
+            if ("true".equalsIgnoreCase(disabledParam)) {
+            	//set the user as disabled
+            	String disabledReason = request.getParameter(":disabledReason");
+            	if (disabledReason == null) {
+            		disabledReason = "";
+            	}
+            	authorizable.disable(disabledReason);
+            } else if ("false".equalsIgnoreCase(disabledParam)) {
+            	//re-enable a disabled user
+            	authorizable.disable(null);
+            }
         } catch (RepositoryException re) {
             throw new RepositoryException("Failed to update user.", re);
         }

Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java (original)
+++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java Fri May  6 03:17:47 2011
@@ -23,6 +23,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.NameValuePair;
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 import org.apache.sling.commons.json.JSONException;
@@ -167,5 +168,46 @@ public class UpdateUserTest extends Abst
 		Credentials creds = new UsernamePasswordCredentials(testUserId, "testPwd");
 		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);
 	}
-	
+
+	/**
+	 * Test for SLING-2072
+	 * @throws IOException
+	 */
+	public void testDisableUser() throws IOException {
+		testUserId = createTestUser();
+
+		//login before the user is disabled, so login should work
+        List<NameValuePair> params = new ArrayList<NameValuePair>();
+        params.add(new NameValuePair("j_username", testUserId));
+        params.add(new NameValuePair("j_password", "testPwd"));
+        params.add(new NameValuePair("j_validate", "true"));
+        HttpMethod post = assertPostStatus(HTTP_BASE_URL + "/j_security_check", HttpServletResponse.SC_OK, params, null);
+        assertNull(post.getResponseHeader("X-Reason"));
+		httpClient.getState().clearCredentials();
+		httpClient.getState().clearCookies();
+
+        //update the user to disable it
+        String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".update.html";
+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
+		postParams.add(new NameValuePair(":disabled", "true"));
+		postParams.add(new NameValuePair(":disabledReason", "Just Testing"));
+		assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
+		
+		//the user is now disabled, so login should fail
+        post = assertPostStatus(HTTP_BASE_URL + "/j_security_check", HttpServletResponse.SC_FORBIDDEN, params, null);
+        assertNotNull(post.getResponseHeader("X-Reason"));
+		httpClient.getState().clearCredentials();
+		httpClient.getState().clearCookies();
+
+		//enable the user again
+		postParams = new ArrayList<NameValuePair>();
+		postParams.add(new NameValuePair(":disabled", "false"));
+		assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
+
+		//login after the user is enabled, so login should work
+        post = assertPostStatus(HTTP_BASE_URL + "/j_security_check", HttpServletResponse.SC_OK, params, null);
+        assertNull(post.getResponseHeader("X-Reason"));
+		httpClient.getState().clearCredentials();
+		httpClient.getState().clearCookies();
+	}
 }

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/SLING-INF/i18n/resources.json
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/SLING-INF/i18n/resources.json?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/SLING-INF/i18n/resources.json (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/SLING-INF/i18n/resources.json Fri May  6 03:17:47 2011
@@ -74,6 +74,27 @@
             "sling:message": "View Group: {0}"
         },            
         
+        "prop.label.loginEnabled": {
+            "jcr:primaryType": "sling:MessageEntry",
+            "sling:key": "prop.label.loginEnabled",
+            "sling:message": "Login Enabled"
+        },
+        "prop.label.loginEnabled.yes": {
+            "jcr:primaryType": "sling:MessageEntry",
+            "sling:key": "prop.label.loginEnabled.yes",
+            "sling:message": "Yes"
+        },
+        "prop.label.loginEnabled.no": {
+            "jcr:primaryType": "sling:MessageEntry",
+            "sling:key": "prop.label.loginEnabled.no",
+            "sling:message": "No"
+        },
+        "prop.label.loginDisabled.reason": {
+            "jcr:primaryType": "sling:MessageEntry",
+            "sling:key": "prop.label.loginDisabled.reason",
+            "sling:message": "Reason"
+        },        
+        
         "prop.label.email": {
             "jcr:primaryType": "sling:MessageEntry",
             "sling:key": "prop.label.email",

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.css
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.css?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.css (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.css Fri May  6 03:17:47 2011
@@ -396,6 +396,30 @@ img, a img
     margin-left: 10px;
 }
 
+#loginStatusInput label,
+#loginStatusInput input
+{
+    width: auto;
+    float: none;
+}
+
+#loginStatusInput
+{
+	width: 75%;
+}
+
+#disabledReasonPanel label 
+{
+    width: auto;
+	margin-left: 15px;
+	float: none;
+}
+
+#disabledReasonPanel input 
+{
+	width: 57%;
+}
+
 .prop-line 
 {
     margin-bottom: 5px;

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css Fri May  6 03:17:47 2011
@@ -1,58 +1,77 @@
-/*!* 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. */ body{background-color:#fff;color:#3b3b3b;font-family:Tahoma,Arial,sans-serif;font-size:10pt;line-height:140%;margin:0;padding:0;}
-a{color:#1980af;text-decoration:none;}
-a:visited{color:#1980af;}
-a:hover{color:#1faae9;text-decoration:underline;}
-img,a img{border:none;}
-.title{position:absolute;left:1px;right:1px;top:25px;height:81px;background:url(../../images/gradient.png) repeat-x;background-position:bottom;}
-.logo{position:absolute;width:15em;height:81px;text-align:center;}
-.header{text-align:right;margin-right:20pt;}
-.menu{border-top:10px solid #f9bb00;position:absolute;top:107px;left:1px;width:15em;bottom:0;padding:0;background-color:#fcfcfc;}
-.menu ul{background-color:#fdf5d9;list-style:none;padding-left:0;margin-top:0;padding-top:2em;padding-bottom:2em;margin-left:0;color:#4a4a43;}
-.menu ul li{padding-left:4em;padding-top:2px;padding-bottom:2px;}
-.menu ul li.ui-state-highlight{font-weight:bold;}
-.menu a{color:#4a4a43;}
-.main{position:absolute;border-top:10px solid #cde0ea;top:107px;left:15em;right:1px;margin-left:2px;padding:10px 10px;}
-#menu_login{display:inline;margin:10px 20px;font-size:11px;padding:5px 7px;position:absolute;right:0;top:0;z-index:10;}
-.usermgmt-body{padding:5px;}
-.usermgmt-header{font-size:14px;padding:5px 10px;margin:0 0 10px 0;}
-.info-msg-block{margin-left:10px;margin-right:10px;margin-bottom:10px;}
-.info-msg-block p{margin:5px;}
-.info-msg-block span.ui-icon{float:left;}
-.info-msg-text{margin-left:5px;}
-#find-authorizables-form fieldset{border:none;margin:0;padding:0;line-height:20px;}
-.search-empty-msg{line-height:100px;font-size:large;font-weight:bold;text-align:center;}
-#authorizables-body{min-width:750px;}
-#find-authorizables-quick-nav{padding:2px 4px;}
-#authorizables-results-body{margin-top:5px;}
-#find-authorizables-quick-nav label{width:auto;padding:3px 5px;}
-#find-authorizables-quick-nav .ui-button-text-only .ui-button-text{line-height:1;padding:3px 3px;font-size:10pt;}
-#find-authorizables-block .ui-button-text-only .ui-button-text{line-height:1;padding:5px 5px;font-size:10pt;}
-#search-result-paging .ui-button-text-only .ui-button-text{line-height:1;font-size:10pt;}
-#search-result-paging span#current_page{margin-left:6px;margin-right:6px;}
-#find-authorizables-block{float:right;line-height:33px;padding-right:10px;}
-#find-authorizables-block input{padding:0 4px;font-size:10pt;}
-#search-result td,#search-result th{padding:5px;}
-#search-result tr.odd{background-color:#eee;}
-#find-authorizables-header{margin-bottom:5px;}
-#find-authorizables-header h3{font-size:14px;font-weight:bold;display:inline;line-height:33px;}
-#create-user-form,#create-group-form{margin:0;padding:0;}
-#create-user-form fieldset,#create-group-form fieldset{border:none;margin:0;padding:0;line-height:20px;}
-#create-user-form label,#create-group-form label{float:left;display:inline;width:15%;text-align:right;}
-#create-user-form input,#create-group-form input{margin-left:10px;width:75%;}
-#create-user-form button,#create-group-form button{margin-left:10px;}
-#update-user-form,#update-password-form,#update-group-form{margin:0;padding:0;}
-#update-user-form fieldset,#update-password-form fieldset,#update-group-form fieldset,#remove-user-form fieldset,#remove-group-form fieldset,#add-property-form fieldset,#add-group-member-form fieldset{border:none;margin:0;padding:0;line-height:20px;}
-#update-user-form label,#update-password-form label,#update-group-form label,#add-property-form label,#add-group-member-form label{float:left;display:inline;width:15%;text-align:right;}
-#update-user-form input,#update-password-form input,#update-group-form input,#add-property-form input,#add-group-member-form input{margin-left:10px;width:75%;}
-#update-user-form button,#update-password-form button,#update-group-form button{margin-left:10px;}
-#update-user-form ol,#update-group-form ol{float:left;display:inline;width:65%;margin:0 5px 0 10px;padding-left:0;list-style-position:inside;list-style-type:none;}
-#update-password-body{margin-top:10px;}
-#update-password-form label{width:15%;text-align:right;}
-#update-password-form input{margin-left:10px;width:75%;}
-#update-password-form button{margin-left:10px;}
-.prop-line{margin-bottom:5px;line-height:26px;}
-.prop-line .remove-property,.prop-line .remove-member{position:absolute;margin:5px 5px;}
-.ui-autocomplete-loading{background:white url('../../images/ui-anim_basic_16x16.gif') right center no-repeat;}
-.noscript-hide{display:none;}
-input.error,textarea.error{border:1px dotted red;}
-label.error,label.error{color:red;font-style:italic;font-weight:bold;margin-left:15%;padding-left:10px;text-align:left!important;width:auto!important;}
\ No newline at end of file
+/*!
+ * 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.
+ */body{background-color:#fff;color:#3b3b3b;font-family:Tahoma,Arial,sans-serif;font-size:10pt;line-height:140%;margin:0;padding:0}
+a{color:#1980af;text-decoration:none}
+a:visited{color:#1980af}
+a:hover{color:#1faae9;text-decoration:underline}
+img,a img{border:0}
+.title{position:absolute;left:1px;right:1px;top:25px;height:81px;background:url(../../images/gradient.png) repeat-x;background-position:bottom}
+.logo{position:absolute;width:15em;height:81px;text-align:center}
+.header{text-align:right;margin-right:20pt}
+.menu{border-top:10px solid #f9bb00;position:absolute;top:107px;left:1px;width:15em;bottom:0;padding:0;background-color:#fcfcfc}
+.menu ul{background-color:#fdf5d9;list-style:none;padding-left:0;margin-top:0;padding-top:2em;padding-bottom:2em;margin-left:0;color:#4a4a43}
+.menu ul li{padding-left:4em;padding-top:2px;padding-bottom:2px}
+.menu ul li.ui-state-highlight{font-weight:bold}
+.menu a{color:#4a4a43}
+.main{position:absolute;border-top:10px solid #cde0ea;top:107px;left:15em;right:1px;margin-left:2px;padding:10px 10px}
+#menu_login{display:inline;margin:10px 20px;font-size:11px;padding:5px 7px;position:absolute;right:0;top:0;z-index:10}
+.usermgmt-body{padding:5px}
+.usermgmt-header{font-size:14px;padding:5px 10px;margin:0 0 10px 0}
+.info-msg-block{margin-left:10px;margin-right:10px;margin-bottom:10px}
+.info-msg-block p{margin:5px}
+.info-msg-block span.ui-icon{float:left}
+.info-msg-text{margin-left:5px}
+#find-authorizables-form fieldset{border:0;margin:0;padding:0;line-height:20px}
+.search-empty-msg{line-height:100px;font-size:large;font-weight:bold;text-align:center}
+#authorizables-body{min-width:750px}
+#find-authorizables-quick-nav{padding:2px 4px}
+#authorizables-results-body{margin-top:5px}
+#find-authorizables-quick-nav label{width:auto;padding:3px 5px}
+#find-authorizables-quick-nav .ui-button-text-only .ui-button-text{line-height:1;padding:3px 3px;font-size:10pt}
+#find-authorizables-block .ui-button-text-only .ui-button-text{line-height:1;padding:5px 5px;font-size:10pt}
+#search-result-paging .ui-button-text-only .ui-button-text{line-height:1;font-size:10pt}
+#search-result-paging span#current_page{margin-left:6px;margin-right:6px}
+#find-authorizables-block{float:right;line-height:33px;padding-right:10px}
+#find-authorizables-block input{padding:0 4px;font-size:10pt}
+#search-result td,#search-result th{padding:5px}
+#search-result tr.odd{background-color:#eee}
+#find-authorizables-header{margin-bottom:5px}
+#find-authorizables-header h3{font-size:14px;font-weight:bold;display:inline;line-height:33px}
+#create-user-form,#create-group-form{margin:0;padding:0}
+#create-user-form fieldset,#create-group-form fieldset{border:0;margin:0;padding:0;line-height:20px}
+#create-user-form label,#create-group-form label{float:left;display:inline;width:15%;text-align:right}
+#create-user-form input,#create-group-form input{margin-left:10px;width:75%}
+#create-user-form button,#create-group-form button{margin-left:10px}
+#update-user-form,#update-password-form,#update-group-form{margin:0;padding:0}
+#update-user-form fieldset,#update-password-form fieldset,#update-group-form fieldset,#remove-user-form fieldset,#remove-group-form fieldset,#add-property-form fieldset,#add-group-member-form fieldset{border:0;margin:0;padding:0;line-height:20px}
+#update-user-form label,#update-password-form label,#update-group-form label,#add-property-form label,#add-group-member-form label{float:left;display:inline;width:15%;text-align:right}
+#update-user-form input,#update-password-form input,#update-group-form input,#add-property-form input,#add-group-member-form input{margin-left:10px;width:75%}
+#update-user-form button,#update-password-form button,#update-group-form button{margin-left:10px}
+#update-user-form ol,#update-group-form ol{float:left;display:inline;width:65%;margin:0 5px 0 10px;padding-left:0;list-style-position:inside;list-style-type:none}
+#update-password-body{margin-top:10px}
+#update-password-form label{width:15%;text-align:right}
+#update-password-form input{margin-left:10px;width:75%}
+#update-password-form button{margin-left:10px}
+#loginStatusInput label,#loginStatusInput input{width:auto;float:none}
+#loginStatusInput{width:75%}
+#disabledReasonPanel label{width:auto;margin-left:15px;float:none}
+#disabledReasonPanel input{width:57%}
+.prop-line{margin-bottom:5px;line-height:26px}
+.prop-line .remove-property,.prop-line .remove-member{position:absolute;margin:5px 5px}
+.ui-autocomplete-loading{background:white url('../../images/ui-anim_basic_16x16.gif') right center no-repeat}
+.noscript-hide{display:none}
+input.error,textarea.error{border:1px dotted red}
+label.error,label.error{color:red;font-style:italic;font-weight:bold;margin-left:15%;padding-left:10px;text-align:left!important;width:auto!important}
\ No newline at end of file

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.js
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.js?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.js (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.js Fri May  6 03:17:47 2011
@@ -760,22 +760,24 @@ UserManager.Group.Update = {
 
         //attach an autocomplete handler to the member name field in
         // the add member dialog
-        $( "#memberName" ).autocomplete({
-            source: UserManager.contextPath + "/system/userManager.autocomplete.json",
-            minLength: 1,
-            select: function(event, ui) {
-                var item = ui.item;
-                $("#memberName")
-                    .val(item.value)
-                    .data("item", item);
-            }
-        })
-        .data( "autocomplete" )._renderItem = function( ul, item ) {
-            return $( "<li></li>" )
-                .data( "item.autocomplete", item )
-                .append( "<a>" + (item.label ? (item.label + " (" + item.value + ")") : item.value) + "</a>" )
-                .appendTo( ul );
-        };        
+        if ($("#memberName").length > 0) {
+            $( "#memberName" ).autocomplete({
+                source: UserManager.contextPath + "/system/userManager.autocomplete.json",
+                minLength: 1,
+                select: function(event, ui) {
+                    var item = ui.item;
+                    $("#memberName")
+                        .val(item.value)
+                        .data("item", item);
+                }
+            })
+            .data( "autocomplete" )._renderItem = function( ul, item ) {
+                return $( "<li></li>" )
+                    .data( "item.autocomplete", item )
+                    .append( "<a>" + (item.label ? (item.label + " (" + item.value + ")") : item.value) + "</a>" )
+                    .appendTo( ul );
+            };        
+        }
     }
 };
 
@@ -875,6 +877,22 @@ UserManager.User.Update = {
             }*/
         });
         
+        var disabledRadioFn = function (e) {
+    	   var disabled = $('input:radio[name=":disabled"]:checked').val();
+    	   if (disabled == "true") {
+    		   $("#disabledReasonPanel").show();
+    	   } else {
+    		   $("#disabledReasonPanel").hide();
+    	   }
+           return false;
+       };
+       
+       /*
+        * Attach event handlers to the status radio buttons
+        */
+       $('input:radio[name=":disabled"]').change(disabledRadioFn);
+       disabledRadioFn();
+        
         //hover states on the remove member icons
         $('.remove-property').hover(
             function() { $(this).addClass('ui-state-hover'); }, 

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js Fri May  6 03:17:47 2011
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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.
@@ -224,11 +224,11 @@ $("#add-group-member-form").submit(funct
 a[0].click();
 return false
 }).validate({rules:{":member":"required"}});
-$("#memberName").autocomplete({source:UserManager.contextPath+"/system/userManager.autocomplete.json",minLength:1,select:function(b,c){var a=c.item;
+if($("#memberName").length>0){$("#memberName").autocomplete({source:UserManager.contextPath+"/system/userManager.autocomplete.json",minLength:1,select:function(b,c){var a=c.item;
 $("#memberName").val(a.value).data("item",a)
 }}).data("autocomplete")._renderItem=function(a,b){return $("<li></li>").data("item.autocomplete",b).append("<a>"+(b.label?(b.label+" ("+b.value+")"):b.value)+"</a>").appendTo(a)
 }
-}};
+}}};
 UserManager.User={};
 UserManager.User.Create={init:function(){$("button#createUserBtn").button();
 $("#create-user-form").validate({rules:{":name":"required",pwd:"required",pwdConfirm:{equalTo:"#pwd"}}});
@@ -251,26 +251,33 @@ return false
 }};
 UserManager.User.Update={init:function(){$("button#updateUserBtn").button();
 $("#update-user-form").validate({rules:{}});
+var a=function(c){var b=$('input:radio[name=":disabled"]:checked').val();
+if(b=="true"){$("#disabledReasonPanel").show()
+}else{$("#disabledReasonPanel").hide()
+}return false
+};
+$('input:radio[name=":disabled"]').change(a);
+a();
 $(".remove-property").hover(function(){$(this).addClass("ui-state-hover")
 },function(){$(this).removeClass("ui-state-hover")
-}).click(function(d){var c,a,b;
-c=$(d.currentTarget.parentNode);
-c.hide("slow");
-a=c.find("input");
-b=a.attr("name");
-a.attr("name",b+"@Delete");
+}).click(function(f){var d,b,c;
+d=$(f.currentTarget.parentNode);
+d.hide("slow");
+b=d.find("input");
+c=b.attr("name");
+b.attr("name",c+"@Delete");
 return false
 });
-$("button#updateUserBtn").click(function(d){var b,a,c;
-b=$("#update-user-form");
-if(!b.valid()){return false
-}a=b.attr("action");
-a=a.substring(0,a.length-4)+"json";
+$("button#updateUserBtn").click(function(f){var c,b,d;
+c=$("#update-user-form");
+if(!c.valid()){return false
+}b=c.attr("action");
+b=b.substring(0,b.length-4)+"json";
 $("#redirect").attr("disabled",true);
-c=b.serialize();
+d=c.serialize();
 $("#redirect").removeAttr("disabled");
 $("#update-user-body div.info-msg-block").hide();
-$.ajax({url:a,type:"POST",data:c,success:function(e,g,f){$("#content").load(UserManager.contextPath+e.path+".update_body.html",function(){$("#update-user-body span.info-msg-text").html(UserManager.messages["user.updated.msg"]);
+$.ajax({url:b,type:"POST",data:d,success:function(e,h,g){$("#content").load(UserManager.contextPath+e.path+".update_body.html",function(){$("#update-user-body span.info-msg-text").html(UserManager.messages["user.updated.msg"]);
 $("#update-user-body div.info-msg-block").show()
 });
 setTimeout(function(){UserManager.User.Update.init();
@@ -279,35 +286,35 @@ $(".noscript-hide").removeClass("noscrip
 },error:UserManager.ErrorDlg.errorHandler});
 return false
 });
-$("a#removeUserLink").click(function(a){$("#remove-user-dialog").dialog({autoOpen:false,height:"auto",width:350,modal:true,resizable:false,buttons:[{text:UserManager.messages["confirm.yes"],click:function(){$("#remove-user-form").submit()
+$("a#removeUserLink").click(function(b){$("#remove-user-dialog").dialog({autoOpen:false,height:"auto",width:350,modal:true,resizable:false,buttons:[{text:UserManager.messages["confirm.yes"],click:function(){$("#remove-user-form").submit()
 }},{text:UserManager.messages["confirm.no"],click:function(){$("#remove-user-dialog").dialog("close")
 }}]});
 $("#remove-user-dialog").dialog("open");
 return false
 });
-$("a#add_property").click(function(a){$("#add-property-dialog").dialog({autoOpen:false,height:"auto",width:350,modal:true,resizable:false,buttons:[{text:UserManager.messages["button.add"],click:function(){var e,c,b,d;
-e=$("#add-property-form");
-if(!e.valid()){return false
-}c=$("#newPropName").val();
-b=c;
-$("#updateSubmitBtns").before('<div class="prop-line ui-helper-clearfix"><label for="'+c+'">'+b+':</label> <input id="'+c+'" type="text" name="'+c+'" /> <a href="#" class="remove-property" title="'+UserManager.messages["tooltip.removeProperty"]+'"><span class="ui-icon ui-icon-circle-close"></span></a></div>');
-d=$("#updateSubmitBtns").prev();
-d.find("a.remove-property").hover(function(){$(this).addClass("ui-state-hover")
+$("a#add_property").click(function(b){$("#add-property-dialog").dialog({autoOpen:false,height:"auto",width:350,modal:true,resizable:false,buttons:[{text:UserManager.messages["button.add"],click:function(){var f,d,c,e;
+f=$("#add-property-form");
+if(!f.valid()){return false
+}d=$("#newPropName").val();
+c=d;
+$("#updateSubmitBtns").before('<div class="prop-line ui-helper-clearfix"><label for="'+d+'">'+c+':</label> <input id="'+d+'" type="text" name="'+d+'" /> <a href="#" class="remove-property" title="'+UserManager.messages["tooltip.removeProperty"]+'"><span class="ui-icon ui-icon-circle-close"></span></a></div>');
+e=$("#updateSubmitBtns").prev();
+e.find("a.remove-property").hover(function(){$(this).addClass("ui-state-hover")
 },function(){$(this).removeClass("ui-state-hover")
-}).click(function(f){var g=$(f.currentTarget.parentNode);
-g.hide("slow",function(){g.remove()
+}).click(function(g){var h=$(g.currentTarget.parentNode);
+h.hide("slow",function(){h.remove()
 });
 return false
 });
 $("#add-property-dialog").dialog("close");
-d.find("input").focus()
+e.find("input").focus()
 }}]});
 $("#newPropName").val("");
 $("#add-property-dialog").dialog("open");
 return false
 });
-$("#add-property-form").submit(function(b){var a=$("#add-property-dialog").dialog("option","buttons");
-a[0].click();
+$("#add-property-form").submit(function(c){var b=$("#add-property-dialog").dialog("option","buttons");
+b[0].click();
 return false
 }).validate({rules:{name:"required"}})
 }};

Modified: sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp?rev=1100034&r1=1100033&r2=1100034&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp Fri May  6 03:17:47 2011
@@ -59,6 +59,22 @@ function displayName(path) {
     }
     return value;
 }
+
+var isAdmin = false;
+if ("admin".equals(request.getRemoteUser())) {
+    isAdmin = true;
+} else {
+    //if the current user is a member of the UserAdmin group, then allow changing the password of other users.
+    var currentUserRes = request.getResourceResolver().resolve("/system/userManager/user/" + request.getRemoteUser());  
+    var currentUserAuthorizable = currentUserRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Authorizable);
+
+    var userAdminRes = request.getResourceResolver().resolve("/system/userManager/group/UserAdmin");
+    var group = userAdminRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Group);
+    if (group) {
+    	isAdmin = group.isMember(currentUserAuthorizable);
+    }
+}
+
 %>
 <div class="ui-widget ui-widget-content ui-corner-all usermgmt-body" id="update-user-body" >
     <h3 class="ui-widget-header ui-corner-all usermgmt-header"><%=format(canEdit ? "header.update.user" : "header.view.user", authorizable.getID())%></h3>
@@ -79,6 +95,21 @@ function displayName(path) {
             <input type="hidden" value="UTF-8" name="_charset_" />
             <input id="redirect" type="hidden" name=":redirect" value="<%=request.contextPath%><%=resource.path %>.html" />
 
+            <%-- Enabled/Disabled Status --%>
+            <% if (isAdmin) { %>
+            <div class="prop-line ui-helper-clearfix">
+                <label><%=propLabel("loginEnabled")%>:</label>
+                <span id="loginStatusInput">
+	                <label for="enabled"><input id="enabled" type="radio" name=":disabled" value='false' <%=authorizable.isDisabled() ? "" : "checked='checked'" %>/> <%=propLabel("loginEnabled.yes")%></label>
+	                <label for="disabled"><input id="disabled" type="radio" name=":disabled" value='true' <%=authorizable.isDisabled() ? "checked='checked'" : "" %>/> <%=propLabel("loginEnabled.no")%></label>
+                </span>
+                <span id="disabledReasonPanel" style="display:none">
+                    <label for="disabledReason"><%=propLabel("loginDisabled.reason")%>:</label>
+                    <input id="disabledReason>" type="text" name=":disabledReason" value='<%=authorizable.getDisabledReason()== null ? "" : authorizable.getDisabledReason()%>'/>
+                </span>
+            </div>
+            <% } /*endif(isAdmin) */ %>
+
             <%-- Member Of --%>
             <% var key = "memberOf"; 
                var value = valueMap.get(key);
@@ -161,23 +192,9 @@ function displayName(path) {
 var canChangePwd = false;
 if (canEdit) {
 	var isMe = authorizable.getID().equals(request.getRemoteUser());
-	if (isMe) {
+	if (isMe || isAdmin) {
 	    //a user can always change their own password
 	    canChangePwd = true;
-	} else {
-		if ("admin".equals(request.getRemoteUser())) {
-			canChangePwd = true;
-		} else {
-	        //if the current user is a member of the UserAdmin group, then allow changing the password of other users.
-	        var currentUserRes = request.getResourceResolver().resolve("/system/userManager/user/" + request.getRemoteUser());  
-	        var currentUserAuthorizable = currentUserRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Authorizable);
-
-	        var userAdminRes = request.getResourceResolver().resolve("/system/userManager/group/UserAdmin");
-	        var group = userAdminRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Group);
-	        if (group) {
-	            canChangePwd = group.isMember(currentUserAuthorizable);
-	        }
-		}
 	}
 }
 if (canChangePwd) { %>