keycloak-memoizeit
Changes
services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProviderFactory.java 46(+46 -0)
services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
services/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory 1(+1 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/InstagramLoginPage.java 43(+43 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java 12(+11 -1)
Details
diff --git a/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProvider.java b/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProvider.java
new file mode 100755
index 0000000..759de42
--- /dev/null
+++ b/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.social.instagram;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
+import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+import org.keycloak.broker.provider.util.SimpleHttp;
+import org.keycloak.broker.provider.BrokeredIdentityContext;
+import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.social.SocialIdentityProvider;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class InstagramIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
+
+ public static final String AUTH_URL = "https://api.instagram.com/oauth/authorize";
+ public static final String TOKEN_URL = "https://api.instagram.com/oauth/access_token";
+ public static final String PROFILE_URL = "https://api.instagram.com/v1/users/self";
+ public static final String DEFAULT_SCOPE = "basic";
+
+ public InstagramIdentityProvider(KeycloakSession session, OAuth2IdentityProviderConfig config) {
+ super(session, config);
+ config.setAuthorizationUrl(AUTH_URL);
+ config.setTokenUrl(TOKEN_URL);
+ config.setUserInfoUrl(PROFILE_URL);
+ }
+
+ protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
+ try {
+ JsonNode raw = SimpleHttp.doGet(PROFILE_URL,session).param("access_token", accessToken).asJson();
+
+ JsonNode profile = raw.get("data");
+
+ logger.debug(profile.toString());
+
+ String id = getJsonProperty(profile, "id");
+
+ BrokeredIdentityContext user = new BrokeredIdentityContext(id);
+
+ String username = getJsonProperty(profile, "username");
+
+ user.setUsername(username);
+
+ String full_name = getJsonProperty(profile, "full_name");
+
+ user.setName(full_name);
+ user.setIdpConfig(getConfig());
+ user.setIdp(this);
+
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
+
+ return user;
+ } catch (Exception e) {
+ throw new IdentityBrokerException("Could not obtain user profile from instagram.", e);
+ }
+ }
+
+ @Override
+ protected String getDefaultScopes() {
+ return DEFAULT_SCOPE;
+ }
+}
diff --git a/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProviderFactory.java b/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProviderFactory.java
new file mode 100755
index 0000000..8eaf333
--- /dev/null
+++ b/services/src/main/java/org/keycloak/social/instagram/InstagramIdentityProviderFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.social.instagram;
+
+import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
+import org.keycloak.broker.social.SocialIdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author Pedro Igor
+ */
+public class InstagramIdentityProviderFactory extends AbstractIdentityProviderFactory<InstagramIdentityProvider> implements SocialIdentityProviderFactory<InstagramIdentityProvider> {
+
+ public static final String PROVIDER_ID = "instagram";
+
+ @Override
+ public String getName() {
+ return "Instagram";
+ }
+
+ @Override
+ public InstagramIdentityProvider create(KeycloakSession session, IdentityProviderModel model) {
+ return new InstagramIdentityProvider(session, new OAuth2IdentityProviderConfig(model));
+ }
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+}
diff --git a/services/src/main/java/org/keycloak/social/instagram/InstagramUserAttributeMapper.java b/services/src/main/java/org/keycloak/social/instagram/InstagramUserAttributeMapper.java
new file mode 100644
index 0000000..e6bba77
--- /dev/null
+++ b/services/src/main/java/org/keycloak/social/instagram/InstagramUserAttributeMapper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.social.instagram;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class InstagramUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { InstagramIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "instagram-user-attribute-mapper";
+ }
+
+}
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
index d907571..378f05e 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
+++ b/services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -32,3 +32,4 @@ org.keycloak.social.google.GoogleUserAttributeMapper
org.keycloak.social.linkedin.LinkedInUserAttributeMapper
org.keycloak.social.stackoverflow.StackoverflowUserAttributeMapper
org.keycloak.social.microsoft.MicrosoftUserAttributeMapper
+org.keycloak.social.instagram.InstagramUserAttributeMapper
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory b/services/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory
index db57e6b..a144165 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory
+++ b/services/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory
@@ -26,3 +26,4 @@ org.keycloak.social.microsoft.MicrosoftIdentityProviderFactory
org.keycloak.social.openshift.OpenshiftV3IdentityProviderFactory
org.keycloak.social.gitlab.GitLabIdentityProviderFactory
org.keycloak.social.bitbucket.BitbucketIdentityProviderFactory
+org.keycloak.social.instagram.InstagramIdentityProviderFactory
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/InstagramLoginPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/InstagramLoginPage.java
new file mode 100644
index 0000000..c9b5165
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/InstagramLoginPage.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.testsuite.pages.social;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class InstagramLoginPage extends AbstractSocialLoginPage {
+ @FindBy(name = "username")
+ private WebElement usernameInput;
+
+ @FindBy(name = "password")
+ private WebElement passwordInput;
+
+ @FindBy(xpath = "//input[@type='submit']")
+ private WebElement loginButton;
+
+ @Override
+ public void login(String user, String password) {
+ usernameInput.clear();
+ usernameInput.sendKeys(user);
+ passwordInput.sendKeys(password);
+ loginButton.click();
+ }
+}
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 4d62187..8118b7f 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
@@ -33,6 +33,7 @@ import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.social.AbstractSocialLoginPage;
import org.keycloak.testsuite.pages.social.BitbucketLoginPage;
import org.keycloak.testsuite.pages.social.FacebookLoginPage;
+import org.keycloak.testsuite.pages.social.InstagramLoginPage;
import org.keycloak.testsuite.pages.social.GitHubLoginPage;
import org.keycloak.testsuite.pages.social.GitLabLoginPage;
import org.keycloak.testsuite.pages.social.GoogleLoginPage;
@@ -67,6 +68,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.BITBUCKET;
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.FACEBOOK;
+import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.INSTAGRAM;
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.GITHUB;
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.GITHUB_PRIVATE_EMAIL;
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.GITLAB;
@@ -108,7 +110,8 @@ public class SocialLoginTest extends AbstractKeycloakTest {
STACKOVERFLOW("stackoverflow", StackOverflowLoginPage.class),
OPENSHIFT("openshift-v3", OpenShiftLoginPage.class),
GITLAB("gitlab", GitLabLoginPage.class),
- BITBUCKET("bitbucket", BitbucketLoginPage.class);
+ BITBUCKET("bitbucket", BitbucketLoginPage.class),
+ INSTAGRAM("instagram", InstagramLoginPage.class);
private String id;
private Class<? extends AbstractSocialLoginPage> pageObjectClazz;
@@ -258,6 +261,13 @@ public class SocialLoginTest extends AbstractKeycloakTest {
testTokenExchange();
}
+ @Test
+ public void instagramLogin() throws InterruptedException {
+ setTestProvider(INSTAGRAM);
+ performLogin();
+ assertUpdateProfile(false, false, true);
+ assertAccount();
+ }
@Test
public void githubLogin() throws InterruptedException {
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram.html
new file mode 100644
index 0000000..a4630ac
--- /dev/null
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram.html
@@ -0,0 +1 @@
+<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram-ext.html b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram-ext.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-instagram-ext.html