KEYCLOAK-19079 Add special case for kubeadmin without uid and OCP4
This commit is contained in:
parent
3abf9283a8
commit
97ee8832a3
3 changed files with 56 additions and 4 deletions
|
@ -3,7 +3,6 @@ package org.keycloak.social.openshift;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
|
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
|
||||||
|
@ -16,7 +15,6 @@ import org.keycloak.connections.httpclient.HttpClientProvider;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -33,6 +31,7 @@ public class OpenshiftV4IdentityProvider extends AbstractOAuth2IdentityProvider<
|
||||||
public static final String OPENSHIFT_OAUTH_METADATA_ENDPOINT = "/.well-known/oauth-authorization-server";
|
public static final String OPENSHIFT_OAUTH_METADATA_ENDPOINT = "/.well-known/oauth-authorization-server";
|
||||||
public static final String PROFILE_RESOURCE = "/apis/user.openshift.io/v1/users/~";
|
public static final String PROFILE_RESOURCE = "/apis/user.openshift.io/v1/users/~";
|
||||||
public static final String DEFAULT_SCOPE = "user:info";
|
public static final String DEFAULT_SCOPE = "user:info";
|
||||||
|
private static final String KUBEADM_NAME = "kube:admin";
|
||||||
|
|
||||||
public OpenshiftV4IdentityProvider(KeycloakSession session, OpenshiftV4IdentityProviderConfig config) {
|
public OpenshiftV4IdentityProvider(KeycloakSession session, OpenshiftV4IdentityProviderConfig config) {
|
||||||
super(session, config);
|
super(session, config);
|
||||||
|
@ -91,7 +90,11 @@ public class OpenshiftV4IdentityProvider extends AbstractOAuth2IdentityProvider<
|
||||||
private BrokeredIdentityContext extractUserContext(JsonNode profile) {
|
private BrokeredIdentityContext extractUserContext(JsonNode profile) {
|
||||||
JsonNode metadata = profile.get("metadata");
|
JsonNode metadata = profile.get("metadata");
|
||||||
logger.debugv("extractUserContext: metadata = {0}", metadata);
|
logger.debugv("extractUserContext: metadata = {0}", metadata);
|
||||||
final BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(metadata, "uid"));
|
final BrokeredIdentityContext user = new BrokeredIdentityContext(
|
||||||
|
getJsonProperty(metadata, "uid") != null
|
||||||
|
? getJsonProperty(metadata, "uid")
|
||||||
|
: tryGetKubeAdmin(metadata)
|
||||||
|
);
|
||||||
user.setUsername(getJsonProperty(metadata, "name"));
|
user.setUsername(getJsonProperty(metadata, "name"));
|
||||||
user.setName(getJsonProperty(profile, "fullName"));
|
user.setName(getJsonProperty(profile, "fullName"));
|
||||||
user.setIdpConfig(getConfig());
|
user.setIdpConfig(getConfig());
|
||||||
|
@ -99,6 +102,14 @@ public class OpenshiftV4IdentityProvider extends AbstractOAuth2IdentityProvider<
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String tryGetKubeAdmin(JsonNode metadata) {
|
||||||
|
String nameProperty = getJsonProperty(metadata, "name");
|
||||||
|
if(!KUBEADM_NAME.equals(nameProperty)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return nameProperty;
|
||||||
|
}
|
||||||
|
|
||||||
private JsonNode fetchProfile(String accessToken) throws IOException {
|
private JsonNode fetchProfile(String accessToken) throws IOException {
|
||||||
return SimpleHttp.doGet(getConfig().getUserInfoUrl(), this.session)
|
return SimpleHttp.doGet(getConfig().getUserInfoUrl(), this.session)
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
|
|
|
@ -17,10 +17,14 @@
|
||||||
|
|
||||||
package org.keycloak.testsuite.pages.social;
|
package org.keycloak.testsuite.pages.social;
|
||||||
|
|
||||||
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.Keys;
|
import org.openqa.selenium.Keys;
|
||||||
|
import org.openqa.selenium.NoSuchElementException;
|
||||||
import org.openqa.selenium.WebElement;
|
import org.openqa.selenium.WebElement;
|
||||||
import org.openqa.selenium.support.FindBy;
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.util.UIUtils.clickLink;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
||||||
*/
|
*/
|
||||||
|
@ -31,10 +35,33 @@ public class OpenShiftLoginPage extends AbstractSocialLoginPage {
|
||||||
@FindBy(name = "password")
|
@FindBy(name = "password")
|
||||||
private WebElement passwordInput;
|
private WebElement passwordInput;
|
||||||
|
|
||||||
|
private String userLoginLinkTitle;
|
||||||
|
|
||||||
|
private WebElement userLoginLink;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void login(String user, String password) {
|
public void login(String user, String password) {
|
||||||
|
if(userLoginLinkTitle != null) {
|
||||||
|
setUserLoginLink(this.userLoginLinkTitle);
|
||||||
|
if(this.userLoginLink != null) {
|
||||||
|
clickLink(this.userLoginLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
usernameInput.sendKeys(user);
|
usernameInput.sendKeys(user);
|
||||||
passwordInput.sendKeys(password);
|
passwordInput.sendKeys(password);
|
||||||
passwordInput.sendKeys(Keys.RETURN);
|
passwordInput.sendKeys(Keys.RETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUserLoginLinkTitle(String title) {
|
||||||
|
this.userLoginLinkTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUserLoginLink(String linkAttrTitle) {
|
||||||
|
try {
|
||||||
|
this.userLoginLink = driver.findElement(By.xpath("//a[contains(@title,'"+linkAttrTitle+"')]"));
|
||||||
|
} catch (NoSuchElementException ex) {
|
||||||
|
log.error("No link with title: '" + linkAttrTitle + "' found on page. If you use the OPENSHIFT4_KUBE_ADMIN provider, set property loginBtnTitle in properties file to an existing title on the page to fix this error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.LINKEDIN;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.MICROSOFT;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.MICROSOFT;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.OPENSHIFT;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.OPENSHIFT;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.OPENSHIFT4;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.OPENSHIFT4;
|
||||||
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.OPENSHIFT4_KUBE_ADMIN;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.PAYPAL;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.PAYPAL;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.STACKOVERFLOW;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.STACKOVERFLOW;
|
||||||
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.TWITTER;
|
import static org.keycloak.testsuite.broker.SocialLoginTest.Provider.TWITTER;
|
||||||
|
@ -129,6 +130,7 @@ public class SocialLoginTest extends AbstractKeycloakTest {
|
||||||
STACKOVERFLOW("stackoverflow", StackOverflowLoginPage.class),
|
STACKOVERFLOW("stackoverflow", StackOverflowLoginPage.class),
|
||||||
OPENSHIFT("openshift-v3", OpenShiftLoginPage.class),
|
OPENSHIFT("openshift-v3", OpenShiftLoginPage.class),
|
||||||
OPENSHIFT4("openshift-v4", OpenShiftLoginPage.class),
|
OPENSHIFT4("openshift-v4", OpenShiftLoginPage.class),
|
||||||
|
OPENSHIFT4_KUBE_ADMIN("openshift-v4", "openshift-v4-admin", OpenShiftLoginPage.class),
|
||||||
GITLAB("gitlab", GitLabLoginPage.class),
|
GITLAB("gitlab", GitLabLoginPage.class),
|
||||||
BITBUCKET("bitbucket", BitbucketLoginPage.class),
|
BITBUCKET("bitbucket", BitbucketLoginPage.class),
|
||||||
INSTAGRAM("instagram", InstagramLoginPage.class);
|
INSTAGRAM("instagram", InstagramLoginPage.class);
|
||||||
|
@ -195,6 +197,10 @@ public class SocialLoginTest extends AbstractKeycloakTest {
|
||||||
log.infof("added '%s' identity provider", provider.id());
|
log.infof("added '%s' identity provider", provider.id());
|
||||||
currentTestProvider = provider;
|
currentTestProvider = provider;
|
||||||
currentSocialLoginPage = Graphene.createPageFragment(currentTestProvider.pageObjectClazz(), driver.findElement(By.tagName("html")));
|
currentSocialLoginPage = Graphene.createPageFragment(currentTestProvider.pageObjectClazz(), driver.findElement(By.tagName("html")));
|
||||||
|
|
||||||
|
if(provider == OPENSHIFT4 || provider == OPENSHIFT4_KUBE_ADMIN) {
|
||||||
|
((OpenShiftLoginPage) currentSocialLoginPage).setUserLoginLinkTitle(getConfig(currentTestProvider, "loginBtnTitle"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -255,6 +261,14 @@ public class SocialLoginTest extends AbstractKeycloakTest {
|
||||||
testTokenExchange();
|
testTokenExchange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openshift4KubeAdminLogin() {
|
||||||
|
setTestProvider(OPENSHIFT4_KUBE_ADMIN);
|
||||||
|
performLogin();
|
||||||
|
assertUpdateProfile(true, true, true);
|
||||||
|
assertAccount();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@UncaughtServerErrorExpected
|
@UncaughtServerErrorExpected
|
||||||
public void openshift4LoginWithGroupsMapper() {
|
public void openshift4LoginWithGroupsMapper() {
|
||||||
|
@ -426,7 +440,7 @@ public class SocialLoginTest extends AbstractKeycloakTest {
|
||||||
if (provider == STACKOVERFLOW) {
|
if (provider == STACKOVERFLOW) {
|
||||||
idp.getConfig().put("key", getConfig(provider, "clientKey"));
|
idp.getConfig().put("key", getConfig(provider, "clientKey"));
|
||||||
}
|
}
|
||||||
if (provider == OPENSHIFT || provider == OPENSHIFT4) {
|
if (provider == OPENSHIFT || provider == OPENSHIFT4 || provider == OPENSHIFT4_KUBE_ADMIN) {
|
||||||
idp.getConfig().put("baseUrl", getConfig(provider, "baseUrl"));
|
idp.getConfig().put("baseUrl", getConfig(provider, "baseUrl"));
|
||||||
}
|
}
|
||||||
if (provider == PAYPAL) {
|
if (provider == PAYPAL) {
|
||||||
|
|
Loading…
Reference in a new issue