diff --git a/pom.xml b/pom.xml index e011988773..87defec5dd 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ 7.1.0 1.0.2.Final 2.0.0.Final - 4.0.7 + 4.1.2 4.1.0 diff --git a/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java b/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java index f3430d4e7b..a893387c02 100755 --- a/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java +++ b/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java @@ -28,6 +28,7 @@ import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.util.IdentityBrokerState; import org.keycloak.broker.social.SocialIdentityProvider; import org.keycloak.common.ClientConnection; +import org.keycloak.common.util.Base64; import org.keycloak.events.Details; import org.keycloak.events.EventBuilder; import org.keycloak.events.EventType; @@ -43,12 +44,14 @@ import org.keycloak.services.managers.ClientSessionCode; import org.keycloak.services.messages.Messages; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.vault.VaultStringSecret; +import twitter4j.AccessToken; +import twitter4j.OAuthAuthorization; +import twitter4j.RequestToken; import twitter4j.Twitter; -import twitter4j.TwitterFactory; -import twitter4j.auth.AccessToken; -import twitter4j.auth.RequestToken; -import twitter4j.conf.ConfigurationBuilder; +import twitter4j.v1.User; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; import javax.ws.rs.GET; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; @@ -67,14 +70,19 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider + */ +public class TwitterConsentLoginPage extends AbstractSocialLoginPage { + + @FindBy(xpath = "//input[@type='submit' and @id='allow']") + private WebElement signInButton; + + @Page + TwitterLoginPage loginPage; + + @Override + public void login(String user, String password) { + // twitter presents a consent page for the application + // the SignIn button should be clicked first to go to the real login + signInButton.click(); + + loginPage.login(user, password); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/TwitterLoginPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/TwitterLoginPage.java index c052b9baad..a4ce458527 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/TwitterLoginPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/TwitterLoginPage.java @@ -17,7 +17,8 @@ package org.keycloak.testsuite.pages.social; -import org.openqa.selenium.NoSuchElementException; +import org.keycloak.testsuite.util.WaitUtils; +import org.openqa.selenium.Keys; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -25,26 +26,25 @@ import org.openqa.selenium.support.FindBy; * @author Vaclav Muzikar */ public class TwitterLoginPage extends AbstractSocialLoginPage { - @FindBy(id = "username_or_email") + + @FindBy(xpath = "//input[@type='text' and @name='text']") private WebElement usernameInput; - @FindBy(id = "password") + @FindBy(xpath = "//input[@type='password']") private WebElement passwordInput; - @FindBy(id = "allow") - private WebElement loginButton; - @Override public void login(String user, String password) { - try { - usernameInput.clear(); - usernameInput.sendKeys(user); - passwordInput.sendKeys(password); - } - catch (NoSuchElementException e) { // at some conditions we are already logged in and just need to confirm it - } - finally { - loginButton.click(); - } + // new login page is two phase login (username and then password) and it + // needs lots of JS, twitter does not work with default HtmlUnit driver + usernameInput.clear(); + usernameInput.sendKeys(user); + usernameInput.sendKeys(Keys.RETURN); + + // wait for the password input to appear + WaitUtils.waitUntilElement(passwordInput).is().visible(); + passwordInput.clear(); + passwordInput.sendKeys(password); + passwordInput.sendKeys(Keys.RETURN); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java index 60fc23eeac..570c61f53a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java @@ -46,7 +46,7 @@ import org.keycloak.testsuite.pages.social.MicrosoftLoginPage; import org.keycloak.testsuite.pages.social.OpenShiftLoginPage; import org.keycloak.testsuite.pages.social.PayPalLoginPage; import org.keycloak.testsuite.pages.social.StackOverflowLoginPage; -import org.keycloak.testsuite.pages.social.TwitterLoginPage; +import org.keycloak.testsuite.pages.social.TwitterConsentLoginPage; import org.keycloak.testsuite.util.IdentityProviderBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; @@ -121,7 +121,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { FACEBOOK_INCLUDE_BIRTHDAY("facebook", FacebookLoginPage.class), GITHUB("github", GitHubLoginPage.class), GITHUB_PRIVATE_EMAIL("github", "github-private-email", GitHubLoginPage.class), - TWITTER("twitter", TwitterLoginPage.class), + TWITTER("twitter", TwitterConsentLoginPage.class), LINKEDIN("linkedin", LinkedInLoginPage.class), LINKEDIN_WITH_PROJECTION("linkedin", LinkedInLoginPage.class), MICROSOFT("microsoft", MicrosoftLoginPage.class),