You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/10/20 17:22:04 UTC

[1/2] usergrid git commit: Configurable Password Policy and 5 supporting JUnit tests.

Repository: usergrid
Updated Branches:
  refs/heads/master 9c5f59932 -> 04e49da58


Configurable Password Policy and 5 supporting JUnit tests.


Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/a30e1a56
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/a30e1a56
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/a30e1a56

Branch: refs/heads/master
Commit: a30e1a564e74b033601db60d37960fca46b34fe7
Parents: c65f903
Author: Dave Johnson <sn...@apache.org>
Authored: Wed Oct 19 13:42:34 2016 -0400
Committer: Dave Johnson <sn...@apache.org>
Committed: Wed Oct 19 14:05:17 2016 -0400

----------------------------------------------------------------------
 .../exceptions/AbstractExceptionMapper.java     |   2 +-
 .../PasswordPolicyViolationExceptionMapper.java |  48 ++++++
 .../collection/users/PermissionsResourceIT.java |   4 +-
 .../collection/users/UserResourceIT.java        |  38 ++++-
 .../usergrid/rest/management/AdminUsersIT.java  |  51 ++++++
 .../rest/management/ManagementResourceIT.java   |   4 +-
 .../rest/management/RegistrationIT.java         |   6 +-
 .../cassandra/ManagementServiceImpl.java        |  73 +++++++--
 .../usergrid/security/PasswordPolicy.java       |  53 ++++++
 .../usergrid/security/PasswordPolicyFig.java    |  79 +++++++++
 .../usergrid/security/PasswordPolicyImpl.java   | 156 ++++++++++++++++++
 .../PasswordPolicyViolationException.java       |  46 ++++++
 .../services/guice/ServiceModuleImpl.java       |   8 +
 .../usergrid/security/PasswordPolicyTest.java   |  47 ++++++
 .../security/PasswordPolicyTestFig.java         | 161 +++++++++++++++++++
 15 files changed, 750 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
index 19d35fd..4a4b8b0 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
@@ -102,7 +102,7 @@ public abstract class AbstractExceptionMapper<E extends java.lang.Throwable> imp
     }
 
 
-    private Response toResponse( int status, String jsonResponse ) {
+    protected Response toResponse( int status, String jsonResponse ) {
         if ( status >= 500 ) {
             // only log real errors as errors
             logger.error( "Server Error ({}):\n{}", status, jsonResponse );

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/PasswordPolicyViolationExceptionMapper.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/PasswordPolicyViolationExceptionMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/PasswordPolicyViolationExceptionMapper.java
new file mode 100644
index 0000000..fcd09e3
--- /dev/null
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/PasswordPolicyViolationExceptionMapper.java
@@ -0,0 +1,48 @@
+/*
+ * 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.usergrid.rest.exceptions;
+
+
+import org.apache.usergrid.rest.ApiResponse;
+import org.apache.usergrid.services.exceptions.PasswordPolicyViolationException;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+import static org.apache.usergrid.utils.JsonUtils.mapToJsonString;
+
+
+/** <p> Mapper for OAuthProblemException. </p> */
+@Provider
+public class PasswordPolicyViolationExceptionMapper extends AbstractExceptionMapper<PasswordPolicyViolationException> {
+
+    @Override
+    public Response toResponse( PasswordPolicyViolationException e ) {
+
+        ApiResponse apiResponse = new ApiResponse();
+        apiResponse.setError( e.getMessage() );
+
+        StringBuilder sb = new StringBuilder();
+        for ( String violation : e.getViolations() ) {
+            sb.append( violation ).append(" ");
+        }
+        apiResponse.setErrorDescription( sb.toString() );
+
+        return toResponse( SC_BAD_REQUEST, mapToJsonString(apiResponse) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
index 5380e00..aff952b 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
@@ -638,12 +638,12 @@ public class PermissionsResourceIT extends AbstractRestIT {
 
         // cannot create app user named me
         try {
-            app().collection( "users" ).post( new User( "me", "it's me", "me@example.com", "me!" ) );
+            app().collection( "users" ).post( new User( "me", "it's me", "me@example.com", "me!me!" ) );
             fail("Must not be able to create app user named me");
         } catch ( BadRequestException expected ) {}
 
         // cannot use update to rename app user to me
-        Entity user = app().collection( "users" ).post( new User( "dave", "Sneaky Me", "me@example.com", "me!" ) );
+        Entity user = app().collection( "users" ).post( new User( "dave", "Sneaky Me", "me@example.com", "me!me!" ) );
         try {
             app().collection( "users" ).entity( user ).put( new Entity().chainPut( "username", "me" ));
             fail("Must not be able to update app user to name me");

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
index d36d0a1..c9dc0d8 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
@@ -47,6 +47,7 @@ import java.io.IOException;
 
 import javax.ws.rs.core.MediaType;
 
+import static org.apache.usergrid.security.PasswordPolicy.ERROR_POLICY_VIOLIATION;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -776,6 +777,7 @@ public class UserResourceIT extends AbstractRestIT {
     }
 
 
+
     @Test
     public void test_PUT_password_ok() {
         Entity entity = usersResource.post(new User("edanuff", "edanuff", "edanuff@email.com", "sesame"));
@@ -798,7 +800,7 @@ public class UserResourceIT extends AbstractRestIT {
     @Test
     public void setUserPasswordAsAdmin() throws IOException {
         usersResource.post(new User("edanuff", "edanuff", "edanuff@email.com", "sesame"));
-        String newPassword = "foo";
+        String newPassword = "foofoo";
         refreshIndex();
 
         // change the password as admin. The old password isn't required
@@ -816,8 +818,8 @@ public class UserResourceIT extends AbstractRestIT {
     public void passwordMismatchErrorUser() {
         usersResource.post(new User("edanuff", "edanuff", "edanuff@email.com", "sesame"));
 
-        String origPassword = "foo";
-        String newPassword = "bar";
+        String origPassword = "foofoo";
+        String newPassword = "barbar";
 
         ChangePasswordEntity data = new ChangePasswordEntity(origPassword, newPassword);
 
@@ -833,6 +835,36 @@ public class UserResourceIT extends AbstractRestIT {
 
 
     @Test
+    public void createAppUserWithInvalidPassword() {
+
+        try {
+            Entity entity = usersResource.post(new User("edanuff", "edanuff", "edanuff@email.com", "foo"));
+            fail("Invalid password should have caused error");
+
+        } catch( ClientErrorException uie ) {
+            errorParse( 400, ERROR_POLICY_VIOLIATION, uie );
+        }
+    }
+
+
+    @Test
+    public void testChangePassordToInvalidValue() {
+
+        Entity entity = usersResource.post(new User("edanuff", "edanuff", "edanuff@email.com", "sesame"));
+        refreshIndex();
+
+        try {
+            usersResource.entity(entity).collection("password").post(new ChangePasswordEntity("sesame", "abc"));
+            fail("Invalid password should have caused error");
+
+        } catch( ClientErrorException uie ) {
+            errorParse( 400, ERROR_POLICY_VIOLIATION, uie );
+        }
+
+    }
+
+
+    @Test
     public void addRemoveRole() throws IOException {
         String roleName = "rolename";
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/test/java/org/apache/usergrid/rest/management/AdminUsersIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/AdminUsersIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/AdminUsersIT.java
index a8bd834..f80f131 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/AdminUsersIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/AdminUsersIT.java
@@ -19,6 +19,7 @@ package org.apache.usergrid.rest.management;
 
 import com.sun.jersey.api.client.UniformInterfaceException;
 import net.jcip.annotations.NotThreadSafe;
+import org.apache.commons.lang.RandomStringUtils;
 import org.apache.usergrid.management.MockImapClient;
 import org.apache.usergrid.persistence.core.util.StringUtils;
 import org.apache.usergrid.persistence.index.utils.UUIDUtils;
@@ -42,6 +43,7 @@ import java.io.IOException;
 import java.util.*;
 
 import static org.apache.usergrid.management.AccountCreationProps.*;
+import static org.apache.usergrid.security.PasswordPolicy.ERROR_POLICY_VIOLIATION;
 import static org.junit.Assert.*;
 
 
@@ -92,6 +94,55 @@ public class AdminUsersIT extends AbstractRestIT {
 
 
     /**
+     * Test that creating user with password that violates policy results in informative error message.
+     */
+    @Test
+    public void createUserWithInvalidPassword() throws IOException {
+
+        String rando = RandomStringUtils.randomAlphanumeric(10);
+        Form userForm = new Form();
+        userForm.param( "username", "user_" + rando );
+        userForm.param( "name", rando);
+        userForm.param( "email", "user_" + rando + "@example.com" );
+        userForm.param( "password", "abc" );
+
+        try {
+            management().users().post( User.class, userForm );
+            fail("Invalid password should have caused error");
+
+        } catch( ClientErrorException uie ) {
+            errorParse( 400, ERROR_POLICY_VIOLIATION, uie );
+        }
+
+    }
+
+
+    /**
+     * Test that setting a password that violates policy results in informative error message.
+     */
+    @Test
+    public void resetPasswordWithInvalidNewPassword() throws IOException {
+
+        String username = clientSetup.getUsername();
+        String password = clientSetup.getPassword();
+
+        Map<String, Object> passwordPayload = new HashMap<String, Object>();
+
+        // Default password policy is lenient, only requires length of 4
+        passwordPayload.put( "newpassword", "abc" );
+        passwordPayload.put( "oldpassword", password );
+
+        try {
+            management.users().user( username ).password().post( Entity.class, passwordPayload );
+            fail("Invalid password should have caused error");
+
+        } catch( ClientErrorException uie ) {
+            errorParse( 400, ERROR_POLICY_VIOLIATION, uie );
+        }
+    }
+
+
+    /**
      * Check that we cannot change the password by using an older password
      */
     @Test

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java
index 1a3eb1d..635368e 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java
@@ -81,7 +81,7 @@ public class ManagementResourceIT extends AbstractRestIT {
             .users()
             .post( ApiResponse.class, new User( "test" + uuid, "test" + uuid, "test" + uuid + "@email.com", "test" ) );
         Map<String, Object> data = new HashMap<>();
-        data.put( "newpassword", "foo" );
+        data.put( "newpassword", "foofoo" );
         data.put( "oldpassword", "test" );
         management.users()
             .user( "test" + uuid )
@@ -90,7 +90,7 @@ public class ManagementResourceIT extends AbstractRestIT {
         Token token = management.token().post(Token.class, new Token( "test"+uuid, "foo" ) );
         management.token().setToken( token );
         data.clear();
-        data.put( "oldpassword", "foo" );
+        data.put( "oldpassword", "foofoo" );
         data.put( "newpassword", "test" );
         management.users().user("test"+uuid).password().post(Entity.class, data);
     }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
index 885710d..8404632 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
@@ -145,6 +145,7 @@ public class RegistrationIT extends AbstractRestIT {
 
     /**
      * Test checking that we should be able to add a admin with no password attached to them.
+     *
      * @throws Exception
      */
 
@@ -163,7 +164,10 @@ public class RegistrationIT extends AbstractRestIT {
             // this should send resetpwd  link in email to newly added org admin user(that did not exist
             ///in usergrid) and "User Invited To Organization" email
             String adminToken = getAdminToken().getAccessToken();
-            Entity node = postAddAdminToOrg(this.clientSetup.getOrganizationName(), this.clientSetup.getUsername()+"@servertest.com", "");
+            Entity node = postAddAdminToOrg(
+                this.clientSetup.getOrganizationName(),
+                this.clientSetup.getUsername()+"@servertest.com",
+                "changeme");
             UUID userId = node.getUuid();
 
             refreshIndex();

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java b/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
index 03377a3..35fdd30 100644
--- a/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
+++ b/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
@@ -54,6 +54,7 @@ import org.apache.usergrid.persistence.model.entity.Id;
 import org.apache.usergrid.persistence.model.entity.SimpleId;
 import org.apache.usergrid.security.AuthPrincipalInfo;
 import org.apache.usergrid.security.AuthPrincipalType;
+import org.apache.usergrid.security.PasswordPolicy;
 import org.apache.usergrid.security.crypto.EncryptionService;
 import org.apache.usergrid.security.oauth.AccessInfo;
 import org.apache.usergrid.security.oauth.ClientCredentialsInfo;
@@ -70,6 +71,7 @@ import org.apache.usergrid.security.tokens.TokenInfo;
 import org.apache.usergrid.security.tokens.TokenService;
 import org.apache.usergrid.security.tokens.exceptions.TokenException;
 import org.apache.usergrid.services.*;
+import org.apache.usergrid.services.exceptions.PasswordPolicyViolationException;
 import org.apache.usergrid.utils.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -172,6 +174,8 @@ public class ManagementServiceImpl implements ManagementService {
 
     protected LocalShiroCache localShiroCache;
 
+    protected PasswordPolicy passwordPolicy;
+
 
     private LoadingCache<UUID, OrganizationConfig> orgConfigByAppCache = CacheBuilder.newBuilder().maximumSize( 1000 )
         .expireAfterWrite( Long.valueOf( System.getProperty(ORG_CONFIG_CACHE_PROP, "30000") ) , TimeUnit.MILLISECONDS)
@@ -215,6 +219,8 @@ public class ManagementServiceImpl implements ManagementService {
         this.service = injector.getInstance(ApplicationService.class);
         this.localShiroCache = injector.getInstance(LocalShiroCache.class);
 
+        this.passwordPolicy = injector.getInstance( PasswordPolicy.class );
+
     }
 
     @Autowired
@@ -929,7 +935,8 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public UserInfo createAdminFromPrexistingPassword( UUID organizationId, User user, CredentialsInfo ci ) throws Exception {
+    public UserInfo createAdminFromPrexistingPassword( UUID organizationId, User user, CredentialsInfo ci )
+        throws Exception {
 
         return doCreateAdmin( organizationId, user, ci,
                 // we can't actually set the mongo password. We never have the plain text in
@@ -941,6 +948,12 @@ public class ManagementServiceImpl implements ManagementService {
 
     @Override
     public UserInfo createAdminFrom( UUID organizationId, User user, String password ) throws Exception {
+
+        Collection<String> policyVioliations = passwordPolicy.policyCheck( password, false );
+        if ( !policyVioliations.isEmpty() ) {
+            throw new PasswordPolicyViolationException( passwordPolicy.getDescription( true ), policyVioliations );
+        }
+
         return doCreateAdmin(organizationId, user,
             encryptionService.defaultEncryptedCredentials(password, user.getUuid(), smf.getManagementAppId()),
             encryptionService.plainTextCredentials(mongoPassword(user.getUsername(), password), user.getUuid(),
@@ -949,20 +962,23 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public UserInfo createAdminUser( UUID organizationId, String username, String name, String email, String password, boolean activated,
+    public UserInfo createAdminUser( UUID organizationId, String username, String name, String email,
+                                     String password, boolean activated,
                                      boolean disabled ) throws Exception {
         return createAdminUser(organizationId, username, name, email, password, activated, disabled, null);
     }
 
 
     @Override
-    public UserInfo createAdminUser( UUID organizationId, String username, String name, String email, String password, boolean activated,
-                                     boolean disabled, Map<String, Object> userProperties ) throws Exception {
+    public UserInfo createAdminUser( UUID organizationId, String username, String name, String email, String password,
+                                     boolean activated, boolean disabled, Map<String, Object> userProperties )
+        throws Exception {
 
         if ( !validateAdminInfo(username, name, email, password) ) {
             return null;
         }
-        return createAdminUserInternal( organizationId, username, name, email, password, activated, disabled, userProperties );
+        return createAdminUserInternal(
+            organizationId, username, name, email, password, activated, disabled, userProperties );
     }
 
 
@@ -976,25 +992,32 @@ public class ManagementServiceImpl implements ManagementService {
 
         EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
 
-        if ( !( tokens.isExternalSSOProviderEnabled() && SubjectUtils.isServiceAdmin()) && !em.isPropertyValueUniqueForEntity( "user", "username", username ) ) {
+        if ( !( tokens.isExternalSSOProviderEnabled() && SubjectUtils.isServiceAdmin())
+            && !em.isPropertyValueUniqueForEntity( "user", "username", username ) ) {
             throw new DuplicateUniquePropertyExistsException( "user", "username", username );
         }
 
-        if ( !(tokens.isExternalSSOProviderEnabled()&& SubjectUtils.isServiceAdmin())  && !em.isPropertyValueUniqueForEntity( "user", "email", email ) ) {
+        if ( !(tokens.isExternalSSOProviderEnabled()&& SubjectUtils.isServiceAdmin())
+            && !em.isPropertyValueUniqueForEntity( "user", "email", email ) ) {
             throw new DuplicateUniquePropertyExistsException( "user", "email", email );
         }
         return true;
     }
 
 
-    protected UserInfo createAdminUserInternal( UUID organizationId, String username, String name, String email, String password,
-                                              boolean activated, boolean disabled, Map<String, Object> userProperties )
+    protected UserInfo createAdminUserInternal( UUID organizationId, String username, String name, String email,
+                                                String password, boolean activated, boolean disabled,
+                                                Map<String, Object> userProperties )
             throws Exception {
+
+
         logger.info( "createAdminUserInternal: {}", username );
 
-        if ( isBlank( password ) ) {
-            password = encodeBase64URLSafeString( bytes( UUID.randomUUID() ) );
+        Collection<String> policyVioliations = passwordPolicy.policyCheck( password, true );
+        if ( !policyVioliations.isEmpty() ) {
+            throw new PasswordPolicyViolationException( passwordPolicy.getDescription( true ), policyVioliations );
         }
+
         if ( username == null ) {
             username = email;
         }
@@ -1265,6 +1288,11 @@ public class ManagementServiceImpl implements ManagementService {
             return;
         }
 
+        Collection<String> policyVioliations = passwordPolicy.policyCheck( newPassword, true );
+        if ( !policyVioliations.isEmpty() ) {
+            throw new PasswordPolicyViolationException( passwordPolicy.getDescription( true ), policyVioliations );
+        }
+
         EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
         User user = em.get( userId, User.class );
 
@@ -1646,7 +1674,8 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public Map<String, Object> getAdminUserOrganizationData(UserInfo user, boolean includeApps, boolean includeOrgUsers) throws Exception {
+    public Map<String, Object> getAdminUserOrganizationData(UserInfo user, boolean includeApps, boolean includeOrgUsers)
+        throws Exception {
 
         Map<String, Object> json = new HashMap<>();
 
@@ -2654,8 +2683,8 @@ public class ManagementServiceImpl implements ManagementService {
             String token = getConfirmationTokenForAdminUser(user.getUuid(), 0, organizationId);
             OrganizationConfig orgConfig = organizationId != null ?
                 getOrganizationConfigByUuid(organizationId) : getOrganizationConfigForUserInfo(user);
-            String confirmation_url = orgConfig.getFullUrl(WorkflowUrl.ADMIN_CONFIRMATION_URL, user.getUuid().toString()) +
-                "?token=" + token;
+            String confirmation_url = orgConfig.getFullUrl(WorkflowUrl.ADMIN_CONFIRMATION_URL,
+                user.getUuid().toString()) + "?token=" + token;
             sendAdminUserEmail(user, "User Account Confirmation: " + user.getEmail(),
                 emailMsg(hashMap("confirm_email", user.getEmail()).map("confirmation_url", confirmation_url),
                     PROPERTIES_EMAIL_ADMIN_CONFIRMATION));
@@ -2779,7 +2808,8 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public boolean checkPasswordResetTokenForAppUser( UUID applicationId, UUID userId, String token ) throws Exception {
+    public boolean checkPasswordResetTokenForAppUser( UUID applicationId, UUID userId, String token )
+        throws Exception {
         AuthPrincipalInfo principal = null;
         try {
             principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_PASSWORD_RESET, APPLICATION_USER );
@@ -3036,10 +3066,16 @@ public class ManagementServiceImpl implements ManagementService {
 
     @Override
     public void setAppUserPassword( UUID applicationId, UUID userId, String newPassword ) throws Exception {
+
         if ( ( userId == null ) || ( newPassword == null ) ) {
             return;
         }
 
+        Collection<String> policyVioliations = passwordPolicy.policyCheck( newPassword, false );
+        if ( !policyVioliations.isEmpty() ) {
+            throw new PasswordPolicyViolationException( passwordPolicy.getDescription( false ), policyVioliations );
+        }
+
         EntityManager em = emf.getEntityManager( applicationId );
         User user = em.get(userId, User.class);
 
@@ -3051,6 +3087,7 @@ public class ManagementServiceImpl implements ManagementService {
     @Override
     public void setAppUserPassword( UUID applicationId, UUID userId, String oldPassword, String newPassword )
             throws Exception {
+
         if ( ( userId == null ) ) {
             throw new IllegalArgumentException( "userId is required" );
         }
@@ -3097,7 +3134,8 @@ public class ManagementServiceImpl implements ManagementService {
         final CredentialsInfo ci = readUserPasswordCredentials( applicationId, userId, User.ENTITY_TYPE );
 
         if ( ci == null ) {
-            throw new EntityNotFoundException("Could not find credentials for user with id " + userId + " in application" + applicationId );
+            throw new EntityNotFoundException("Could not find credentials for user with id " + userId
+                + " in application" + applicationId );
         }
 
         return ci;
@@ -3242,7 +3280,8 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     /** read the user password credential's info */
-    protected CredentialsInfo readUserPasswordCredentials( UUID appId, UUID ownerId, String ownerType ) throws Exception {
+    protected CredentialsInfo readUserPasswordCredentials( UUID appId, UUID ownerId, String ownerType )
+        throws Exception {
         return readCreds( appId, ownerId, ownerType, USER_PASSWORD );
     }
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicy.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicy.java b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicy.java
new file mode 100644
index 0000000..cc29b20
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicy.java
@@ -0,0 +1,53 @@
+/*
+ * 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.usergrid.security;
+
+
+import java.util.Collection;
+
+
+/**
+ * Interface to password policy.
+ */
+public interface PasswordPolicy {
+
+    String ERROR_POLICY_VIOLIATION    = "error_password_policy_violation";
+
+    String ERROR_UPPERCASE_POLICY     = "error_uppercase_policy";
+
+    String ERROR_DIGITS_POLICY        = "error_digits_policy";
+
+    String ERROR_SPECIAL_CHARS_POLICY = "error_special_chars_policy";
+
+    String ERROR_LENGTH_POLICY        = "error_length_policy";
+
+
+    /**
+     * Check to see if password conforms to policy.
+     *
+     * @param password Password to check.
+     * @return Collection of error strings, one for each policy violated or empty if password conforms.
+     */
+    Collection<String> policyCheck( String password, boolean isAdminUser );
+
+
+    /**
+     * Get description of password policy for error messages.
+     */
+    String getDescription( boolean isAdminUser );
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyFig.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyFig.java b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyFig.java
new file mode 100644
index 0000000..41cda7c
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyFig.java
@@ -0,0 +1,79 @@
+/*
+ * 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.usergrid.security;
+
+import org.safehaus.guicyfig.Default;
+import org.safehaus.guicyfig.FigSingleton;
+import org.safehaus.guicyfig.GuicyFig;
+import org.safehaus.guicyfig.Key;
+
+
+@FigSingleton
+public interface PasswordPolicyFig extends GuicyFig {
+
+    String ALLOWED_SPECIAL_CHARS       = "usergrid.password-policy.allowed-special-chars";
+
+    String MIN_UPPERCASE_ADMIN         = "usergrid.password-policy.min-uppercase-admin";
+    String MIN_UPPERCASE               = "usergrid.password-policy.min-uppercase";
+
+    String MIN_DIGITS_ADMIN            = "usergrid.password-policy.min-uppercase-admin";
+    String MIN_DIGITS                  = "usergrid.password-policy.min-uppercase";
+
+    String MIN_SPECIAL_CHARS_ADMIN     = "usergrid.password-policy.min-special-chars-admin";
+    String MIN_SPECIAL_CHARS           = "usergrid.password-policy.min-special-chars";
+
+    String MIN_LENGTH_ADMIN            = "usergrid.password-policy.min-length-admin";
+    String MIN_LENGTH                  = "usergrid.password-policy.min-length";
+
+
+    @Key(MIN_UPPERCASE_ADMIN)
+    @Default("0")
+    int getMinUppercaseAdmin();
+
+    @Key(MIN_UPPERCASE)
+    @Default("0")
+    int getMinUppercase();
+
+    @Key(MIN_DIGITS_ADMIN)
+    @Default("0")
+    int getMinDigitsAdmin();
+
+    @Key(MIN_DIGITS)
+    @Default("0")
+    int getMinDigits();
+
+    @Key(MIN_SPECIAL_CHARS_ADMIN)
+    @Default("0")
+    int getMinSpecialCharsAdmin();
+
+    @Key(MIN_SPECIAL_CHARS)
+    @Default("0")
+    int getMinSpecialChars();
+
+    @Key(MIN_LENGTH_ADMIN)
+    @Default("4")
+    int getMinLengthAdmin();
+
+    @Key(MIN_LENGTH)
+    @Default("4")
+    int getMinLength();
+
+    @Key(ALLOWED_SPECIAL_CHARS)
+    @Default("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?")
+    String getAllowedSpecialChars();
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyImpl.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyImpl.java b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyImpl.java
new file mode 100644
index 0000000..500592a
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/security/PasswordPolicyImpl.java
@@ -0,0 +1,156 @@
+/*
+ * 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.usergrid.security;
+
+import com.google.inject.Inject;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+
+public class PasswordPolicyImpl implements PasswordPolicy {
+
+    private final PasswordPolicyFig passwordPolicyFig;
+
+
+    @Inject
+    PasswordPolicyImpl( PasswordPolicyFig passwordPolicyFig ) {
+        this.passwordPolicyFig = passwordPolicyFig;
+    }
+
+
+    @Override
+    public String getDescription( boolean isAdminUser ) {
+
+        final int minLength;
+        final int minUppercase;
+        final int minDigits;
+        final int minSpecialChars;
+
+        if ( isAdminUser ) {
+            minLength       = passwordPolicyFig.getMinLengthAdmin();
+            minUppercase    = passwordPolicyFig.getMinUppercaseAdmin();
+            minDigits       = passwordPolicyFig.getMinDigitsAdmin();
+            minSpecialChars = passwordPolicyFig.getMinSpecialCharsAdmin();
+        } else {
+            minLength       = passwordPolicyFig.getMinLength();
+            minUppercase    = passwordPolicyFig.getMinUppercase();
+            minDigits       = passwordPolicyFig.getMinDigits();
+            minSpecialChars = passwordPolicyFig.getMinSpecialChars();
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append( "Password must be at least " ).append( minLength ).append(" characters. ");
+        if ( minUppercase > 0 ) {
+            sb.append( "Must include " ).append( minUppercase ).append(" uppercase characters. ");
+        }
+        if ( minDigits > 0 ) {
+            sb.append( "Must include " ).append( minDigits ).append(" numbers. ");
+        }
+        if ( minSpecialChars > 0 ) {
+            sb.append( "Must include " ).append( minUppercase ).append(" special characters. ");
+        }
+        return sb.toString();
+    }
+
+
+    @Override
+    public Collection<String> policyCheck( String password, boolean isAdminUser ) {
+
+        final int minLength;
+        final int minUppercase;
+        final int minDigits;
+        final int minSpecialChars;
+
+        if ( isAdminUser ) {
+            minLength       = passwordPolicyFig.getMinLengthAdmin();
+            minUppercase    = passwordPolicyFig.getMinUppercaseAdmin();
+            minDigits       = passwordPolicyFig.getMinDigitsAdmin();
+            minSpecialChars = passwordPolicyFig.getMinSpecialCharsAdmin();
+        } else {
+            minLength       = passwordPolicyFig.getMinLength();
+            minUppercase    = passwordPolicyFig.getMinUppercase();
+            minDigits       = passwordPolicyFig.getMinDigits();
+            minSpecialChars = passwordPolicyFig.getMinSpecialChars();
+        }
+
+        return policyCheck( password, minLength, minUppercase, minDigits, minSpecialChars );
+    }
+
+
+    public Collection<String> policyCheck(
+        String password, int minLength, int minUppercase, int minDigits, int minSpecialChars ) {
+
+
+        List<String> violations = new ArrayList<>(3);
+
+        // check length
+        if ( password == null || password.length() < minLength ) {
+            violations.add( PasswordPolicy.ERROR_LENGTH_POLICY
+                + ": must be at least " + minLength + " characters" );
+        }
+
+        // count upper case
+        if ( minUppercase > 0 ) {
+            int upperCaseCount = 0;
+            for (char c : password.toCharArray()) {
+                if (StringUtils.isAllUpperCase( String.valueOf( c ) )) {
+                    upperCaseCount++;
+                }
+            }
+            if (upperCaseCount < minUppercase) {
+                violations.add( PasswordPolicy.ERROR_UPPERCASE_POLICY
+                    + ": requires " + minUppercase + " uppercase characters" );
+            }
+        }
+
+        // count digits case
+        if ( minDigits > 0 ) {
+            int digitCount = 0;
+            for (char c : password.toCharArray()) {
+                if (StringUtils.isNumeric( String.valueOf( c ) )) {
+                    digitCount++;
+                }
+            }
+            if (digitCount < minDigits) {
+                violations.add( PasswordPolicy.ERROR_DIGITS_POLICY
+                    + ": requires " + minDigits + " digits" );
+            }
+        }
+
+        // count special characters
+        if ( minSpecialChars > 0 ) {
+            int specialCharCount = 0;
+            for (char c : password.toCharArray()) {
+                if (passwordPolicyFig.getAllowedSpecialChars().contains( String.valueOf( c ) )) {
+                    specialCharCount++;
+                }
+            }
+            if (specialCharCount < minSpecialChars) {
+                violations.add( PasswordPolicy.ERROR_SPECIAL_CHARS_POLICY
+                    + ": requires " + minSpecialChars + " special characters" );
+            }
+        }
+
+        return violations;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/services/exceptions/PasswordPolicyViolationException.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/exceptions/PasswordPolicyViolationException.java b/stack/services/src/main/java/org/apache/usergrid/services/exceptions/PasswordPolicyViolationException.java
new file mode 100644
index 0000000..531e3fd
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/services/exceptions/PasswordPolicyViolationException.java
@@ -0,0 +1,46 @@
+/*
+ * 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.usergrid.services.exceptions;
+
+
+import java.util.Collection;
+
+import static org.apache.usergrid.security.PasswordPolicy.ERROR_POLICY_VIOLIATION;
+
+
+public class PasswordPolicyViolationException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    private final Collection<String> violations;
+    private final String description;
+
+    public PasswordPolicyViolationException( String description, Collection<String> violations ) {
+        super( ERROR_POLICY_VIOLIATION );
+        this.violations = violations;
+        this.description = description;
+    }
+
+
+    public Collection<String> getViolations() {
+        return violations;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/main/java/org/apache/usergrid/services/guice/ServiceModuleImpl.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/guice/ServiceModuleImpl.java b/stack/services/src/main/java/org/apache/usergrid/services/guice/ServiceModuleImpl.java
index 58b301a..c7f7d08 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/guice/ServiceModuleImpl.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/guice/ServiceModuleImpl.java
@@ -24,6 +24,7 @@ import com.google.inject.TypeLiteral;
 import com.google.inject.multibindings.Multibinder;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.usergrid.corepersistence.ServiceModule;
+import org.apache.usergrid.corepersistence.index.CoreIndexFig;
 import org.apache.usergrid.locking.guice.LockModule;
 import org.apache.usergrid.management.AppInfoMigrationPlugin;
 import org.apache.usergrid.persistence.cache.CacheFactory;
@@ -31,8 +32,12 @@ import org.apache.usergrid.persistence.cache.impl.CacheFactoryImpl;
 import org.apache.usergrid.persistence.cache.impl.ScopedCacheSerialization;
 import org.apache.usergrid.persistence.cache.impl.ScopedCacheSerializationImpl;
 import org.apache.usergrid.persistence.core.migration.data.MigrationPlugin;
+import org.apache.usergrid.security.PasswordPolicy;
+import org.apache.usergrid.security.PasswordPolicyFig;
+import org.apache.usergrid.security.PasswordPolicyImpl;
 import org.apache.usergrid.security.shiro.UsergridAuthenticationInfo;
 import org.apache.usergrid.security.shiro.UsergridAuthorizationInfo;
+import org.safehaus.guicyfig.GuicyFigModule;
 
 
 // <bean id="notificationsQueueListener" class="org.apache.usergrid.services.notifications.QueueListener"
@@ -70,5 +75,8 @@ public class ServiceModuleImpl extends AbstractModule implements ServiceModule {
         bind(    new TypeLiteral<ScopedCacheSerialization<String, UsergridAuthenticationInfo>>() {})
             .to( new TypeLiteral<ScopedCacheSerializationImpl<String, UsergridAuthenticationInfo>>() {});
 
+        bind( PasswordPolicy.class ).to( PasswordPolicyImpl.class );
+
+        install( new GuicyFigModule( PasswordPolicyFig.class ) );
     }
 }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTest.java
----------------------------------------------------------------------
diff --git a/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTest.java b/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTest.java
new file mode 100644
index 0000000..1599b18
--- /dev/null
+++ b/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.usergrid.security;
+
+import org.apache.usergrid.ServiceITSetup;
+import org.apache.usergrid.ServiceITSetupImpl;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+public class PasswordPolicyTest {
+
+    @ClassRule
+    public static ServiceITSetup setup = new ServiceITSetupImpl();
+
+
+    @Test
+    public void testBasicOperation() {
+
+        PasswordPolicyImpl passwordPolicy =
+            (PasswordPolicyImpl)setup.getInjector().getInstance( PasswordPolicy.class );
+
+        Assert.assertEquals( 4, passwordPolicy.policyCheck( "secret", 12, 1, 1, 1 ).size() );
+        Assert.assertEquals( 3, passwordPolicy.policyCheck( "Secret", 12, 1, 1, 1 ).size() );
+        Assert.assertEquals( 2, passwordPolicy.policyCheck( "Secr3t", 12, 1, 1, 1 ).size() );
+        Assert.assertEquals( 1, passwordPolicy.policyCheck( "Secr3t!", 12, 1, 1, 1 ).size() );
+        Assert.assertEquals( 0, passwordPolicy.policyCheck( "Secr3t!longer", 12, 1, 1, 1 ).size() );
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid/blob/a30e1a56/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTestFig.java
----------------------------------------------------------------------
diff --git a/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTestFig.java b/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTestFig.java
new file mode 100644
index 0000000..27a74d0
--- /dev/null
+++ b/stack/services/src/test/java/org/apache/usergrid/security/PasswordPolicyTestFig.java
@@ -0,0 +1,161 @@
+/*
+ * 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.usergrid.security;
+
+import org.apache.usergrid.ServiceITSetup;
+import org.apache.usergrid.ServiceITSetupImpl;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.safehaus.guicyfig.Bypass;
+import org.safehaus.guicyfig.OptionState;
+import org.safehaus.guicyfig.Overrides;
+
+import java.beans.PropertyChangeListener;
+import java.util.Map;
+import java.util.Properties;
+
+
+public class PasswordPolicyTestFig implements PasswordPolicyFig {
+
+
+    @Override
+    public int getMinUppercaseAdmin() {
+        return 1;
+    }
+
+    @Override
+    public int getMinUppercase() {
+        return 1;
+    }
+
+    @Override
+    public int getMinDigitsAdmin() {
+        return 1;
+    }
+
+    @Override
+    public int getMinDigits() {
+        return 1;
+    }
+
+    @Override
+    public int getMinSpecialCharsAdmin() {
+        return 1;
+    }
+
+    @Override
+    public int getMinSpecialChars() {
+        return 1;
+    }
+
+    @Override
+    public int getMinLengthAdmin() {
+        return 1;
+    }
+
+    @Override
+    public int getMinLength() {
+        return 1;
+    }
+
+    @Override
+    public String getAllowedSpecialChars() {
+        return null;
+    }
+
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+
+    }
+
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+
+    }
+
+    @Override
+    public OptionState[] getOptions() {
+        return new OptionState[0];
+    }
+
+    @Override
+    public OptionState getOption(String key) {
+        return null;
+    }
+
+    @Override
+    public String getKeyByMethod(String methodName) {
+        return null;
+    }
+
+    @Override
+    public Object getValueByMethod(String methodName) {
+        return null;
+    }
+
+    @Override
+    public Properties filterOptions(Properties properties) {
+        return null;
+    }
+
+    @Override
+    public Map<String, Object> filterOptions(Map<String, Object> entries) {
+        return null;
+    }
+
+    @Override
+    public void override(String key, String override) {
+
+    }
+
+    @Override
+    public boolean setOverrides(Overrides overrides) {
+        return false;
+    }
+
+    @Override
+    public Overrides getOverrides() {
+        return null;
+    }
+
+    @Override
+    public void bypass(String key, String bypass) {
+
+    }
+
+    @Override
+    public boolean setBypass(Bypass bypass) {
+        return false;
+    }
+
+    @Override
+    public Bypass getBypass() {
+        return null;
+    }
+
+    @Override
+    public Class getFigInterface() {
+        return null;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return false;
+    }
+}


[2/2] usergrid git commit: Merge commit 'refs/pull/560/head' of github.com:apache/usergrid

Posted by mr...@apache.org.
Merge commit 'refs/pull/560/head' of github.com:apache/usergrid


Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/04e49da5
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/04e49da5
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/04e49da5

Branch: refs/heads/master
Commit: 04e49da589ec303efd03939a6faf21fb3aee0760
Parents: 9c5f599 a30e1a5
Author: Michael Russo <mr...@apigee.com>
Authored: Thu Oct 20 10:21:53 2016 -0700
Committer: Michael Russo <mr...@apigee.com>
Committed: Thu Oct 20 10:21:53 2016 -0700

----------------------------------------------------------------------
 .../exceptions/AbstractExceptionMapper.java     |   2 +-
 .../PasswordPolicyViolationExceptionMapper.java |  48 ++++++
 .../collection/users/PermissionsResourceIT.java |   4 +-
 .../collection/users/UserResourceIT.java        |  38 ++++-
 .../usergrid/rest/management/AdminUsersIT.java  |  51 ++++++
 .../rest/management/ManagementResourceIT.java   |   4 +-
 .../rest/management/RegistrationIT.java         |   6 +-
 .../cassandra/ManagementServiceImpl.java        |  73 +++++++--
 .../usergrid/security/PasswordPolicy.java       |  53 ++++++
 .../usergrid/security/PasswordPolicyFig.java    |  79 +++++++++
 .../usergrid/security/PasswordPolicyImpl.java   | 156 ++++++++++++++++++
 .../PasswordPolicyViolationException.java       |  46 ++++++
 .../services/guice/ServiceModuleImpl.java       |   8 +
 .../usergrid/security/PasswordPolicyTest.java   |  47 ++++++
 .../security/PasswordPolicyTestFig.java         | 161 +++++++++++++++++++
 15 files changed, 750 insertions(+), 26 deletions(-)
----------------------------------------------------------------------