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),