You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/06/13 20:54:04 UTC

[25/50] [abbrv] git commit: 1. the property name is not matched in the admin confirmation mail template 2. enable application 'allow_open_registration', 'registration_requires_email_confirmation', 'registration_requires_admin_approval', 'notify_admin_of_

1. the property name is not matched in the admin confirmation mail template
2. enable application 'allow_open_registration', 'registration_requires_email_confirmation', 'registration_requires_admin_approval', 'notify_admin_of_new_users' property
3. correct spring configuration, clockResolution as a static filed, can't be injected directly
4. remove duplicated stack/core/src/main/resources/usergrid-scheduler-context.xml
5. allow custom properties when creating new app, that was ignored.
6. checking if the UserInfo has a valid email predefined when sending email to the user
7. more token checking in case


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

Branch: refs/pull/198/merge
Commit: 6595f919321c721d01e116a45d016e786d565fee
Parents: 19cf0cd
Author: Strong Liu <st...@hibernate.org>
Authored: Thu Jun 12 14:08:23 2014 +0800
Committer: Strong Liu <st...@hibernate.org>
Committed: Thu Jun 12 14:08:23 2014 +0800

----------------------------------------------------------------------
 .../main/resources/usergrid-default.properties  |   2 +-
 .../persistence/entities/Application.java       |  27 ++---
 .../main/resources/usergrid-core-context.xml    |   9 +-
 .../resources/usergrid-scheduler-context.xml    |  49 --------
 .../rest/applications/users/UsersResource.java  |  17 ++-
 .../applications/ApplicationsResource.java      |   3 +-
 .../usergrid/management/ManagementService.java  |   1 +
 .../cassandra/ManagementServiceImpl.java        | 116 ++++++++++---------
 .../exceptions/MissingEmailException.java       |  48 ++++++++
 .../usergrid/security/tokens/TokenCategory.java |   8 +-
 .../tokens/cassandra/TokenServiceImpl.java      |  23 +++-
 .../apache/usergrid/services/ServiceInfo.java   |   4 +-
 12 files changed, 175 insertions(+), 132 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/config/src/main/resources/usergrid-default.properties
----------------------------------------------------------------------
diff --git a/stack/config/src/main/resources/usergrid-default.properties b/stack/config/src/main/resources/usergrid-default.properties
index 09c0df5..cae9a85 100644
--- a/stack/config/src/main/resources/usergrid-default.properties
+++ b/stack/config/src/main/resources/usergrid-default.properties
@@ -250,7 +250,7 @@ usergrid.management.email.sysadmin-admin-activation=\
 
 # email to admin user to confirm email
 usergrid.management.email.admin-confirmation=\
-    <p>To confirm your email address ${confirm_email}, click here:</p>\n\
+    <p>To confirm your email address ${user_email}, click here:</p>\n\
     <p><a href="${confirmation_url}">${confirmation_url}</a></p>
 
 # email to admin user to notify email has been confirmed

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/core/src/main/java/org/apache/usergrid/persistence/entities/Application.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/entities/Application.java b/stack/core/src/main/java/org/apache/usergrid/persistence/entities/Application.java
index 6dbbdd2..695ab74 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/entities/Application.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/entities/Application.java
@@ -76,16 +76,16 @@ public class Application extends TypedEntity {
     protected Boolean disabled;
 
     @EntityProperty(name = "allow_open_registration", indexed = false)
-    protected Boolean allowOpenRegistration;
+    protected Boolean allowOpenRegistration = true;
 
     @EntityProperty(name = "registration_requires_email_confirmation", indexed = false)
-    protected Boolean registrationRequiresEmailConfirmation;
+    protected Boolean registrationRequiresEmailConfirmation = false;
 
     @EntityProperty(name = "registration_requires_admin_approval", indexed = false)
-    protected Boolean registrationRequiresAdminApproval;
+    protected Boolean registrationRequiresAdminApproval = false;
 
     @EntityProperty(name = "notify_admin_of_new_users", indexed = false)
-    protected Boolean notifyAdminOfNewUsers;
+    protected Boolean notifyAdminOfNewUsers = false;
 
     @EntityDictionary(keyType = java.lang.String.class, valueType = OAuthProvider.class)
     protected Map<String, OAuthProvider> oauthproviders;
@@ -198,12 +198,11 @@ public class Application extends TypedEntity {
 
 
     public boolean allowOpenRegistration() {
-        return ( allowOpenRegistration != null ) && allowOpenRegistration;
+        return allowOpenRegistration;
     }
 
 
     @JsonProperty("allow_open_registration")
-    @JsonSerialize(include = Inclusion.NON_NULL)
     public Boolean getAllowOpenRegistration() {
         return allowOpenRegistration;
     }
@@ -215,13 +214,12 @@ public class Application extends TypedEntity {
     }
 
 
-    public boolean registrationRequiresEmailConfirmation() {
-        return ( registrationRequiresEmailConfirmation != null ) && registrationRequiresEmailConfirmation;
+    public Boolean registrationRequiresEmailConfirmation() {
+        return registrationRequiresEmailConfirmation;
     }
 
 
     @JsonProperty("registration_requires_email_confirmation")
-    @JsonSerialize(include = Inclusion.NON_NULL)
     public Boolean getRegistrationRequiresEmailConfirmation() {
         return registrationRequiresEmailConfirmation;
     }
@@ -233,12 +231,11 @@ public class Application extends TypedEntity {
     }
 
 
-    public boolean registrationRequiresAdminApproval() {
-        return ( registrationRequiresAdminApproval != null ) && registrationRequiresAdminApproval;
+    public Boolean registrationRequiresAdminApproval() {
+        return registrationRequiresAdminApproval;
     }
 
 
-    @JsonSerialize(include = Inclusion.NON_NULL)
     @JsonProperty("registration_requires_admin_approval")
     public Boolean getRegistrationRequiresAdminApproval() {
         return registrationRequiresAdminApproval;
@@ -251,12 +248,11 @@ public class Application extends TypedEntity {
     }
 
 
-    public boolean notifyAdminOfNewUsers() {
-        return ( notifyAdminOfNewUsers != null ) && notifyAdminOfNewUsers;
+    public Boolean notifyAdminOfNewUsers() {
+        return notifyAdminOfNewUsers;
     }
 
 
-    @JsonSerialize(include = Inclusion.NON_NULL)
     @JsonProperty("notify_admin_of_new_users")
     public Boolean getNotifyAdminOfNewUsers() {
         return notifyAdminOfNewUsers;
@@ -426,6 +422,7 @@ public class Application extends TypedEntity {
 
 
     /** @return the accesstokenttl */
+    @JsonSerialize(include = Inclusion.NON_NULL)
     public Long getAccesstokenttl() {
         return accesstokenttl;
     }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/core/src/main/resources/usergrid-core-context.xml
----------------------------------------------------------------------
diff --git a/stack/core/src/main/resources/usergrid-core-context.xml b/stack/core/src/main/resources/usergrid-core-context.xml
index 7e4e202..37593b8 100644
--- a/stack/core/src/main/resources/usergrid-core-context.xml
+++ b/stack/core/src/main/resources/usergrid-core-context.xml
@@ -49,12 +49,19 @@
   <bean id="taggedOpTimer" class="org.apache.usergrid.persistence.cassandra.util.TaggedOpTimer">
     <constructor-arg ref="traceTagManager"/>
   </bean>
+    <bean name="staticHubInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
+        <property name="staticMethod" value="me.prettyprint.cassandra.service.CassandraHostConfigurator.setClockResolution"/>
+        <property name="arguments">
+            <list>
+                <ref bean="microsecondsTimeResolution"/>
+            </list>
+        </property>
+    </bean>
 
 	<bean id="cassandraHostConfigurator" class="me.prettyprint.cassandra.service.CassandraHostConfigurator">
 		<constructor-arg value="${cassandra.url}" />
         <!-- set the pool size if it's available.  If not go with 50 -->
         <property name="maxActive" value="${cassandra.connections:20}"/>
-        <property name="clockResolution" ref="microsecondsTimeResolution" />
         <property name="opTimer" ref="taggedOpTimer"/>
         <property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
 	</bean>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/core/src/main/resources/usergrid-scheduler-context.xml
----------------------------------------------------------------------
diff --git a/stack/core/src/main/resources/usergrid-scheduler-context.xml b/stack/core/src/main/resources/usergrid-scheduler-context.xml
deleted file mode 100644
index f2c2a27..0000000
--- a/stack/core/src/main/resources/usergrid-scheduler-context.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns:context="http://www.springframework.org/schema/context"
-	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
-           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
-
-	<import resource="classpath:/usergrid-core-context.xml" />
-
-	<bean id="jobSchedulerBackgroundService" class="org.apache.usergrid.batch.service.JobSchedulerService">
-		<property name="jobFactory" ref="jobFactory" />
-		<property name="jobAccessor" ref="schedulerService" />
-		<property name="workerSize" value="${usergrid.scheduler.job.workers}" />
-		<property name="interval" value="${usergrid.scheduler.job.interval}" />
-		<property name="maxFailCount" value="${usergrid.scheduler.job.maxfail}" />
-	</bean>
-
-	<bean id="schedulerService" class="org.apache.usergrid.batch.service.SchedulerServiceImpl">
-		<property name="jobTimeout" value="${usergrid.scheduler.job.timeout}" />
-		<property name="jobQueueName" value="${usergrid.scheduler.job.queueName}" />
-	</bean>
-
-
-	<bean id="jobFactory" class="org.apache.usergrid.batch.UsergridJobFactory" />
-
-
-	<!-- scan all job classes -->
-	<context:component-scan base-package="org.apache.usergrid.batch.job" />
-	<context:annotation-config />
-	
-	<!-- other beans -->
-
-</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
index 1a1b576..c7e5970 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/users/UsersResource.java
@@ -36,7 +36,9 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.PathSegment;
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.usergrid.persistence.entities.Application;
 import org.apache.usergrid.rest.RootResource;
+import org.apache.usergrid.security.shiro.utils.SubjectUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Scope;
@@ -60,6 +62,7 @@ import net.tanesha.recaptcha.ReCaptchaResponse;
 
 import static org.apache.commons.lang.StringUtils.isBlank;
 import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
 import static org.apache.usergrid.services.ServiceParameter.addParameter;
 
 
@@ -204,6 +207,9 @@ public class UsersResource extends ServiceResource {
         }
         return super.executePut( ui, json, callback );
     }
+    private boolean hasAdminAccess() {
+        return SubjectUtils.isApplicationAdmin() || SubjectUtils.isOrganizationAdmin();
+    }
 
 
     @POST
@@ -215,14 +221,13 @@ public class UsersResource extends ServiceResource {
         Object json = body.getEntity();
         String password = null;
         String pin = null;
+        boolean allowOpenRegistration = management.appAllowOpenRegistration(getApplicationId());
+        if (!allowOpenRegistration && !hasAdminAccess()) {
+            throw mappableSecurityException("unauthorized", "registration is not open, please contact the app admin");
+        }
 
-        Boolean registration_requires_email_confirmation = ( Boolean ) this.getServices().getEntityManager()
-                                                                           .getProperty( this.getServices()
-                                                                                             .getApplicationRef(),
-                                                                                   "registration_requires_email_confirmation" );
-        boolean activated =
-                !( ( registration_requires_email_confirmation != null ) && registration_requires_email_confirmation );
 
+        boolean activated = !management.newAppUsersRequireConfirmation(getApplicationId());
         if ( json instanceof Map ) {
             @SuppressWarnings("unchecked") Map<String, Object> map = ( Map<String, Object> ) json;
             password = ( String ) map.get( "password" );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/applications/ApplicationsResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/applications/ApplicationsResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/applications/ApplicationsResource.java
index d7c8468..59c6f05 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/applications/ApplicationsResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/applications/ApplicationsResource.java
@@ -98,6 +98,7 @@ public class ApplicationsResource extends AbstractContextResource {
     public JSONWithPadding newApplicationForOrganization( @Context UriInfo ui, Map<String, Object> json,
                                                           @QueryParam( "callback" ) @DefaultValue( "callback" )
                                                           String callback ) throws Exception {
+        Preconditions.checkArgument((json != null && json.containsKey("name")), "The 'name' parameter is required and cannot be empty");
         String applicationName = ( String ) json.get( "name" );
         return newApplicationForOrganizationFromForm( ui, json, callback, applicationName );
     }
@@ -118,7 +119,7 @@ public class ApplicationsResource extends AbstractContextResource {
         ApiResponse response = createApiResponse();
         response.setAction( "new application for organization" );
 
-        ApplicationInfo applicationInfo = management.createApplication( organization.getUuid(), applicationName );
+        ApplicationInfo applicationInfo = management.createApplication( organization.getUuid(), applicationName, json );
 
         LinkedHashMap<String, UUID> applications = new LinkedHashMap<String, UUID>();
         applications.put( applicationInfo.getName(), applicationInfo.getId() );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/services/src/main/java/org/apache/usergrid/management/ManagementService.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/ManagementService.java b/stack/services/src/main/java/org/apache/usergrid/management/ManagementService.java
index a7c4752..db6a8ba 100644
--- a/stack/services/src/main/java/org/apache/usergrid/management/ManagementService.java
+++ b/stack/services/src/main/java/org/apache/usergrid/management/ManagementService.java
@@ -302,6 +302,7 @@ public interface ManagementService {
     public boolean newAppUsersNeedAdminApproval( UUID applicationId ) throws Exception;
 
     public boolean newAppUsersRequireConfirmation( UUID applicationId ) throws Exception;
+    public boolean appAllowOpenRegistration( UUID applicationId ) throws Exception;
 
     public abstract void provisionSuperuser() throws Exception;
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/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 7c2cff9..c321d12 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
@@ -28,6 +28,7 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
 
+import org.apache.usergrid.management.exceptions.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,15 +41,6 @@ import org.apache.usergrid.management.ManagementService;
 import org.apache.usergrid.management.OrganizationInfo;
 import org.apache.usergrid.management.OrganizationOwnerInfo;
 import org.apache.usergrid.management.UserInfo;
-import org.apache.usergrid.management.exceptions.DisabledAdminUserException;
-import org.apache.usergrid.management.exceptions.DisabledAppUserException;
-import org.apache.usergrid.management.exceptions.IncorrectPasswordException;
-import org.apache.usergrid.management.exceptions.ManagementException;
-import org.apache.usergrid.management.exceptions.RecentlyUsedPasswordException;
-import org.apache.usergrid.management.exceptions.UnableToLeaveOrganizationException;
-import org.apache.usergrid.management.exceptions.UnactivatedAdminUserException;
-import org.apache.usergrid.management.exceptions.UnactivatedAppUserException;
-import org.apache.usergrid.management.exceptions.UnconfirmedAdminUserException;
 import org.apache.usergrid.persistence.CredentialsInfo;
 import org.apache.usergrid.persistence.Entity;
 import org.apache.usergrid.persistence.EntityManager;
@@ -212,6 +204,7 @@ public class ManagementServiceImpl implements ManagementService {
     public static final String REGISTRATION_REQUIRES_ADMIN_APPROVAL = "registration_requires_admin_approval";
     public static final String REGISTRATION_REQUIRES_EMAIL_CONFIRMATION = "registration_requires_email_confirmation";
     public static final String NOTIFY_ADMIN_OF_NEW_USERS = "notify_admin_of_new_users";
+    public static final String ALLOW_OPEN_REGISTRATION = "allow_open_registration";
 
     protected ServiceManagerFactory smf;
 
@@ -349,8 +342,7 @@ public class ManagementServiceImpl implements ManagementService {
         long timestamp = System.currentTimeMillis();
         ByteBuffer bytes = ByteBuffer.allocate( 20 );
         bytes.put( sha( timestamp + OAUTH_SECRET_SALT + UUID.randomUUID() ) );
-        String secret = type.getBase64Prefix() + encodeBase64URLSafeString( bytes.array() );
-        return secret;
+        return type.getBase64Prefix() + encodeBase64URLSafeString( bytes.array() );
     }
 
 
@@ -792,11 +784,10 @@ public class ManagementServiceImpl implements ManagementService {
                 user.getDynamicProperties() );
 
         // special case for sysadmin and test account only
-        if ( !user.getEmail().equals( properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_EMAIL ) ) && !user.getEmail()
-                                                                                                          .equals(
-                                                                                                                  properties
-                                                                                                                          .getProperty(
-                                                                                                                                  PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL ) ) ) {
+        String sysAdminLoginEmail =  properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_EMAIL );
+        String testAdminUserEmail = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL );
+        if (  !user.getEmail().equals( sysAdminLoginEmail )
+                && !user.getEmail().equals( testAdminUserEmail ) ) {
             this.startAdminUserActivationFlow( userInfo );
         }
 
@@ -1403,8 +1394,7 @@ public class ManagementServiceImpl implements ManagementService {
     @Override
     public Entity getAdminUserEntityFromAccessToken( String token ) throws Exception {
 
-        Entity user = getEntityFromAccessToken( token, null, ADMIN_USER );
-        return user;
+        return getEntityFromAccessToken( token, null, ADMIN_USER );
     }
 
 
@@ -1427,11 +1417,10 @@ public class ManagementServiceImpl implements ManagementService {
         Results results = em.getCollection( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "groups", null, 10000,
                 Level.ALL_PROPERTIES, false );
 
-        String path = null;
 
         for ( Entity entity : results.getEntities() ) {
 
-            path = ( String ) entity.getProperty( "path" );
+            String path = ( String ) entity.getProperty( "path" );
 
             if ( path != null ) {
                 path = path.toLowerCase();
@@ -1585,6 +1574,10 @@ public class ManagementServiceImpl implements ManagementService {
             properties = new HashMap<String, Object>();
         }
 
+        if( properties.containsKey("name")){
+            properties.remove("name");
+        }
+
         OrganizationInfo organizationInfo = getOrganizationByUuid( organizationId );
 
         UUID applicationId = emf.createApplication( organizationInfo.getName(), applicationName, properties );
@@ -2152,11 +2145,15 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public void sendOrganizationEmail( OrganizationInfo organization, String subject, String html ) throws Exception {
-        List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
-        for ( UserInfo user : users ) {
-            sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
-                    subject, appendEmailFooter( html ) );
+    public void sendOrganizationEmail(OrganizationInfo organization, String subject, String html) throws Exception {
+        List<UserInfo> users = getAdminUsersForOrganization(organization.getUuid());
+        for (UserInfo user : users) {
+            if (StringUtils.isNotBlank(user.getEmail())) {
+                sendHtmlMail(properties, user.getDisplayEmailAddress(), properties.getProperty(PROPERTIES_MAILER_EMAIL),
+                        subject, appendEmailFooter(html));
+            } else {
+                throw new MissingEmailException();
+            }
         }
     }
 
@@ -2276,9 +2273,11 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     @Override
-    public void sendAdminUserEmail( UserInfo user, String subject, String html ) throws Exception {
-        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
-                subject, appendEmailFooter( html ) );
+    public void sendAdminUserEmail(UserInfo user, String subject, String html) throws Exception {
+        if (StringUtils.isNotBlank(user.getEmail())) {
+            sendHtmlMail(properties, user.getDisplayEmailAddress(), properties.getProperty(PROPERTIES_MAILER_EMAIL),
+                    subject, appendEmailFooter(html));
+        }
     }
 
 
@@ -2434,30 +2433,43 @@ public class ManagementServiceImpl implements ManagementService {
 
     @Override
     public boolean newAppUsersNeedAdminApproval( UUID applicationId ) throws Exception {
-        EntityManager em = emf.getEntityManager( applicationId );
-        Boolean registration_requires_admin_approval = ( Boolean ) em
-                .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
-                        REGISTRATION_REQUIRES_ADMIN_APPROVAL );
-        return registration_requires_admin_approval != null && registration_requires_admin_approval.booleanValue();
+//        return checkApplicationBooleanProperty(applicationId, REGISTRATION_REQUIRES_ADMIN_APPROVAL, false);
+        EntityManager em = emf.getEntityManager(applicationId);
+        Application application = em.getApplication();
+        return application.registrationRequiresAdminApproval();
     }
 
 
     @Override
     public boolean newAppUsersRequireConfirmation( UUID applicationId ) throws Exception {
-        EntityManager em = emf.getEntityManager( applicationId );
-        Boolean registration_requires_email_confirmation = ( Boolean ) em
-                .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
-                        REGISTRATION_REQUIRES_EMAIL_CONFIRMATION );
-        return registration_requires_email_confirmation != null && registration_requires_email_confirmation.booleanValue();
+//        return checkApplicationBooleanProperty(applicationId, REGISTRATION_REQUIRES_EMAIL_CONFIRMATION, false);
+        EntityManager em = emf.getEntityManager(applicationId);
+        Application application = em.getApplication();
+        return application.registrationRequiresEmailConfirmation();
     }
 
 
+    @Override
+    public boolean appAllowOpenRegistration( UUID applicationId ) throws Exception{
+        EntityManager em = emf.getEntityManager(applicationId);
+        Application application = em.getApplication();
+        return application.allowOpenRegistration();
+//        return checkApplicationBooleanProperty(applicationId, ALLOW_OPEN_REGISTRATION, true);
+    }
+
     public boolean notifyAdminOfNewAppUsers( UUID applicationId ) throws Exception {
+//        return checkApplicationBooleanProperty(applicationId, NOTIFY_ADMIN_OF_NEW_USERS, false);
+        EntityManager em = emf.getEntityManager(applicationId);
+        Application application = em.getApplication();
+        return application.notifyAdminOfNewUsers();
+    }
+
+    private boolean checkApplicationBooleanProperty(UUID applicationId, String property, boolean defaultValue) throws Exception{
         EntityManager em = emf.getEntityManager( applicationId );
-        Boolean notify_admin_of_new_users = ( Boolean ) em
+        Boolean value = ( Boolean ) em
                 .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
-                        NOTIFY_ADMIN_OF_NEW_USERS );
-        return notify_admin_of_new_users != null && notify_admin_of_new_users.booleanValue();
+                        property);
+        return value != null ? value : defaultValue;
     }
 
 
@@ -2520,6 +2532,9 @@ public class ManagementServiceImpl implements ManagementService {
 
 
     public void sendAppUserConfirmationEmail( UUID applicationId, User user ) throws Exception {
+        if (StringUtils.isBlank(user.getEmail())) {
+            throw new MissingEmailException();
+        }
         String token = getConfirmationTokenForAppUser( applicationId, user.getUuid() );
         String confirmation_url =
                 buildUserAppUrl( applicationId, properties.getProperty( PROPERTIES_USER_CONFIRMATION_URL ), user,
@@ -2653,9 +2668,11 @@ public class ManagementServiceImpl implements ManagementService {
     }
 
 
-    public void sendAppUserEmail( User user, String subject, String html ) throws Exception {
-        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
-                subject, appendEmailFooter( html ) );
+    public void sendAppUserEmail(User user, String subject, String html) throws Exception {
+        if (StringUtils.isNotBlank(user.getEmail())) {
+            sendHtmlMail(properties, user.getDisplayEmailAddress(), properties.getProperty(PROPERTIES_MAILER_EMAIL),
+                    subject, appendEmailFooter(html));
+        }
     }
 
 
@@ -2684,10 +2701,7 @@ public class ManagementServiceImpl implements ManagementService {
     public void sendAppUserPin( UUID applicationId, UUID userId ) throws Exception {
         EntityManager em = emf.getEntityManager( applicationId );
         User user = em.get( userId, User.class );
-        if ( user == null ) {
-            return;
-        }
-        if ( user.getEmail() == null ) {
+        if ( user == null || StringUtils.isBlank(user.getEmail()) ) {
             return;
         }
         String pin = getCredentialsSecret( readUserPin( applicationId, userId ) );
@@ -2862,12 +2876,8 @@ public class ManagementServiceImpl implements ManagementService {
 
     private boolean verify( UUID applicationId, UUID userId, String password ) throws Exception {
         CredentialsInfo ci = readUserPasswordCredentials( applicationId, userId );
+        return ci != null && encryptionService.verify(password, ci, userId, applicationId);
 
-        if ( ci == null ) {
-            return false;
-        }
-
-        return encryptionService.verify( password, ci, userId, applicationId );
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/services/src/main/java/org/apache/usergrid/management/exceptions/MissingEmailException.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/exceptions/MissingEmailException.java b/stack/services/src/main/java/org/apache/usergrid/management/exceptions/MissingEmailException.java
new file mode 100644
index 0000000..03d280d
--- /dev/null
+++ b/stack/services/src/main/java/org/apache/usergrid/management/exceptions/MissingEmailException.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.management.exceptions;
+
+import org.apache.usergrid.persistence.entities.User;
+
+/**
+ * @author stliu
+ * @date 6/10/14
+ */
+public class MissingEmailException extends ManagementException {
+
+    private static final long serialVersionUID = 1L;
+
+
+    public MissingEmailException() {
+        super();
+    }
+
+
+    public MissingEmailException( String arg0, Throwable arg1 ) {
+        super( arg0, arg1 );
+    }
+
+
+    public MissingEmailException( String arg0 ) {
+        super( arg0 );
+    }
+
+
+    public MissingEmailException( Throwable arg0 ) {
+        super( arg0 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/services/src/main/java/org/apache/usergrid/security/tokens/TokenCategory.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/tokens/TokenCategory.java b/stack/services/src/main/java/org/apache/usergrid/security/tokens/TokenCategory.java
index 121901d..f414d7d 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/tokens/TokenCategory.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/tokens/TokenCategory.java
@@ -17,6 +17,8 @@
 package org.apache.usergrid.security.tokens;
 
 
+import org.apache.usergrid.utils.StringUtils;
+
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -72,11 +74,11 @@ public enum TokenCategory {
 
 
     public static TokenCategory getFromBase64String( String token ) {
-        if ( token == null ) {
+        if ( StringUtils.isBlank(token) ) {
             return null;
         }
-        if ( token.length() >= 4 ) {
-            return base64Prefixes.get( token.substring( 0, 4 ) );
+        if ( token.length() >= BASE64_PREFIX_LENGTH ) {
+            return base64Prefixes.get( token.substring( 0, BASE64_PREFIX_LENGTH ) );
         }
         return null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/services/src/main/java/org/apache/usergrid/security/tokens/cassandra/TokenServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/security/tokens/cassandra/TokenServiceImpl.java b/stack/services/src/main/java/org/apache/usergrid/security/tokens/cassandra/TokenServiceImpl.java
index 50156b5..21e8a1e 100644
--- a/stack/services/src/main/java/org/apache/usergrid/security/tokens/cassandra/TokenServiceImpl.java
+++ b/stack/services/src/main/java/org/apache/usergrid/security/tokens/cassandra/TokenServiceImpl.java
@@ -20,6 +20,7 @@ package org.apache.usergrid.security.tokens.cassandra;
 import java.nio.ByteBuffer;
 import java.util.*;
 
+import org.apache.usergrid.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -356,6 +357,9 @@ public class TokenServiceImpl implements TokenService {
             logger.error( "Unable to find token with the specified value ignoring request.  Value : {}", token );
             return;
         }
+        if(info == null){
+            return;
+        }
 
         UUID tokenId = info.getUuid();
 
@@ -497,15 +501,30 @@ public class TokenServiceImpl implements TokenService {
         return buff;
     }
 
+    private void assertToken(TokenCategory tokenCategory, byte[] tokenBytes) throws BadTokenException{
+        int expectedLength = tokenCategory.getExpires() ? 44 : 36;
+        if(expectedLength != tokenBytes.length){
+            throw new BadTokenException( "Invalid token signature" );
+        }
+    }
 
     private UUID getUUIDForToken( String token ) throws ExpiredTokenException, BadTokenException {
+        if(StringUtils.isBlank(token)){
+            return null;
+        }
         TokenCategory tokenCategory = TokenCategory.getFromBase64String( token );
+        if(tokenCategory == null){
+            return null;
+        }
         byte[] bytes = decodeBase64( token.substring( TokenCategory.BASE64_PREFIX_LENGTH ) );
+
+        assertToken(tokenCategory, bytes);
+
         UUID uuid = uuid( bytes );
         int i = 16;
         long expires = Long.MAX_VALUE;
-        if ( tokenCategory.getExpires() ) {
-            expires = ByteBuffer.wrap( bytes, i, 8 ).getLong();
+        if (tokenCategory.getExpires()) {
+            expires = ByteBuffer.wrap(bytes, i, 8).getLong();
             i = 24;
         }
         ByteBuffer expected = ByteBuffer.allocate( 20 );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/6595f919/stack/services/src/main/java/org/apache/usergrid/services/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/ServiceInfo.java b/stack/services/src/main/java/org/apache/usergrid/services/ServiceInfo.java
index ea85686..37c99b1 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/ServiceInfo.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/ServiceInfo.java
@@ -17,6 +17,7 @@
 package org.apache.usergrid.services;
 
 
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
@@ -52,6 +53,7 @@ public class ServiceInfo {
     private final String itemType;
     private final List<String> patterns;
     private final List<String> collections;
+    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
 
     /** Pre calced since we cache this class */
     private int hashCode;
@@ -71,7 +73,7 @@ public class ServiceInfo {
         Hasher hasher = Hashing.md5().newHasher();
 
         for ( String pattern : patterns ) {
-            hasher.putString( pattern );
+            hasher.putString( pattern, DEFAULT_CHARSET );
         }
 
         hashCode = hasher.hash().asInt();