From 2e90c52576f7389ffae99175654dede9995686ce Mon Sep 17 00:00:00 2001 From: mitchellsundt Date: Fri, 24 Feb 2012 15:31:24 -0800 Subject: [PATCH] Remove Enable Tokens flag. --- .../permissions/AccessConfigurationSheet.java | 79 +----------- .../AccessConfigurationSheet.ui.xml | 4 +- .../security/client/UserSecurityInfo.java | 12 +- .../security/server/SecurityServiceImpl.java | 122 +++++++++--------- .../security/server/SecurityServiceUtil.java | 4 +- .../security/spring/RegisteredUsersTable.java | 16 --- .../spring/UserDetailsServiceImpl.java | 6 +- 7 files changed, 73 insertions(+), 170 deletions(-) diff --git a/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.java b/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.java index e353745fe9..42567f0ed7 100644 --- a/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.java +++ b/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.java @@ -122,7 +122,7 @@ private static final class AuthChangeValidation implements public boolean isValid(boolean prospectiveValue, UserSecurityInfo key) { // data collector must be an ODK account boolean badCollector = auth.equals(GrantedAuthorityName.GROUP_DATA_COLLECTORS) - && (key.getUsername() == null && !key.getEnableGoogleAuthTokens()); + && (key.getUsername() == null); // site admin must not be the anonymous user boolean badSiteAdmin = auth.equals(GrantedAuthorityName.GROUP_SITE_ADMINS) && (key.getType() == UserType.ANONYMOUS); @@ -147,9 +147,7 @@ public boolean isVisible(UserSecurityInfo key) { if (auth == GrantedAuthorityName.GROUP_DATA_COLLECTORS) { // data collectors can only be ODK accounts... - // or OpenId accounts that have tokens enabled... - return ((key.getUsername() != null) || - (key.getUsername() == null && key.getEnableGoogleAuthTokens())); + return (key.getUsername() != null); } return true; } @@ -172,10 +170,8 @@ public boolean isEnabled(UserSecurityInfo info) { case GROUP_DATA_COLLECTORS: // data collectors must be anonymous // or an ODK account type - // or have 'Enable Tokens' checked return (info.getType() == UserType.ANONYMOUS) || - (info.getUsername() != null) || - ((info.getUsername() == null && info.getEnableGoogleAuthTokens())); + (info.getUsername() != null); case GROUP_DATA_VIEWERS: if (assignedGroups.contains(GrantedAuthorityName.GROUP_FORM_MANAGERS) || assignedGroups.contains(GrantedAuthorityName.GROUP_SITE_ADMINS)) { @@ -233,58 +229,6 @@ public int compare(UserSecurityInfo arg0, UserSecurityInfo arg1) { return 1; } } - - private class EnableGoogleOauth2Column extends UIEnabledValidatingCheckboxColumn { - - protected EnableGoogleOauth2Column() { - super(new BooleanValidationPredicate() { - @Override - public boolean isValid(boolean prospectiveValue, UserSecurityInfo key) { - return (key.getUsername() == null); - }}, - new UIVisiblePredicate() { - @Override - public boolean isVisible(UserSecurityInfo key) { - return (key.getUsername() == null); - } - }, new EnableOpenIdAccountPredicate(), - new Comparator() { - - @Override - public int compare(UserSecurityInfo arg0, UserSecurityInfo arg1) { - boolean arg0Enabled = arg0.getEnableGoogleAuthTokens(); - boolean arg1Enabled = arg1.getEnableGoogleAuthTokens(); - - if (arg0Enabled == arg1Enabled) { - // same value. Order by whether or not we can enable - // this box (whether the user is an OpenId user). - arg0Enabled = (arg0.getUsername() == null); - arg1Enabled = (arg1.getUsername() == null); - if (arg0Enabled == arg1Enabled) - return 0; - if (arg0Enabled) - return -1; - return 1; - } - // checked before unchecked... - if (arg0Enabled) - return -1; - return 1; - }} ); - } - - @Override - public void setValue(UserSecurityInfo object, Boolean value) { - object.setEnableGoogleAuthTokens(value); - uiOutOfSyncWithServer(); - userTable.redraw(); // because this changes the Data Collector checkbox visibility... - } - - @Override - public Boolean getValue(UserSecurityInfo object) { - return object.getEnableGoogleAuthTokens(); - } - } private class GroupMembershipColumn extends UIEnabledValidatingCheckboxColumn { final GrantedAuthorityName auth; @@ -404,8 +348,8 @@ public void updateUsersOnServer() { } break; } else { - if (i.getUsername() == null && !i.getEnableGoogleAuthTokens()) { - // don't allow Google users without Tokens to be data collectors + if (i.getUsername() == null) { + // don't allow Google users to be data collectors i.getAssignedUserGroups().remove(GrantedAuthorityName.GROUP_DATA_COLLECTORS); } } @@ -469,14 +413,6 @@ public boolean isEnabled(UserSecurityInfo info) { } }; - private static final class EnableOpenIdAccountPredicate implements - UIEnabledPredicate { - @Override - public boolean isEnabled(UserSecurityInfo info) { - return (info.getType() == UserType.REGISTERED && info.getUsername() == null); - } - }; - /** * Username cannot be null or zero-length. If it is a Google account type (an * e-mail address), then it should look like an e-mail address. @@ -749,9 +685,6 @@ public AccessConfigurationSheet(PermissionsSubTab permissionsTab) { UIEnabledActionColumn changePassword = new UIEnabledActionColumn( "Change Password", new EnableLocalAccountPredicate(), new ChangePasswordActionCallback()); userTable.addColumn(changePassword, ""); - - EnableGoogleOauth2Column ec = new EnableGoogleOauth2Column(); - userTable.addColumn( ec, "Enable Tokens"); // Type of User AccountTypeSelectionColumn type = new AccountTypeSelectionColumn(); @@ -830,7 +763,7 @@ void onAddUsersClick(ClickEvent e) { ++nUnchanged; } else { u = new UserSecurityInfo(email.getUsername(), email.getFullName(), email.getEmail(), - UserType.REGISTERED, false); + UserType.REGISTERED); list.add(u); if (localUser) { localUsers.put(u.getUsername(), u); diff --git a/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.ui.xml b/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.ui.xml index 9bc00697b0..5e34cf5540 100644 --- a/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.ui.xml +++ b/src/main/java/org/opendatakit/aggregate/client/permissions/AccessConfigurationSheet.ui.xml @@ -7,11 +7,11 @@

Users access the site either

  • anonymously (i.e., as the anonymousUser), or
  • via a Google account, using OpenID (requires an Email account (e.g., user@gmail.com)), or
  • -
  • via an Oauth 1.0 or Oauth 2.0 token (check the Enable Tokens checkbox on a Google account), or
  • +
  • via an Oauth 1.0 or Oauth 2.0 token (issued by Google with access to userInfo.email), or
  • via an ODK account, with a username and password that a site administrator has configured for them.

Capabilities are as follows:

  • Data Collector - able to download forms to ODK Collect and submit data from ODK Collect to ODK Aggregate. -
    Only ODK accounts, the anonymousUser and Oauth-enabled Google accounts can be granted Data Collector rights. +
    Only ODK accounts and the anonymousUser can be granted Data Collector rights.
    The anonymousUser must be granted Data Collector rights to accept submissions from unidentified sources (e.g., from ODK Collect 1.1.5 and earlier, or from ODK Collect 1.1.7 and later if not authenticating).
  • Data Viewer - able to log onto the ODK Aggregate website, filter and view submissions, and generate diff --git a/src/main/java/org/opendatakit/common/security/client/UserSecurityInfo.java b/src/main/java/org/opendatakit/common/security/client/UserSecurityInfo.java index 448433941d..17680524c8 100644 --- a/src/main/java/org/opendatakit/common/security/client/UserSecurityInfo.java +++ b/src/main/java/org/opendatakit/common/security/client/UserSecurityInfo.java @@ -48,32 +48,22 @@ public enum UserType implements Serializable { String fullname; // tie-back to whatever the site admin wants to know. String email; // null if username is non-null UserType type; - boolean enableGoogleAuthTokens; TreeSet assignedUserGroups = new TreeSet(); TreeSet grantedAuthorities = new TreeSet(); public UserSecurityInfo() { } - public UserSecurityInfo(String username, String fullname, String email, UserType type, boolean enableGoogleAuthTokens) { + public UserSecurityInfo(String username, String fullname, String email, UserType type) { this.username = username; this.fullname = fullname; this.email = email; this.type = type; - this.enableGoogleAuthTokens = enableGoogleAuthTokens; if ( (email != null && username != null) || (email == null && username == null) ) { throw new IllegalArgumentException("must have either just username or just email non-null"); } } - public boolean getEnableGoogleAuthTokens() { - return enableGoogleAuthTokens; - } - - public void setEnableGoogleAuthTokens(boolean enableGoogleAuthTokens) { - this.enableGoogleAuthTokens = enableGoogleAuthTokens; - } - public UserType getType() { return type; } diff --git a/src/main/java/org/opendatakit/common/security/server/SecurityServiceImpl.java b/src/main/java/org/opendatakit/common/security/server/SecurityServiceImpl.java index 31722f5104..ba7ce3127c 100644 --- a/src/main/java/org/opendatakit/common/security/server/SecurityServiceImpl.java +++ b/src/main/java/org/opendatakit/common/security/server/SecurityServiceImpl.java @@ -37,78 +37,78 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet; /** - * GWT Server implementation for the SecurityService interface. - * This provides privileges context to the client and is therefore - * accessible to anyone with a ROLE_USER privilege. - * + * GWT Server implementation for the SecurityService interface. This provides + * privileges context to the client and is therefore accessible to anyone with a + * ROLE_USER privilege. + * * @author mitchellsundt@gmail.com - * + * */ public class SecurityServiceImpl extends RemoteServiceServlet implements -org.opendatakit.common.security.client.security.SecurityService { + org.opendatakit.common.security.client.security.SecurityService { - /** + /** * */ - private static final long serialVersionUID = -7360632450727200941L; + private static final long serialVersionUID = -7360632450727200941L; + + @Override + public UserSecurityInfo getUserInfo() throws AccessDeniedException, DatastoreFailureException { - @Override - public UserSecurityInfo getUserInfo() throws AccessDeniedException, - DatastoreFailureException { + HttpServletRequest req = this.getThreadLocalRequest(); + CallingContext cc = ContextFactory.getCallingContext(this, req); - HttpServletRequest req = this.getThreadLocalRequest(); - CallingContext cc = ContextFactory.getCallingContext(this, req); + Datastore ds = cc.getDatastore(); + User user = cc.getCurrentUser(); - Datastore ds = cc.getDatastore(); - User user = cc.getCurrentUser(); - - String uriUser = user.getUriUser(); - UserSecurityInfo info; - try { - if ( user.isRegistered() ) { - RegisteredUsersTable t; - t = RegisteredUsersTable.getUserByUri(uriUser, ds, user); - if ( t != null ) { - info = new UserSecurityInfo(t.getUsername(), t.getFullName(), t.getEmail(), - UserSecurityInfo.UserType.REGISTERED, - t.getGoogleTokenEnabled()); - SecurityServiceUtil.setAuthenticationLists(info, t.getUri(), cc); - } else { - throw new DatastoreFailureException("Unable to retrieve user record"); - } - } else if ( user.isAnonymous() ) { - info = new UserSecurityInfo(User.ANONYMOUS_USER, User.ANONYMOUS_USER_NICKNAME, null, - UserSecurityInfo.UserType.ANONYMOUS, false); - SecurityServiceUtil.setAuthenticationListsForSpecialUser(info, GrantedAuthorityName.USER_IS_ANONYMOUS, cc); - } else { - // should never get to this case via interactive actions... - throw new DatastoreFailureException("Internal error: 45443"); - } - } catch (ODKDatastoreException e) { - e.printStackTrace(); - throw new DatastoreFailureException(e); - } - return info; - } + String uriUser = user.getUriUser(); + UserSecurityInfo info; + try { + if (user.isRegistered()) { + RegisteredUsersTable t; + t = RegisteredUsersTable.getUserByUri(uriUser, ds, user); + if (t != null) { + info = new UserSecurityInfo(t.getUsername(), t.getFullName(), t.getEmail(), + UserSecurityInfo.UserType.REGISTERED); + SecurityServiceUtil.setAuthenticationLists(info, t.getUri(), cc); + } else { + throw new DatastoreFailureException("Unable to retrieve user record"); + } + } else if (user.isAnonymous()) { + info = new UserSecurityInfo(User.ANONYMOUS_USER, User.ANONYMOUS_USER_NICKNAME, null, + UserSecurityInfo.UserType.ANONYMOUS); + SecurityServiceUtil.setAuthenticationListsForSpecialUser(info, + GrantedAuthorityName.USER_IS_ANONYMOUS, cc); + } else { + // should never get to this case via interactive actions... + throw new DatastoreFailureException("Internal error: 45443"); + } + } catch (ODKDatastoreException e) { + e.printStackTrace(); + throw new DatastoreFailureException(e); + } + return info; + } - @Override - public RealmSecurityInfo getRealmInfo(String xsrfString) throws AccessDeniedException { + @Override + public RealmSecurityInfo getRealmInfo(String xsrfString) throws AccessDeniedException { - HttpServletRequest req = this.getThreadLocalRequest(); - CallingContext cc = ContextFactory.getCallingContext(this, req); + HttpServletRequest req = this.getThreadLocalRequest(); + CallingContext cc = ContextFactory.getCallingContext(this, req); - if ( !req.getSession().getId().equals(xsrfString) ) { - throw new AccessDeniedException("Invalid request"); - } + if (!req.getSession().getId().equals(xsrfString)) { + throw new AccessDeniedException("Invalid request"); + } - RealmSecurityInfo r = new RealmSecurityInfo(); - r.setRealmString(cc.getUserService().getCurrentRealm().getRealmString()); - MessageDigestPasswordEncoder mde = - (MessageDigestPasswordEncoder) cc.getBean(SecurityBeanDefs.BASIC_AUTH_PASSWORD_ENCODER); - r.setBasicAuthHashEncoding(mde.getAlgorithm()); - r.setSuperUserEmail(cc.getUserService().getSuperUserEmail()); - // User interface layer uses this URL to submit password changes securely - r.setChangeUserPasswordURL(cc.getSecureServerURL() + BasicConsts.FORWARDSLASH + UserManagePasswordsServlet.ADDR); - return r; - } + RealmSecurityInfo r = new RealmSecurityInfo(); + r.setRealmString(cc.getUserService().getCurrentRealm().getRealmString()); + MessageDigestPasswordEncoder mde = (MessageDigestPasswordEncoder) cc + .getBean(SecurityBeanDefs.BASIC_AUTH_PASSWORD_ENCODER); + r.setBasicAuthHashEncoding(mde.getAlgorithm()); + r.setSuperUserEmail(cc.getUserService().getSuperUserEmail()); + // User interface layer uses this URL to submit password changes securely + r.setChangeUserPasswordURL(cc.getSecureServerURL() + BasicConsts.FORWARDSLASH + + UserManagePasswordsServlet.ADDR); + return r; + } } diff --git a/src/main/java/org/opendatakit/common/security/server/SecurityServiceUtil.java b/src/main/java/org/opendatakit/common/security/server/SecurityServiceUtil.java index 8b93a12e68..d1a961ff03 100644 --- a/src/main/java/org/opendatakit/common/security/server/SecurityServiceUtil.java +++ b/src/main/java/org/opendatakit/common/security/server/SecurityServiceUtil.java @@ -127,14 +127,14 @@ public static ArrayList getAllUsers(boolean withAuthorities, C for ( CommonFieldsBase cb : l ) { RegisteredUsersTable t = (RegisteredUsersTable) cb; UserSecurityInfo i = new UserSecurityInfo(t.getUsername(), t.getFullName(), t.getEmail(), - UserSecurityInfo.UserType.REGISTERED, t.getGoogleTokenEnabled()); + UserSecurityInfo.UserType.REGISTERED); if ( withAuthorities ) { SecurityServiceUtil.setAuthenticationLists(i, t.getUri(), cc); } users.add(i); } // TODO: why doesn't this work? - UserSecurityInfo anonymous = new UserSecurityInfo(User.ANONYMOUS_USER, User.ANONYMOUS_USER_NICKNAME, null, UserSecurityInfo.UserType.ANONYMOUS, false); + UserSecurityInfo anonymous = new UserSecurityInfo(User.ANONYMOUS_USER, User.ANONYMOUS_USER_NICKNAME, null, UserSecurityInfo.UserType.ANONYMOUS); if ( withAuthorities ) { SecurityServiceUtil.setAuthenticationListsForSpecialUser(anonymous, GrantedAuthorityName.USER_IS_ANONYMOUS, cc); } diff --git a/src/main/java/org/opendatakit/common/security/spring/RegisteredUsersTable.java b/src/main/java/org/opendatakit/common/security/spring/RegisteredUsersTable.java index 5dcbf49edc..54e373c313 100644 --- a/src/main/java/org/opendatakit/common/security/spring/RegisteredUsersTable.java +++ b/src/main/java/org/opendatakit/common/security/spring/RegisteredUsersTable.java @@ -101,9 +101,6 @@ public final class RegisteredUsersTable extends CommonFieldsBase { private static final DataField IS_REMOVED = new DataField( "IS_REMOVED", DataField.DataType.BOOLEAN, false ); - - private static final DataField GOOGLE_TOKEN_ENABLED = new DataField( - "GOOGLE_TOKEN_ENABLED", DataField.DataType.BOOLEAN, true); /** * Construct a relation prototype. Only called via {@link #assertRelation(Datastore, User)} @@ -119,7 +116,6 @@ protected RegisteredUsersTable(String schemaName) { fieldList.add(BASIC_AUTH_SALT); fieldList.add(DIGEST_AUTH_PASSWORD); fieldList.add(IS_REMOVED); - fieldList.add(GOOGLE_TOKEN_ENABLED); } /** @@ -228,16 +224,6 @@ public void setIsRemoved(Boolean value) { setBooleanField(IS_REMOVED, value); } - public boolean getGoogleTokenEnabled() { - Boolean value = getBooleanField(GOOGLE_TOKEN_ENABLED); - if ( value == null ) return false; - return value; - } - - public void setGoogleTokenEnabled(Boolean value) { - setBooleanField(GOOGLE_TOKEN_ENABLED, value); - } - private static RegisteredUsersTable relation = null; /** @@ -458,8 +444,6 @@ public static RegisteredUsersTable assertActiveUserByUserSecurityInfo(UserSecuri return r; } else { t.setFullName(u.getFullName()); - t.setGoogleTokenEnabled(( u.getUsername() == null ) && - u.getEnableGoogleAuthTokens()); ds.putEntity(t, user); return t; } diff --git a/src/main/java/org/opendatakit/common/security/spring/UserDetailsServiceImpl.java b/src/main/java/org/opendatakit/common/security/spring/UserDetailsServiceImpl.java index 710dd21fbc..b82bb9245a 100644 --- a/src/main/java/org/opendatakit/common/security/spring/UserDetailsServiceImpl.java +++ b/src/main/java/org/opendatakit/common/security/spring/UserDetailsServiceImpl.java @@ -146,7 +146,7 @@ public UserDetails loadUserByUsername(String name) final String password; final String salt; final Set grantedAuthorities; - boolean isEnabled = true; + final boolean isEnabled = true; final boolean isCredentialNonExpired = true; try { if ( credentialType == CredentialType.Username ) { @@ -200,10 +200,6 @@ public UserDetails loadUserByUsername(String name) if ( eUser != null ) { uriUser = eUser.getUri(); grantedAuthorities = getGrantedAuthorities(eUser.getUri()); - // allow for Oauth and Oauth2 to be disabled. - if ( credentialType == CredentialType.Token ) { - isEnabled = eUser.getGoogleTokenEnabled(); - } } else { throw new UsernameNotFoundException("User " + name + " is not registered"); }