From c913d457c0d437586d10e8ceccf4cc15e9fa552a Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 10 Nov 2016 16:39:57 -0500 Subject: [PATCH] scalable login page #3338 --- .../data/authentication-providers/github.json | 8 + .../data/authentication-providers/google.json | 8 + .../orcid-sandbox.json | 2 +- .../data/authentication-providers/orcid.json | 8 + scripts/api/setup-identity-providers.sh | 6 +- .../database/upgrades/3338-oauth-login.sql | 2 + src/main/java/Bundle.properties | 14 +- .../edu/harvard/iq/dataverse/LoginPage.java | 20 +- .../BuiltinAuthenticationProvider.java | 2 +- .../providers/oauth2/impl/GitHubOAuth2AP.java | 3 +- .../providers/oauth2/impl/GoogleOAuth2AP.java | 3 +- .../shib/ShibAuthenticationProvider.java | 3 +- .../settings/SettingsServiceBean.java | 2 + .../iq/dataverse/util/SystemConfig.java | 14 + src/main/webapp/loginpage.xhtml | 360 +++++++----------- 15 files changed, 231 insertions(+), 224 deletions(-) create mode 100644 scripts/api/data/authentication-providers/github.json create mode 100644 scripts/api/data/authentication-providers/google.json create mode 100644 scripts/api/data/authentication-providers/orcid.json create mode 100644 scripts/database/upgrades/3338-oauth-login.sql diff --git a/scripts/api/data/authentication-providers/github.json b/scripts/api/data/authentication-providers/github.json new file mode 100644 index 00000000000..9ae9cc4641d --- /dev/null +++ b/scripts/api/data/authentication-providers/github.json @@ -0,0 +1,8 @@ +{ + "id":"github", + "factoryAlias":"oauth2", + "title":"GitHub", + "subtitle":"", + "factoryData":"type: github | userEndpoint: NONE | clientId: FIXME | clientSecret: FIXME", + "enabled":true +} diff --git a/scripts/api/data/authentication-providers/google.json b/scripts/api/data/authentication-providers/google.json new file mode 100644 index 00000000000..514fa99bf01 --- /dev/null +++ b/scripts/api/data/authentication-providers/google.json @@ -0,0 +1,8 @@ +{ + "id":"google", + "factoryAlias":"oauth2", + "title":"Google", + "subtitle":"", + "factoryData":"type: google | userEndpoint: NONE | clientId: FIXME | clientSecret: FIXME", + "enabled":true +} diff --git a/scripts/api/data/authentication-providers/orcid-sandbox.json b/scripts/api/data/authentication-providers/orcid-sandbox.json index 18519c4674b..7f017add1e6 100644 --- a/scripts/api/data/authentication-providers/orcid-sandbox.json +++ b/scripts/api/data/authentication-providers/orcid-sandbox.json @@ -1,7 +1,7 @@ { "id":"orcid-sandbox", "factoryAlias":"oauth2", - "title":"Login using ORCiD (sandbox)", + "title":"ORCID Sandbox", "subtitle":"ORCiD - sandbox", "factoryData":"type: orcid | userEndpoint: https://api.sandbox.orcid.org/v1.2/{ORCID}/orcid-profile | clientId: APP-HIV99BRM37FSWPH6 | clientSecret: ee844b70-f223-4f15-9b6f-4991bf8ed7f0", "enabled":true diff --git a/scripts/api/data/authentication-providers/orcid.json b/scripts/api/data/authentication-providers/orcid.json new file mode 100644 index 00000000000..0615bacb056 --- /dev/null +++ b/scripts/api/data/authentication-providers/orcid.json @@ -0,0 +1,8 @@ +{ + "id":"orcid", + "factoryAlias":"oauth2", + "title":"ORCID", + "subtitle":"", + "factoryData":"type: orcid | userEndpoint: https://api.orcid.org/v1.2/{ORCID}/orcid-profile | clientId: FIXME | clientSecret: FIXME", + "enabled":true +} diff --git a/scripts/api/setup-identity-providers.sh b/scripts/api/setup-identity-providers.sh index 1ef2cd17d0f..9aa3f6a3ab3 100755 --- a/scripts/api/setup-identity-providers.sh +++ b/scripts/api/setup-identity-providers.sh @@ -4,6 +4,6 @@ SERVER=http://localhost:8080/api echo "Setting up internal user provider" curl -H "Content-type:application/json" -d @data/aupr-builtin.json http://localhost:8080/api/admin/authenticationProviders/ -echo "Setting up Echo providers" -curl -H "Content-type:application/json" -d @data/aupr-echo.json http://localhost:8080/api/admin/authenticationProviders/ -curl -H "Content-type:application/json" -d @data/aupr-echo-dignified.json http://localhost:8080/api/admin/authenticationProviders/ +#echo "Setting up Echo providers" +#curl -H "Content-type:application/json" -d @data/aupr-echo.json http://localhost:8080/api/admin/authenticationProviders/ +#curl -H "Content-type:application/json" -d @data/aupr-echo-dignified.json http://localhost:8080/api/admin/authenticationProviders/ diff --git a/scripts/database/upgrades/3338-oauth-login.sql b/scripts/database/upgrades/3338-oauth-login.sql new file mode 100644 index 00000000000..226711ef3f3 --- /dev/null +++ b/scripts/database/upgrades/3338-oauth-login.sql @@ -0,0 +1,2 @@ +DELETE FROM authenticationproviderrow where id = 'echo-simple'; +DELETE FROM authenticationproviderrow where id = 'echo-dignified'; diff --git a/src/main/java/Bundle.properties b/src/main/java/Bundle.properties index c0c17d47ebb..33c6e69b21b 100755 --- a/src/main/java/Bundle.properties +++ b/src/main/java/Bundle.properties @@ -1461,4 +1461,16 @@ oauth2.convertAccount.explanation=Please log in to the account you wish to conve oauth2.convertAccount.username=Existing username oauth2.convertAccount.password=Password oauth2.convertAccount.authenticationFailed=Authentication failed - bad username or password. -oauth2.convertAccount.buttonTitle=Convert Account \ No newline at end of file +oauth2.convertAccount.buttonTitle=Convert Account + +# authentication providers +auth.providers.title.builtin=Local +auth.providers.title.shib=Your Institution +auth.providers.title.orcid=ORCID +auth.providers.title.orcid-sandbox=ORCID Sandbox +auth.providers.title.google=Google +auth.providers.title.github=GitHub +auth.providers.title.blurb.orcid=Log in with your ORCID credentials. Having trouble? Please contact support. +auth.providers.title.blurb.orcid-sandbox=Log in with your ORCID Sandbox credentials. Having trouble? Please contact support. +auth.providers.title.blurb.google=Log in with your Google credentials. Having trouble? Please contact support. +auth.providers.title.blurb.github=Log in with your GitHub credentials. Having trouble? Please contact support. diff --git a/src/main/java/edu/harvard/iq/dataverse/LoginPage.java b/src/main/java/edu/harvard/iq/dataverse/LoginPage.java index a92134fd4fd..aacabebd115 100644 --- a/src/main/java/edu/harvard/iq/dataverse/LoginPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/LoginPage.java @@ -13,6 +13,7 @@ import edu.harvard.iq.dataverse.util.BundleUtil; import edu.harvard.iq.dataverse.util.JsfHelper; import static edu.harvard.iq.dataverse.util.JsfHelper.JH; +import edu.harvard.iq.dataverse.util.SystemConfig; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Iterator; @@ -84,6 +85,9 @@ public enum EditMode {LOGIN, SUCCESS, FAILED}; @EJB SettingsServiceBean settingsService; + + @EJB + SystemConfig systemConfig; @Inject DataverseRequestServiceBean dvRequestService; @@ -93,13 +97,17 @@ public enum EditMode {LOGIN, SUCCESS, FAILED}; private List filledCredentials; private String redirectPage = "dataverse.xhtml"; - + private String provider; + public void init() { Iterator credentialsIterator = authSvc.getAuthenticationProviderIdsOfType( CredentialsAuthenticationProvider.class ).iterator(); if ( credentialsIterator.hasNext() ) { setCredentialsAuthProviderId(credentialsIterator.next()); } resetFilledCredentials(null); + if (provider == null) { + provider = systemConfig.getDefaultAuthProvider(); + } } public boolean isAuthenticationProvidersAvailable() { @@ -229,5 +237,13 @@ public String getRedirectPage() { public void setRedirectPage(String redirectPage) { this.redirectPage = redirectPage; } - + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/builtin/BuiltinAuthenticationProvider.java b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/builtin/BuiltinAuthenticationProvider.java index b9fad9aebae..c496c77e9ba 100644 --- a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/builtin/BuiltinAuthenticationProvider.java +++ b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/builtin/BuiltinAuthenticationProvider.java @@ -40,7 +40,7 @@ public String getId() { @Override public AuthenticationProviderDisplayInfo getInfo() { - return new AuthenticationProviderDisplayInfo(getId(), "Build-in Provider", "Internal user repository"); + return new AuthenticationProviderDisplayInfo(getId(), BundleUtil.getStringFromBundle("auth.providers.title.builtin"), "Internal user repository"); } @Override diff --git a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GitHubOAuth2AP.java b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GitHubOAuth2AP.java index 83118379b95..24364fe3bc8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GitHubOAuth2AP.java +++ b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GitHubOAuth2AP.java @@ -5,6 +5,7 @@ import edu.emory.mathcs.backport.java.util.Collections; import edu.harvard.iq.dataverse.authorization.AuthenticatedUserDisplayInfo; import edu.harvard.iq.dataverse.authorization.providers.oauth2.AbstractOAuth2AuthenticationProvider; +import edu.harvard.iq.dataverse.util.BundleUtil; import java.io.StringReader; import javax.json.Json; import javax.json.JsonObject; @@ -18,7 +19,7 @@ public class GitHubOAuth2AP extends AbstractOAuth2AuthenticationProvider { public GitHubOAuth2AP(String aClientId, String aClientSecret) { id = "github"; - title = "GitHub"; + title = BundleUtil.getStringFromBundle("auth.providers.title.github"); clientId = aClientId; clientSecret = aClientSecret; baseUserEndpoint = "https://api.github.com/user"; diff --git a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GoogleOAuth2AP.java b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GoogleOAuth2AP.java index bd3395e74eb..feb4c72b701 100644 --- a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GoogleOAuth2AP.java +++ b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/oauth2/impl/GoogleOAuth2AP.java @@ -4,6 +4,7 @@ import com.github.scribejava.core.builder.api.BaseApi; import edu.harvard.iq.dataverse.authorization.AuthenticatedUserDisplayInfo; import edu.harvard.iq.dataverse.authorization.providers.oauth2.AbstractOAuth2AuthenticationProvider; +import edu.harvard.iq.dataverse.util.BundleUtil; import java.io.StringReader; import java.util.UUID; import javax.json.Json; @@ -18,7 +19,7 @@ public class GoogleOAuth2AP extends AbstractOAuth2AuthenticationProvider { public GoogleOAuth2AP(String aClientId, String aClientSecret) { id = "google"; - title = "Google"; + title = BundleUtil.getStringFromBundle("auth.providers.title.google"); clientId = aClientId; clientSecret = aClientSecret; scope = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"; diff --git a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/shib/ShibAuthenticationProvider.java b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/shib/ShibAuthenticationProvider.java index dab41c03cfb..bebfd9d4b58 100644 --- a/src/main/java/edu/harvard/iq/dataverse/authorization/providers/shib/ShibAuthenticationProvider.java +++ b/src/main/java/edu/harvard/iq/dataverse/authorization/providers/shib/ShibAuthenticationProvider.java @@ -2,6 +2,7 @@ import edu.harvard.iq.dataverse.authorization.AuthenticationProvider; import edu.harvard.iq.dataverse.authorization.AuthenticationProviderDisplayInfo; +import edu.harvard.iq.dataverse.util.BundleUtil; public class ShibAuthenticationProvider implements AuthenticationProvider { @@ -14,7 +15,7 @@ public String getId() { @Override public AuthenticationProviderDisplayInfo getInfo() { - return new AuthenticationProviderDisplayInfo(getId(), "Shibboleth Provider", "Shibboleth user repository"); + return new AuthenticationProviderDisplayInfo(getId(), BundleUtil.getStringFromBundle("auth.providers.title.shib"), "Shibboleth user repository"); } } diff --git a/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java index 96fe1da403a..c8cbcf1e7ee 100644 --- a/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java @@ -33,6 +33,8 @@ public class SettingsServiceBean { * So there. */ public enum Key { + /** @todo document DefaultAuthProvider in guides */ + DefaultAuthProvider, FooterCopyright, FileFixityChecksumAlgorithm, MinutesUntilConfirmEmailTokenExpires, diff --git a/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java b/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java index f262be3ff81..652bc6b1170 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java @@ -2,6 +2,7 @@ import com.ocpsoft.pretty.PrettyContext; import edu.harvard.iq.dataverse.DataFile; +import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinAuthenticationProvider; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.io.FileInputStream; import java.io.IOException; @@ -547,4 +548,17 @@ public DataFile.ChecksumType getFileFixityChecksumAlgorithm() { return saneDefault; } } + + public String getDefaultAuthProvider() { + String saneDefault = BuiltinAuthenticationProvider.PROVIDER_ID; + String settingInDatabase = settingsService.getValueForKey(SettingsServiceBean.Key.DefaultAuthProvider, saneDefault); + if (settingInDatabase != null && !settingInDatabase.isEmpty()) { + /** + * @todo Add more sanity checking. + */ + return settingInDatabase; + } + return saneDefault; + } + } diff --git a/src/main/webapp/loginpage.xhtml b/src/main/webapp/loginpage.xhtml index 0a635c62ef8..e23c1936719 100644 --- a/src/main/webapp/loginpage.xhtml +++ b/src/main/webapp/loginpage.xhtml @@ -12,6 +12,7 @@ + @@ -33,244 +34,177 @@ -
- - - +
+

-
- - -
-
- -
- -
-
-
- -
- -
-
-
-
- - -
-
- -
-
-
-
-

- Use Root Dataverse with your institutional log in instead of creating an account. Learn More. Leaving your institution? Please contact Root Dataverse Support for assistance. -

-
-
-
-
-
-
-

- Log in to the Root Dataverse with your ORCID credentials. Having trouble? Please contact Root Dataverse Support. -

-
-
-
-
-
-
-

- Log in to the Root Dataverse with your Google credentials. Having trouble? Please contact Root Dataverse Support. -

-
-
-
-
-
-
-

- Log in to the Root Dataverse with your GitHub credentials. Having trouble? Please contact Root Dataverse Support. -

-
-
-
-
-

Other Log In Options

- -
-
- - - -
-
- -
-

#{bundle['login.builtin']}

- - - - +
+
+ + + + +
+ +
+ + + + +
+
+
+
+
-
- - - -
- -
- - - - + +
+
+ +
- -
-
- - -
-
- + +
+
-
 
+
+

#{bundle['login.institution']}

-
-

#{bundle['login.institution']}

- -
- - -

- - - - - - - - - - - - - -

-
- - - +
- + +

+ + + + + + + + + + + + + +

+
- - + - -
+
- -
-
- - -
-
-

Or choose one of the following login services:

-
    - -
  • -
    -
-
- -
-
-
-
-

- OAuth2 configuration warning

-
-
-
- OAuth2 protocol requires a callback URL. Normally, this URL should go to page - /oauth2/callback.xhtml in this installation of Dataverse.
- This parameter is read from the settings table, with key OAuth2CallbackUrl.
- The table contains no such entry, so the system defaults to #{OAuth2Page.callbackUrl}. - This setup is suitable for development, but cannot work in production. + Your Browser does not support javascript. Please use + + +
+
+

#{bundle['auth.providers.title.orcid']}

+

+ + +

+ + +
+ +
+
+
+
+

#{bundle['auth.providers.title.orcid-sandbox']}

+

+ + +

+ +
+ +
+
+
+
+

#{bundle['auth.providers.title.google']}

+

+ + +

+ +
+ +
+
+
+
+

#{bundle['auth.providers.title.github']}

+

+ + +

+ +
+ +
+
+
-
+
+

Other Log In Options

+ + + +
+
- - - +