diff --git a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml index cb1e6a3320..b4f2825322 100755 --- a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml +++ b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml @@ -88,7 +88,6 @@ org.jboss.logging jboss-logging - 3.1.0.GA @@ -104,7 +103,6 @@ projects that depend on this project.--> org.jboss.msc jboss-msc - 1.0.2.GA diff --git a/adapters/oidc/as7-eap6/pom.xml b/adapters/oidc/as7-eap6/pom.xml index d4286ac249..5bb51bd5db 100755 --- a/adapters/oidc/as7-eap6/pom.xml +++ b/adapters/oidc/as7-eap6/pom.xml @@ -30,6 +30,18 @@ keycloak-as7-integration-pom pom + + + + org.jboss.as + jboss-as-parent + ${jboss.as.version} + pom + import + + + + as7-adapter-spi as7-adapter diff --git a/adapters/oidc/jetty/pom.xml b/adapters/oidc/jetty/pom.xml index 2922021aec..01c07da2d2 100755 --- a/adapters/oidc/jetty/pom.xml +++ b/adapters/oidc/jetty/pom.xml @@ -33,9 +33,22 @@ jetty-core jetty8.1 - jetty9.1 jetty9.2 - jetty9.3 - jetty9.4 + + + + community + + + !product + + + + jetty9.1 + jetty9.3 + jetty9.4 + + + diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js index 2def1e2a8e..ff7fb6f5fc 100755 --- a/adapters/oidc/js/src/main/resources/keycloak.js +++ b/adapters/oidc/js/src/main/resources/keycloak.js @@ -832,11 +832,16 @@ document.body.appendChild(iframe); var messageCallback = function(event) { - if (event.origin !== loginIframe.iframeOrigin) { + if ((event.origin !== loginIframe.iframeOrigin) || (loginIframe.iframe.contentWindow !== event.source)) { return; } - if (event.data != "unchanged") { + if (!(event.data == 'unchanged' || event.data == 'changed' || event.data == 'error')) { + return; + } + + + if (event.data != 'unchanged') { kc.clearToken(); } @@ -844,7 +849,7 @@ for (var i = callbacks.length - 1; i >= 0; --i) { var promise = callbacks[i]; - if (event.data == "unchanged") { + if (event.data == 'unchanged') { promise.setSuccess(); } else { promise.setError(); diff --git a/adapters/oidc/pom.xml b/adapters/oidc/pom.xml index 91a99a54c0..ef9e79edcb 100755 --- a/adapters/oidc/pom.xml +++ b/adapters/oidc/pom.xml @@ -45,5 +45,6 @@ tomcat undertow wildfly + wildfly-elytron diff --git a/adapters/oidc/tomcat/pom.xml b/adapters/oidc/tomcat/pom.xml index 0c5bb7952f..e2413e4d07 100755 --- a/adapters/oidc/tomcat/pom.xml +++ b/adapters/oidc/tomcat/pom.xml @@ -32,8 +32,21 @@ tomcat-core - tomcat6 - tomcat7 tomcat8 + + + + community + + + !product + + + + tomcat6 + tomcat7 + + + diff --git a/adapters/oidc/tomcat/tomcat-core/pom.xml b/adapters/oidc/tomcat/tomcat-core/pom.xml index 3e769ee32b..209e5b3075 100755 --- a/adapters/oidc/tomcat/tomcat-core/pom.xml +++ b/adapters/oidc/tomcat/tomcat-core/pom.xml @@ -29,8 +29,6 @@ keycloak-tomcat-core-adapter Keycloak Tomcat Core Integration - - 6.0.41 diff --git a/adapters/oidc/wildfly-elytron/pom.xml b/adapters/oidc/wildfly-elytron/pom.xml new file mode 100755 index 0000000000..5aefb70fc3 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/pom.xml @@ -0,0 +1,99 @@ + + + + + + keycloak-parent + org.keycloak + 3.1.0.CR1-SNAPSHOT + ../../../pom.xml + + 4.0.0 + + keycloak-wildfly-elytron-oidc-adapter + Keycloak Wildfly Elytron OIDC Adapter + + + + 1.8 + 1.8 + + + + + org.wildfly.common + wildfly-common + 1.2.0.Beta1 + + + org.wildfly.security + wildfly-elytron + provided + + + org.wildfly.security.elytron-web + undertow-server + provided + + + org.jboss.logging + jboss-logging + ${jboss.logging.version} + provided + + + org.keycloak + keycloak-core + + + org.keycloak + keycloak-adapter-spi + + + org.keycloak + keycloak-adapter-core + + + org.apache.httpcomponents + httpclient + + + org.bouncycastle + bcprov-jdk15on + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + provided + + + \ No newline at end of file diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronAccount.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronAccount.java new file mode 100644 index 0000000000..c8db009779 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronAccount.java @@ -0,0 +1,103 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import org.jboss.logging.Logger; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.AdapterTokenStore; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.OidcKeycloakAccount; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.wildfly.security.auth.server.SecurityIdentity; + +import javax.security.auth.callback.CallbackHandler; +import java.security.Principal; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Pedro Igor + */ +public class ElytronAccount implements OidcKeycloakAccount { + + protected static Logger log = Logger.getLogger(ElytronAccount.class); + + private final KeycloakPrincipal principal; + + public ElytronAccount(KeycloakPrincipal principal) { + this.principal = principal; + } + + @Override + public RefreshableKeycloakSecurityContext getKeycloakSecurityContext() { + return principal.getKeycloakSecurityContext(); + } + + @Override + public Principal getPrincipal() { + return principal; + } + + @Override + public Set getRoles() { + Set roles = new HashSet<>(); + + return roles; + } + + void setCurrentRequestInfo(KeycloakDeployment deployment, AdapterTokenStore tokenStore) { + principal.getKeycloakSecurityContext().setCurrentRequestInfo(deployment, tokenStore); + } + + public boolean checkActive() { + RefreshableKeycloakSecurityContext session = getKeycloakSecurityContext(); + + if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) { + log.debug("session is active"); + return true; + } + + log.debug("session not active"); + + return false; + } + + boolean tryRefresh(CallbackHandler callbackHandler) { + log.debug("Trying to refresh"); + + RefreshableKeycloakSecurityContext securityContext = getKeycloakSecurityContext(); + + if (securityContext == null) { + log.debug("No security context. Aborting refresh."); + } + + if (securityContext.refreshExpiredToken(false)) { + SecurityIdentity securityIdentity = SecurityIdentityUtil.authorize(callbackHandler, principal); + + if (securityIdentity != null) { + log.debug("refresh succeeded"); + return true; + } + + return false; + } + + return checkActive(); + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronCookieTokenStore.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronCookieTokenStore.java new file mode 100644 index 0000000000..eda7d17231 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronCookieTokenStore.java @@ -0,0 +1,164 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import java.security.Principal; + +import org.jboss.logging.Logger; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.AdapterTokenStore; +import org.keycloak.adapters.CookieTokenStore; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.OidcKeycloakAccount; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.adapters.RequestAuthenticator; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.Scope; + +import javax.security.auth.callback.CallbackHandler; + +/** + * @author Pedro Igor + */ +public class ElytronCookieTokenStore implements ElytronTokeStore { + + protected static Logger log = Logger.getLogger(ElytronCookieTokenStore.class); + + private final ElytronHttpFacade httpFacade; + private final CallbackHandler callbackHandler; + + public ElytronCookieTokenStore(ElytronHttpFacade httpFacade, CallbackHandler callbackHandler) { + this.httpFacade = httpFacade; + this.callbackHandler = callbackHandler; + } + + @Override + public void checkCurrentToken() { + KeycloakDeployment deployment = httpFacade.getDeployment(); + KeycloakPrincipal principal = CookieTokenStore.getPrincipalFromCookie(deployment, httpFacade, this); + + if (principal == null) { + return; + } + + RefreshableKeycloakSecurityContext securityContext = principal.getKeycloakSecurityContext(); + + if (securityContext.isActive() && !securityContext.getDeployment().isAlwaysRefreshToken()) return; + + // FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will + // not be updated + boolean success = securityContext.refreshExpiredToken(false); + if (success && securityContext.isActive()) return; + + saveAccountInfo(new ElytronAccount(principal)); + } + + @Override + public boolean isCached(RequestAuthenticator authenticator) { + KeycloakDeployment deployment = httpFacade.getDeployment(); + KeycloakPrincipal principal = CookieTokenStore.getPrincipalFromCookie(deployment, httpFacade, this); + if (principal == null) { + log.debug("Account was not in cookie or was invalid, returning null"); + return false; + } + ElytronAccount account = new ElytronAccount(principal); + + if (!deployment.getRealm().equals(account.getKeycloakSecurityContext().getRealm())) { + log.debug("Account in session belongs to a different realm than for this request."); + return false; + } + + boolean active = account.checkActive(); + + if (!active) { + active = account.tryRefresh(this.callbackHandler); + } + + if (active) { + log.debug("Cached account found"); + restoreRequest(); + httpFacade.authenticationComplete(account, true); + return true; + } else { + log.debug("Account was not active, removing cookie and returning false"); + CookieTokenStore.removeCookie(httpFacade); + return false; + } + } + + @Override + public void saveAccountInfo(OidcKeycloakAccount account) { + RefreshableKeycloakSecurityContext secContext = (RefreshableKeycloakSecurityContext)account.getKeycloakSecurityContext(); + CookieTokenStore.setTokenCookie(this.httpFacade.getDeployment(), this.httpFacade, secContext); + HttpScope exchange = this.httpFacade.getScope(Scope.EXCHANGE); + + exchange.registerForNotification(httpServerScopes -> logout()); + + exchange.setAttachment(ElytronAccount.class.getName(), account); + exchange.setAttachment(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext()); + + restoreRequest(); + } + + @Override + public void logout() { + logout(false); + } + + @Override + public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) { + CookieTokenStore.setTokenCookie(this.httpFacade.getDeployment(), httpFacade, securityContext); + } + + @Override + public void saveRequest() { + + } + + @Override + public boolean restoreRequest() { + return false; + } + + @Override + public void logout(boolean glo) { + KeycloakPrincipal principal = CookieTokenStore.getPrincipalFromCookie(this.httpFacade.getDeployment(), this.httpFacade, this); + + if (principal == null) { + return; + } + + CookieTokenStore.removeCookie(this.httpFacade); + + if (glo) { + KeycloakSecurityContext ksc = (KeycloakSecurityContext) principal.getKeycloakSecurityContext(); + + if (ksc == null) { + return; + } + + KeycloakDeployment deployment = httpFacade.getDeployment(); + + if (!deployment.isBearerOnly() && ksc != null && ksc instanceof RefreshableKeycloakSecurityContext) { + ((RefreshableKeycloakSecurityContext) ksc).logout(deployment); + } + } + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java new file mode 100644 index 0000000000..bc2e9039ca --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronHttpFacade.java @@ -0,0 +1,394 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import org.bouncycastle.asn1.cmp.Challenge; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.AdapterTokenStore; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.OIDCHttpFacade; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.adapters.spi.AuthChallenge; +import org.keycloak.adapters.spi.AuthenticationError; +import org.keycloak.adapters.spi.LogoutError; +import org.keycloak.enums.TokenStore; +import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.HttpServerCookie; +import org.wildfly.security.http.HttpServerMechanismsResponder; +import org.wildfly.security.http.HttpServerRequest; +import org.wildfly.security.http.HttpServerResponse; +import org.wildfly.security.http.Scope; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.cert.X509Certificate; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URLDecoder; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +/** + * @author Pedro Igor + */ +class ElytronHttpFacade implements OIDCHttpFacade { + + private final HttpServerRequest request; + private final CallbackHandler callbackHandler; + private final AdapterTokenStore tokenStore; + private final AdapterDeploymentContext deploymentContext; + private Consumer responseConsumer; + private ElytronAccount account; + private SecurityIdentity securityIdentity; + private boolean restored; + + public ElytronHttpFacade(HttpServerRequest request, AdapterDeploymentContext deploymentContext, CallbackHandler handler) { + this.request = request; + this.deploymentContext = deploymentContext; + this.callbackHandler = handler; + this.tokenStore = createTokenStore(); + this.responseConsumer = response -> {}; + } + + void authenticationComplete(ElytronAccount account, boolean storeToken) { + this.securityIdentity = SecurityIdentityUtil.authorize(this.callbackHandler, account.getPrincipal()); + + if (securityIdentity != null) { + this.account = account; + RefreshableKeycloakSecurityContext keycloakSecurityContext = account.getKeycloakSecurityContext(); + account.setCurrentRequestInfo(keycloakSecurityContext.getDeployment(), this.tokenStore); + if (storeToken) { + this.tokenStore.saveAccountInfo(account); + } + } + } + + void authenticationComplete() { + if (securityIdentity != null) { + this.request.authenticationComplete(response -> { + if (!restored) { + responseConsumer.accept(response); + } + }, () -> ((ElytronTokeStore) tokenStore).logout(true)); + } + } + + void authenticationFailed() { + this.request.authenticationFailed("Authentication Failed", response -> responseConsumer.accept(response)); + } + + void noAuthenticationInProgress() { + this.request.noAuthenticationInProgress(); + } + + void noAuthenticationInProgress(AuthChallenge challenge) { + if (challenge != null) { + challenge.challenge(this); + } + this.request.noAuthenticationInProgress(response -> responseConsumer.accept(response)); + } + + void authenticationInProgress() { + this.request.authenticationInProgress(response -> responseConsumer.accept(response)); + } + + HttpScope getScope(Scope scope) { + return request.getScope(scope); + } + + HttpScope getScope(Scope scope, String id) { + return request.getScope(scope, id); + } + + Collection getScopeIds(Scope scope) { + return request.getScopeIds(scope); + } + + AdapterTokenStore getTokenStore() { + return this.tokenStore; + } + + KeycloakDeployment getDeployment() { + return deploymentContext.resolveDeployment(this); + } + + private AdapterTokenStore createTokenStore() { + KeycloakDeployment deployment = getDeployment(); + + if (TokenStore.SESSION.equals(deployment.getTokenStore())) { + return new ElytronSessionTokenStore(this, this.callbackHandler); + } else { + return new ElytronCookieTokenStore(this, this.callbackHandler); + } + } + + @Override + public Request getRequest() { + return new Request() { + @Override + public String getMethod() { + return request.getRequestMethod(); + } + + @Override + public String getURI() { + try { + return URLDecoder.decode(request.getRequestURI().toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Failed to decode request URI", e); + } + } + + @Override + public String getRelativePath() { + return request.getRequestPath(); + } + + @Override + public boolean isSecure() { + return request.getRequestURI().getScheme().equals("https"); + } + + @Override + public String getFirstParam(String param) { + throw new RuntimeException("Not implemented."); + } + + @Override + public String getQueryParamValue(String param) { + URI requestURI = request.getRequestURI(); + String query = requestURI.getQuery(); + if (query != null) { + String[] parameters = query.split("&"); + for (String parameter : parameters) { + String[] keyValue = parameter.split("="); + if (keyValue[0].equals(param)) { + return keyValue[1]; + } + } + } + return null; + } + + @Override + public Cookie getCookie(final String cookieName) { + List cookies = request.getCookies(); + + if (cookies != null) { + for (HttpServerCookie cookie : cookies) { + if (cookie.getName().equals(cookieName)) { + return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath()); + } + } + } + + return null; + } + + @Override + public String getHeader(String name) { + return request.getFirstRequestHeaderValue(name); + } + + @Override + public List getHeaders(String name) { + return request.getRequestHeaderValues(name); + } + + @Override + public InputStream getInputStream() { + return request.getInputStream(); + } + + @Override + public String getRemoteAddr() { + InetSocketAddress sourceAddress = request.getSourceAddress(); + if (sourceAddress == null) { + return ""; + } + InetAddress address = sourceAddress.getAddress(); + if (address == null) { + // this is unresolved, so we just return the host name not exactly spec, but if the name should be + // resolved then a PeerNameResolvingHandler should be used and this is probably better than just + // returning null + return sourceAddress.getHostString(); + } + return address.getHostAddress(); + } + + @Override + public void setError(AuthenticationError error) { + request.getScope(Scope.EXCHANGE).setAttachment(AuthenticationError.class.getName(), error); + } + + @Override + public void setError(LogoutError error) { + request.getScope(Scope.EXCHANGE).setAttachment(LogoutError.class.getName(), error); + } + }; + } + + @Override + public Response getResponse() { + return new Response() { + @Override + public void setStatus(final int status) { + responseConsumer = responseConsumer.andThen(response -> response.setStatusCode(status)); + } + + @Override + public void addHeader(final String name, final String value) { + responseConsumer = responseConsumer.andThen(response -> response.addResponseHeader(name, value)); + } + + @Override + public void setHeader(String name, String value) { + addHeader(name, value); + } + + @Override + public void resetCookie(final String name, final String path) { + responseConsumer = responseConsumer.andThen(response -> setCookie(name, "", path, null, 0, false, false, response)); + } + + @Override + public void setCookie(final String name, final String value, final String path, final String domain, final int maxAge, final boolean secure, final boolean httpOnly) { + responseConsumer = responseConsumer.andThen(response -> setCookie(name, value, path, domain, maxAge, secure, httpOnly, response)); + } + + private void setCookie(final String name, final String value, final String path, final String domain, final int maxAge, final boolean secure, final boolean httpOnly, HttpServerResponse response) { + response.setResponseCookie(new HttpServerCookie() { + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getDomain() { + return domain; + } + + @Override + public int getMaxAge() { + return maxAge; + } + + @Override + public String getPath() { + return path; + } + + @Override + public boolean isSecure() { + return secure; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public boolean isHttpOnly() { + return httpOnly; + } + }); + } + + @Override + public OutputStream getOutputStream() { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + responseConsumer = responseConsumer.andThen(new Consumer() { + @Override + public void accept(HttpServerResponse httpServerResponse) { + try { + httpServerResponse.getOutputStream().write(stream.toByteArray()); + } catch (IOException e) { + throw new RuntimeException("Failed to write to response output stream", e); + } + } + }); + return stream; + } + + @Override + public void sendError(int code) { + setStatus(code); + } + + @Override + public void sendError(final int code, final String message) { + responseConsumer = responseConsumer.andThen(response -> { + response.setStatusCode(code); + response.addResponseHeader("Content-Type", "text/html"); + try { + response.getOutputStream().write(message.getBytes()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + @Override + public void end() { + + } + }; + } + + @Override + public X509Certificate[] getCertificateChain() { + return new X509Certificate[0]; + } + + @Override + public KeycloakSecurityContext getSecurityContext() { + if (account == null) { + return null; + } + return this.account.getKeycloakSecurityContext(); + } + + public boolean restoreRequest() { + restored = this.request.resumeRequest(); + return restored; + } + + public void suspendRequest() { + responseConsumer = responseConsumer.andThen(httpServerResponse -> request.suspendRequest()); + } + + public boolean isAuthorized() { + return this.securityIdentity != null; + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronRequestAuthenticator.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronRequestAuthenticator.java new file mode 100644 index 0000000000..643a71660d --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronRequestAuthenticator.java @@ -0,0 +1,86 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.BearerTokenRequestAuthenticator; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.OAuthRequestAuthenticator; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.adapters.RequestAuthenticator; +import org.keycloak.adapters.spi.AuthOutcome; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.Scope; + +import javax.security.auth.callback.CallbackHandler; + +/** + * @author Pedro Igor + */ +public class ElytronRequestAuthenticator extends RequestAuthenticator { + + public ElytronRequestAuthenticator(CallbackHandler callbackHandler, ElytronHttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort) { + super(facade, deployment, facade.getTokenStore(), sslRedirectPort); + } + + @Override + public AuthOutcome authenticate() { + AuthOutcome authenticate = super.authenticate(); + + if (AuthOutcome.AUTHENTICATED.equals(authenticate)) { + if (!getElytronHttpFacade().isAuthorized()) { + return AuthOutcome.FAILED; + } + } + + return authenticate; + } + + @Override + protected OAuthRequestAuthenticator createOAuthAuthenticator() { + return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore); + } + + @Override + protected void completeOAuthAuthentication(final KeycloakPrincipal principal) { + getElytronHttpFacade().authenticationComplete(new ElytronAccount(principal), true); + } + + @Override + protected void completeBearerAuthentication(KeycloakPrincipal principal, String method) { + getElytronHttpFacade().authenticationComplete(new ElytronAccount(principal), false); + } + + @Override + protected String changeHttpSessionId(boolean create) { + HttpScope session = getElytronHttpFacade().getScope(Scope.SESSION); + + if (create) { + if (!session.exists()) { + session.create(); + } + } + + return session != null ? session.getID() : null; + } + + private ElytronHttpFacade getElytronHttpFacade() { + return (ElytronHttpFacade) facade; + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronSessionTokenStore.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronSessionTokenStore.java new file mode 100644 index 0000000000..385a8a6d43 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronSessionTokenStore.java @@ -0,0 +1,202 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import java.util.function.Consumer; + +import javax.security.auth.callback.CallbackHandler; + +import org.jboss.logging.Logger; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.AdapterTokenStore; +import org.keycloak.adapters.AdapterUtils; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.OidcKeycloakAccount; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.adapters.RequestAuthenticator; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.HttpScopeNotification; +import org.wildfly.security.http.Scope; + +/** + * @author Pedro Igor + */ +public class ElytronSessionTokenStore implements ElytronTokeStore { + + private static Logger log = Logger.getLogger(ElytronSessionTokenStore.class); + + private final ElytronHttpFacade httpFacade; + private final CallbackHandler callbackHandler; + + public ElytronSessionTokenStore(ElytronHttpFacade httpFacade, CallbackHandler callbackHandler) { + this.httpFacade = httpFacade; + this.callbackHandler = callbackHandler; + } + + @Override + public void checkCurrentToken() { + HttpScope session = httpFacade.getScope(Scope.SESSION); + if (!session.exists()) return; + RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) session.getAttachment(KeycloakSecurityContext.class.getName()); + if (securityContext == null) return; + + // just in case session got serialized + if (securityContext.getDeployment() == null) securityContext.setCurrentRequestInfo(httpFacade.getDeployment(), this); + + if (securityContext.isActive() && !securityContext.getDeployment().isAlwaysRefreshToken()) return; + + // FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will + // not be updated + boolean success = securityContext.refreshExpiredToken(false); + if (success && securityContext.isActive()) return; + + // Refresh failed, so user is already logged out from keycloak. Cleanup and expire our session + session.setAttachment(KeycloakSecurityContext.class.getName(), null); + session.invalidate(); + } + + @Override + public boolean isCached(RequestAuthenticator authenticator) { + HttpScope session = this.httpFacade.getScope(Scope.SESSION); + + if (session == null) { + log.debug("session was null, returning null"); + return false; + } + + ElytronAccount account; + + try { + account = (ElytronAccount) session.getAttachment(ElytronAccount.class.getName()); + } catch (IllegalStateException e) { + log.debug("session was invalidated. Return false."); + return false; + } + if (account == null) { + log.debug("Account was not in session, returning null"); + return false; + } + + KeycloakDeployment deployment = httpFacade.getDeployment(); + + if (!deployment.getRealm().equals(account.getKeycloakSecurityContext().getRealm())) { + log.debug("Account in session belongs to a different realm than for this request."); + return false; + } + + boolean active = account.checkActive(); + + if (!active) { + active = account.tryRefresh(this.callbackHandler); + } + + if (active) { + log.debug("Cached account found"); + restoreRequest(); + httpFacade.authenticationComplete(account, true); + return true; + } else { + log.debug("Refresh failed. Account was not active. Returning null and invalidating Http session"); + try { + session.setAttachment(KeycloakSecurityContext.class.getName(), null); + session.setAttachment(ElytronAccount.class.getName(), null); + session.invalidate(); + } catch (Exception e) { + log.debug("Failed to invalidate session, might already be invalidated"); + } + return false; + } + } + + @Override + public void saveAccountInfo(OidcKeycloakAccount account) { + HttpScope session = this.httpFacade.getScope(Scope.SESSION); + + if (!session.exists()) { + session.create(); + } + + session.setAttachment(ElytronAccount.class.getName(), account); + session.setAttachment(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext()); + + session.registerForNotification(httpScopeNotification -> { + if (!httpScopeNotification.isOfType(HttpScopeNotification.SessionNotificationType.UNDEPLOY)) { + logout(); + } + }); + + HttpScope scope = this.httpFacade.getScope(Scope.EXCHANGE); + + scope.setAttachment(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext()); + } + + @Override + public void logout() { + logout(false); + } + + @Override + public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) { + KeycloakPrincipal principal = new KeycloakPrincipal(AdapterUtils.getPrincipalName(this.httpFacade.getDeployment(), securityContext.getToken()), securityContext); + saveAccountInfo(new ElytronAccount(principal)); + } + + @Override + public void saveRequest() { + this.httpFacade.suspendRequest(); + } + + @Override + public boolean restoreRequest() { + return this.httpFacade.restoreRequest(); + } + + @Override + public void logout(boolean glo) { + HttpScope session = this.httpFacade.getScope(Scope.SESSION); + + if (!session.exists()) { + return; + } + + try { + if (glo) { + KeycloakSecurityContext ksc = (KeycloakSecurityContext) session.getAttachment(KeycloakSecurityContext.class.getName()); + + if (ksc == null) { + return; + } + + KeycloakDeployment deployment = httpFacade.getDeployment(); + + if (!deployment.isBearerOnly() && ksc != null && ksc instanceof RefreshableKeycloakSecurityContext) { + ((RefreshableKeycloakSecurityContext) ksc).logout(deployment); + } + } + + session.setAttachment(KeycloakSecurityContext.class.getName(), null); + session.setAttachment(ElytronAccount.class.getName(), null); + session.invalidate(); + } catch (IllegalStateException ise) { + // Session may be already logged-out in case that app has adminUrl + log.debugf("Session %s logged-out already", session.getID()); + } + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronTokeStore.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronTokeStore.java new file mode 100644 index 0000000000..dc1486eb85 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/ElytronTokeStore.java @@ -0,0 +1,26 @@ +/* + * 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.adapters.elytron; + +import org.keycloak.adapters.AdapterTokenStore; + +/** + * @author Pedro Igor + */ +public interface ElytronTokeStore extends AdapterTokenStore { + void logout(boolean glo); +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakConfigurationServletListener.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakConfigurationServletListener.java new file mode 100644 index 0000000000..ad8e9d5215 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakConfigurationServletListener.java @@ -0,0 +1,109 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.KeycloakDeploymentBuilder; +import org.keycloak.constants.AdapterConstants; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + *

A {@link ServletContextListener} that parses the keycloak adapter configuration and set the same configuration + * as a {@link ServletContext} attribute in order to provide to {@link KeycloakHttpServerAuthenticationMechanism} a way + * to obtain the configuration when processing requests. + * + *

This listener should be automatically registered to a deployment using the subsystem. + * + * @author Pedro Igor + */ +public class KeycloakConfigurationServletListener implements ServletContextListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext servletContext = sce.getServletContext(); + String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver"); + KeycloakConfigResolver configResolver; + AdapterDeploymentContext deploymentContext; + + if (configResolverClass != null) { + try { + configResolver = (KeycloakConfigResolver) servletContext.getClassLoader().loadClass(configResolverClass).newInstance(); + deploymentContext = new AdapterDeploymentContext(configResolver); + } catch (Exception ex) { + deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment()); + } + } else { + InputStream is = getConfigInputStream(servletContext); + + KeycloakDeployment deployment; + + if (is == null) { + deployment = new KeycloakDeployment(); + } else { + deployment = KeycloakDeploymentBuilder.build(is); + } + + deploymentContext = new AdapterDeploymentContext(deployment); + } + + servletContext.setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + } + + private InputStream getConfigInputStream(ServletContext servletContext) { + InputStream is = getJSONFromServletContext(servletContext); + + if (is == null) { + String path = servletContext.getInitParameter("keycloak.config.file"); + + if (path == null) { + is = servletContext.getResourceAsStream("/WEB-INF/keycloak.json"); + } else { + try { + is = new FileInputStream(path); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + } + return is; + } + + private InputStream getJSONFromServletContext(ServletContext servletContext) { + String json = servletContext.getInitParameter(AdapterConstants.AUTH_DATA_PARAM_NAME); + + if (json == null) { + return null; + } + + return new ByteArrayInputStream(json.getBytes()); + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java new file mode 100644 index 0000000000..3fcf9bf484 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanism.java @@ -0,0 +1,168 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; + +import org.jboss.logging.Logger; +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.AuthenticatedActionsHandler; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.NodesRegistrationManagement; +import org.keycloak.adapters.PreAuthActionsHandler; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.adapters.RequestAuthenticator; +import org.keycloak.adapters.spi.AuthChallenge; +import org.keycloak.adapters.spi.AuthOutcome; +import org.keycloak.adapters.spi.UserSessionManagement; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.HttpServerAuthenticationMechanism; +import org.wildfly.security.http.HttpServerRequest; +import org.wildfly.security.http.Scope; + +/** + * @author Pedro Igor + */ +class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticationMechanism { + + static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanismFactory.class); + static final String NAME = "KEYCLOAK"; + + private final Map properties; + private final CallbackHandler callbackHandler; + private final AdapterDeploymentContext deploymentContext; + + public KeycloakHttpServerAuthenticationMechanism(Map properties, CallbackHandler callbackHandler, AdapterDeploymentContext deploymentContext) { + this.properties = properties; + this.callbackHandler = callbackHandler; + this.deploymentContext = deploymentContext; + } + + @Override + public String getMechanismName() { + return NAME; + } + + @Override + public void evaluateRequest(HttpServerRequest request) throws HttpAuthenticationException { + LOGGER.debugf("Evaluating request for path [%s]", request.getRequestURI()); + AdapterDeploymentContext deploymentContext = getDeploymentContext(request); + + if (deploymentContext == null) { + LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI()); + request.noAuthenticationInProgress(); + return; + } + + ElytronHttpFacade httpFacade = new ElytronHttpFacade(request, deploymentContext, callbackHandler); + KeycloakDeployment deployment = httpFacade.getDeployment(); + + if (!deployment.isConfigured()) { + request.noAuthenticationInProgress(); + return; + } + + RequestAuthenticator authenticator = createRequestAuthenticator(request, httpFacade, deployment); + + httpFacade.getTokenStore().checkCurrentToken(); + + if (preActions(httpFacade, deploymentContext)) { + LOGGER.debugf("Pre-actions has aborted the evaluation of [%s]", request.getRequestURI()); + httpFacade.authenticationInProgress(); + return; + } + + AuthOutcome outcome = authenticator.authenticate(); + + if (AuthOutcome.AUTHENTICATED.equals(outcome)) { + if (new AuthenticatedActionsHandler(deployment, httpFacade).handledRequest()) { + httpFacade.authenticationInProgress(); + } else { + httpFacade.authenticationComplete(); + } + return; + } + + AuthChallenge challenge = authenticator.getChallenge(); + + if (challenge != null) { + httpFacade.noAuthenticationInProgress(challenge); + return; + } + + if (AuthOutcome.FAILED.equals(outcome)) { + httpFacade.getResponse().setStatus(403); + httpFacade.authenticationFailed(); + return; + } + + httpFacade.noAuthenticationInProgress(); + } + + private ElytronRequestAuthenticator createRequestAuthenticator(HttpServerRequest request, ElytronHttpFacade httpFacade, KeycloakDeployment deployment) { + return new ElytronRequestAuthenticator(this.callbackHandler, httpFacade, deployment, getConfidentialPort(request)); + } + + private AdapterDeploymentContext getDeploymentContext(HttpServerRequest request) { + if (this.deploymentContext == null) { + return (AdapterDeploymentContext) request.getScope(Scope.APPLICATION).getAttachment(AdapterDeploymentContext.class.getName()); + } + + return this.deploymentContext; + } + + private boolean preActions(ElytronHttpFacade httpFacade, AdapterDeploymentContext deploymentContext) { + NodesRegistrationManagement nodesRegistrationManagement = new NodesRegistrationManagement(); + + nodesRegistrationManagement.tryRegister(httpFacade.getDeployment()); + + PreAuthActionsHandler preActions = new PreAuthActionsHandler(new UserSessionManagement() { + @Override + public void logoutAll() { + Collection sessions = httpFacade.getScopeIds(Scope.SESSION); + logoutHttpSessions(new ArrayList<>(sessions)); + } + + @Override + public void logoutHttpSessions(List ids) { + for (String id : ids) { + HttpScope session = httpFacade.getScope(Scope.SESSION, id); + + if (session != null) { + session.invalidate(); + } + } + + } + }, deploymentContext, httpFacade); + + return preActions.handleRequest(); + } + + // TODO: obtain confidential port from Elytron + private int getConfidentialPort(HttpServerRequest request) { + return 8443; + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java new file mode 100644 index 0000000000..eb6b333310 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java @@ -0,0 +1,67 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import org.keycloak.adapters.AdapterDeploymentContext; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpServerAuthenticationMechanism; +import org.wildfly.security.http.HttpServerAuthenticationMechanismFactory; + +import javax.security.auth.callback.CallbackHandler; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Pedro Igor + */ +public class KeycloakHttpServerAuthenticationMechanismFactory implements HttpServerAuthenticationMechanismFactory { + + private final AdapterDeploymentContext deploymentContext; + + /** + *

Creates a new instance. + * + *

A default constructor is necessary in order to allow this factory to be loaded via {@link java.util.ServiceLoader}. + */ + public KeycloakHttpServerAuthenticationMechanismFactory() { + this(null); + } + + public KeycloakHttpServerAuthenticationMechanismFactory(AdapterDeploymentContext deploymentContext) { + this.deploymentContext = deploymentContext; + } + + @Override + public String[] getMechanismNames(Map properties) { + return new String[] {KeycloakHttpServerAuthenticationMechanism.NAME}; + } + + @Override + public HttpServerAuthenticationMechanism createAuthenticationMechanism(String mechanismName, Map properties, CallbackHandler callbackHandler) throws HttpAuthenticationException { + Map mechanismProperties = new HashMap(); + + mechanismProperties.putAll(properties); + + if (KeycloakHttpServerAuthenticationMechanism.NAME.equals(mechanismName)) { + return new KeycloakHttpServerAuthenticationMechanism(properties, callbackHandler, this.deploymentContext); + } + + return null; + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakSecurityRealm.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakSecurityRealm.java new file mode 100644 index 0000000000..6042ec82d1 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/KeycloakSecurityRealm.java @@ -0,0 +1,103 @@ +/* + * 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.adapters.elytron; + +import java.security.Principal; +import java.util.Set; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.AdapterUtils; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.wildfly.security.auth.SupportLevel; +import org.wildfly.security.auth.server.RealmIdentity; +import org.wildfly.security.auth.server.RealmUnavailableException; +import org.wildfly.security.auth.server.SecurityRealm; +import org.wildfly.security.authz.Attributes; +import org.wildfly.security.authz.AuthorizationIdentity; +import org.wildfly.security.authz.MapAttributes; +import org.wildfly.security.authz.RoleDecoder; +import org.wildfly.security.credential.Credential; +import org.wildfly.security.evidence.Evidence; + +/** + * @author Pedro Igor + */ +public class KeycloakSecurityRealm implements SecurityRealm { + + @Override + public RealmIdentity getRealmIdentity(Principal principal) throws RealmUnavailableException { + if (principal instanceof KeycloakPrincipal) { + return createRealmIdentity((KeycloakPrincipal) principal); + } + return RealmIdentity.NON_EXISTENT; + } + + private RealmIdentity createRealmIdentity(KeycloakPrincipal principal) { + return new RealmIdentity() { + @Override + public Principal getRealmIdentityPrincipal() { + return principal; + } + + @Override + public SupportLevel getCredentialAcquireSupport(Class credentialType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.UNSUPPORTED; + } + + @Override + public C getCredential(Class credentialType) throws RealmUnavailableException { + return null; + } + + @Override + public SupportLevel getEvidenceVerifySupport(Class evidenceType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.SUPPORTED; + } + + @Override + public boolean verifyEvidence(Evidence evidence) throws RealmUnavailableException { + return principal != null; + } + + @Override + public boolean exists() throws RealmUnavailableException { + return principal != null; + } + + @Override + public AuthorizationIdentity getAuthorizationIdentity() throws RealmUnavailableException { + RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) principal.getKeycloakSecurityContext(); + Attributes attributes = new MapAttributes(); + Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext); + + attributes.addAll(RoleDecoder.KEY_ROLES, roles); + + return AuthorizationIdentity.basicIdentity(attributes); + } + }; + } + + @Override + public SupportLevel getCredentialAcquireSupport(Class credentialType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.UNSUPPORTED; + } + + @Override + public SupportLevel getEvidenceVerifySupport(Class evidenceType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.POSSIBLY_SUPPORTED; + } +} diff --git a/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/SecurityIdentityUtil.java b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/SecurityIdentityUtil.java new file mode 100644 index 0000000000..28f6eb9094 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/java/org/keycloak/adapters/elytron/SecurityIdentityUtil.java @@ -0,0 +1,82 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 Red Hat, Inc., and individual 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.adapters.elytron; + +import java.io.IOException; +import java.security.Principal; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.wildfly.security.auth.callback.AuthenticationCompleteCallback; +import org.wildfly.security.auth.callback.EvidenceVerifyCallback; +import org.wildfly.security.auth.callback.SecurityIdentityCallback; +import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.evidence.Evidence; +import org.wildfly.security.http.HttpAuthenticationException; + +/** + * @author Pedro Igor + */ +final class SecurityIdentityUtil { + + static final SecurityIdentity authorize(CallbackHandler callbackHandler, Principal principal) { + try { + EvidenceVerifyCallback evidenceVerifyCallback = new EvidenceVerifyCallback(new Evidence() { + @Override + public Principal getPrincipal() { + return principal; + } + }); + + callbackHandler.handle(new Callback[]{evidenceVerifyCallback}); + + if (evidenceVerifyCallback.isVerified()) { + AuthorizeCallback authorizeCallback = new AuthorizeCallback(null, null); + + try { + callbackHandler.handle(new Callback[] {authorizeCallback}); + + authorizeCallback.isAuthorized(); + } catch (Exception e) { + throw new HttpAuthenticationException(e); + } + + SecurityIdentityCallback securityIdentityCallback = new SecurityIdentityCallback(); + + callbackHandler.handle(new Callback[]{AuthenticationCompleteCallback.SUCCEEDED, securityIdentityCallback}); + + SecurityIdentity securityIdentity = securityIdentityCallback.getSecurityIdentity(); + + return securityIdentity; + } + } catch (UnsupportedCallbackException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return null; + } + +} diff --git a/adapters/oidc/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory b/adapters/oidc/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory new file mode 100644 index 0000000000..96a0441f32 --- /dev/null +++ b/adapters/oidc/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory @@ -0,0 +1,19 @@ +# +# JBoss, Home of Professional Open Source. +# Copyright 2016 Red Hat, Inc., and individual 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. +# + +org.keycloak.adapters.elytron.KeycloakHttpServerAuthenticationMechanismFactory \ No newline at end of file diff --git a/adapters/oidc/wildfly/pom.xml b/adapters/oidc/wildfly/pom.xml index 982ec22537..6b9cd8f879 100755 --- a/adapters/oidc/wildfly/pom.xml +++ b/adapters/oidc/wildfly/pom.xml @@ -32,7 +32,20 @@ wildfly-adapter - wf8-subsystem wildfly-subsystem + + + + community + + + !product + + + + wf8-subsystem + + + \ No newline at end of file diff --git a/adapters/oidc/wildfly/wildfly-adapter/pom.xml b/adapters/oidc/wildfly/wildfly-adapter/pom.xml old mode 100755 new mode 100644 diff --git a/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java b/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java old mode 100755 new mode 100644 diff --git a/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java b/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java old mode 100755 new mode 100644 diff --git a/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java b/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java old mode 100755 new mode 100644 diff --git a/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java b/adapters/oidc/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java old mode 100755 new mode 100644 diff --git a/adapters/oidc/wildfly/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension b/adapters/oidc/wildfly/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension old mode 100755 new mode 100644 diff --git a/adapters/saml/as7-eap6/pom.xml b/adapters/saml/as7-eap6/pom.xml index 667dad5126..aca1189ba4 100755 --- a/adapters/saml/as7-eap6/pom.xml +++ b/adapters/saml/as7-eap6/pom.xml @@ -30,6 +30,18 @@ keycloak-saml-eap-integration-pom pom + + + + org.jboss.as + jboss-as-parent + ${jboss.as.version} + pom + import + + + + adapter subsystem diff --git a/adapters/saml/as7-eap6/subsystem/pom.xml b/adapters/saml/as7-eap6/subsystem/pom.xml index a3d76a6e8c..93aed3a74b 100755 --- a/adapters/saml/as7-eap6/subsystem/pom.xml +++ b/adapters/saml/as7-eap6/subsystem/pom.xml @@ -88,7 +88,6 @@ org.jboss.logging jboss-logging - 3.1.0.GA diff --git a/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java b/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java index f9a1e77c29..280c3fe459 100755 --- a/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java +++ b/adapters/saml/core-public/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java @@ -24,6 +24,7 @@ import java.io.Serializable; import java.security.Principal; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -31,6 +32,9 @@ import java.util.Set; * @version $Revision: 1 $ */ public class SamlPrincipal implements Serializable, Principal { + + public static final String DEFAULT_ROLE_ATTRIBUTE_NAME = "Roles"; + private MultivaluedHashMap attributes = new MultivaluedHashMap<>(); private MultivaluedHashMap friendlyAttributes = new MultivaluedHashMap<>(); private String name; @@ -98,6 +102,15 @@ public class SamlPrincipal implements Serializable, Principal { } + /** + * Convenience function that gets the attributes associated with this principal + * + * @return attributes associated with this principal + */ + public Map> getAttributes() { + return Collections.unmodifiableMap(attributes); + } + /** * Convenience function that gets Attribute value by attribute friendly name * diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java index cb9b4d9fd7..550eeeb616 100644 --- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java +++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java @@ -17,6 +17,8 @@ package org.keycloak.adapters.saml.profile; +import static org.keycloak.adapters.saml.SamlPrincipal.DEFAULT_ROLE_ATTRIBUTE_NAME; + import org.jboss.logging.Logger; import org.keycloak.adapters.saml.AbstractInitiateLogin; import org.keycloak.adapters.saml.OnSessionCreated; @@ -422,6 +424,11 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic } } } + + // roles should also be there as regular attributes + // this mainly required for elytron and its ABAC nature + attributes.put(DEFAULT_ROLE_ATTRIBUTE_NAME, new ArrayList<>(roles)); + if (deployment.getPrincipalNamePolicy() == SamlDeployment.PrincipalNamePolicy.FROM_ATTRIBUTE) { if (deployment.getPrincipalAttributeName() != null) { String attribute = attributes.getFirst(deployment.getPrincipalAttributeName()); diff --git a/adapters/saml/pom.xml b/adapters/saml/pom.xml index 614646d37a..0f6305bdf1 100755 --- a/adapters/saml/pom.xml +++ b/adapters/saml/pom.xml @@ -35,9 +35,23 @@ core undertow tomcat - jetty wildfly as7-eap6 servlet-filter + wildfly-elytron + + + + community + + + !product + + + + jetty + + + diff --git a/adapters/saml/tomcat/pom.xml b/adapters/saml/tomcat/pom.xml index 85a5978c27..078515692e 100755 --- a/adapters/saml/tomcat/pom.xml +++ b/adapters/saml/tomcat/pom.xml @@ -32,8 +32,21 @@ tomcat-core - tomcat6 - tomcat7 tomcat8 + + + + community + + + !product + + + + tomcat6 + tomcat7 + + + diff --git a/adapters/saml/wildfly-elytron/pom.xml b/adapters/saml/wildfly-elytron/pom.xml new file mode 100755 index 0000000000..51af38019b --- /dev/null +++ b/adapters/saml/wildfly-elytron/pom.xml @@ -0,0 +1,102 @@ + + + + + + keycloak-parent + org.keycloak + 3.1.0.CR1-SNAPSHOT + ../../../pom.xml + + 4.0.0 + + keycloak-saml-wildfly-elytron-adapter + Keycloak WildFly Elytron SAML Adapter + + + + 1.8 + 1.8 + + + + + org.keycloak + keycloak-adapter-core + provided + + + org.keycloak + keycloak-saml-core + provided + + + org.keycloak + keycloak-adapter-spi + provided + + + org.keycloak + keycloak-common + provided + + + org.keycloak + keycloak-saml-adapter-api-public + provided + + + org.keycloak + keycloak-saml-adapter-core + provided + + + org.jboss.logging + jboss-logging + provided + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + provided + + + org.wildfly.security + wildfly-elytron + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java new file mode 100644 index 0000000000..88e96f8bd3 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronHttpFacade.java @@ -0,0 +1,377 @@ +/* + * 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.adapters.saml.elytron; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URLDecoder; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.cert.X509Certificate; + +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlDeploymentContext; +import org.keycloak.adapters.saml.SamlSession; +import org.keycloak.adapters.saml.SamlSessionStore; +import org.keycloak.adapters.spi.AuthChallenge; +import org.keycloak.adapters.spi.AuthenticationError; +import org.keycloak.adapters.spi.HttpFacade; +import org.keycloak.adapters.spi.LogoutError; +import org.keycloak.adapters.spi.SessionIdMapper; +import org.wildfly.security.auth.callback.AnonymousAuthorizationCallback; +import org.wildfly.security.auth.callback.AuthenticationCompleteCallback; +import org.wildfly.security.auth.callback.SecurityIdentityCallback; +import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.HttpServerCookie; +import org.wildfly.security.http.HttpServerMechanismsResponder; +import org.wildfly.security.http.HttpServerRequest; +import org.wildfly.security.http.HttpServerResponse; +import org.wildfly.security.http.Scope; + +/** + * @author Pedro Igor + */ +class ElytronHttpFacade implements HttpFacade { + + private final HttpServerRequest request; + private final CallbackHandler callbackHandler; + private final SamlDeploymentContext deploymentContext; + private final SamlSessionStore sessionStore; + private Consumer responseConsumer; + private SecurityIdentity securityIdentity; + private boolean restored; + private SamlSession samlSession; + + public ElytronHttpFacade(HttpServerRequest request, SessionIdMapper idMapper, SamlDeploymentContext deploymentContext, CallbackHandler handler) { + this.request = request; + this.deploymentContext = deploymentContext; + this.callbackHandler = handler; + this.responseConsumer = response -> {}; + this.sessionStore = createTokenStore(idMapper); + } + + private SamlSessionStore createTokenStore(SessionIdMapper idMapper) { + return new ElytronSamlSessionStore(this, idMapper, getDeployment()); + } + + void authenticationComplete(SamlSession samlSession) { + this.samlSession = samlSession; + } + + void authenticationComplete() { + this.securityIdentity = SecurityIdentityUtil.authorize(this.callbackHandler, samlSession.getPrincipal()); + this.request.authenticationComplete(response -> { + if (!restored) { + responseConsumer.accept(response); + } + }, () -> ((ElytronTokeStore) sessionStore).logout(true)); + } + + void authenticationCompleteAnonymous() { + try { + AnonymousAuthorizationCallback anonymousAuthorizationCallback = new AnonymousAuthorizationCallback(null); + + callbackHandler.handle(new Callback[]{anonymousAuthorizationCallback}); + + if (anonymousAuthorizationCallback.isAuthorized()) { + callbackHandler.handle(new Callback[]{AuthenticationCompleteCallback.SUCCEEDED, new SecurityIdentityCallback()}); + } + + request.authenticationComplete(response -> response.forward(getRequest().getRelativePath())); + } catch (Exception e) { + throw new RuntimeException("Unexpected error processing callbacks during logout.", e); + } + } + + void authenticationFailed() { + this.request.authenticationFailed("Authentication Failed", response -> responseConsumer.accept(response)); + } + + void noAuthenticationInProgress(AuthChallenge challenge) { + if (challenge != null) { + challenge.challenge(this); + } + this.request.noAuthenticationInProgress(response -> responseConsumer.accept(response)); + } + + void authenticationInProgress() { + this.request.authenticationInProgress(response -> responseConsumer.accept(response)); + } + + HttpScope getScope(Scope scope) { + return request.getScope(scope); + } + + HttpScope getScope(Scope scope, String id) { + return request.getScope(scope, id); + } + + Collection getScopeIds(Scope scope) { + return request.getScopeIds(scope); + } + + SamlDeployment getDeployment() { + return deploymentContext.resolveDeployment(this); + } + + @Override + public Request getRequest() { + return new Request() { + @Override + public String getMethod() { + return request.getRequestMethod(); + } + + @Override + public String getURI() { + try { + return URLDecoder.decode(request.getRequestURI().toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Failed to decode request URI", e); + } + } + + @Override + public String getRelativePath() { + return request.getRequestPath(); + } + + @Override + public boolean isSecure() { + return request.getRequestURI().getScheme().equals("https"); + } + + @Override + public String getFirstParam(String param) { + return request.getFirstParameterValue(param); + } + + @Override + public String getQueryParamValue(String param) { + return request.getFirstParameterValue(param); + } + + @Override + public Cookie getCookie(final String cookieName) { + List cookies = request.getCookies(); + + if (cookies != null) { + for (HttpServerCookie cookie : cookies) { + if (cookie.getName().equals(cookieName)) { + return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath()); + } + } + } + + return null; + } + + @Override + public String getHeader(String name) { + return request.getFirstRequestHeaderValue(name); + } + + @Override + public List getHeaders(String name) { + return request.getRequestHeaderValues(name); + } + + @Override + public InputStream getInputStream() { + return request.getInputStream(); + } + + @Override + public String getRemoteAddr() { + InetSocketAddress sourceAddress = request.getSourceAddress(); + if (sourceAddress == null) { + return ""; + } + InetAddress address = sourceAddress.getAddress(); + if (address == null) { + // this is unresolved, so we just return the host name not exactly spec, but if the name should be + // resolved then a PeerNameResolvingHandler should be used and this is probably better than just + // returning null + return sourceAddress.getHostString(); + } + return address.getHostAddress(); + } + + @Override + public void setError(AuthenticationError error) { + request.getScope(Scope.EXCHANGE).setAttachment(AuthenticationError.class.getName(), error); + } + + @Override + public void setError(LogoutError error) { + request.getScope(Scope.EXCHANGE).setAttachment(LogoutError.class.getName(), error); + } + }; + } + + @Override + public Response getResponse() { + return new Response() { + @Override + public void setStatus(final int status) { + responseConsumer = responseConsumer.andThen(response -> response.setStatusCode(status)); + } + + @Override + public void addHeader(final String name, final String value) { + responseConsumer = responseConsumer.andThen(response -> response.addResponseHeader(name, value)); + } + + @Override + public void setHeader(String name, String value) { + addHeader(name, value); + } + + @Override + public void resetCookie(final String name, final String path) { + responseConsumer = responseConsumer.andThen(response -> setCookie(name, "", path, null, 0, false, false, response)); + } + + @Override + public void setCookie(final String name, final String value, final String path, final String domain, final int maxAge, final boolean secure, final boolean httpOnly) { + responseConsumer = responseConsumer.andThen(response -> setCookie(name, value, path, domain, maxAge, secure, httpOnly, response)); + } + + private void setCookie(final String name, final String value, final String path, final String domain, final int maxAge, final boolean secure, final boolean httpOnly, HttpServerResponse response) { + response.setResponseCookie(new HttpServerCookie() { + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getDomain() { + return domain; + } + + @Override + public int getMaxAge() { + return maxAge; + } + + @Override + public String getPath() { + return path; + } + + @Override + public boolean isSecure() { + return secure; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public boolean isHttpOnly() { + return httpOnly; + } + }); + } + + @Override + public OutputStream getOutputStream() { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + responseConsumer = responseConsumer.andThen(new Consumer() { + @Override + public void accept(HttpServerResponse httpServerResponse) { + try { + httpServerResponse.getOutputStream().write(stream.toByteArray()); + } catch (IOException e) { + throw new RuntimeException("Failed to write to response output stream", e); + } + } + }); + return stream; + } + + @Override + public void sendError(int code) { + setStatus(code); + } + + @Override + public void sendError(final int code, final String message) { + responseConsumer = responseConsumer.andThen(response -> { + response.setStatusCode(code); + response.addResponseHeader("Content-Type", "text/html"); + try { + response.getOutputStream().write(message.getBytes()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + @Override + public void end() { + + } + }; + } + + @Override + public X509Certificate[] getCertificateChain() { + return new X509Certificate[0]; + } + + public boolean restoreRequest() { + restored = this.request.resumeRequest(); + return restored; + } + + public void suspendRequest() { + responseConsumer = responseConsumer.andThen(httpServerResponse -> request.suspendRequest()); + } + + public boolean isAuthorized() { + return this.securityIdentity != null; + } + + public URI getURI() { + return request.getRequestURI(); + } + + public SamlSessionStore getSessionStore() { + return sessionStore; + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlAuthenticator.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlAuthenticator.java new file mode 100644 index 0000000000..29975edc9c --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlAuthenticator.java @@ -0,0 +1,51 @@ +/* + * 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.adapters.saml.elytron; + +import javax.security.auth.callback.CallbackHandler; + +import org.keycloak.adapters.saml.SamlAuthenticator; +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlSession; +import org.keycloak.adapters.saml.SamlSessionStore; +import org.keycloak.adapters.saml.profile.SamlAuthenticationHandler; +import org.keycloak.adapters.saml.profile.webbrowsersso.BrowserHandler; +import org.keycloak.adapters.spi.HttpFacade; + +/** + * @author Pedro Igor + */ +public class ElytronSamlAuthenticator extends SamlAuthenticator { + private final CallbackHandler callbackHandler; + private final ElytronHttpFacade facade; + + public ElytronSamlAuthenticator(ElytronHttpFacade facade, SamlDeployment samlDeployment, CallbackHandler callbackHandler) { + super(facade, samlDeployment, facade.getSessionStore()); + this.callbackHandler = callbackHandler; + this.facade = facade; + } + + @Override + protected void completeAuthentication(SamlSession samlSession) { + facade.authenticationComplete(samlSession); + } + + @Override + protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) { + return new BrowserHandler(facade, deployment, sessionStore); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlEndpoint.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlEndpoint.java new file mode 100644 index 0000000000..17997e5273 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlEndpoint.java @@ -0,0 +1,39 @@ +/* + * 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.adapters.saml.elytron; + +import org.keycloak.adapters.saml.SamlAuthenticator; +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlSession; + +/** + * @author Pedro Igor + */ +public class ElytronSamlEndpoint extends SamlAuthenticator { + + private final ElytronHttpFacade facade; + + public ElytronSamlEndpoint(ElytronHttpFacade facade, SamlDeployment samlDeployment) { + super(facade, samlDeployment, facade.getSessionStore()); + this.facade = facade; + } + + @Override + protected void completeAuthentication(SamlSession samlSession) { + facade.authenticationComplete(samlSession); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlSessionStore.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlSessionStore.java new file mode 100644 index 0000000000..2ce62928df --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronSamlSessionStore.java @@ -0,0 +1,226 @@ +/* + * 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.adapters.saml.elytron; + +import java.net.URI; +import java.security.Principal; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.jboss.logging.Logger; +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlSession; +import org.keycloak.adapters.saml.SamlSessionStore; +import org.keycloak.adapters.saml.SamlUtil; +import org.keycloak.adapters.spi.SessionIdMapper; +import org.keycloak.common.util.KeycloakUriBuilder; +import org.wildfly.security.http.HttpScope; +import org.wildfly.security.http.Scope; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class ElytronSamlSessionStore implements SamlSessionStore, ElytronTokeStore { + protected static Logger log = Logger.getLogger(SamlSessionStore.class); + public static final String SAML_REDIRECT_URI = "SAML_REDIRECT_URI"; + + private final SessionIdMapper idMapper; + protected final SamlDeployment deployment; + private final ElytronHttpFacade exchange; + + + public ElytronSamlSessionStore(ElytronHttpFacade exchange, SessionIdMapper idMapper, SamlDeployment deployment) { + this.exchange = exchange; + this.idMapper = idMapper; + this.deployment = deployment; + } + + @Override + public void setCurrentAction(CurrentAction action) { + if (action == CurrentAction.NONE && !exchange.getScope(Scope.SESSION).exists()) return; + exchange.getScope(Scope.SESSION).setAttachment(CURRENT_ACTION, action); + } + + @Override + public boolean isLoggingIn() { + HttpScope session = exchange.getScope(Scope.SESSION); + if (!session.exists()) return false; + CurrentAction action = (CurrentAction) session.getAttachment(CURRENT_ACTION); + return action == CurrentAction.LOGGING_IN; + } + + @Override + public boolean isLoggingOut() { + HttpScope session = exchange.getScope(Scope.SESSION); + if (!session.exists()) return false; + CurrentAction action = (CurrentAction) session.getAttachment(CURRENT_ACTION); + return action == CurrentAction.LOGGING_OUT; + } + + @Override + public void logoutAccount() { + HttpScope session = getSession(false); + if (session.exists()) { + SamlSession samlSession = (SamlSession)session.getAttachment(SamlSession.class.getName()); + if (samlSession != null) { + if (samlSession.getSessionIndex() != null) { + idMapper.removeSession(session.getID()); + } + session.setAttachment(SamlSession.class.getName(), null); + } + session.setAttachment(SAML_REDIRECT_URI, null); + } + } + + @Override + public void logoutByPrincipal(String principal) { + Set sessions = idMapper.getUserSessions(principal); + if (sessions != null) { + List ids = new LinkedList<>(); + ids.addAll(sessions); + logoutSessionIds(ids); + for (String id : ids) { + idMapper.removeSession(id); + } + } + + } + + @Override + public void logoutBySsoId(List ssoIds) { + if (ssoIds == null) return; + List sessionIds = new LinkedList<>(); + for (String id : ssoIds) { + String sessionId = idMapper.getSessionFromSSO(id); + if (sessionId != null) { + sessionIds.add(sessionId); + idMapper.removeSession(sessionId); + } + + } + logoutSessionIds(sessionIds); + } + + protected void logoutSessionIds(List sessionIds) { + sessionIds.forEach(id -> { + HttpScope scope = exchange.getScope(Scope.SESSION, id); + + if (scope.exists()) { + scope.invalidate(); + } + }); + } + + @Override + public boolean isLoggedIn() { + HttpScope session = getSession(false); + if (!session.exists()) { + log.debug("session was null, returning null"); + return false; + } + final SamlSession samlSession = (SamlSession)session.getAttachment(SamlSession.class.getName()); + if (samlSession == null) { + log.debug("SamlSession was not in session, returning null"); + return false; + } + + exchange.authenticationComplete(samlSession); + restoreRequest(); + return true; + } + + @Override + public void saveAccount(SamlSession account) { + HttpScope session = getSession(true); + session.setAttachment(SamlSession.class.getName(), account); + String sessionId = changeSessionId(session); + idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), sessionId); + + } + + protected String changeSessionId(HttpScope session) { + if (!deployment.turnOffChangeSessionIdOnLogin()) return session.getID(); + else return session.getID(); + } + + @Override + public SamlSession getAccount() { + HttpScope session = getSession(true); + return (SamlSession)session.getAttachment(SamlSession.class.getName()); + } + + @Override + public String getRedirectUri() { + HttpScope session = exchange.getScope(Scope.SESSION); + String redirect = (String) session.getAttachment(SAML_REDIRECT_URI); + if (redirect == null) { + URI uri = exchange.getURI(); + String path = uri.getPath(); + String relativePath = exchange.getRequest().getRelativePath(); + String contextPath = path.substring(0, path.indexOf(relativePath)); + + if (!contextPath.isEmpty()) { + contextPath = contextPath + "/"; + } + + String baseUri = KeycloakUriBuilder.fromUri(path).replacePath(contextPath).build().toString(); + return SamlUtil.getRedirectTo(exchange, contextPath, baseUri); + } + return redirect; + } + + @Override + public void saveRequest() { + exchange.suspendRequest(); + HttpScope scope = exchange.getScope(Scope.SESSION); + + if (!scope.exists()) { + scope.create(); + } + + KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(exchange.getURI()).replaceQuery(exchange.getURI().getQuery()); + String uri = uriBuilder.build().toString(); + + scope.setAttachment(SAML_REDIRECT_URI, uri); + } + + @Override + public boolean restoreRequest() { + return exchange.restoreRequest(); + } + + protected HttpScope getSession(boolean create) { + HttpScope scope = exchange.getScope(Scope.SESSION); + + if (!scope.exists() && create) { + scope.create(); + } + + return scope; + } + + @Override + public void logout(boolean glo) { + logoutAccount(); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronTokeStore.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronTokeStore.java new file mode 100644 index 0000000000..a658464d3a --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/ElytronTokeStore.java @@ -0,0 +1,24 @@ +/* + * 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.adapters.saml.elytron; + +/** + * @author Pedro Igor + */ +public interface ElytronTokeStore { + void logout(boolean glo); +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakConfigurationServletListener.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakConfigurationServletListener.java new file mode 100644 index 0000000000..94ae5920d3 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakConfigurationServletListener.java @@ -0,0 +1,121 @@ +/* + * 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.adapters.saml.elytron; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.jboss.logging.Logger; +import org.keycloak.adapters.saml.AdapterConstants; +import org.keycloak.adapters.saml.DefaultSamlDeployment; +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlDeploymentContext; +import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder; +import org.keycloak.adapters.saml.config.parsers.ResourceLoader; +import org.keycloak.saml.common.exceptions.ParsingException; + +/** + *

A {@link ServletContextListener} that parses the keycloak adapter configuration and set the same configuration + * as a {@link ServletContext} attribute in order to provide to {@link KeycloakHttpServerAuthenticationMechanism} a way + * to obtain the configuration when processing requests. + * + *

This listener should be automatically registered to a deployment using the subsystem. + * + * @author Pedro Igor + */ +public class KeycloakConfigurationServletListener implements ServletContextListener { + + protected static Logger log = Logger.getLogger(KeycloakConfigurationServletListener.class); + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext servletContext = sce.getServletContext(); + String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver"); + SamlDeploymentContext deploymentContext = null; + if (configResolverClass != null) { + try { + throw new RuntimeException("Not implemented yet"); + //configResolver = (SamlConfigResolver) deploymentInfo.getClassLoader().loadClass(configResolverClass).newInstance(); + //deploymentContext = new AdapterDeploymentContext(configResolver); + //log.info("Using " + configResolverClass + " to resolve Keycloak configuration on a per-request basis."); + } catch (Exception ex) { + log.warn("The specified resolver " + configResolverClass + " could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: " + ex.getMessage()); + //deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment()); + } + } else { + InputStream is = getConfigInputStream(servletContext); + final SamlDeployment deployment; + if (is == null) { + log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests."); + deployment = new DefaultSamlDeployment(); + } else { + try { + ResourceLoader loader = new ResourceLoader() { + @Override + public InputStream getResourceAsStream(String resource) { + return servletContext.getResourceAsStream(resource); + } + }; + deployment = new DeploymentBuilder().build(is, loader); + } catch (ParsingException e) { + throw new RuntimeException(e); + } + } + deploymentContext = new SamlDeploymentContext(deployment); + servletContext.setAttribute(SamlDeploymentContext.class.getName(), deploymentContext); + log.debug("Keycloak is using a per-deployment configuration."); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + } + + private static InputStream getConfigInputStream(ServletContext context) { + InputStream is = getXMLFromServletContext(context); + if (is == null) { + String path = context.getInitParameter("keycloak.config.file"); + if (path == null) { + log.debug("using /WEB-INF/keycloak-saml.xml"); + is = context.getResourceAsStream("/WEB-INF/keycloak-saml.xml"); + } else { + try { + is = new FileInputStream(path); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + } + return is; + } + + private static InputStream getXMLFromServletContext(ServletContext servletContext) { + String json = servletContext.getInitParameter(AdapterConstants.AUTH_DATA_PARAM_NAME); + if (json == null) { + return null; + } + return new ByteArrayInputStream(json.getBytes()); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java new file mode 100644 index 0000000000..9fce501d93 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanism.java @@ -0,0 +1,155 @@ +/* + * 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.adapters.saml.elytron; + +import java.net.URI; +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; + +import org.jboss.logging.Logger; +import org.keycloak.adapters.saml.SamlAuthenticator; +import org.keycloak.adapters.saml.SamlDeployment; +import org.keycloak.adapters.saml.SamlDeploymentContext; +import org.keycloak.adapters.spi.AuthChallenge; +import org.keycloak.adapters.spi.AuthOutcome; +import org.keycloak.adapters.spi.SessionIdMapper; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpServerAuthenticationMechanism; +import org.wildfly.security.http.HttpServerRequest; +import org.wildfly.security.http.Scope; + +/** + * @author Pedro Igor + */ +class KeycloakHttpServerAuthenticationMechanism implements HttpServerAuthenticationMechanism { + + static Logger LOGGER = Logger.getLogger(KeycloakHttpServerAuthenticationMechanismFactory.class); + static final String NAME = "KEYCLOAK-SAML"; + + private final Map properties; + private final CallbackHandler callbackHandler; + private final SamlDeploymentContext deploymentContext; + private final SessionIdMapper idMapper; + + public KeycloakHttpServerAuthenticationMechanism(Map properties, CallbackHandler callbackHandler, SamlDeploymentContext deploymentContext, SessionIdMapper idMapper) { + this.properties = properties; + this.callbackHandler = callbackHandler; + this.deploymentContext = deploymentContext; + this.idMapper = idMapper; + } + + @Override + public String getMechanismName() { + return NAME; + } + + @Override + public void evaluateRequest(HttpServerRequest request) throws HttpAuthenticationException { + LOGGER.debugf("Evaluating request for path [%s]", request.getRequestURI()); + SamlDeploymentContext deploymentContext = getDeploymentContext(request); + + if (deploymentContext == null) { + LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI()); + request.noAuthenticationInProgress(); + return; + } + + ElytronHttpFacade httpFacade = new ElytronHttpFacade(request, idMapper, deploymentContext, callbackHandler); + SamlDeployment deployment = httpFacade.getDeployment(); + + if (!deployment.isConfigured()) { + request.noAuthenticationInProgress(); + return; + } + + if (httpFacade.getRequest().getRelativePath().contains(deployment.getLogoutPage())) { + LOGGER.debugf("Ignoring request for [%s] and logout page [%s].", request.getRequestURI(), deployment.getLogoutPage()); + httpFacade.authenticationCompleteAnonymous(); + return; + } + + SamlAuthenticator authenticator; + + if (httpFacade.getRequest().getRelativePath().endsWith("/saml")) { + authenticator = new ElytronSamlEndpoint(httpFacade, deployment); + } else { + authenticator = new ElytronSamlAuthenticator(httpFacade, deployment, callbackHandler); + + } + + AuthOutcome outcome = authenticator.authenticate(); + + if (outcome == AuthOutcome.AUTHENTICATED) { + httpFacade.authenticationComplete(); + return; + } + + if (outcome == AuthOutcome.NOT_AUTHENTICATED) { + httpFacade.noAuthenticationInProgress(null); + return; + } + + if (outcome == AuthOutcome.LOGGED_OUT) { + if (deployment.getLogoutPage() != null) { + redirectLogout(deployment, httpFacade); + } + httpFacade.authenticationInProgress(); + return; + } + + AuthChallenge challenge = authenticator.getChallenge(); + + if (challenge != null) { + httpFacade.noAuthenticationInProgress(challenge); + return; + } + + if (outcome == AuthOutcome.FAILED) { + httpFacade.authenticationFailed(); + return; + } + + httpFacade.authenticationInProgress(); + } + + private SamlDeploymentContext getDeploymentContext(HttpServerRequest request) { + if (this.deploymentContext == null) { + return (SamlDeploymentContext) request.getScope(Scope.APPLICATION).getAttachment(SamlDeploymentContext.class.getName()); + } + + return this.deploymentContext; + } + + protected void redirectLogout(SamlDeployment deployment, ElytronHttpFacade exchange) { + String page = deployment.getLogoutPage(); + sendRedirect(exchange, page); + exchange.getResponse().setStatus(302); + } + + static void sendRedirect(final ElytronHttpFacade exchange, final String location) { + // TODO - String concatenation to construct URLS is extremely error prone - switch to a URI which will better + // handle this. + URI uri = exchange.getURI(); + String path = uri.getPath(); + String relativePath = exchange.getRequest().getRelativePath(); + String contextPath = path.substring(0, path.indexOf(relativePath)); + String loc = exchange.getURI().getScheme() + "://" + exchange.getURI().getHost() + ":" + exchange.getURI().getPort() + contextPath + location; + exchange.getResponse().setHeader("Location", loc); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java new file mode 100644 index 0000000000..c1b69a4435 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakHttpServerAuthenticationMechanismFactory.java @@ -0,0 +1,70 @@ +/* + * 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.adapters.saml.elytron; + +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.callback.CallbackHandler; + +import org.keycloak.adapters.saml.SamlDeploymentContext; +import org.keycloak.adapters.spi.InMemorySessionIdMapper; +import org.keycloak.adapters.spi.SessionIdMapper; +import org.wildfly.security.http.HttpAuthenticationException; +import org.wildfly.security.http.HttpServerAuthenticationMechanism; +import org.wildfly.security.http.HttpServerAuthenticationMechanismFactory; + +/** + * @author Pedro Igor + */ +public class KeycloakHttpServerAuthenticationMechanismFactory implements HttpServerAuthenticationMechanismFactory { + + private SessionIdMapper idMapper = new InMemorySessionIdMapper(); + private final SamlDeploymentContext deploymentContext; + + /** + *

Creates a new instance. + * + *

A default constructor is necessary in order to allow this factory to be loaded via {@link java.util.ServiceLoader}. + */ + public KeycloakHttpServerAuthenticationMechanismFactory() { + this(null); + } + + public KeycloakHttpServerAuthenticationMechanismFactory(SamlDeploymentContext deploymentContext) { + this.deploymentContext = deploymentContext; + } + + @Override + public String[] getMechanismNames(Map properties) { + return new String[] {KeycloakHttpServerAuthenticationMechanism.NAME}; + } + + @Override + public HttpServerAuthenticationMechanism createAuthenticationMechanism(String mechanismName, Map properties, CallbackHandler callbackHandler) throws HttpAuthenticationException { + Map mechanismProperties = new HashMap(); + + mechanismProperties.putAll(properties); + + if (KeycloakHttpServerAuthenticationMechanism.NAME.equals(mechanismName)) { + return new KeycloakHttpServerAuthenticationMechanism(properties, callbackHandler, this.deploymentContext, idMapper); + } + + return null; + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakSecurityRealm.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakSecurityRealm.java new file mode 100644 index 0000000000..3207835360 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/KeycloakSecurityRealm.java @@ -0,0 +1,109 @@ +/* + * 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.adapters.saml.elytron; + +import java.security.Principal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.keycloak.adapters.saml.SamlPrincipal; +import org.wildfly.security.auth.SupportLevel; +import org.wildfly.security.auth.server.RealmIdentity; +import org.wildfly.security.auth.server.RealmUnavailableException; +import org.wildfly.security.auth.server.SecurityRealm; +import org.wildfly.security.authz.AuthorizationIdentity; +import org.wildfly.security.authz.MapAttributes; +import org.wildfly.security.credential.Credential; +import org.wildfly.security.evidence.BearerTokenEvidence; +import org.wildfly.security.evidence.Evidence; + +/** + * @author Pedro Igor + */ +public class KeycloakSecurityRealm implements SecurityRealm { + + @Override + public RealmIdentity getRealmIdentity(Principal principal) throws RealmUnavailableException { + if (principal instanceof SamlPrincipal) { + return createRealmIdentity((SamlPrincipal) principal); + } + return RealmIdentity.NON_EXISTENT; + } + + private RealmIdentity createRealmIdentity(SamlPrincipal principal) { + return new RealmIdentity() { + @Override + public Principal getRealmIdentityPrincipal() { + return principal; + } + + @Override + public SupportLevel getCredentialAcquireSupport(Class credentialType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.UNSUPPORTED; + } + + @Override + public C getCredential(Class credentialType) throws RealmUnavailableException { + return null; + } + + @Override + public SupportLevel getEvidenceVerifySupport(Class evidenceType, String algorithmName) throws RealmUnavailableException { + if (isBearerTokenEvidence(evidenceType)) { + return SupportLevel.SUPPORTED; + } + + return SupportLevel.UNSUPPORTED; + } + + @Override + public boolean verifyEvidence(Evidence evidence) throws RealmUnavailableException { + return principal != null; + } + + @Override + public boolean exists() throws RealmUnavailableException { + return principal != null; + } + + @Override + public AuthorizationIdentity getAuthorizationIdentity() throws RealmUnavailableException { + Map> attributes = new HashMap<>(principal.getAttributes()); + return AuthorizationIdentity.basicIdentity(new MapAttributes(attributes)); + } + }; + } + + @Override + public SupportLevel getCredentialAcquireSupport(Class credentialType, String algorithmName) throws RealmUnavailableException { + return SupportLevel.UNSUPPORTED; + } + + @Override + public SupportLevel getEvidenceVerifySupport(Class evidenceType, String algorithmName) throws RealmUnavailableException { + if (isBearerTokenEvidence(evidenceType)) { + return SupportLevel.POSSIBLY_SUPPORTED; + } + + return SupportLevel.UNSUPPORTED; + } + + private boolean isBearerTokenEvidence(Class evidenceType) { + return evidenceType != null && evidenceType.equals(BearerTokenEvidence.class); + } +} diff --git a/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/SecurityIdentityUtil.java b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/SecurityIdentityUtil.java new file mode 100644 index 0000000000..ce45db651b --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/java/org/keycloak/adapters/saml/elytron/SecurityIdentityUtil.java @@ -0,0 +1,80 @@ +/* + * 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.adapters.saml.elytron; + +import java.io.IOException; +import java.security.Principal; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; + +import org.keycloak.adapters.saml.SamlPrincipal; +import org.wildfly.security.auth.callback.AuthenticationCompleteCallback; +import org.wildfly.security.auth.callback.EvidenceVerifyCallback; +import org.wildfly.security.auth.callback.SecurityIdentityCallback; +import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.evidence.Evidence; +import org.wildfly.security.http.HttpAuthenticationException; + +/** + * @author Pedro Igor + */ +final class SecurityIdentityUtil { + + static final SecurityIdentity authorize(CallbackHandler callbackHandler, SamlPrincipal principal) { + try { + EvidenceVerifyCallback evidenceVerifyCallback = new EvidenceVerifyCallback(new Evidence() { + @Override + public Principal getPrincipal() { + return principal; + } + }); + + callbackHandler.handle(new Callback[]{evidenceVerifyCallback}); + + if (evidenceVerifyCallback.isVerified()) { + AuthorizeCallback authorizeCallback = new AuthorizeCallback(null, null); + + try { + callbackHandler.handle(new Callback[] {authorizeCallback}); + } catch (Exception e) { + throw new HttpAuthenticationException(e); + } + + if (authorizeCallback.isAuthorized()) { + SecurityIdentityCallback securityIdentityCallback = new SecurityIdentityCallback(); + + callbackHandler.handle(new Callback[]{AuthenticationCompleteCallback.SUCCEEDED, securityIdentityCallback}); + + SecurityIdentity securityIdentity = securityIdentityCallback.getSecurityIdentity(); + + return securityIdentity; + } + } + } catch (UnsupportedCallbackException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return null; + } + +} diff --git a/adapters/saml/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory b/adapters/saml/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory new file mode 100644 index 0000000000..a41c127bd9 --- /dev/null +++ b/adapters/saml/wildfly-elytron/src/main/resources/META-INF/services/org.wildfly.security.http.HttpServerAuthenticationMechanismFactory @@ -0,0 +1,19 @@ +# +# JBoss, Home of Professional Open Source. +# Copyright 2016 Red Hat, Inc., and individual 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. +# + +org.keycloak.adapters.saml.elytron.KeycloakHttpServerAuthenticationMechanismFactory \ No newline at end of file diff --git a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml index bea6742330..a69a607934 100755 --- a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml @@ -93,4 +93,18 @@ + + + product + + + product + + + + ${product.name}-${product.filename.version}-eap6-adapter + + + + diff --git a/distribution/adapters/as7-eap6-adapter/pom.xml b/distribution/adapters/as7-eap6-adapter/pom.xml index 4d4830f244..5d407d8793 100644 --- a/distribution/adapters/as7-eap6-adapter/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/pom.xml @@ -32,7 +32,20 @@ as7-modules - as7-adapter-zip eap6-adapter-zip + + + + community + + + !product + + + + as7-adapter-zip + + + diff --git a/distribution/adapters/js-adapter-zip/pom.xml b/distribution/adapters/js-adapter-zip/pom.xml index 3dafa00f4e..bf4d2656c4 100755 --- a/distribution/adapters/js-adapter-zip/pom.xml +++ b/distribution/adapters/js-adapter-zip/pom.xml @@ -85,4 +85,18 @@ + + + product + + + product + + + + ${product.name}-${product.filename.version}-js-adapter + + + + diff --git a/distribution/adapters/pom.xml b/distribution/adapters/pom.xml index 02b84f1729..e4569ac83e 100755 --- a/distribution/adapters/pom.xml +++ b/distribution/adapters/pom.xml @@ -33,17 +33,31 @@ as7-eap6-adapter fuse-adapter-zip - jetty81-adapter-zip - jetty91-adapter-zip - jetty92-adapter-zip - jetty93-adapter-zip - jetty94-adapter-zip js-adapter-zip osgi - tomcat6-adapter-zip - tomcat7-adapter-zip - tomcat8-adapter-zip - wf8-adapter + wildfly-adapter + + + + community + + + !product + + + + tomcat6-adapter-zip + tomcat7-adapter-zip + tomcat8-adapter-zip + jetty81-adapter-zip + jetty91-adapter-zip + jetty92-adapter-zip + jetty93-adapter-zip + jetty94-adapter-zip + wf8-adapter + + + diff --git a/distribution/adapters/shared-cli/adapter-elytron-install.cli b/distribution/adapters/shared-cli/adapter-elytron-install.cli new file mode 100644 index 0000000000..16f17ce9a8 --- /dev/null +++ b/distribution/adapters/shared-cli/adapter-elytron-install.cli @@ -0,0 +1,57 @@ +if (outcome != success) of /extension=org.keycloak.keycloak-adapter-subsystem:read-resource + /extension=org.keycloak.keycloak-adapter-subsystem/:add(module=org.keycloak.keycloak-adapter-subsystem) +else + echo Keycloak OpenID Connect Extension already installed +end-if + +if (outcome != success) of /subsystem=keycloak:read-resource + /subsystem=keycloak:add +else + echo Keycloak OpenID Connect Subsystem already installed +end-if + +if (outcome != success) of /subsystem=elytron/custom-realm=KeycloakOIDCRealm:read-resource + /subsystem=elytron/custom-realm=KeycloakOIDCRealm:add(class-name=org.keycloak.adapters.elytron.KeycloakSecurityRealm, module=org.keycloak.keycloak-wildfly-elytron-oidc-adapter) +else + echo Keycloak OpenID Connect Realm already installed +end-if + +if (outcome != success) of /subsystem=elytron/security-domain=KeycloakDomain:read-resource + /subsystem=elytron/security-domain=KeycloakDomain:add(default-realm=KeycloakOIDCRealm,permission-mapper=default-permission-mapper,security-event-listener=local-audit,realms=[{realm=KeycloakOIDCRealm}]) +else + echo Keycloak Security Domain already installed. Trying to install Keycloak OpenID Connect Realm. + /subsystem=elytron/security-domain=KeycloakDomain:list-add(name=realms, value={realm=KeycloakOIDCRealm}) +end-if + +if (outcome != success) of /subsystem=elytron/constant-realm-mapper=keycloak-oidc-realm-mapper:read-resource + /subsystem=elytron/constant-realm-mapper=keycloak-oidc-realm-mapper:add(realm-name=KeycloakOIDCRealm) +else + echo Keycloak OpenID Connect Realm Mapper already installed +end-if + +if (outcome != success) of /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-oidc-http-server-mechanism-factory:read-resource + /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-oidc-http-server-mechanism-factory:add(module=org.keycloak.keycloak-wildfly-elytron-oidc-adapter) +else + echo Keycloak OpenID Connect HTTP Mechanism already installed +end-if + +if (outcome != success) of /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:read-resource + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:add(http-server-factories=[keycloak-oidc-http-server-mechanism-factory, global]) +else + echo Keycloak HTTP Mechanism Factory already installed. Trying to install Keycloak OpenID Connect HTTP Mechanism Factory. + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:list-add(name=http-server-factories, value=keycloak-oidc-http-server-mechanism-factory) +end-if + + +if (outcome != success) of /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:read-resource + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:add(security-domain=KeycloakDomain,http-server-mechanism-factory=keycloak-http-server-mechanism-factory,mechanism-configurations=[{mechanism-name=KEYCLOAK,mechanism-realm-configurations=[{realm-name=KeycloakOIDCRealm,realm-mapper=keycloak-oidc-realm-mapper}]}]) +else + echo Keycloak HTTP Authentication Factory already installed. Trying to install Keycloak OpenID Connect Mechanism Configuration + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:list-add(name=mechanism-configurations, value={mechanism-name=KEYCLOAK,mechanism-realm-configurations=[{realm-name=KeycloakOIDCRealm,realm-mapper=keycloak-oidc-realm-mapper}]}) +end-if + +if (outcome != success) of /subsystem=undertow/application-security-domain=other:read-resource + /subsystem=undertow/application-security-domain=other:add(http-authentication-factory=keycloak-http-authentication) +else + echo Undertow already configured with Keycloak +end-if \ No newline at end of file diff --git a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml index ece320bd02..fcecc4845d 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml @@ -35,6 +35,7 @@ org/keycloak/keycloak-jboss-adapter-core/** org/keycloak/keycloak-undertow-adapter/** org/keycloak/keycloak-wildfly-adapter/** + org/keycloak/keycloak-wildfly-elytron-oidc-adapter/** org/keycloak/keycloak-wildfly-subsystem/** org/keycloak/keycloak-adapter-subsystem/** org/keycloak/keycloak-servlet-oauth-client/** @@ -57,5 +58,13 @@ cli/adapter-install-offline.cli bin + + ../../shared-cli/adapter-elytron-install.cli + bin + + + cli/adapter-elytron-install-offline.cli + bin + - + \ No newline at end of file diff --git a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/cli/adapter-elytron-install-offline.cli b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/cli/adapter-elytron-install-offline.cli new file mode 100644 index 0000000000..8e0335ac02 --- /dev/null +++ b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/cli/adapter-elytron-install-offline.cli @@ -0,0 +1,59 @@ +embed-server --server-config=standalone.xml + +if (outcome != success) of /extension=org.keycloak.keycloak-adapter-subsystem:read-resource + /extension=org.keycloak.keycloak-adapter-subsystem/:add(module=org.keycloak.keycloak-adapter-subsystem) +else + echo Keycloak OpenID Connect Extension already installed +end-if + +if (outcome != success) of /subsystem=keycloak:read-resource + /subsystem=keycloak:add +else + echo Keycloak OpenID Connect Subsystem already installed +end-if + +if (outcome != success) of /subsystem=elytron/custom-realm=KeycloakOIDCRealm:read-resource + /subsystem=elytron/custom-realm=KeycloakOIDCRealm:add(class-name=org.keycloak.adapters.elytron.KeycloakSecurityRealm, module=org.keycloak.keycloak-wildfly-elytron-oidc-adapter) +else + echo Keycloak OpenID Connect Realm already installed +end-if + +if (outcome != success) of /subsystem=elytron/security-domain=KeycloakDomain:read-resource + /subsystem=elytron/security-domain=KeycloakDomain:add(default-realm=KeycloakOIDCRealm,permission-mapper=default-permission-mapper,security-event-listener=local-audit,realms=[{realm=KeycloakOIDCRealm}]) +else + echo Keycloak Security Domain already installed. Trying to install Keycloak OpenID Connect Realm. + /subsystem=elytron/security-domain=KeycloakDomain:list-add(name=realms, value={realm=KeycloakOIDCRealm}) +end-if + +if (outcome != success) of /subsystem=elytron/constant-realm-mapper=keycloak-oidc-realm-mapper:read-resource + /subsystem=elytron/constant-realm-mapper=keycloak-oidc-realm-mapper:add(realm-name=KeycloakOIDCRealm) +else + echo Keycloak OpenID Connect Realm Mapper already installed +end-if + +if (outcome != success) of /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-oidc-http-server-mechanism-factory:read-resource + /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-oidc-http-server-mechanism-factory:add(module=org.keycloak.keycloak-wildfly-elytron-oidc-adapter) +else + echo Keycloak OpenID Connect HTTP Mechanism already installed +end-if + +if (outcome != success) of /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:read-resource + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:add(http-server-factories=[keycloak-oidc-http-server-mechanism-factory, global]) +else + echo Keycloak HTTP Mechanism Factory already installed. Trying to install Keycloak OpenID Connect HTTP Mechanism Factory. + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:list-add(name=http-server-factories, value=keycloak-oidc-http-server-mechanism-factory) +end-if + + +if (outcome != success) of /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:read-resource + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:add(security-domain=KeycloakDomain,http-server-mechanism-factory=keycloak-http-server-mechanism-factory,mechanism-configurations=[{mechanism-name=KEYCLOAK,mechanism-realm-configurations=[{realm-name=KeycloakOIDCRealm,realm-mapper=keycloak-oidc-realm-mapper}]}]) +else + echo Keycloak HTTP Authentication Factory already installed. Trying to install Keycloak OpenID Connect Mechanism Configuration + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:list-add(name=mechanism-configurations, value={mechanism-name=KEYCLOAK,mechanism-realm-configurations=[{realm-name=KeycloakOIDCRealm,realm-mapper=keycloak-oidc-realm-mapper}]}) +end-if + +if (outcome != success) of /subsystem=undertow/application-security-domain=other:read-resource + /subsystem=undertow/application-security-domain=other:add(http-authentication-factory=keycloak-http-authentication) +else + echo Undertow already configured with Keycloak +end-if \ No newline at end of file diff --git a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml index 2e0343166a..fe4006c681 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml @@ -90,4 +90,18 @@ + + + product + + + product + + + + ${product.name}-${product.filename.version}-eap7-adapter + + + + diff --git a/distribution/adapters/wildfly-adapter/wildfly-modules/build.xml b/distribution/adapters/wildfly-adapter/wildfly-modules/build.xml index a534b4f9a9..8e608a59ee 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-modules/build.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-modules/build.xml @@ -77,6 +77,10 @@ + + + + diff --git a/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml b/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml index b5a3d5ee53..00eef5800a 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml @@ -66,6 +66,10 @@ org.keycloak keycloak-wildfly-adapter + + org.keycloak + keycloak-wildfly-elytron-oidc-adapter + org.keycloak keycloak-wildfly-subsystem diff --git a/distribution/adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-elytron-oidc-adapter/main/module.xml b/distribution/adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-elytron-oidc-adapter/main/module.xml new file mode 100755 index 0000000000..1ca98391a2 --- /dev/null +++ b/distribution/adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-elytron-oidc-adapter/main/module.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/distribution/demo-dist/pom.xml b/distribution/demo-dist/pom.xml index 84b2ed5b05..dbe33ccf77 100755 --- a/distribution/demo-dist/pom.xml +++ b/distribution/demo-dist/pom.xml @@ -29,199 +29,209 @@ Keycloak Demo Distribution - - - org.keycloak - keycloak-server-overlay - zip - - - org.keycloak - keycloak-wildfly-adapter-dist - zip - - - org.keycloak - keycloak-saml-wildfly-adapter-dist - zip - - - org.keycloak - keycloak-examples-dist - zip - - + + + community + + + !product + + + + + org.keycloak + keycloak-server-overlay + zip + + + org.keycloak + keycloak-wildfly-adapter-dist + zip + + + org.keycloak + keycloak-saml-wildfly-adapter-dist + zip + + + org.keycloak + keycloak-examples-dist + zip + + - - keycloak-demo-${project.version} - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack-wildfly - prepare-package - - unpack - + + keycloak-demo-${project.version} + + + org.apache.maven.plugins + maven-deploy-plugin - - - org.wildfly - wildfly-dist - zip - ${project.build.directory}/unpacked - - + true - - - unpack-server - prepare-package - - unpack - - - - - org.keycloak - keycloak-server-overlay - zip - ${project.build.directory}/unpacked/keycloak-server-overlay-${project.version} - - - - - - unpack-adapter - prepare-package - - unpack - - - - - org.keycloak - keycloak-wildfly-adapter-dist - zip - ${project.build.directory}/unpacked/keycloak-wildfly-adapter-${project.version} - - - - - - unpack-saml-adapter - prepare-package - - unpack - - - - - org.keycloak - keycloak-saml-wildfly-adapter-dist - zip - ${project.build.directory}/unpacked/keycloak-saml-wildfly-adapter-${project.version} - - - - - - unpack-examples - prepare-package - - unpack - - - - - org.keycloak - keycloak-examples-dist - zip - ${project.build.directory}/unpacked - - - - - - unpack - compile - - unpack - - - - - org.keycloak - keycloak-wildfly-server-subsystem - ${project.version} - jar - default-config/*.xml - - - - - - + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack-wildfly + prepare-package + + unpack + + + + + org.wildfly + wildfly-dist + zip + ${project.build.directory}/unpacked + + + + + + unpack-server + prepare-package + + unpack + + + + + org.keycloak + keycloak-server-overlay + zip + ${project.build.directory}/unpacked/keycloak-server-overlay-${project.version} + + + + + + unpack-adapter + prepare-package + + unpack + + + + + org.keycloak + keycloak-wildfly-adapter-dist + zip + ${project.build.directory}/unpacked/keycloak-wildfly-adapter-${project.version} + + + + + + unpack-saml-adapter + prepare-package + + unpack + + + + + org.keycloak + keycloak-saml-wildfly-adapter-dist + zip + ${project.build.directory}/unpacked/keycloak-saml-wildfly-adapter-${project.version} + + + + + + unpack-examples + prepare-package + + unpack + + + + + org.keycloak + keycloak-examples-dist + zip + ${project.build.directory}/unpacked + + + + + + unpack + compile + + unpack + + + + + org.keycloak + keycloak-wildfly-server-subsystem + ${project.version} + jar + default-config/*.xml + + + + + + - - org.codehaus.mojo - xml-maven-plugin - 1.0 - - - generate-resources - package - - transform - - - - -

${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration - src/main/xslt/standalone.xsl - - standalone.xml - - ${project.build.directory}/unpacked/ - - - - - - + + org.codehaus.mojo + xml-maven-plugin + 1.0 + + + generate-resources + package + + transform + + + + + ${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration + src/main/xslt/standalone.xsl + + standalone.xml + + ${project.build.directory}/unpacked/ + + + + + + - - maven-assembly-plugin - - - assemble - package - - single - - - - assembly.xml - - target - target/assembly/work - false - gnu - - - - + + maven-assembly-plugin + + + assemble + package + + single + + + + assembly.xml + + target + target/assembly/work + false + gnu + + + + - - + + + + diff --git a/distribution/downloads/pom.xml b/distribution/downloads/pom.xml index b8ee00775f..5886b021fe 100755 --- a/distribution/downloads/pom.xml +++ b/distribution/downloads/pom.xml @@ -34,44 +34,54 @@ 1.8 - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.codehaus.mojo - exec-maven-plugin - - - server-downloads - package - - java - + + + community + + + !product + + + + + + org.apache.maven.plugins + maven-compiler-plugin - CopyDependencies - - ${settings.localRepository} - ${project.build.directory} - ${project.version} - + ${maven.compiler.source} + ${maven.compiler.target} - - - - - + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.codehaus.mojo + exec-maven-plugin + + + server-downloads + package + + java + + + CopyDependencies + + ${settings.localRepository} + ${project.build.directory} + ${project.version} + + + + + + + + + diff --git a/distribution/examples-dist/pom.xml b/distribution/examples-dist/pom.xml index 6219adc916..a57ea243b2 100755 --- a/distribution/examples-dist/pom.xml +++ b/distribution/examples-dist/pom.xml @@ -29,77 +29,85 @@ Keycloak Examples Distribution - - - - keycloak-examples-${project.version} - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.apache.maven.plugins - maven-antrun-plugin - false - - - build-example - - run - - compile + + + community + + + !product + + + + keycloak-examples-${project.version} + + + org.apache.maven.plugins + maven-deploy-plugin - - - - - + true - - - - - ant-contrib - ant-contrib - 1.0b3 - - - ant - ant - - - - - - - maven-assembly-plugin - - - assemble - package - - single - - - - assembly.xml - - - target - - - target/assembly/work - - false - - - - - - + + + org.apache.maven.plugins + maven-antrun-plugin + false + + + build-example + + run + + compile + + + + + + + + + + + + ant-contrib + ant-contrib + 1.0b3 + + + ant + ant + + + + + + + maven-assembly-plugin + + + assemble + package + + single + + + + assembly.xml + + + target + + + target/assembly/work + + false + + + + + + + + diff --git a/distribution/feature-packs/server-feature-pack/assembly.xml b/distribution/feature-packs/server-feature-pack/assembly.xml index 861c698224..1fdde3f439 100644 --- a/distribution/feature-packs/server-feature-pack/assembly.xml +++ b/distribution/feature-packs/server-feature-pack/assembly.xml @@ -23,40 +23,11 @@ zip false - - + target/${project.build.finalName} - - true - - **/module.xml - **/MANIFEST.MF - - - - target/${project.build.finalName} - - false - - **/module.xml - **/MANIFEST.MF - - - - ../../../ - - License.html - - content - - - ../../../themes/src/main/resources/theme - content/themes - - **/** - + diff --git a/distribution/feature-packs/server-feature-pack/feature-pack-build.xml b/distribution/feature-packs/server-feature-pack/feature-pack-build.xml index 8db3dfca2f..2cb52d6bd4 100644 --- a/distribution/feature-packs/server-feature-pack/feature-pack-build.xml +++ b/distribution/feature-packs/server-feature-pack/feature-pack-build.xml @@ -17,7 +17,7 @@ - + diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml index 2232d88c8e..46fee49f59 100644 --- a/distribution/feature-packs/server-feature-pack/pom.xml +++ b/distribution/feature-packs/server-feature-pack/pom.xml @@ -47,27 +47,153 @@ org.keycloak keycloak-wildfly-server-subsystem
- - org.wildfly - wildfly-feature-pack - zip - - - - com.google.guava - guava - - - org.apache.maven.plugins - maven-resources-plugin - + maven-dependency-plugin + + + unpack-theme + validate + + unpack + + + + + org.keycloak + keycloak-themes + target/unpacked-themes + + + + + + + + maven-resources-plugin + + + copy-configuration + validate + + copy-resources + + + target/resources/configuration + + + src/main/resources/configuration + true + + + + + + copy-modules + validate + + copy-resources + + + target/resources/modules + + + src/main/resources/modules + + + + + + copy-content + validate + + copy-resources + + + target/resources/content + + + src/main/resources/content + + + + + + copy-identity + validate + + copy-resources + + + target/resources/content/bin + + + src/main/resources/identity + + **/product.conf + + true + + + + + + copy-identity-module + validate + + copy-resources + + + target/resources/modules/system/layers/keycloak/org/jboss/as/product/${product.slot} + + + src/main/resources/identity/module + true + + + + + + copy-themes + validate + + copy-resources + + + target/resources/content/themes + + + target/unpacked-themes/theme + + + + + + copy-license + validate + + copy-resources + + + target/resources/content + + + ../../../ + + License.html + + + + + + + + org.wildfly.build wildfly-feature-pack-build-maven-plugin @@ -80,6 +206,7 @@ compile feature-pack-build.xml + target/resources @@ -111,4 +238,121 @@ + + + community + + + !product + + + + + org.wildfly:wildfly-feature-pack + urn:jboss:domain:4.0 + + + + + org.wildfly + wildfly-feature-pack + zip + + + + + + + wf11 + + + urn:jboss:domain:5.0 + + + + + org.wildfly + wildfly-feature-pack + ${wildfly11.version} + zip + + + + + + + maven-resources-plugin + + + copy-configuration-wf11 + validate + + copy-resources + + + target/resources/configuration + + + src/main/resources-wf11/configuration + true + + + + + + + + + + + product + + + product + + + + + org.jboss.eap:wildfly-feature-pack + urn:jboss:domain:5.0 + + + + + org.jboss.eap + wildfly-feature-pack + ${eap.version} + zip + + + + + + + maven-resources-plugin + + + copy-configuration-wf11 + validate + + copy-resources + + + target/resources/configuration + + + src/main/resources-wf11/configuration + true + + + + + + + + + + + + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems-ha.xml b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems-ha.xml new file mode 100755 index 0000000000..9d9954de9b --- /dev/null +++ b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems-ha.xml @@ -0,0 +1,49 @@ + + + + + + + logging.xml + bean-validation.xml + keycloak-datasources.xml + deployment-scanner.xml + ee.xml + ejb3.xml + io.xml + keycloak-infinispan.xml + jaxrs.xml + jca.xml + jdr.xml + jgroups.xml + jmx.xml + jpa.xml + jsf.xml + mail.xml + mod_cluster.xml + naming.xml + remoting.xml + request-controller.xml + security-manager.xml + elytron.xml + security.xml + transactions.xml + undertow.xml + keycloak-server.xml + + \ No newline at end of file diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems.xml b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems.xml new file mode 100755 index 0000000000..823b45cebc --- /dev/null +++ b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/subsystems.xml @@ -0,0 +1,47 @@ + + + + + + + logging.xml + bean-validation.xml + keycloak-datasources2.xml + deployment-scanner.xml + ee.xml + ejb3.xml + io.xml + keycloak-infinispan2.xml + jaxrs.xml + jca.xml + jdr.xml + jmx.xml + jpa.xml + jsf.xml + mail.xml + naming.xml + remoting.xml + request-controller.xml + security-manager.xml + elytron.xml + security.xml + transactions.xml + undertow.xml + keycloak-server.xml + + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/template.xml new file mode 100644 index 0000000000..e28a49ba48 --- /dev/null +++ b/distribution/feature-packs/server-feature-pack/src/main/resources-wf11/configuration/standalone/template.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml index e7b5885177..7a9d6a0c17 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml @@ -17,7 +17,7 @@ ~ limitations under the License. --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml index f5d89ee791..6366860354 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml @@ -22,7 +22,7 @@ is also started by this host controller file. The other instance must be started via host-slave.xml --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml index f8695d71a0..e90b782f8d 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml @@ -17,7 +17,7 @@ ~ limitations under the License. --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml index a5c9afbdcc..1dce732bec 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml @@ -23,7 +23,7 @@ via host-slave.xml --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml index c0cc9e578a..0a72df3d4c 100644 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml @@ -17,7 +17,7 @@ ~ limitations under the License. --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/product.conf b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/product.conf deleted file mode 100644 index 030791ca69..0000000000 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/product.conf +++ /dev/null @@ -1 +0,0 @@ -slot=keycloak diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/providers/README.txt b/distribution/feature-packs/server-feature-pack/src/main/resources/content/providers/README.txt index a6d523b43f..20b281aefd 100644 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/providers/README.txt +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/providers/README.txt @@ -1,2 +1,2 @@ -Any provider implementation jars and libraries in this folder will be loaded by Keycloak. See the providers -section in the documentation for more details. \ No newline at end of file +Any provider implementation jars and libraries in this folder will be loaded. See the providers section in the +documentation for more details. \ No newline at end of file diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/dir/META-INF/MANIFEST.MF b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/dir/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..a467c06b87 --- /dev/null +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/dir/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +JBoss-Product-Release-Name: ${product.name.full} +JBoss-Product-Release-Version: ${product.version} +JBoss-Product-Console-Slot: ${product.wildfly.console.slot} diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/module.xml similarity index 97% rename from distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/module.xml rename to distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/module.xml index 739393a414..272eb54de5 100644 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/module.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/module/module.xml @@ -15,7 +15,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/identity/product.conf b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/product.conf new file mode 100644 index 0000000000..523592f81b --- /dev/null +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/identity/product.conf @@ -0,0 +1 @@ +slot=${product.slot} diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/dir/META-INF/MANIFEST.MF b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/dir/META-INF/MANIFEST.MF deleted file mode 100644 index dbaf97f345..0000000000 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/jboss/as/product/keycloak/dir/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -JBoss-Product-Release-Name: ${product.name} -JBoss-Product-Release-Version: ${product.version} -JBoss-Product-Console-Slot: main diff --git a/distribution/pom.xml b/distribution/pom.xml index 9cdf5ae983..a670f2700f 100755 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -34,10 +34,6 @@ adapters saml-adapters - demo-dist - api-docs-dist - examples-dist - proxy-dist server-dist server-overlay feature-packs @@ -47,7 +43,11 @@ jboss-release + api-docs-dist downloads + demo-dist + examples-dist + proxy-dist diff --git a/distribution/proxy-dist/pom.xml b/distribution/proxy-dist/pom.xml index 93fcbfa3b6..35f09f6937 100755 --- a/distribution/proxy-dist/pom.xml +++ b/distribution/proxy-dist/pom.xml @@ -29,45 +29,55 @@ Proxy Distro - - - org.keycloak - launcher - - - org.keycloak - keycloak-proxy-server - - + + + community + + + !product + + + + + org.keycloak + launcher + + + org.keycloak + keycloak-proxy-server + + - - keycloak-proxy-${project.version} - - - maven-assembly-plugin - - - assemble - package - - single - - - - assembly.xml - - - target - - - target/assembly/work - - false - - - - - - + + keycloak-proxy-${project.version} + + + maven-assembly-plugin + + + assemble + package + + single + + + + assembly.xml + + + target + + + target/assembly/work + + false + + + + + + + + diff --git a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml index 689ccdfd79..678667f546 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml @@ -93,4 +93,18 @@ + + + product + + + product + + + + ${product.name}-${product.filename.version}-saml-eap6-adapter + + + + diff --git a/distribution/saml-adapters/as7-eap6-adapter/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/pom.xml index ed0792b61d..428d97498a 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/pom.xml @@ -32,7 +32,20 @@ as7-modules - as7-adapter-zip eap6-adapter-zip + + + + community + + + !product + + + + as7-adapter-zip + + + diff --git a/distribution/saml-adapters/pom.xml b/distribution/saml-adapters/pom.xml index 09177682cd..e2706413f1 100755 --- a/distribution/saml-adapters/pom.xml +++ b/distribution/saml-adapters/pom.xml @@ -32,15 +32,29 @@ wildfly-adapter - tomcat6-adapter-zip - tomcat7-adapter-zip - tomcat8-adapter-zip - jetty81-adapter-zip - - jetty92-adapter-zip - jetty93-adapter-zip - jetty94-adapter-zip as7-eap6-adapter + + + + community + + + !product + + + + jetty81-adapter-zip + + jetty92-adapter-zip + jetty93-adapter-zip + jetty94-adapter-zip + tomcat6-adapter-zip + tomcat7-adapter-zip + tomcat8-adapter-zip + + + + diff --git a/distribution/saml-adapters/shared-cli/adapter-elytron-install-saml.cli b/distribution/saml-adapters/shared-cli/adapter-elytron-install-saml.cli new file mode 100755 index 0000000000..1f24085459 --- /dev/null +++ b/distribution/saml-adapters/shared-cli/adapter-elytron-install-saml.cli @@ -0,0 +1,56 @@ +if (outcome != success) of /extension=org.keycloak.keycloak-saml-adapter-subsystem:read-resource + /extension=org.keycloak.keycloak-saml-adapter-subsystem/:add(module=org.keycloak.keycloak-saml-adapter-subsystem) +else + echo Keycloak SAML Extension already installed +end-if + +if (outcome != success) of /subsystem=keycloak-saml:read-resource + /subsystem=keycloak-saml:add +else + echo Keycloak SAML Subsystem already installed +end-if + +if (outcome != success) of /subsystem=elytron/custom-realm=KeycloakSAMLRealm:read-resource + /subsystem=elytron/custom-realm=KeycloakSAMLRealm:add(class-name=org.keycloak.adapters.saml.elytron.KeycloakSecurityRealm, module=org.keycloak.keycloak-saml-wildfly-elytron-adapter) +else + echo Keycloak SAML Realm already installed +end-if + +if (outcome != success) of /subsystem=elytron/security-domain=KeycloakDomain:read-resource + /subsystem=elytron/security-domain=KeycloakDomain:add(default-realm=KeycloakSAMLRealm,permission-mapper=default-permission-mapper,security-event-listener=local-audit,realms=[{realm=KeycloakSAMLRealm}]) +else + echo Keycloak Security Domain already installed. Trying to install Keycloak SAML Realm. + /subsystem=elytron/security-domain=KeycloakDomain:list-add(name=realms, value={realm=KeycloakSAMLRealm}) +end-if + +if (outcome != success) of /subsystem=elytron/constant-realm-mapper=keycloak-saml-realm-mapper:read-resource + /subsystem=elytron/constant-realm-mapper=keycloak-saml-realm-mapper:add(realm-name=KeycloakSAMLRealm) +else + echo Keycloak SAML Realm Mapper already installed +end-if + +if (outcome != success) of /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-saml-http-server-mechanism-factory:read-resource + /subsystem=elytron/service-loader-http-server-mechanism-factory=keycloak-saml-http-server-mechanism-factory:add(module=org.keycloak.keycloak-saml-wildfly-elytron-adapter) +else + echo Keycloak SAML HTTP Mechanism Factory already installed +end-if + +if (outcome != success) of /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:read-resource + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:add(http-server-factories=[keycloak-saml-http-server-mechanism-factory, global]) +else + echo Keycloak HTTP Mechanism Factory already installed. Trying to install Keycloak SAML HTTP Mechanism Factory. + /subsystem=elytron/aggregate-http-server-mechanism-factory=keycloak-http-server-mechanism-factory:list-add(name=http-server-factories, value=keycloak-saml-http-server-mechanism-factory) +end-if + +if (outcome != success) of /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:read-resource + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:add(security-domain=KeycloakDomain,http-server-mechanism-factory=keycloak-http-server-mechanism-factory,mechanism-configurations=[{mechanism-name=KEYCLOAK-SAML,mechanism-realm-configurations=[{realm-name=KeycloakSAMLCRealm,realm-mapper=keycloak-saml-realm-mapper}]}]) +else + echo Keycloak HTTP Authentication Factory already installed. Trying to install Keycloak SAML Mechanism Configuration + /subsystem=elytron/http-authentication-factory=keycloak-http-authentication:list-add(name=mechanism-configurations, value={mechanism-name=KEYCLOAK-SAML,mechanism-realm-configurations=[{realm-name=KeycloakSAMLRealm,realm-mapper=keycloak-saml-realm-mapper}]}) +end-if + +if (outcome != success) of /subsystem=undertow/application-security-domain=other:read-resource + /subsystem=undertow/application-security-domain=other:add(http-authentication-factory=keycloak-http-authentication) +else + echo Undertow already configured with Keycloak +end-if \ No newline at end of file diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml index b91b2dc594..398930dcf9 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/assembly.xml @@ -37,6 +37,7 @@ org/keycloak/keycloak-jboss-adapter-core/** org/keycloak/keycloak-saml-undertow-adapter/** org/keycloak/keycloak-saml-wildfly-adapter/** + org/keycloak/keycloak-saml-wildfly-elytron-adapter/** org/keycloak/keycloak-saml-wildfly-subsystem/** org/keycloak/keycloak-saml-adapter-subsystem/** @@ -51,5 +52,9 @@ ../../shared-cli/adapter-install-saml.cli bin + + ../../shared-cli/adapter-elytron-install-saml.cli + bin + diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml index 76ecc40693..8badfef8a9 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml @@ -90,4 +90,18 @@ + + + product + + + product + + + + ${product.name}-${product.filename.version}-saml-eap7-adapter + + + + diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/build.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/build.xml index abbe9d3b65..885ed811a4 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/build.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/build.xml @@ -76,6 +76,10 @@ + + + + diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml index 06f0dedc8a..026d8696f1 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml @@ -70,6 +70,10 @@ org.keycloak keycloak-saml-wildfly-adapter
+ + org.keycloak + keycloak-saml-wildfly-elytron-adapter + org.keycloak keycloak-saml-wildfly-subsystem diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-wildfly-elytron-adapter/main/module.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-wildfly-elytron-adapter/main/module.xml new file mode 100755 index 0000000000..393eac929c --- /dev/null +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/src/main/resources/modules/org/keycloak/keycloak-saml-wildfly-elytron-adapter/main/module.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/distribution/server-dist/assembly.xml b/distribution/server-dist/assembly.xml index b7881589b1..dc0790454f 100755 --- a/distribution/server-dist/assembly.xml +++ b/distribution/server-dist/assembly.xml @@ -39,21 +39,23 @@ false - **/*.sh - **/module.xml + bin/*.sh + module.xml welcome-content/** - appclient appclient/** + bin/appclient.* copyright.txt README.txt themes/** + version.txt + ${profileExcludes} target/${project.build.finalName} - **/*.sh + bin/*.sh 0755 @@ -88,4 +90,13 @@ + + + + src/main/version.txt + + true + + + diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml index f34601f193..c870aba3de 100755 --- a/distribution/server-dist/pom.xml +++ b/distribution/server-dist/pom.xml @@ -38,8 +38,6 @@ - keycloak-${project.version} - org.wildfly.build @@ -69,7 +67,7 @@ - assembly.xml + ${assemblyFile} true ${project.build.finalName} @@ -107,4 +105,44 @@ + + + community + + + !product + + + + assembly.xml + + + keycloak-${project.version} + + + + + product + + + product + + + + assembly.xml + %regex[(providers.*)|(docs/contrib.*)|(docs/examples.*)|(docs/schema.*)] + + + + org.wildfly + wildfly-dist + zip + + + + ${product.name}-${product.filename.version} + + + + diff --git a/distribution/server-dist/src/main/version.txt b/distribution/server-dist/src/main/version.txt new file mode 100644 index 0000000000..c9db8ca50e --- /dev/null +++ b/distribution/server-dist/src/main/version.txt @@ -0,0 +1 @@ +${product.name.full} - Version ${product.version} diff --git a/distribution/server-dist/src/main/welcome-content/index.html b/distribution/server-dist/src/main/welcome-content/index.html index bcf20acc25..762ad2be4c 100644 --- a/distribution/server-dist/src/main/welcome-content/index.html +++ b/distribution/server-dist/src/main/welcome-content/index.html @@ -18,11 +18,13 @@ - Welcome to Keycloak + - + If you are not redirected automatically, follow this link. diff --git a/distribution/server-overlay/assembly.xml b/distribution/server-overlay/assembly.xml index 47a108a981..c2b5275c51 100755 --- a/distribution/server-overlay/assembly.xml +++ b/distribution/server-overlay/assembly.xml @@ -26,34 +26,6 @@ false - - ${project.build.directory}/unpacked/keycloak-${project.version}/modules/system/layers/keycloak - modules/system/add-ons/keycloak - - **/** - - - - ${project.build.directory}/unpacked/keycloak-${project.version}/themes - themes - - **/** - - - - ${project.build.directory}/unpacked/keycloak-${project.version}/providers - providers - - **/** - - - - ../../ - - License.html - - - ${project.build.directory}/cli @@ -62,21 +34,21 @@ bin - ${project.build.directory}/unpacked/keycloak-${project.version}/bin + ${project.build.directory}/unpacked/${serverDistDir} + - add-user-keycloak.* - federation-sssd-setup.sh - kcadm.* - kcreg.* + **/** - bin + + modules/** + - ${project.build.directory}/unpacked/keycloak-${project.version}/bin/client + ${project.build.directory}/unpacked/${serverDistDir}/modules/system/layers/keycloak + modules/system/${identityType}/keycloak - keycloak* + **/** - bin/client diff --git a/distribution/server-overlay/pom.xml b/distribution/server-overlay/pom.xml index f2e727e352..6b6143f64d 100755 --- a/distribution/server-overlay/pom.xml +++ b/distribution/server-overlay/pom.xml @@ -37,9 +37,22 @@ + + + ${serverDistDir}/modules/system/layers/keycloak/**, + ${serverDistDir}/themes/**, + ${serverDistDir}/providers/**, + ${serverDistDir}/License.html, + ${serverDistDir}/bin/client/keycloak*, + ${serverDistDir}/bin/*keycloak*, + ${serverDistDir}/bin/kc*, + ${serverDistDir}/bin/federation-sssd-setup.sh, + ${serverDistDir}/bin/migrate* + + + keycloak-overlay-${project.version} - org.apache.maven.plugins @@ -77,6 +90,7 @@ keycloak-server-dist zip ${project.build.directory}/unpacked + ${filesToInclude} @@ -169,4 +183,38 @@ + + + + community + + + !product + + + + add-ons + keycloak-${project.version} + ${commonFilesToInclude} + + + + + product + + + product + + + + layers + ${product.name}-${product.filename.version} + + ${commonFilesToInclude}, + ${serverDistDir}/bin/product.conf, + ${serverDistDir}/modules/layers.conf + + + + diff --git a/integration/client-cli/client-registration-cli/pom.xml b/integration/client-cli/client-registration-cli/pom.xml index b2eaf5720d..5be530431f 100755 --- a/integration/client-cli/client-registration-cli/pom.xml +++ b/integration/client-cli/client-registration-cli/pom.xml @@ -50,6 +50,13 @@ + + org.apache.maven.plugins + maven-deploy-plugin + + true + + org.apache.maven.plugins maven-shade-plugin diff --git a/misc/keycloak-test-helper/src/main/java/org/keycloak/helper/TestsHelper.java b/misc/keycloak-test-helper/src/main/java/org/keycloak/test/TestsHelper.java similarity index 84% rename from misc/keycloak-test-helper/src/main/java/org/keycloak/helper/TestsHelper.java rename to misc/keycloak-test-helper/src/main/java/org/keycloak/test/TestsHelper.java index 4beb57af41..fecfbc76da 100644 --- a/misc/keycloak-test-helper/src/main/java/org/keycloak/helper/TestsHelper.java +++ b/misc/keycloak-test-helper/src/main/java/org/keycloak/test/TestsHelper.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.keycloak.helper; +package org.keycloak.test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -27,20 +27,21 @@ import org.keycloak.admin.client.Keycloak; import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistration; import org.keycloak.client.registration.ClientRegistrationException; -import org.keycloak.representations.idm.ClientRepresentation; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.Arrays; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.test.builders.ClientBuilder; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Arrays; public class TestsHelper { @@ -53,6 +54,8 @@ public class TestsHelper { public static String initialAccessCode; public static String appName; + + public static int initialAccessTokenCount = 2; protected static String clientConfiguration; @@ -80,30 +83,7 @@ public class TestsHelper { } public static String createDirectGrantClient() { - ClientRepresentation clientRepresentation = new ClientRepresentation(); - clientRepresentation.setClientId("test-dga"); - clientRepresentation.setFullScopeAllowed(true); - clientRepresentation.setPublicClient(Boolean.TRUE); - clientRepresentation.setDirectAccessGrantsEnabled(true); - - ClientRegistration reg = ClientRegistration.create() - .url(keycloakBaseUrl, testRealm) - .build(); - - reg.auth(Auth.token(initialAccessCode)); - try { - clientRepresentation = reg.create(clientRepresentation); - registrationAccessCode = clientRepresentation.getRegistrationAccessToken(); - ObjectMapper mapper = new ObjectMapper(); - reg.auth(Auth.token(registrationAccessCode)); - clientConfiguration = mapper.writeValueAsString(reg.getAdapterConfig(clientRepresentation.getClientId())); - } catch (ClientRegistrationException e) { - e.printStackTrace(); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - - return clientConfiguration; + return createClient(ClientBuilder.create("test-dga").publicClient(true)); } public static void deleteClient(String clientId) { @@ -169,7 +149,7 @@ public class TestsHelper { } - public static boolean ImportTestRealm(String username, String password, String realmJsonPath) throws IOException { + public static boolean importTestRealm(String username, String password, String realmJsonPath) throws IOException { ObjectMapper mapper = new ObjectMapper(); ClassLoader classLoader = TestsHelper.class.getClassLoader(); @@ -184,16 +164,12 @@ public class TestsHelper { "admin-cli"); keycloak.realms().create(realmRepresentation); testRealm = realmRepresentation.getRealm(); - ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation(); - rep.setCount(2); - rep.setExpiration(100); - ClientInitialAccessPresentation initialAccess = keycloak.realms().realm(testRealm).clientInitialAccess().create(rep); - initialAccessCode = initialAccess.getToken(); + generateInitialAccessToken(keycloak); return true; } - public static boolean ImportTestRealm(String username, String password) throws IOException { + public static boolean importTestRealm(String username, String password) throws IOException { testRealm = appName + "-realm"; RealmRepresentation realmRepresentation = new RealmRepresentation(); realmRepresentation.setRealm(testRealm); @@ -205,12 +181,16 @@ public class TestsHelper { password, "admin-cli"); keycloak.realms().create(realmRepresentation); + generateInitialAccessToken(keycloak); + return true; + } + + private static void generateInitialAccessToken(Keycloak keycloak) { ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation(); - rep.setCount(2); + rep.setCount(initialAccessTokenCount); rep.setExpiration(100); ClientInitialAccessPresentation initialAccess = keycloak.realms().realm(testRealm).clientInitialAccess().create(rep); initialAccessCode = initialAccess.getToken(); - return true; } public static boolean deleteRealm(String username, String password, String realmName) throws IOException { @@ -235,19 +215,20 @@ public class TestsHelper { password, "admin-cli"); UserRepresentation userRepresentation = new UserRepresentation(); - userRepresentation.setUsername("testuser"); + userRepresentation.setUsername(username); userRepresentation.setEnabled(Boolean.TRUE); Response response = keycloak.realms().realm(realmName).users().create(userRepresentation); String userId = getCreatedId(response); response.close(); CredentialRepresentation rep = new CredentialRepresentation(); rep.setType(CredentialRepresentation.PASSWORD); - rep.setValue("password"); + rep.setValue(password); rep.setTemporary(false); keycloak.realms().realm(realmName).users().get(userId).resetPassword(rep); //add roles RoleRepresentation representation = new RoleRepresentation(); representation.setName("user"); + keycloak.realms().realm(realmName).roles().create(representation); RoleRepresentation realmRole = keycloak.realms().realm(realmName).roles().get("user").toRepresentation(); keycloak.realms().realm(realmName).users().get(userId).roles().realmLevel().add(Arrays.asList(realmRole)); diff --git a/misc/keycloak-test-helper/src/main/java/org/keycloak/test/builders/ClientBuilder.java b/misc/keycloak-test-helper/src/main/java/org/keycloak/test/builders/ClientBuilder.java new file mode 100644 index 0000000000..0e51c9058e --- /dev/null +++ b/misc/keycloak-test-helper/src/main/java/org/keycloak/test/builders/ClientBuilder.java @@ -0,0 +1,78 @@ +/* + * 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.test.builders; + +import org.keycloak.representations.idm.ClientRepresentation; + +import java.util.Collections; + +/** + * @author Bruno Oliveira + */ +public class ClientBuilder { + + private ClientRepresentation rep; + + public static ClientBuilder create(String clientId) { + ClientRepresentation rep = new ClientRepresentation(); + rep.setEnabled(Boolean.TRUE); + rep.setClientId(clientId); + return new ClientBuilder(rep); + } + + private ClientBuilder(ClientRepresentation rep) { + this.rep = rep; + } + + public ClientRepresentation bearerOnly(boolean bearerOnly) { + rep.setBearerOnly(bearerOnly); + return rep; + } + + public ClientBuilder rootUrl(String rootUrl) { + rep.setRootUrl(rootUrl); + return this; + } + + public ClientBuilder redirectUri(String redirectUri) { + rep.setRedirectUris(Collections.singletonList(redirectUri)); + return this; + } + + public ClientBuilder baseUrl(String baseUrl) { + rep.setBaseUrl(baseUrl); + return this; + } + + public ClientBuilder adminUrl(String adminUrl) { + rep.setAdminUrl(adminUrl); + return this; + } + + public ClientRepresentation publicClient(boolean publicClient) { + rep.setFullScopeAllowed(true); + rep.setPublicClient(publicClient); + rep.setDirectAccessGrantsEnabled(true); + rep.setAdminUrl(rep.getRootUrl()); + + if (rep.getRedirectUris() == null && rep.getRootUrl() != null) + rep.setRedirectUris(Collections.singletonList(rep.getRootUrl().concat("/*"))); + return rep; + } + +} diff --git a/pom.xml b/pom.xml index e545c8e17b..364121c10c 100755 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,4 @@ + - 7.0.0.Beta 7.2.0.Final 10.0.0.Final + 11.0.0.Alpha1 + 7.1.0.Alpha1-redhat-16 + 2.0.10.Final + 1.1.8.Final - 0.66.12 + 1.1.0.Beta32 + 1.0.0.Beta14 + + 0.66.15 4.5 4.4.1 0.6 @@ -75,8 +78,6 @@ 2.2.11 20140925 1.3.15.Final - 2.0.10.Final - 1.1.0.Final 2.0.5 @@ -112,6 +113,7 @@ 1.4 1.3.5 + 3.0.2 7.5.Final 1.9.0 1.0.4 @@ -178,7 +180,6 @@ server-spi-private saml-core-api saml-core - proxy federation services themes @@ -360,6 +361,7 @@ log4j log4j ${log4j.version} + test junit @@ -621,6 +623,16 @@ wildfly-web-common ${wildfly.version} + + org.wildfly.security + wildfly-elytron + ${version.org.wildfly.security.wildfly-elytron} + + + org.wildfly.security.elytron-web + undertow-server + ${version.org.wildfly.security.elytron-web.undertow-server} + org.infinispan infinispan-core @@ -921,6 +933,16 @@ keycloak-wildfly-adapter ${project.version} + + org.keycloak + keycloak-wildfly-elytron-oidc-adapter + ${project.version} + + + org.keycloak + keycloak-saml-wildfly-elytron-adapter + ${project.version} + org.keycloak keycloak-wildfly-adduser @@ -1386,6 +1408,11 @@ ${surefire.memory.settings} + + org.apache.maven.plugins + maven-jar-plugin + ${jar.plugin.version} + com.google.code.maven-replacer-plugin maven-replacer-plugin @@ -1474,6 +1501,46 @@ + + community + + + !product + + + + Keycloak + Keycloak + keycloak + main + \u003Cdiv class="kc-logo-text"\u003E\u003Cspan\u003EKeycloak\u003C\u002Fspan\u003E\u003C\u002Fdiv\u003E + ${project.version} + community + + + proxy + + + + + product + + + product + + + + Red Hat Single Sign-On + rh-sso + rh-sso + eap + \u003Cstrong\u003ERed Hat\u003C\u002Fstrong\u003E\u003Csup\u003E\u00AE\u003C\u002Fsup\u003E Single Sign On + ${project.version} + product + 7.1 + + + distribution diff --git a/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java b/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java index 83cdd84e5e..1a36d7a853 100755 --- a/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java +++ b/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java @@ -33,6 +33,7 @@ import org.keycloak.migration.migrators.MigrateTo2_2_0; import org.keycloak.migration.migrators.MigrateTo2_3_0; import org.keycloak.migration.migrators.MigrateTo2_5_0; import org.keycloak.migration.migrators.MigrateTo3_0_0; +import org.keycloak.migration.migrators.MigrateTo3_1_0; import org.keycloak.migration.migrators.Migration; import org.keycloak.models.KeycloakSession; @@ -52,13 +53,14 @@ public class MigrationModelManager { new MigrateTo1_7_0(), new MigrateTo1_8_0(), new MigrateTo1_9_0(), - new MigrateTo1_9_2(), - new MigrateTo2_0_0(), - new MigrateTo2_1_0(), - new MigrateTo2_2_0(), - new MigrateTo2_3_0(), + new MigrateTo1_9_2(), + new MigrateTo2_0_0(), + new MigrateTo2_1_0(), + new MigrateTo2_2_0(), + new MigrateTo2_3_0(), new MigrateTo2_5_0(), - new MigrateTo3_0_0() + new MigrateTo3_0_0(), + new MigrateTo3_1_0() }; public static void migrate(KeycloakSession session) { diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_1_0.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_1_0.java new file mode 100644 index 0000000000..22da4f8e06 --- /dev/null +++ b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo3_1_0.java @@ -0,0 +1,54 @@ +/* + * 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.migration.migrators; + + +import org.keycloak.migration.ModelVersion; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Bill Burke + */ +public class MigrateTo3_1_0 implements Migration { + + public static final ModelVersion VERSION = new ModelVersion("3.1.0"); + + @Override + public void migrate(KeycloakSession session) { + for (RealmModel realm : session.realms().getRealms()) { + if (realm.getBrowserSecurityHeaders() != null) { + + Map browserSecurityHeaders = new HashMap<>(realm.getBrowserSecurityHeaders()); + browserSecurityHeaders.put("xRobotsTag", "none"); + + realm.setBrowserSecurityHeaders(Collections.unmodifiableMap(browserSecurityHeaders)); + } + } + } + + @Override + public ModelVersion getVersion() { + return VERSION; + } + +} diff --git a/server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java b/server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java index 10560271b0..f384f7b885 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java +++ b/server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java @@ -34,11 +34,13 @@ public class BrowserSecurityHeaders { headerMap.put("xFrameOptions", "X-Frame-Options"); headerMap.put("contentSecurityPolicy", "Content-Security-Policy"); headerMap.put("xContentTypeOptions", "X-Content-Type-Options"); + headerMap.put("xRobotsTag", "X-Robots-Tag"); Map dh = new HashMap<>(); dh.put("xFrameOptions", "SAMEORIGIN"); dh.put("contentSecurityPolicy", "frame-src 'self'"); dh.put("xContentTypeOptions", "nosniff"); + dh.put("xRobotsTag", "none"); defaultHeaders = Collections.unmodifiableMap(dh); headerAttributeMap = Collections.unmodifiableMap(headerMap); diff --git a/services/pom.xml b/services/pom.xml index 341a02c2bf..0329f55063 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -218,6 +218,27 @@ + + maven-resources-plugin + + + copy-resources + validate + + copy-resources + + + target/docs + + + src/docs + true + + + + + + org.apache.maven.plugins maven-javadoc-plugin @@ -244,7 +265,7 @@ ${project.basedir}/target/apidocs-rest/swagger false - -skipUiFiles -apiVersion 1 -includeResourcePrefixes org.keycloak.services.resources.admin,org.keycloak.protocol.oidc -docBasePath /apidocs -apiBasePath http://localhost:8080/auth -apiInfoFile ${project.basedir}/src/docs/swagger/apiinfo.json + -skipUiFiles -apiVersion 1 -includeResourcePrefixes org.keycloak.services.resources.admin,org.keycloak.protocol.oidc -docBasePath /apidocs -apiBasePath http://localhost:8080/auth -apiInfoFile ${project.basedir}/target/docs/swagger/apiinfo.json javadoc @@ -289,7 +310,7 @@ process-asciidoc - ${project.basedir}/src/docs/asciidoc + ${project.basedir}/target/docs/asciidoc index.adoc ${project.basedir}/target/apidocs-rest/output html5 diff --git a/services/src/docs/asciidoc/overview.adoc b/services/src/docs/asciidoc/overview.adoc index e2457abf15..1d19c96e93 100644 --- a/services/src/docs/asciidoc/overview.adoc +++ b/services/src/docs/asciidoc/overview.adoc @@ -1,7 +1,7 @@ -= Keycloak Admin REST API += ${product.name.full} Admin REST API == Overview -This is a REST API reference for the Keycloak Admin +This is a REST API reference for the ${product.name.full} Admin === Version information Version: 1 @@ -10,4 +10,3 @@ Version: 1 Host: localhost:8080 BasePath: /auth Schemes: HTTP - diff --git a/services/src/docs/swagger/apiinfo.json b/services/src/docs/swagger/apiinfo.json index 575955f57d..870e294748 100644 --- a/services/src/docs/swagger/apiinfo.json +++ b/services/src/docs/swagger/apiinfo.json @@ -1,4 +1,4 @@ { - "title": "Keycloak Admin REST API", - "description": "This is a REST API reference for the Keycloak Admin" + "title": "${product.name.full} Admin REST API", + "description": "This is a REST API reference for the ${product.name.full} Admin" } \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java index 3caf2ea886..8982a298f1 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java @@ -21,6 +21,7 @@ import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation; import static org.keycloak.models.utils.RepresentationToModel.toModel; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -48,9 +49,9 @@ import org.keycloak.authorization.policy.provider.PolicyProviderAdminService; import org.keycloak.authorization.policy.provider.PolicyProviderFactory; import org.keycloak.authorization.store.PolicyStore; import org.keycloak.authorization.store.ResourceStore; +import org.keycloak.authorization.store.ScopeStore; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.Constants; -import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; @@ -299,6 +300,7 @@ public class PolicyService { @QueryParam("name") String name, @QueryParam("type") String type, @QueryParam("resource") String resource, + @QueryParam("scope") String scope, @QueryParam("permission") Boolean permission, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResult) { @@ -319,27 +321,40 @@ public class PolicyService { } StoreFactory storeFactory = authorization.getStoreFactory(); - PolicyStore policyStore = storeFactory.getPolicyStore(); - if (resource != null && !"".equals(resource.trim())) { + + if (resource != null || scope != null) { List policies = new ArrayList<>(); - HashMap resourceSearch = new HashMap<>(); - resourceSearch.put("name", new String[] {resource}); + if (resource != null && !"".equals(resource.trim())) { + HashMap resourceSearch = new HashMap<>(); - ResourceStore resourceStore = storeFactory.getResourceStore(); - resourceStore.findByResourceServer(resourceSearch, resourceServer.getId(), -1, -1).forEach(resource1 -> { - policyStore.findByResource(resource1.getId(), resourceServer.getId()).forEach(policyRepresentation -> { - Policy associated = policyStore.findById(policyRepresentation.getId(), resourceServer.getId()); - policies.add(associated); - findAssociatedPolicies(associated, policies); + resourceSearch.put("name", new String[]{resource}); + + storeFactory.getResourceStore().findByResourceServer(resourceSearch, resourceServer.getId(), -1, 1).forEach(resource1 -> { + policies.addAll(policyStore.findByResource(resource1.getId(), resourceServer.getId())); + if (resource1.getType() != null) { + policies.addAll(policyStore.findByResourceType(resource1.getType(), resourceServer.getId())); + } }); - }); + } + + if (scope != null && !"".equals(scope.trim())) { + HashMap scopeSearch = new HashMap<>(); + + scopeSearch.put("name", new String[]{scope}); + + storeFactory.getScopeStore().findByResourceServer(scopeSearch, resourceServer.getId(), -1, 1).forEach(scope1 -> { + policies.addAll(policyStore.findByScopeIds(Arrays.asList(scope1.getId()), resourceServer.getId())); + }); + } if (policies.isEmpty()) { return Response.ok(Collections.emptyList()).build(); } + new ArrayList<>(policies).forEach(policy -> findAssociatedPolicies(policy, policies)); + search.put("id", policies.stream().map(Policy::getId).toArray(String[]::new)); } diff --git a/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java index 311627a6bf..7477d843fa 100644 --- a/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java +++ b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java @@ -17,6 +17,7 @@ package org.keycloak.email; +import com.sun.mail.smtp.SMTPMessage; import org.jboss.logging.Logger; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -25,15 +26,17 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.truststore.HostnameVerificationPolicy; import org.keycloak.truststore.JSSETruststoreConfigurator; +import javax.mail.Address; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; +import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.net.ssl.SSLSocketFactory; +import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.Date; @@ -91,6 +94,10 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider { props.setProperty("mail.smtp.connectiontimeout", "10000"); String from = config.get("from"); + String fromDisplayName = config.get("fromDisplayName"); + String replyTo = config.get("replyTo"); + String replyToDisplayName = config.get("replyToDisplayName"); + String envelopeFrom = config.get("envelopeFrom"); Session session = Session.getInstance(props); @@ -108,8 +115,17 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider { multipart.addBodyPart(htmlPart); } - MimeMessage msg = new MimeMessage(session); - msg.setFrom(new InternetAddress(from)); + SMTPMessage msg = new SMTPMessage(session); + msg.setFrom(toInternetAddress(from, fromDisplayName)); + + msg.setReplyTo(new Address[]{toInternetAddress(from, fromDisplayName)}); + if (replyTo != null) { + msg.setReplyTo(new Address[]{toInternetAddress(replyTo, replyToDisplayName)}); + } + if (envelopeFrom != null) { + msg.setEnvelopeFrom(envelopeFrom); + } + msg.setHeader("To", address); msg.setSubject(subject, "utf-8"); msg.setContent(multipart); @@ -136,6 +152,13 @@ public class DefaultEmailSenderProvider implements EmailSenderProvider { } } } + + protected InternetAddress toInternetAddress(String email, String displayName) throws UnsupportedEncodingException, AddressException { + if (displayName == null || "".equals(displayName.trim())) { + return new InternetAddress(email); + } + return new InternetAddress(email, displayName, "utf-8"); + } protected String retrieveEmailAddress(UserModel user) { return user.getEmail(); diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index bf3bc9f9f4..f9efe19ab6 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -815,52 +815,58 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal return browserAuthentication(clientCode.getClientSession(), message); } - private Response performAccountLinking(ClientSessionModel clientSession, BrokeredIdentityContext context, FederatedIdentityModel federatedIdentityModel, UserModel federatedUser) { + private Response performAccountLinking(ClientSessionModel clientSession, BrokeredIdentityContext context, FederatedIdentityModel newModel, UserModel federatedUser) { this.event.event(EventType.FEDERATED_IDENTITY_LINK); + + UserModel authenticatedUser = clientSession.getUserSession().getUser(); - if (federatedUser != null) { - if (authenticatedUser.getId().equals(federatedUser.getId())) { - // refresh the token - if (context.getIdpConfig().isStoreToken()) { - federatedIdentityModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel); - if (!ObjectUtil.isEqualOrBothNull(context.getToken(), federatedIdentityModel.getToken())) { - - this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, federatedIdentityModel); - - if (isDebugEnabled()) { - logger.debugf("Identity [%s] update with response from identity provider [%s].", federatedUser, context.getIdpConfig().getAlias()); - } - } - } - return Response.status(302).location(UriBuilder.fromUri(clientSession.getRedirectUri()).build()).build(); - } else { - return redirectToAccountErrorPage(clientSession, Messages.IDENTITY_PROVIDER_ALREADY_LINKED, context.getIdpConfig().getAlias()); - } - } - - - if (isDebugEnabled()) { - logger.debugf("Linking account [%s] from identity provider [%s] to user [%s].", federatedIdentityModel, context.getIdpConfig().getAlias(), authenticatedUser); - } - - if (!authenticatedUser.isEnabled()) { - return redirectToAccountErrorPage(clientSession, Messages.ACCOUNT_DISABLED); + if (federatedUser != null && !authenticatedUser.getId().equals(federatedUser.getId())) { + return redirectToAccountErrorPage(clientSession, Messages.IDENTITY_PROVIDER_ALREADY_LINKED, context.getIdpConfig().getAlias()); } if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(MANAGE_ACCOUNT))) { return redirectToErrorPage(Messages.INSUFFICIENT_PERMISSION); } - this.session.users().addFederatedIdentity(this.realmModel, authenticatedUser, federatedIdentityModel); + if (!authenticatedUser.isEnabled()) { + return redirectToAccountErrorPage(clientSession, Messages.ACCOUNT_DISABLED); + } + + + + if (federatedUser != null) { + if (context.getIdpConfig().isStoreToken()) { + FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel); + if (!ObjectUtil.isEqualOrBothNull(context.getToken(), oldModel.getToken())) { + this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, newModel); + if (isDebugEnabled()) { + logger.debugf("Identity [%s] update with response from identity provider [%s].", federatedUser, context.getIdpConfig().getAlias()); + } + } + } + } else { + this.session.users().addFederatedIdentity(this.realmModel, authenticatedUser, newModel); + } context.getIdp().attachUserSession(clientSession.getUserSession(), clientSession, context); + + if (isDebugEnabled()) { + logger.debugf("Linking account [%s] from identity provider [%s] to user [%s].", newModel, context.getIdpConfig().getAlias(), authenticatedUser); + } + this.event.user(authenticatedUser) .detail(Details.USERNAME, authenticatedUser.getUsername()) - .detail(Details.IDENTITY_PROVIDER, federatedIdentityModel.getIdentityProvider()) - .detail(Details.IDENTITY_PROVIDER_USERNAME, federatedIdentityModel.getUserName()) + .detail(Details.IDENTITY_PROVIDER, newModel.getIdentityProvider()) + .detail(Details.IDENTITY_PROVIDER_USERNAME, newModel.getUserName()) .success(); + + // we do this to make sure that the parent IDP is logged out when this user session is complete. + + clientSession.getUserSession().setNote(Details.IDENTITY_PROVIDER, context.getIdpConfig().getAlias()); + clientSession.getUserSession().setNote(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername()); + return Response.status(302).location(UriBuilder.fromUri(clientSession.getRedirectUri()).build()).build(); } diff --git a/services/src/main/java/org/keycloak/services/resources/JsResource.java b/services/src/main/java/org/keycloak/services/resources/JsResource.java index c74abf0e52..3e41dad355 100755 --- a/services/src/main/java/org/keycloak/services/resources/JsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/JsResource.java @@ -19,6 +19,7 @@ package org.keycloak.services.resources; import org.keycloak.Config; import org.keycloak.common.Version; +import org.keycloak.utils.MediaType; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -43,14 +44,14 @@ public class JsResource { */ @GET @Path("/keycloak.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakJs() { return getJs("keycloak.js"); } @GET @Path("/{version}/keycloak.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakJsWithVersion(@PathParam("version") String version) { if (!version.equals(Version.RESOURCES_VERSION)) { return Response.status(Response.Status.NOT_FOUND).build(); @@ -61,14 +62,14 @@ public class JsResource { @GET @Path("/keycloak.min.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakMinJs() { return getJs("keycloak.min.js"); } @GET @Path("/{version}/keycloak.min.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakMinJsWithVersion(@PathParam("version") String version) { if (!version.equals(Version.RESOURCES_VERSION)) { return Response.status(Response.Status.NOT_FOUND).build(); @@ -84,14 +85,14 @@ public class JsResource { */ @GET @Path("/keycloak-authz.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakAuthzJs() { return getJs("keycloak-authz.js"); } @GET @Path("/{version}/keycloak-authz.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakAuthzJsWithVersion(@PathParam("version") String version) { if (!version.equals(Version.RESOURCES_VERSION)) { return Response.status(Response.Status.NOT_FOUND).build(); @@ -102,14 +103,14 @@ public class JsResource { @GET @Path("/keycloak-authz.min.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakAuthzMinJs() { return getJs("keycloak-authz.min.js"); } @GET @Path("/{version}/keycloak-authz.min.js") - @Produces("text/javascript") + @Produces(MediaType.TEXT_PLAIN_JAVASCRIPT) public Response getKeycloakAuthzMinJsWithVersion(@PathParam("version") String version) { if (!version.equals(Version.RESOURCES_VERSION)) { return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/services/src/main/java/org/keycloak/services/resources/RobotsResource.java b/services/src/main/java/org/keycloak/services/resources/RobotsResource.java index 16e9393c66..b4c37719cc 100755 --- a/services/src/main/java/org/keycloak/services/resources/RobotsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RobotsResource.java @@ -17,10 +17,11 @@ package org.keycloak.services.resources; +import org.keycloak.utils.MediaType; + import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; @Path("/robots.txt") public class RobotsResource { @@ -28,7 +29,7 @@ public class RobotsResource { private static final String robots = "User-agent: *\n" + "Disallow: /"; @GET - @Produces(MediaType.TEXT_PLAIN) + @Produces(MediaType.TEXT_PLAIN_UTF_8) public String getRobots() { return robots; } diff --git a/services/src/main/java/org/keycloak/social/openshift/OpenshifV3IdentityProviderConfig.java b/services/src/main/java/org/keycloak/social/openshift/OpenshifV3IdentityProviderConfig.java new file mode 100644 index 0000000000..cd931f82e5 --- /dev/null +++ b/services/src/main/java/org/keycloak/social/openshift/OpenshifV3IdentityProviderConfig.java @@ -0,0 +1,27 @@ +package org.keycloak.social.openshift; + +import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig; +import org.keycloak.models.IdentityProviderModel; + +public class OpenshifV3IdentityProviderConfig extends OAuth2IdentityProviderConfig { + private static final String BASE_URL = "baseUrl"; + + public OpenshifV3IdentityProviderConfig(IdentityProviderModel identityProviderModel) { + super(identityProviderModel); + } + + public String getBaseUrl() { + return getConfig().get(BASE_URL); + } + + public void setBaseUrl(String baseUrl) { + getConfig().put(BASE_URL, trimTrailingSlash(baseUrl)); + } + + private String trimTrailingSlash(String baseUrl) { + if (baseUrl != null && baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + return baseUrl; + } +} diff --git a/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProvider.java b/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProvider.java new file mode 100644 index 0000000000..8bc4bd5e4f --- /dev/null +++ b/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProvider.java @@ -0,0 +1,66 @@ +package org.keycloak.social.openshift; + +import com.fasterxml.jackson.databind.JsonNode; +import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider; +import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper; +import org.keycloak.broker.oidc.util.JsonSimpleHttp; +import org.keycloak.broker.provider.BrokeredIdentityContext; +import org.keycloak.broker.provider.IdentityBrokerException; +import org.keycloak.broker.provider.util.SimpleHttp; +import org.keycloak.broker.social.SocialIdentityProvider; +import org.keycloak.models.KeycloakSession; + +import java.io.IOException; +import java.util.Optional; + +/** + * Identity provider for Openshift V3. Check official documentation for more details. + */ +public class OpenshiftV3IdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider { + + public static final String BASE_URL = "https://api.preview.openshift.com"; + private static final String AUTH_RESOURCE = "/oauth/authorize"; + private static final String TOKEN_RESOURCE = "/oauth/token"; + private static final String PROFILE_RESOURCE = "/oapi/v1/users/~"; + private static final String DEFAULT_SCOPE = "user:info"; + + public OpenshiftV3IdentityProvider(KeycloakSession session, OpenshifV3IdentityProviderConfig config) { + super(session, config); + final String baseUrl = Optional.ofNullable(config.getBaseUrl()).orElse(BASE_URL); + config.setAuthorizationUrl(baseUrl + AUTH_RESOURCE); + config.setTokenUrl(baseUrl + TOKEN_RESOURCE); + config.setUserInfoUrl(baseUrl + PROFILE_RESOURCE); + } + + @Override + protected String getDefaultScopes() { + return DEFAULT_SCOPE; + } + + @Override + protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) { + try { + final JsonNode profile = fetchProfile(accessToken); + final BrokeredIdentityContext user = extractUserContext(profile.get("metadata")); + AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias()); + return user; + } catch (Exception e) { + throw new IdentityBrokerException("Could not obtain user profile from Openshift.", e); + } + } + + private BrokeredIdentityContext extractUserContext(JsonNode metadata) { + final BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(metadata, "uid")); + user.setUsername(getJsonProperty(metadata, "name")); + user.setName(getJsonProperty(metadata, "fullName")); + user.setIdpConfig(getConfig()); + user.setIdp(this); + return user; + } + + private JsonNode fetchProfile(String accessToken) throws IOException { + return JsonSimpleHttp.asJson(SimpleHttp.doGet(getConfig().getUserInfoUrl(), this.session) + .header("Authorization", "Bearer " + accessToken)); + } + +} diff --git a/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderFactory.java b/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderFactory.java new file mode 100644 index 0000000000..b3705301d6 --- /dev/null +++ b/services/src/main/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderFactory.java @@ -0,0 +1,27 @@ +package org.keycloak.social.openshift; + +import org.keycloak.broker.provider.AbstractIdentityProviderFactory; +import org.keycloak.broker.social.SocialIdentityProviderFactory; +import org.keycloak.models.IdentityProviderModel; +import org.keycloak.models.KeycloakSession; + +public class OpenshiftV3IdentityProviderFactory extends AbstractIdentityProviderFactory implements SocialIdentityProviderFactory { + + public static final String PROVIDER_ID = "openshift-v3"; + + @Override + public String getName() { + return "Openshift v3"; + } + + @Override + public OpenshiftV3IdentityProvider create(KeycloakSession keycloakSession, IdentityProviderModel identityProviderModel) { + return new OpenshiftV3IdentityProvider(keycloakSession, new OpenshifV3IdentityProviderConfig(identityProviderModel)); + } + + @Override + public String getId() { + return PROVIDER_ID; + } + +} diff --git a/services/src/main/java/org/keycloak/utils/MediaType.java b/services/src/main/java/org/keycloak/utils/MediaType.java index c34858dccd..acb0b4134e 100644 --- a/services/src/main/java/org/keycloak/utils/MediaType.java +++ b/services/src/main/java/org/keycloak/utils/MediaType.java @@ -25,6 +25,12 @@ public class MediaType { public static final String TEXT_HTML_UTF_8 = "text/html; charset=utf-8"; public static final javax.ws.rs.core.MediaType TEXT_HTML_UTF_8_TYPE = new javax.ws.rs.core.MediaType("text", "html", "utf-8"); + public static final String TEXT_PLAIN_UTF_8 = "text/plain; charset=utf-8"; + public static final javax.ws.rs.core.MediaType TEXT_PLAIN_UTF_8_TYPE = new javax.ws.rs.core.MediaType("text", "plain", "utf-8"); + + public static final String TEXT_PLAIN_JAVASCRIPT = "text/javascript; charset=utf-8"; + public static final javax.ws.rs.core.MediaType TEXT_JAVASCRIPT_UTF_8_TYPE = new javax.ws.rs.core.MediaType("text", "javascript", "utf-8"); + public static final String APPLICATION_JSON = javax.ws.rs.core.MediaType.APPLICATION_JSON; public static final javax.ws.rs.core.MediaType APPLICATION_JSON_TYPE = javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; 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 1311132928..00a5e5163d 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 @@ -22,3 +22,4 @@ org.keycloak.social.linkedin.LinkedInIdentityProviderFactory org.keycloak.social.stackoverflow.StackoverflowIdentityProviderFactory org.keycloak.social.twitter.TwitterIdentityProviderFactory org.keycloak.social.microsoft.MicrosoftIdentityProviderFactory +org.keycloak.social.openshift.OpenshiftV3IdentityProviderFactory diff --git a/services/src/test/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderTest.java b/services/src/test/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderTest.java new file mode 100644 index 0000000000..e39f157681 --- /dev/null +++ b/services/src/test/java/org/keycloak/social/openshift/OpenshiftV3IdentityProviderTest.java @@ -0,0 +1,33 @@ +package org.keycloak.social.openshift; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.models.IdentityProviderModel; + +public class OpenshiftV3IdentityProviderTest { + + @Test + public void shouldConstructProviderUrls() throws Exception { + final OpenshifV3IdentityProviderConfig config = new OpenshifV3IdentityProviderConfig(new IdentityProviderModel()); + config.setBaseUrl("http://openshift.io:8443"); + final OpenshiftV3IdentityProvider openshiftV3IdentityProvider = new OpenshiftV3IdentityProvider(null, config); + + assertConfiguredUrls(openshiftV3IdentityProvider); + } + + @Test + public void shouldConstructProviderUrlsForBaseUrlWithTrailingSlash() throws Exception { + final OpenshifV3IdentityProviderConfig config = new OpenshifV3IdentityProviderConfig(new IdentityProviderModel()); + config.setBaseUrl("http://openshift.io:8443/"); + final OpenshiftV3IdentityProvider openshiftV3IdentityProvider = new OpenshiftV3IdentityProvider(null, config); + + assertConfiguredUrls(openshiftV3IdentityProvider); + } + + private void assertConfiguredUrls(OpenshiftV3IdentityProvider openshiftV3IdentityProvider) { + Assert.assertEquals("http://openshift.io:8443/oauth/authorize", openshiftV3IdentityProvider.getConfig().getAuthorizationUrl()); + Assert.assertEquals("http://openshift.io:8443/oauth/token", openshiftV3IdentityProvider.getConfig().getTokenUrl()); + Assert.assertEquals("http://openshift.io:8443/oapi/v1/users/~", openshiftV3IdentityProvider.getConfig().getUserInfoUrl()); + } + +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml index 9c66b1a54a..c05b4a9082 100644 --- a/testsuite/integration-arquillian/pom.xml +++ b/testsuite/integration-arquillian/pom.xml @@ -43,7 +43,7 @@ 1.1.11.Final 2.53.0 - 2.0.0.Beta1 + 2.0.1.Final 2.1.0.Alpha3 2.0.0.Final 2.2.2 @@ -52,7 +52,7 @@ 1.9.8.Final 2.2.1.Final - + 2.5.5.Final 1.8 1.8 @@ -176,7 +176,7 @@ - + diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/common/install-adapters.sh b/testsuite/integration-arquillian/servers/app-server/jboss/common/install-adapters.sh index 460599234b..bd9e65b25e 100755 --- a/testsuite/integration-arquillian/servers/app-server/jboss/common/install-adapters.sh +++ b/testsuite/integration-arquillian/servers/app-server/jboss/common/install-adapters.sh @@ -23,10 +23,20 @@ do echo "Server is running. Installing adapter." ./jboss-cli.sh -c --file="adapter-install.cli" + + if [ "$ELYTRON_SUPPORTED" = true ]; then + ./jboss-cli.sh -c --file="adapter-elytron-install.cli" + fi + if [ $? -ne 0 ]; then RESULT=1; fi if [ "$SAML_SUPPORTED" = true ]; then ./jboss-cli.sh -c --file="adapter-install-saml.cli" + + if [ "$ELYTRON_SUPPORTED" = true ]; then + ./jboss-cli.sh -c --file="adapter-elytron-install-saml.cli" + fi + if [ $? -ne 0 ]; then RESULT=1; fi fi diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml index 658fb39123..5299493e09 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml @@ -200,6 +200,7 @@ ${app.server.java.home} ${app.server.jboss.home} ${app.server.saml.adapter.supported} + ${app.server.elytron.adapter.supported} @@ -444,6 +445,17 @@ eap6-fuse + + + app-server-wildfly-elytron + + false + + + ${elytron.wildfly.version} + true + + diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml index 1a34edc8b8..e36fa48401 100644 --- a/testsuite/integration-arquillian/servers/pom.xml +++ b/testsuite/integration-arquillian/servers/pom.xml @@ -35,8 +35,8 @@ 9.0.2.Final 8.2.1.Final - 7.0.0.ER6-redhat-1 - 7.5.6.Final-redhat-2 + 7.0.5.GA-redhat-2 + 7.5.14.Final-redhat-2 7.1.1.Final 7.0.68 8.0.32 diff --git a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html index f34878afd3..0f1d3f2dd2 100755 --- a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html +++ b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html @@ -194,9 +194,6 @@ TimeSkew: function sendBearerToKeycloak() { var url = 'http://localhost:8180/auth/admin/realms/example/roles'; if (window.location.href.indexOf("8643") > -1) { - url = url.replace("8180","8543"); - url = url.replace("http","https"); - if (window.location.href.indexOf("8543") > -1) { url = url.replace("8180", "8543"); url = url.replace("http", "https"); } diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkServlet.java index d0678cf1a4..45bbc60a1b 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkServlet.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkServlet.java @@ -21,6 +21,7 @@ import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.representations.AccessToken; +import javax.servlet.annotation.WebServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -36,6 +37,7 @@ import java.util.UUID; * @author Bill Burke * @version $Revision: 1 $ */ +@WebServlet("/client-linking") public class ClientInitiatedAccountLinkServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java index ea70450924..312223476c 100755 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java @@ -68,7 +68,7 @@ public class SamlSPFacade extends HttpServlet { private String getSamlRequest() { if (System.getProperty("auth.server.ssl.required", "false").equals("true")) { - return "jZJJT8MwEIXvSPyHyPfUTrokWE2lQoWoxBLRwoELMs6UWnLs4HFY%2Fj1OoALEIiQfLPt55r1vPEVR64bPW781l%2FDQAvroudYGeX9RkNYZbgUq5EbUgNxLvpqfnfJ0wHjjrLfSavL25G%2BxQATnlTUkmu%2B2R9ZgW4NbgXtUEq4uTwuy9b5BTqm2UuitRc%2FzyWhIoW60fQGgJFoEk8qIrsCP8nGQixCIOhC6RlpBbenOK%2B1ykejYOgl96oJshEYg0XJRkOXidlTlMJaQxlnKJvEoS%2B9ikR9kcVrlw4wdMMnYOIixDIHUI3w8R2xhadAL4wuSsmQcs2HMJus05WEl2SAYuyFR%2BW7kUJlKmfu%2Fod29iZCfrNdlXF6s1iS6Bod99CAgs%2F29aZeI9%2B3dp9n9dxqzjuBXgCxPPnhP6af6u3YNPw8ll4vSaiVfornW9uko4PaBh3ct9IBr4X83kQyS%2FkRV8aaX8tZgA1JtFFSEdo3o9785ewU%3D\n"; + return "jZJJT8MwEIXvSPyHyPfUTrokWE2lQoWoxBLRwoELMs6UWnLs4HFY%2Fj1OoALEIiQfLPt55r1vPEVR64bPW781l%2FDQAvroudYGeX9RkNYZbgUq5EbUgNxLvpqfnfJ0wHjjrLfSavL25G%2BxQATnlTUkmu%2B2R9ZgW4NbgXtUEq4uTwuy9b5BTqm2UuitRc%2FzyWhIoW60fQGgJFoEk8qIrsCP8nGQixCIOhC6RlpBbenOK%2B1ykejYOgl96oJshEYg0XJRkOXidlTlMJaQxlnKJvEoS%2B9ikR9kcVrlw4wdMMnYOIixDIHUI3w8R2xhadAL4wuSsmQcs2HMJus05WEl2SAYuyFR%2BW7kUJlKmfu%2Fod29iZCfrNdlXF6s1iS6Bod99CAgs%2F29aZeI9%2B3dp9n9dxqzjuBXgCxPPnhP6af6u3YNPw8ll4vSaiVfornW9uko4PaBh3ct9IBr4X83kQyS%2FkRV8aaX8tZgA1JtFFSEdo3o9785ewU%3D"; } return "jZJdS8MwFIbvBf9DyX2XNG62hnUwHeLAj7JNL7yRmJ65QJrUnNSPf29WHQp%2BIOQiJM%2FJed%2F3ZIyyMa2YdmFjF%2FDYAYbkpTEWRX9Rks5b4SRqFFY2gCIosZxenAs%2BYKL1LjjlDHkv%2BRuWiOCDdpYk0932xFnsGvBL8E9awfXivCSbEFpBqXFKmo3DIApeMApNa9wrACXJLGrUVm7rf6KzSMtoh3qQpkFaQ%2BPoTinduiLJqfMKes8lWUuDQJL5rCTz2d2wLmCkgKc5Z4fpMOf3qSyO8pTXxUHOjphibBRhrKId%2FQSf5YgdzC0GaUNJOMtGKTtI2eGKcxFXlg%2BK0fCWJNWHkGNta20f%2Fo7s%2Fh1CcbZaVWl1tVyR5AY89s4jQCb7e%2BOtI9G3918m999ZTL4HyIrsM%2B4x%2FfL%2Brl0rLuOT81nljFavydQY93wS4w4xj%2BA76ANuZPhdRDbI%2BhNdp%2BseFZ3FFpRea6gJ3Tai33%2Fm5A0%3D"; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/DifferentCookieNameServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/DifferentCookieNameServlet.java new file mode 100644 index 0000000000..5594b9665f --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/DifferentCookieNameServlet.java @@ -0,0 +1,39 @@ +/* + * 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.testsuite.adapter.page; + +import org.jboss.arquillian.container.test.api.OperateOnDeployment; +import org.jboss.arquillian.test.api.ArquillianResource; + +import java.net.URL; + +/** + * @author mhajas + */ +public class DifferentCookieNameServlet extends SAMLServlet { + public static final String DEPLOYMENT_NAME = "different-cookie-name"; + + @ArquillianResource + @OperateOnDeployment(DEPLOYMENT_NAME) + private URL url; + + @Override + public URL getInjectedUrl() { + return url; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java index fb7d9b1d65..a732c473f7 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java @@ -17,6 +17,7 @@ package org.keycloak.testsuite.auth.page.login; import org.keycloak.testsuite.util.UIUtils; +import org.keycloak.testsuite.util.WaitUtils; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -41,9 +42,11 @@ public class TermsAndConditions extends LoginActions { public void acceptTerms() { acceptButton.click(); + WaitUtils.waitForPageToLoad(driver); } public void declineTerms() { declineButton.click(); + WaitUtils.waitForPageToLoad(driver); } public String getAcceptButtonText() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java index 4e6d767a5b..cfe13e2df6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java @@ -74,12 +74,13 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest { public void setDefaultPageUriParameters() { super.setDefaultPageUriParameters(); testRealmPage.setAuthRealm(TEST); - testRealmLoginPage.setAuthRealm(testRealmPage); - testRealmAccountPage.setAuthRealm(testRealmPage); } @Before public void beforeAuthTest() { + testRealmLoginPage.setAuthRealm(testRealmPage); + testRealmAccountPage.setAuthRealm(testRealmPage); + testUser = createUserRepresentation("test", "test@email.test", "test", "user", true); setPasswordFor(testUser, PASSWORD); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java index 539267fa9e..eb719d884b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java @@ -46,7 +46,6 @@ import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.MimeMessage; import java.io.IOException; -import java.util.Collections; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -98,6 +97,28 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo ApiUtil.createUserAndResetPasswordWithAdminClient(testRealm(), user, "password"); } + /** + * see KEYCLOAK-4163 + */ + @Test + public void verifyEmailConfig() throws IOException, MessagingException { + + loginPage.open(); + loginPage.login("test-user@localhost", "password"); + + Assert.assertTrue(verifyEmailPage.isCurrent()); + + Assert.assertEquals(1, greenMail.getReceivedMessages().length); + + MimeMessage message = greenMail.getReceivedMessages()[0]; + + // see testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json + Assert.assertEquals("", message.getHeader("Return-Path")[0]); + // displayname + Assert.assertEquals("Keycloak SSO ", message.getHeader("From")[0]); + Assert.assertEquals("Keycloak no-reply ", message.getHeader("Reply-To")[0]); + } + @Test public void verifyEmailExisting() throws IOException, MessagingException { loginPage.open(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java index 534e0b1fe9..43981645aa 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java @@ -22,12 +22,16 @@ import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.AfterClass; import org.junit.Test; +import org.keycloak.representations.VersionRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; import org.keycloak.testsuite.adapter.page.AngularCorsProductTestApp; import org.keycloak.testsuite.adapter.page.CorsDatabaseServiceTestApp; import org.keycloak.testsuite.auth.page.account.Account; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; import java.io.File; import java.io.IOException; import java.util.List; @@ -112,9 +116,12 @@ public abstract class AbstractCorsExampleAdapterTest extends AbstractExampleAdap angularCorsProductPage.loadPublicRealmInfo(); waitUntilElement(angularCorsProductPage.getOutput()).text().contains("Realm name: cors"); - angularCorsProductPage.loadVersion(); - waitUntilElement(angularCorsProductPage.getOutput()).text().contains("Keycloak version: " + System.getProperty("project.version")); + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(authServerPage.createUriBuilder()).path("version"); + VersionRepresentation version = target.request().get(VersionRepresentation.class); + angularCorsProductPage.loadVersion(); + waitUntilElement(angularCorsProductPage.getOutput()).text().contains("Keycloak version: " + version.getVersion()); } @AfterClass diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/ClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java similarity index 83% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/ClientInitiatedAccountLinkTest.java rename to testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java index e63912791f..72e8c46622 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/ClientInitiatedAccountLinkTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.keycloak.testsuite.broker; +package org.keycloak.testsuite.adapter.servlet; -import org.apache.http.client.utils.URIBuilder; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.arquillian.graphene.page.Page; @@ -25,30 +24,31 @@ import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.common.util.Base64Url; +import org.keycloak.models.Constants; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocolService; +import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.FederatedIdentityRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.adapter.page.AppServerContextRoot; -import org.keycloak.testsuite.adapter.servlet.ClientInitiatedAccountLinkServlet; +import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProvider; +import org.keycloak.testsuite.broker.BrokerTestTools; import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl; -import org.keycloak.testsuite.pages.AccountFederatedIdentityPage; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.UpdateAccountInformationPage; -import org.keycloak.testsuite.util.AdapterServletDeployment; +import org.keycloak.testsuite.util.OAuthClient; +import org.keycloak.testsuite.util.WaitUtils; +import org.keycloak.util.JsonSerialization; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.core.UriBuilder; import java.net.URL; import java.util.LinkedList; @@ -57,7 +57,6 @@ import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.junit.Assert.assertTrue; import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT; import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS; import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID; @@ -67,8 +66,7 @@ import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWit * @author Bill Burke * @version $Revision: 1 $ */ -@AppServerContainer("auth-server-undertow") -public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { +public abstract class AbstractClientInitiatedAccountLinkTest extends AbstractServletsAdapterTest { public static final String CHILD_IDP = "child"; public static final String PARENT_IDP = "parent-idp"; public static final String PARENT_USERNAME = "parent"; @@ -77,14 +75,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { protected UpdateAccountInformationPage profilePage; @Page - protected LoginPage loginPage; - - @Page - protected AppServerContextRoot appServerContextRootPage; - - public boolean isRelative() { - return testContext.isRelativeAdapterTest(); - } + private LoginPage loginPage; public static class ClientApp extends AbstractPageWithInjectedUrl { @@ -102,15 +93,14 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { } @Page - protected ClientApp appPage; + private ClientApp appPage; @Override - protected boolean isImportAfterEachMethod() { - return true; + public void beforeAuthTest() { } - + @Override - public void addTestRealms(List testRealms) { + public void addAdapterTestRealms(List testRealms) { RealmRepresentation realm = new RealmRepresentation(); realm.setRealm(CHILD_IDP); realm.setEnabled(true); @@ -122,6 +112,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { uri = appServerContextRootPage.toString() + uri; } servlet.setAdminUrl(uri); + servlet.setDirectAccessGrantsEnabled(true); servlet.setBaseUrl(uri); servlet.setRedirectUris(new LinkedList<>()); servlet.getRedirectUris().add(uri + "/*"); @@ -139,13 +130,12 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { testRealms.add(realm); } - - @Deployment(name = "client-linking") - public static WebArchive customerPortal() { - return AdapterServletDeployment.oidcDeployment("client-linking", "/account-link-test", ClientInitiatedAccountLinkServlet.class); + + @Deployment(name = ClientApp.DEPLOYMENT_NAME) + protected static WebArchive accountLink() { + return servletDeployment(ClientApp.DEPLOYMENT_NAME, ClientInitiatedAccountLinkServlet.class, ServletTestUtils.class); } - - + @Before public void addIdpUser() { RealmResource realm = adminClient.realms().realm(PARENT_IDP); @@ -172,6 +162,11 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { List roles = new LinkedList<>(); roles.add(role); realm.users().get(childUserId).roles().realmLevel().add(roles); + ClientRepresentation brokerService = realm.clients().findByClientId(Constants.BROKER_SERVICE_CLIENT_ID).get(0); + role = realm.clients().get(brokerService.getId()).roles().get(Constants.READ_TOKEN_ROLE).toRepresentation(); + roles.clear(); + roles.add(role); + realm.users().get(childUserId).roles().clientLevel(brokerService.getId()).add(roles); } @@ -184,7 +179,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { BrokerTestTools.createKcOidcBroker(adminClient, CHILD_IDP, PARENT_IDP, suiteContext); } - //@Test +// @Test public void testUi() throws Exception { Thread.sleep(1000000000); @@ -215,7 +210,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { // test not logged in - driver.navigate().to(linkUrl); + navigateTo(linkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); @@ -225,7 +220,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { // now log in - driver.navigate().to( appPage.getInjectedUrl() + "/hello"); + navigateTo( appPage.getInjectedUrl() + "/hello"); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); Assert.assertTrue(driver.getCurrentUrl().startsWith(appPage.getInjectedUrl() + "/hello")); @@ -233,7 +228,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { // now test CSRF with bad hash. - driver.navigate().to(linkUrl); + navigateTo(linkUrl); Assert.assertTrue(driver.getPageSource().contains("We're sorry...")); @@ -254,7 +249,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { roles.add(userRole); clientResource.getScopeMappings().realmLevel().add(roles); - driver.navigate().to( appPage.getInjectedUrl() + "/hello"); + navigateTo( appPage.getInjectedUrl() + "/hello"); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); Assert.assertTrue(driver.getCurrentUrl().startsWith(appPage.getInjectedUrl() + "/hello")); @@ -268,7 +263,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { .queryParam("provider", PARENT_IDP).build().toString(); - driver.navigate().to(clientLinkUrl); + navigateTo(clientLinkUrl); Assert.assertTrue(driver.getCurrentUrl().contains("error=not_allowed")); @@ -284,7 +279,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { roles.add(manageLinks); clientResource.getScopeMappings().clientLevel(accountId).add(roles); - driver.navigate().to(clientLinkUrl); + navigateTo(clientLinkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); Assert.assertTrue(loginPage.isCurrent(PARENT_IDP)); @@ -304,7 +299,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { logoutAll(); - driver.navigate().to(clientLinkUrl); + navigateTo(clientLinkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); @@ -322,7 +317,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { roles.add(manageAccount); clientResource.getScopeMappings().clientLevel(accountId).add(roles); - driver.navigate().to(clientLinkUrl); + navigateTo(clientLinkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); Assert.assertTrue(loginPage.isCurrent(PARENT_IDP)); @@ -342,7 +337,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { logoutAll(); - driver.navigate().to(clientLinkUrl); + navigateTo(clientLinkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); loginPage.login("child", "password"); @@ -380,7 +375,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { String linkUrl = linkBuilder.clone() .queryParam("realm", CHILD_IDP) .queryParam("provider", PARENT_IDP).build().toString(); - driver.navigate().to(linkUrl); + navigateTo(linkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); Assert.assertTrue(driver.getPageSource().contains(PARENT_IDP)); loginPage.login("child", "password"); @@ -391,6 +386,25 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate())); Assert.assertTrue(driver.getPageSource().contains("Account Linked")); + OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest(CHILD_IDP, "child", "password", null, "client-linking", "password"); + Assert.assertNotNull(response.getAccessToken()); + Assert.assertNull(response.getError()); + Client httpClient = ClientBuilder.newClient(); + String firstToken = getToken(response, httpClient); + Assert.assertNotNull(firstToken); + + + navigateTo(linkUrl); + Assert.assertTrue(driver.getPageSource().contains("Account Linked")); + String nextToken = getToken(response, httpClient); + Assert.assertNotNull(nextToken); + Assert.assertNotEquals(firstToken, nextToken); + + + + + + links = realm.users().get(childUserId).getFederatedIdentity(); Assert.assertFalse(links.isEmpty()); @@ -403,11 +417,24 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { } + private String getToken(OAuthClient.AccessTokenResponse response, Client httpClient) throws Exception { + String idpToken = httpClient.target(OAuthClient.AUTH_SERVER_ROOT) + .path("realms") + .path("child/broker") + .path(PARENT_IDP) + .path("token") + .request() + .header("Authorization", "Bearer " + response.getAccessToken()) + .get(String.class); + AccessTokenResponse res = JsonSerialization.readValue(idpToken, AccessTokenResponse.class); + return res.getToken(); + } + public void logoutAll() { String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()).build(CHILD_IDP).toString(); - driver.navigate().to(logoutUri); + navigateTo(logoutUri); logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()).build(PARENT_IDP).toString(); - driver.navigate().to(logoutUri); + navigateTo(logoutUri); } @Test @@ -426,7 +453,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { String linkUrl = linkBuilder.clone() .queryParam("realm", CHILD_IDP) .queryParam("provider", PARENT_IDP).build().toString(); - driver.navigate().to(linkUrl); + navigateTo(linkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); // should not be on login page. This is what we are testing @@ -452,7 +479,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { System.out.println("testing link-only attack"); - driver.navigate().to(linkUrl); + navigateTo(linkUrl); Assert.assertTrue(loginPage.isCurrent(CHILD_IDP)); System.out.println("login page uri is: " + driver.getCurrentUrl()); @@ -488,7 +515,7 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { System.out.println("hack uri: " + uri); - driver.navigate().to(uri); + navigateTo(uri); Assert.assertTrue(driver.getPageSource().contains("Could not send authentication request to identity provider.")); @@ -505,5 +532,11 @@ public class ClientInitiatedAccountLinkTest extends AbstractKeycloakTest { } + private void navigateTo(String uri) { + driver.navigate().to(uri); + WaitUtils.waitForPageToLoad(driver); + } + + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java index 10d3ab7dab..a199636e57 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java @@ -60,6 +60,7 @@ import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; import org.keycloak.testsuite.adapter.page.BadAssertionSalesPostSig; import org.keycloak.testsuite.adapter.page.BadClientSalesPostSigServlet; import org.keycloak.testsuite.adapter.page.BadRealmSalesPostSigServlet; +import org.keycloak.testsuite.adapter.page.DifferentCookieNameServlet; import org.keycloak.testsuite.adapter.page.Employee2Servlet; import org.keycloak.testsuite.adapter.page.EmployeeServlet; import org.keycloak.testsuite.adapter.page.EmployeeSigFrontServlet; @@ -205,6 +206,9 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd @Page protected EmployeeServlet employeeServletPage; + @Page + protected DifferentCookieNameServlet differentCookieNameServletPage; + @Page private InputPortal inputPortalPage; @@ -303,6 +307,11 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd return samlServletDeployment(SalesPost2Servlet.DEPLOYMENT_NAME, SendUsernameServlet.class); } + @Deployment(name = DifferentCookieNameServlet.DEPLOYMENT_NAME) + protected static WebArchive differentCokieName() { + return samlServletDeployment(DifferentCookieNameServlet.DEPLOYMENT_NAME, "different-cookie-name/WEB-INF/web.xml", SendUsernameServlet.class); + } + @Deployment(name = SalesPostAssertionAndResponseSig.DEPLOYMENT_NAME) protected static WebArchive salesPostAssertionAndResponseSig() { return samlServletDeployment(SalesPostAssertionAndResponseSig.DEPLOYMENT_NAME, SendUsernameServlet.class); @@ -1069,6 +1078,18 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd } } + @Test + // KEYCLOAK-4141 + public void testDifferentCookieName() { + assertSuccessfulLogin(differentCookieNameServletPage, bburkeUser, testRealmSAMLPostLoginPage, "principal=bburke"); + + assertThat(driver.manage().getCookieNamed("DIFFERENT_SESSION_ID"), notNullValue()); + assertThat(driver.manage().getCookieNamed("JSESSIONID"), nullValue()); + + salesPost2ServletPage.logout(); + checkLoggedOut(differentCookieNameServletPage, testRealmSAMLPostLoginPage); + } + private URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException { return RealmsResource .protocolUrl(UriBuilder.fromUri(getAuthServerRoot())) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowClientInitiatedAccountLinkTest.java new file mode 100644 index 0000000000..a1eef978a1 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowClientInitiatedAccountLinkTest.java @@ -0,0 +1,29 @@ +/* + * 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.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * + * @author Vlastislav Ramik + */ +@AppServerContainer("auth-server-undertow") +public class UndertowClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest { + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerTestTools.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerTestTools.java index 40c1f704fa..a43d842c84 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerTestTools.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerTestTools.java @@ -93,12 +93,12 @@ public class BrokerTestTools { public static void createKcOidcBroker(Keycloak adminClient, String childRealm, String idpRealm, SuiteContext suiteContext, String alias, boolean linkOnly) { IdentityProviderRepresentation idp = createIdentityProvider(alias, IDP_OIDC_PROVIDER_ID); idp.setLinkOnly(linkOnly); + idp.setStoreToken(true); Map config = idp.getConfig(); config.put("clientId", childRealm); config.put("clientSecret", childRealm); - config.put("prompt", "login"); config.put("authorizationUrl", getAuthRoot(suiteContext) + "/auth/realms/" + idpRealm + "/protocol/openid-connect/auth"); config.put("tokenUrl", getAuthRoot(suiteContext) + "/auth/realms/" + idpRealm + "/protocol/openid-connect/token"); config.put("logoutUrl", getAuthRoot(suiteContext) + "/auth/realms/" + idpRealm + "/protocol/openid-connect/logout"); 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 6ac3970ca6..2882e81189 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 @@ -2,15 +2,14 @@ package org.keycloak.testsuite.broker; import org.jboss.arquillian.graphene.Graphene; import org.jboss.arquillian.graphene.page.Page; -import org.jboss.arquillian.graphene.wait.WebDriverWait; -import org.junit.Assume; +import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; -import org.keycloak.common.Profile; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.social.openshift.OpenshiftV3IdentityProvider; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.cli.exec.ExecutionException; import org.keycloak.testsuite.pages.AccountUpdateProfilePage; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginUpdateProfilePage; @@ -34,6 +33,7 @@ import static org.junit.Assume.assumeTrue; public class SocialLoginTest extends AbstractKeycloakTest { public static final String SOCIAL_CONFIG = "social.config"; + public static final String REALM = "social"; private static Properties config = new Properties(); @@ -53,12 +53,21 @@ public class SocialLoginTest extends AbstractKeycloakTest { config.load(new FileInputStream(System.getProperty(SOCIAL_CONFIG))); } + @After + public void removeUser() { + List users = adminClient.realm(REALM).users().search(null, null, null); + for (UserRepresentation user : users) { + adminClient.realm(REALM).users().get(user.getId()).remove(); + } + } + @Override public void addTestRealms(List testRealms) { - RealmRepresentation rep = RealmBuilder.create().name("social").build(); + RealmRepresentation rep = RealmBuilder.create().name(REALM).build(); List idps = new LinkedList<>(); rep.setIdentityProviders(idps); + idps.add(buildIdp("openshift-v3")); idps.add(buildIdp("google")); idps.add(buildIdp("facebook")); idps.add(buildIdp("github")); @@ -70,9 +79,25 @@ public class SocialLoginTest extends AbstractKeycloakTest { testRealms.add(rep); } + @Test + public void openshiftLogin() throws Exception { + account.open(REALM); + loginPage.clickSocial("openshift-v3"); + + Graphene.waitGui().until(ExpectedConditions.visibilityOfElementLocated(By.id("inputUsername"))); + driver.findElement(By.id("inputUsername")).sendKeys(config.getProperty("openshift-v3.username", config.getProperty("common.username"))); + driver.findElement(By.id("inputPassword")).sendKeys(config.getProperty("openshift-v3.password", config.getProperty("common.password"))); + driver.findElement(By.cssSelector("button[type=submit]")).click(); + + Graphene.waitGui().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input[name=approve]"))); + driver.findElement(By.cssSelector("input[name=approve]")).click(); + + assertEquals(config.getProperty("openshift-v3.username", config.getProperty("common.profile.username")), account.getUsername()); + } + @Test public void googleLogin() throws InterruptedException { - account.open("social"); + account.open(REALM); loginPage.clickSocial("google"); @@ -97,7 +122,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void faceBookLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("facebook"); @@ -114,7 +139,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void githubLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("github"); @@ -131,7 +156,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void twitterLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("twitter"); @@ -156,7 +181,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void linkedinLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("linkedin"); @@ -173,7 +198,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void microsoftLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("microsoft"); @@ -192,7 +217,7 @@ public class SocialLoginTest extends AbstractKeycloakTest { @Test public void stackoverflowLogin() { - account.open("social"); + account.open(REALM); loginPage.clickSocial("stackoverflow"); @@ -226,6 +251,9 @@ public class SocialLoginTest extends AbstractKeycloakTest { if (id.equals("stackoverflow")) { idp.getConfig().put("key", config.getProperty(id + ".clientKey")); } + if (id.equals("openshift-v3")) { + idp.getConfig().put("baseUrl", config.getProperty(id + ".baseUrl", OpenshiftV3IdentityProvider.BASE_URL)); + } return idp; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java index 0526ab227f..1315b180d7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java @@ -59,6 +59,9 @@ import org.keycloak.testsuite.runonserver.RunHelpers; import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.util.OAuthClient; +import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT; +import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS; +import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID; import static org.keycloak.testsuite.Assert.assertEquals; import static org.keycloak.testsuite.Assert.assertFalse; import static org.keycloak.testsuite.Assert.assertNames; @@ -111,6 +114,13 @@ public class MigrationTest extends AbstractKeycloakTest { } } + @Test + @Migration(versionFrom = "2.5.5.Final") + public void migration2_5_5Test() { + testMigratedData(); + testMigrationTo3_0_0(); + } + @Test @Migration(versionFrom = "1.9.8.Final") public void migration1_9_8Test() { @@ -121,6 +131,7 @@ public class MigrationTest extends AbstractKeycloakTest { testMigrationTo2_3_0(); testMigrationTo2_5_0(); testMigrationTo2_5_1(); + testMigrationTo3_0_0(); } @Test @@ -179,6 +190,9 @@ public class MigrationTest extends AbstractKeycloakTest { testExtractRealmKeys(masterRealm, migrationRealm); } + /** + * @see org.keycloak.migration.migrators.MigrateTo2_5_0 + */ private void testMigrationTo2_5_0() { testLdapKerberosMigration_2_5_0(); @@ -189,6 +203,36 @@ public class MigrationTest extends AbstractKeycloakTest { private void testMigrationTo2_5_1() { testOfflineTokenLogin(); } + + /** + * @see org.keycloak.migration.migrators.MigrateTo3_0_0 + */ + private void testMigrationTo3_0_0() { + testRoleManageAccountLinks(masterRealm, migrationRealm); + } + + private void testRoleManageAccountLinks(RealmResource... realms) { + log.info("testing role manage account links"); + for (RealmResource realm : realms) { + List clients = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID); + if (!clients.isEmpty()) { + String accountClientId = clients.get(0).getId(); + ClientResource accountClient = realm.clients().get(accountClientId); + accountClient.roles().get(MANAGE_ACCOUNT_LINKS).toRepresentation(); //the role should be presented, it'll throw javax.ws.rs.NotFoundException in case the role is not found + + Set roleComposites = accountClient.roles().get(MANAGE_ACCOUNT).getRoleComposites(); + boolean success = false; + for (RoleRepresentation roleComposite : roleComposites) { + if (roleComposite.getName().equals(MANAGE_ACCOUNT_LINKS)) { + success = true; + } + } + if (!success) { + fail("'manage-account' role of client 'account' should have composite role 'manage-account-links'."); + } + } + } + } private void testExtractRealmKeys(RealmResource masterRealm, RealmResource migrationRealm) { log.info("testing extract realm keys"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/NonIDERunListener.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/NonIDERunListener.java new file mode 100644 index 0000000000..17947e4b6c --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/NonIDERunListener.java @@ -0,0 +1,52 @@ +/* + * 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.testsuite.util; + +import org.apache.log4j.Level; +import org.jboss.logging.Logger; +import org.junit.runner.Description; +import org.junit.runner.notification.RunListener; + +/** + * This is executed when test is run from maven (maven-surefire-plugin), but not when it is run from IDE. That allows to run some actions, which should be + * executed just for maven build (eg. disable logging) + * + * @author Marek Posolda + */ +public class NonIDERunListener extends RunListener { + + private static final Logger log = Logger.getLogger(NonIDERunListener.class); + + private static final String KEYCLOAK_LOGGING_LEVEL_NAME = "keycloak.logging.level"; + + @Override + public void testRunStarted(Description description) throws Exception { + disableKeycloakLogging(); + } + + private void disableKeycloakLogging() { + String loggingLevel = System.getProperty(KEYCLOAK_LOGGING_LEVEL_NAME); + if (loggingLevel == null || loggingLevel.isEmpty()) { + + log.infof("Setting %s to off. Keycloak server logging will be disabled", KEYCLOAK_LOGGING_LEVEL_NAME); + System.setProperty(KEYCLOAK_LOGGING_LEVEL_NAME, "off"); + org.apache.log4j.Logger.getLogger("org.keycloak").setLevel(Level.OFF); + } + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/META-INF/context.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/META-INF/context.xml similarity index 100% rename from testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/META-INF/context.xml rename to testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/META-INF/context.xml diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/jetty-web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/jetty-web.xml similarity index 100% rename from testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/jetty-web.xml rename to testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/jetty-web.xml diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/keycloak.json similarity index 100% rename from testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/keycloak.json rename to testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/keycloak.json diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/web.xml similarity index 100% rename from testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/client-linking/WEB-INF/web.xml rename to testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/web.xml diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/childrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/childrealm.json similarity index 100% rename from testsuite/integration-arquillian/tests/base/src/test/resources/account-link-test/childrealm.json rename to testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/childrealm.json diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..389239a211 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/keycloak-saml.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/web.xml new file mode 100644 index 0000000000..adb9182233 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/different-cookie-name/WEB-INF/web.xml @@ -0,0 +1,59 @@ + + + + + + %CONTEXT_PATH% + + + javax.ws.rs.core.Application + /* + + + + /error.html + + + + + Application + /* + + + manager + + + + + KEYCLOAK-SAML + demo + + + + manager + + + + + DIFFERENT_SESSION_ID + + + diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json index 6bed985683..87a4fc8d67 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json @@ -162,6 +162,21 @@ "saml_idp_initiated_sso_relay_state": "redirectTo=/foo" } }, + { + "clientId": "http://localhost:8081/different-cookie-name/", + "enabled": true, + "fullScopeAllowed": true, + "protocol": "saml", + "baseUrl": "http://localhost:8080/different-cookie-name", + "redirectUris": [ + "http://localhost:8080/different-cookie-name/*" + ], + "attributes": { + "saml.authnstatement": "true", + "saml_assertion_consumer_url_post": "http://localhost:8080/different-cookie-name/saml", + "saml_single_logout_service_url_post": "http://localhost:8080/different-cookie-name/saml" + } + }, { "clientId": "http://localhost:8081/sales-post/", "enabled": true, diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index e63edcd7b4..e01a4d5fb4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -26,6 +26,7 @@ ${browser} ${htmlUnitBrowserVersion} ${firefox_binary} + ${chromeArguments} ${phantomjs.cli.args} --ssl-certificates-path=${client.certificate.ca.path} --ssl-client-certificate-file=${client.certificate.file} --ssl-client-key-file=${client.key.file} --ssl-client-key-passphrase=${client.key.passphrase} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties b/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties index 58fde2c984..9c9bfc259c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/log4j.properties @@ -27,7 +27,7 @@ log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%C{1}] # Logging with "info" when running test from IDE, but disabled when running test with "mvn" . Both cases can be overriden by use system property "keycloak.logging.level" (eg. -Dkeycloak.logging.level=debug ) keycloak.logging.level=info -log4j.logger.org.keycloak=${keycloak.logging.level}, keycloak +log4j.logger.org.keycloak=${keycloak.logging.level} log4j.logger.org.jboss.resteasy.resteasy_jaxrs.i18n=off diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.5.5.Final.json b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.5.5.Final.json new file mode 100644 index 0000000000..aa649caaf5 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.5.5.Final.json @@ -0,0 +1,4439 @@ +[ { + "id" : "master", + "realm" : "master", + "displayName" : "Keycloak", + "displayNameHtml" : "
Keycloak
", + "notBefore" : 0, + "revokeRefreshToken" : false, + "accessTokenLifespan" : 60, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "offlineSessionIdleTimeout" : 2592000, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "ef0b1123-6d34-4bcd-a91e-d7e85f63f3d2", + "name" : "create-realm", + "description" : "${role_create-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "master" + }, { + "id" : "0398c8e8-ac85-492a-bb65-5b757664edc0", + "name" : "offline_access", + "description" : "${role_offline-access}", + "scopeParamRequired" : true, + "composite" : false, + "clientRole" : false, + "containerId" : "master" + }, { + "id" : "d9512952-9ca0-4c61-9cc1-6260fe102650", + "name" : "master-test-realm-role", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "master" + }, { + "id" : "cc8bf72b-c430-4c8c-ba33-c8b7c321674e", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "master" + }, { + "id" : "1d4e9d65-6d21-4751-b461-ea34d4a122d6", + "name" : "admin", + "description" : "${role_admin}", + "scopeParamRequired" : false, + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "Migration-realm" : [ "view-events", "view-realm", "manage-authorization", "impersonation", "manage-realm", "manage-users", "view-users", "view-clients", "view-identity-providers", "manage-clients", "manage-identity-providers", "create-client", "manage-events", "view-authorization" ], + "master-realm" : [ "manage-realm", "manage-events", "view-clients", "create-client", "view-identity-providers", "view-realm", "manage-users", "manage-authorization", "manage-identity-providers", "view-events", "view-users", "view-authorization", "impersonation", "manage-clients" ], + "Migration2-realm" : [ "manage-authorization", "view-realm", "view-identity-providers", "view-authorization", "manage-identity-providers", "view-events", "create-client", "manage-users", "manage-clients", "manage-realm", "view-users", "impersonation", "view-clients", "manage-events" ] + } + }, + "clientRole" : false, + "containerId" : "master" + } ], + "client" : { + "security-admin-console" : [ ], + "master-test-client" : [ { + "id" : "a69d83c3-c1e0-4b4c-b6e2-9c5ea4cefdb9", + "name" : "master-test-client-role", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c74f3ddd-7a3d-4ecd-8967-d89e2138e4c1" + } ], + "admin-cli" : [ ], + "Migration-realm" : [ { + "id" : "69088781-7ee2-4e3e-9007-1800f6b116d1", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "81880d61-6186-430b-b5bb-995e0a11fad0", + "name" : "view-events", + "description" : "${role_view-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "0fbc6b25-79ae-4129-8cb2-9f966157c135", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "25b0a8c1-2c8f-4d93-8036-4440c1de6a1a", + "name" : "view-realm", + "description" : "${role_view-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "fa9f7d2b-61ec-4611-a47c-a1764ee936e5", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "7e11814f-6a38-4821-bf71-6e90fc56af37", + "name" : "impersonation", + "description" : "${role_impersonation}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "144be4a8-9368-460c-b95d-41cad64232c0", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "c0de8dfa-f906-4802-b93f-5a0cde6f2b43", + "name" : "manage-users", + "description" : "${role_manage-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "bcfe4261-8592-46b4-9ae4-62c8ef1c574d", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "a5dbd4ba-ccd9-4d97-9644-125a741485bf", + "name" : "create-client", + "description" : "${role_create-client}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "ac6186f7-21d3-4443-affc-f2aa744dde36", + "name" : "manage-events", + "description" : "${role_manage-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "c292c4d7-e15c-459f-a414-2067b381aaeb", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "71402ffc-70a3-4340-ad05-c9c9facb80a2", + "name" : "view-users", + "description" : "${role_view-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + }, { + "id" : "0ff155ab-2d99-4ef7-b7a5-0aeb53dc918c", + "name" : "view-clients", + "description" : "${role_view-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "29244735-e475-4355-9b0e-6d41d9270870" + } ], + "broker" : [ { + "id" : "cfe92094-cf37-4312-9622-bebe5f20b7ad", + "name" : "read-token", + "description" : "${role_read-token}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "3069ca02-e036-476d-b425-2cc965e6763f" + } ], + "master-realm" : [ { + "id" : "2fded3fa-0773-4838-886a-9851dcc3d0cd", + "name" : "manage-users", + "description" : "${role_manage-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "8319fd2c-5de2-44b7-add3-f4d8715e9b33", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "e01b416b-9eb7-48bc-a29c-501bac43ab8d", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "d4cb5518-6793-4015-a4db-b5e58cab35c6", + "name" : "view-events", + "description" : "${role_view-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "efa08022-9356-4cc0-b2b5-dde4778ee2d6", + "name" : "view-users", + "description" : "${role_view-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "9b23220c-b741-4a4d-a344-23d8d1be2e88", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "75db1573-3356-4a3a-b095-e4801e541117", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "dbfccefc-070e-4240-afcc-e7309f59b158", + "name" : "manage-events", + "description" : "${role_manage-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "14b36bab-5aaf-47ef-9300-55d585673e15", + "name" : "view-clients", + "description" : "${role_view-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "ee23bd41-a1a5-4b2f-806f-0aaff9cff9fe", + "name" : "impersonation", + "description" : "${role_impersonation}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "e16e564d-d3ca-4cc2-a423-a1f9a7a77b8b", + "name" : "create-client", + "description" : "${role_create-client}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "76ceb0bf-3868-4182-9017-bb0814a0b612", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "dcacac6e-381a-4842-87ae-d924a920d23f", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + }, { + "id" : "180f2d18-420d-49bf-8cb2-a4c637365911", + "name" : "view-realm", + "description" : "${role_view-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d" + } ], + "Migration2-realm" : [ { + "id" : "7de3d7b5-1fac-4fd6-b990-beacab8540d1", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "ebca292a-b94f-46a7-b536-f4a9e0bf0578", + "name" : "view-events", + "description" : "${role_view-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "8efd0ce4-02dc-4e30-86e9-0c3fb5cf3735", + "name" : "create-client", + "description" : "${role_create-client}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "f41e09a0-72ee-4aa7-ab45-0b349c5231ce", + "name" : "view-realm", + "description" : "${role_view-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "5bde4652-277a-4f6e-a92b-c00d18aca1bc", + "name" : "manage-users", + "description" : "${role_manage-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "e039a406-987b-4862-83c6-030f1cc4dfbb", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "a31c3926-b445-408d-aa3e-28d8d9638e81", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "477fe08e-35fe-4ddf-806d-839632716153", + "name" : "view-users", + "description" : "${role_view-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "fbd0be16-54f7-44a2-b4ae-4dfc8690b33b", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "b4ac9f18-a857-47dd-b741-c0aa56604d46", + "name" : "impersonation", + "description" : "${role_impersonation}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "1bef7689-4591-4d5c-86b7-ff9c4a719340", + "name" : "view-clients", + "description" : "${role_view-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "cd2d4875-1e94-4d5c-99bb-ccb64be5acdc", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "3667596d-8ff4-4ca5-9de3-b6dee0e41ef0", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + }, { + "id" : "a32d5ab7-a82e-42c5-9403-bf95ad99a71a", + "name" : "manage-events", + "description" : "${role_manage-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1" + } ], + "account" : [ { + "id" : "456aa889-e839-4108-a126-6a647aae1662", + "name" : "view-profile", + "description" : "${role_view-profile}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "ec45df9d-e110-4f87-874d-e0f684543c80" + }, { + "id" : "7b25b1b0-fe55-42fe-975a-51d40e858139", + "name" : "manage-account", + "description" : "${role_manage-account}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "ec45df9d-e110-4f87-874d-e0f684543c80" + } ] + } + }, + "groups" : [ { + "id" : "75afcc87-19bf-4cdd-ae6b-5b539f423339", + "name" : "master-test-group", + "path" : "/master-test-group", + "attributes" : { }, + "realmRoles" : [ ], + "clientRoles" : { }, + "subGroups" : [ ] + } ], + "defaultRoles" : [ "offline_access", "uma_authorization" ], + "requiredCredentials" : [ "password" ], + "passwordPolicy" : "hashIterations(20000)", + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "users" : [ { + "id" : "17b6ae2e-169c-41e4-815f-2956c86ac6ba", + "createdTimestamp" : 1489756582886, + "username" : "admin", + "enabled" : true, + "totp" : false, + "emailVerified" : false, + "credentials" : [ { + "type" : "password", + "hashedSaltedValue" : "UahGF6QpiHbshvw6GmaLR+cgM7v6ZxNKd3mPywudvAz3KWOhv0sMvespERCykvSC2xP4OBMzbwwxBACRSmGE0w==", + "salt" : "mnR0QbmURHVkSej+2eG9ng==", + "hashIterations" : 20000, + "counter" : 0, + "algorithm" : "pbkdf2", + "digits" : 0, + "period" : 0, + "createdDate" : 1489756582960, + "config" : { } + } ], + "disableableCredentialTypes" : [ "password" ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "uma_authorization", "admin" ], + "clientRoles" : { + "account" : [ "view-profile", "manage-account" ] + }, + "groups" : [ ] + }, { + "id" : "757d5b1e-fed9-4dec-b935-6d865563b26a", + "createdTimestamp" : 1489756871870, + "username" : "master-test-user", + "enabled" : true, + "totp" : false, + "emailVerified" : false, + "credentials" : [ ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "uma_authorization" ], + "clientRoles" : { + "account" : [ "view-profile", "manage-account" ] + }, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "client" : "admin-cli", + "roles" : [ "admin" ] + }, { + "client" : "security-admin-console", + "roles" : [ "admin" ] + } ], + "clients" : [ { + "id" : "29244735-e475-4355-9b0e-6d41d9270870", + "clientId" : "Migration-realm", + "name" : "Migration Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "af26f8af-8d47-4bd8-ad42-fcb172dd272c", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "10a8be93-07d9-48cc-acfa-a16402a1646a", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "77a4d3ec-c5ea-44d5-bcdd-7e836cd10c32", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "1c3eb495-7ad5-4c74-8e00-351225b25616", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "eba679fe-5384-4f4b-9afe-da49f85a5374", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "d346ff3b-db3e-41d8-b483-5d72a3c14980", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "a8e89ec5-3dd0-4a19-8c2d-8c3f24eebf46", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "7dfdf2da-3b6c-4014-b28f-fff402b446e1", + "clientId" : "Migration2-realm", + "name" : "Migration2 Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8573a6bd-4a64-4946-b2a7-8782e72e20b1", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "0ef33aa3-4ec2-4534-9930-3922f234ec1d", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "09049ebd-d7a9-41b0-bc7f-2479d91354ae", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "c8f0a824-acc0-42d0-9531-05782ab81848", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "8ee906ab-7bc2-4f85-8669-df17c3845901", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "7c65a5de-3c7f-4bc4-819e-827df3457f6a", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "988c26d6-9f3f-40b8-aef2-bfcf16cc9f34", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "ec45df9d-e110-4f87-874d-e0f684543c80", + "clientId" : "account", + "name" : "${client_account}", + "baseUrl" : "/auth/realms/master/account", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "ce49d798-ce8f-400e-b113-3e562da9b70a", + "defaultRoles" : [ "view-profile", "manage-account" ], + "redirectUris" : [ "/auth/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "17879387-1da1-4031-ab89-2dfeceefab58", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "8ba06688-9217-45d4-9cc7-ac8bc9584776", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "2c257c6b-4084-4f8c-aab5-584c82c94545", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "33513775-4978-43cd-aad1-188b060bed59", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "4beeea08-33c9-46f6-90dc-18d3b0062baa", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "6be10118-4680-4e84-b501-65e7d9514cff", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "af37f4e2-1d2e-464c-b0d9-430e93df26ab", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "10fc8525-6695-4a69-a8cd-7e7e483498a3", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "c69aea6f-3ce9-49af-9497-ace7ca5b0aee", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "303b3957-f1b2-470e-bf30-8dbf4f0fb56f", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "4ece3544-abae-4e99-b357-4009366fd942", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "df016daa-5590-4493-a506-bddf8227198e", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "3a826d25-916e-4e16-b64c-83812def6944", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "3c5e56c2-7e95-4c40-9d76-5f4127625fc0", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "3069ca02-e036-476d-b425-2cc965e6763f", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8bd856ff-6f3c-4be6-9e66-3176b647e1c0", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "2a7c65ec-517f-4437-b046-3ea42420a5bf", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "515a42d8-6010-4559-b167-d7eeab3efa1b", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "9c449cf9-0d22-43cd-850a-0f3ce5c6b2ec", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "4627b4a3-5b0c-4021-9a02-6e957889d694", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "690c8fd8-4421-4cf0-a807-162bf6cf7732", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "9156c1c8-3a7f-42a9-9612-844a03faf11b", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "577ac9f2-9252-4f64-8b67-006b2f2c6c9d", + "clientId" : "master-realm", + "name" : "master Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "98f111af-ee62-423e-91f9-e5be90ce51fe", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "81c57a41-c922-4251-9ec5-fa7097adfd26", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "c46bbab4-344e-417a-b241-588415de8725", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "2bc0f24e-88f7-4c32-a735-991300ca05bd", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "25c4af98-2158-473a-b6fb-190a0477ce5a", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "ae8e5033-2c0f-4041-bd2d-7ea0efadca7f", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "8b72a9e2-3acf-44c0-b992-9483144d834d", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "c74f3ddd-7a3d-4ecd-8967-d89e2138e4c1", + "clientId" : "master-test-client", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "4f427905-9843-4986-9d6c-97a304055f92", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "2018f7f2-c517-4ddb-88ea-b977c44471a1", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "e772b240-ea55-402c-aa60-e1ce4271d7d5", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "405a50a7-3daa-46ef-9896-3ae09f8f5960", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "b04a8ae1-7739-4fe9-88e4-c62335bbd5ea", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "c7fedad1-6591-45b4-bfa8-890bbefc8fdc", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "39a869ab-5446-4f1e-bad5-569f21297324", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "71e56ab0-802a-43eb-8690-b22f462eb032", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "baseUrl" : "/auth/admin/master/console/index.html", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "f305cbec-b5bd-47eb-b9d9-10234fac5336", + "redirectUris" : [ "/auth/admin/master/console/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "865640e9-9ee1-430f-b667-aa758915c7be", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "e871b99c-3764-46f7-b59c-121d0d46dc43", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "b0fb1a73-1275-458d-8aed-257820f6becd", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "d9844860-d9a6-4c40-8c64-733ffa886e68", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "bb5c5fd3-2767-4b4e-9994-8e4fb0d5539f", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "61d7f735-9487-474f-802c-23af1bdee98f", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "consentText" : "${locale}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "1a3769ef-5d2d-4b2f-8bba-156bc1e19ac1", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + } ], + "clientTemplates" : [ ], + "browserSecurityHeaders" : { + "xContentTypeOptions" : "nosniff", + "xFrameOptions" : "SAMEORIGIN", + "contentSecurityPolicy" : "frame-src 'self'" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "b4d32642-74c3-4405-85a6-6fd7bc82314e", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "fbab53ba-4a40-4df8-9357-38d4f12549e8", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "167887f3-bd5d-41ec-8b26-deeddfb759ba", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "ec767d9f-b8c9-4dc4-be2e-c306e34f0986", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "0c3da821-e9ba-408b-8457-c6e7fde7880f", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "df60926f-e9d8-4764-9c97-85b192966425", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "844f7dcb-e17c-4fb1-bbd5-c0b17bc8c6d7", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "6d602e59-7138-4ab8-b4db-3a9952c28986", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "a792d72c-c8e5-4934-b2f5-fb0483703377", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEAjiiXzintKn00WYaUB8+8C77UB8qYbi6SkPxNJBMHGf8v4UqY150YzGmq9nhXcju54XPhc9kIgw8PVqulfEtcCMszxYT03A0TidGw/BVaxGG/GEnd6+UsCJm5bRjFzWHAGPROY97b0g8oTDqalLr6wHamljaCismxw/yfRuxRm1g7IAYtDPvQEaBzbHGB5X21bechFqcwr7svHaUBsuVN6T17tsbXAwafv8V3YsRk+r+4gPhRJwOdpq7pdxiNa6Ye2Ls6NFPXYUoHxGPSWk98ba0VqErKVxVWQFEpdrD1gAYwmdhNwXN6BIUiwgSKMiK3uePoPRSfpG/tAtjKQ3VxUQIDAQABAoIBAC5XZUU7vaiAMDSO/mqdeXuKtavki1Q/sl+5H5yG52W+Hmme27xN5euc9rJqAHeoqKuqDvCo63Ft0145jjS6jEIBm9rjwL6LNLdUuBE1FOW3x4evbLyddIFJO30o+jI9j1WTLoq394i+kDBpWkLpwRxEkYGeO2fq4Bw3meSQ3Pl6hwHKMq4FeHQybtHMG8s5cvIOVl+gYuXG4D4XgumsqBwBGy9n6KnFqKt+K6tO03ve2dFt+y7gHWWxNG/o+PsSqSWdNxeG3myglInmEejZXAJRMN9gy4os8gW7AIEcE9wcu2UzgsINACkq6rYtMNFff//GmARPEq7tqdwgEN4FfQECgYEA5wZ5fufc+zLYr2BEN5YM71MGbRA1zzl7dMLYLGmPerNqnyrJeYpiRBYBGQbt0rpLp5cmgevt+rredQHp7iaVKh9P3m2OwDdb6hb9hmnw89P8YEWBk739I0WSUKcBoDHxuFCclijozbL2CZ3XKTVqZHC0S8sAS8Wj7mFYW+WFXIkCgYEAnYbFIzCrhw7eWmeYKFXM61p3iYjg1pRgWEasCUcKKxujg+qFTAES9CqGHbrbCxoIWDtBxOpUOy01hB4rl4Eg0YohiUERCbOBG0yMKhzPZqtEQAsyJb0VwJV0blrerXKxNeDaOc5SwksA41l6UgCAtXUblBIh2zQocb1sJPWcjIkCgYB6CS6Gvf46Z3qU8Zo3brj4dvgPBqAWDfxMClzc4Qocu8fXumdhH5uW8bS0vrdEOIqcRbjeqn00lB/M2Sz0U0c6T/4FtgPRP6z69BgKN85DTrijNjQjkhm01xxaJE40jA1u2o5Mt+F6P02+eLVenEvOMMbcvqgyXn2g/6UILi8LWQKBgQCY5uDheHN2I+OGQvm5ZRcD94sCD7+V6O3fobGJS9A96ZT9DZ2XGY/JOqF1qBLHotwosFP1jDJ4Qjio5hQP+gHeAkLtFCAyl28hDVsb4V0bXfBgbb2eTfwYM7mRCFkOaL5D+t43r+I6v0y8YPTPNbe46lP7lOISAH2lcWTQNyteaQKBgAS3YMhslJU8N6LtHSIAQXF1yXSDWg5P+e95bnYYVwqTPU6LErMonwmARVMfufOOsNfHvxJylnSXPn9hZdUtKIKTIdBs/DzVggOve7spp9qxi5FkhnSqa8U+UCh8I8nnFkCn67Y+qlbCVjESNGfCHFlCdRPbeWGAY1oXeT11tDfC" ], + "certificate" : [ "MIICmzCCAYMCBgFa3Gga8zANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTcwMzE3MTMxMzE0WhcNMjcwMzE3MTMxNDU0WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCOKJfOKe0qfTRZhpQHz7wLvtQHyphuLpKQ/E0kEwcZ/y/hSpjXnRjMaar2eFdyO7nhc+Fz2QiDDw9Wq6V8S1wIyzPFhPTcDROJ0bD8FVrEYb8YSd3r5SwImbltGMXNYcAY9E5j3tvSDyhMOpqUuvrAdqaWNoKKybHD/J9G7FGbWDsgBi0M+9ARoHNscYHlfbVt5yEWpzCvuy8dpQGy5U3pPXu2xtcDBp+/xXdixGT6v7iA+FEnA52mrul3GI1rph7Yuzo0U9dhSgfEY9JaT3xtrRWoSspXFVZAUSl2sPWABjCZ2E3Bc3oEhSLCBIoyIre54+g9FJ+kb+0C2MpDdXFRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAG+ckqM0jyz4pTgm2utIsaYjTGj77YyfL7kU49dhq8H9VBl1NL4gwOLT3pmHX4aCp08vgBmoNknCZjUN92yFi9k1qpfdsu+wFOO52N4wO2EGm7hRTL4lmf5J4eQmPoZBUidZr5yKKIhSqHCgJ2B2LkC95f5uz9lC5Gx2YwJ3DSTm51W518L+oDXocIhgVLmX2DKDR52ffqIzuNp20UrLXRFVKq2LLGbOaaJugCiIkhZD5W+2xTCdtlOfhvhGTK6+CnW7+/I5tk36AA9dlYYLffo39TlGToN0ZVWEINf99NjFAquxw/pKzz2gXWsCjDRmgpjGKUSnQEQD4sEmZ2Ophcs=" ], + "priority" : [ "100" ] + } + }, { + "id" : "fe3b0025-77f1-4f64-8d25-1af1c9459109", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "e5ae3dae-37e5-4c2a-843c-0031e151cf8e" ], + "secret" : [ "dsePpP-5kWD4YoWLjiPB8jfRXblKOPSGG4mlxsR_Gtk" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "5e5f94b1-0109-495e-8bac-f846b38490e4", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "idp-email-verification", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "b345033e-74d5-4e40-b17b-cdef469f7b80", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "3b6b1de8-5e70-4ec9-aae3-d2ba8e52c270", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-spnego", + "requirement" : "DISABLED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "identity-provider-redirector", + "requirement" : "ALTERNATIVE", + "priority" : 25, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "forms", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "ae8d0df6-8b13-4ea8-9c0d-0825c07aa964", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-jwt", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "8c19d745-b49c-47ac-8d50-68d1e1f7518c", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-password", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "requirement" : "OPTIONAL", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "b8e0c30c-214d-4e54-b4e2-44b021093e6b", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "d6030c45-c50f-498b-a08e-1caaf3fcd7ac", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "7c95a872-2b24-4efc-b97e-1a8c63e822e1", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "requirement" : "REQUIRED", + "priority" : 10, + "flowAlias" : "registration form", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "22532bcc-4537-4b3d-9b68-b434d6ebbe99", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-profile-action", + "requirement" : "REQUIRED", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-password-action", + "requirement" : "REQUIRED", + "priority" : 50, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-recaptcha-action", + "requirement" : "DISABLED", + "priority" : 60, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "29fb380e-6428-4ee7-8295-6ddf54b7dc66", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-credential-email", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-password", + "requirement" : "REQUIRED", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-otp", + "requirement" : "OPTIONAL", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "b4b2903b-e1e3-4a7c-9458-aef65f3252ad", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "49618dba-24ee-474f-8994-36ef63e8343c", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "a81032a6-f288-41b7-9fa6-afb7c696f539", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "terms_and_conditions", + "name" : "Terms and Conditions", + "providerId" : "terms_and_conditions", + "enabled" : false, + "defaultAction" : false, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "attributes" : { + "_browser_header.xFrameOptions" : "SAMEORIGIN", + "failureFactor" : "30", + "quickLoginCheckMilliSeconds" : "1000", + "maxDeltaTimeSeconds" : "43200", + "displayName" : "Keycloak", + "_browser_header.xContentTypeOptions" : "nosniff", + "bruteForceProtected" : "false", + "maxFailureWaitSeconds" : "900", + "_browser_header.contentSecurityPolicy" : "frame-src 'self'", + "minimumQuickLoginWaitSeconds" : "60", + "displayNameHtml" : "
Keycloak
", + "waitIncrementSeconds" : "60" + }, + "keycloakVersion" : "2.5.5.Final" +}, { + "id" : "Migration", + "realm" : "Migration", + "notBefore" : 0, + "revokeRefreshToken" : false, + "accessTokenLifespan" : 300, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "offlineSessionIdleTimeout" : 2592000, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "9264fdb4-d8a1-4793-b54c-4cc8fd04f682", + "name" : "migration-test-realm-role", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "Migration" + }, { + "id" : "0d3c10ef-eacd-4368-bf43-5b0c01644a3f", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "Migration" + }, { + "id" : "7eac8ffa-aaf7-417a-9f4e-0d6aae747d66", + "name" : "offline_access", + "description" : "${role_offline-access}", + "scopeParamRequired" : true, + "composite" : false, + "clientRole" : false, + "containerId" : "Migration" + } ], + "client" : { + "migration-test-client" : [ { + "id" : "fd5b3ce2-f2aa-4889-bf5d-477270b0e570", + "name" : "migration-test-client-role", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "1903b814-7b40-4bc0-a69c-fd1380cf1fb8" + } ], + "realm-management" : [ { + "id" : "efd9585f-dd86-4aa8-a425-5f5989db2cd3", + "name" : "view-events", + "description" : "${role_view-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "0ea6f2ae-dc32-44dd-a673-0a58ada6507e", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "ec18ab2c-f6d0-44e8-b000-53bd065ba6ad", + "name" : "create-client", + "description" : "${role_create-client}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "3af1fee4-3cb6-4acb-8e7f-3b91db767e24", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "dfca60b5-509f-4e26-a19e-b882e34bfb3d", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "scopeParamRequired" : false, + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "view-events", "view-identity-providers", "create-client", "manage-authorization", "view-clients", "manage-realm", "view-realm", "manage-clients", "manage-events", "view-authorization", "impersonation", "view-users", "manage-users", "manage-identity-providers" ] + } + }, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "a6d4dc7a-d8e5-4dc5-8b65-a2c73ad971f5", + "name" : "view-clients", + "description" : "${role_view-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "ac85bace-ddc2-4066-a1d1-5b51c4cd4e65", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "e6b0fd16-e699-41b2-a11e-7ce9a34f6017", + "name" : "view-realm", + "description" : "${role_view-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "24f10acf-5693-4235-ad91-ae83774c7d87", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "5d4f0d6a-a0f4-4147-93da-7637944635fc", + "name" : "manage-events", + "description" : "${role_manage-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "7acd37ad-cacd-4d55-9bc7-fb80817a77bf", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "d23cacab-0c06-4bb5-af63-081aec7bfe91", + "name" : "impersonation", + "description" : "${role_impersonation}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "a5a89dff-954d-43ae-9436-a3b1d7f7e414", + "name" : "view-users", + "description" : "${role_view-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "e87a2a2b-2094-441a-b4f9-c33f6717f1e0", + "name" : "manage-users", + "description" : "${role_manage-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + }, { + "id" : "86e36aee-c71b-4c33-bf6a-0650b349ddd3", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b" + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "broker" : [ { + "id" : "7c6fd1f8-56a9-425b-bf6a-432ae9439328", + "name" : "read-token", + "description" : "${role_read-token}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "573d0751-2969-4060-b668-6c924f25e4f4" + } ], + "account" : [ { + "id" : "c7ae7cd6-2d32-41f2-b58e-8ef9e1c08aa9", + "name" : "view-profile", + "description" : "${role_view-profile}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "6f27b0c3-9fc0-4e04-b69a-2031349acf04" + }, { + "id" : "811da1a3-3239-40ce-b896-1ddc2c6d3822", + "name" : "manage-account", + "description" : "${role_manage-account}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "6f27b0c3-9fc0-4e04-b69a-2031349acf04" + } ] + } + }, + "groups" : [ { + "id" : "fdd708ff-49a8-4141-979e-1cabf867918d", + "name" : "migration-test-group", + "path" : "/migration-test-group", + "attributes" : { }, + "realmRoles" : [ ], + "clientRoles" : { }, + "subGroups" : [ ] + } ], + "defaultRoles" : [ "offline_access", "uma_authorization" ], + "requiredCredentials" : [ "password" ], + "passwordPolicy" : "hashIterations(20000)", + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "users" : [ { + "id" : "456eb430-d574-4956-908a-83527a77932a", + "createdTimestamp" : 1489756947105, + "username" : "migration-test-user", + "enabled" : true, + "totp" : false, + "emailVerified" : false, + "credentials" : [ ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "uma_authorization", "offline_access" ], + "clientRoles" : { + "account" : [ "view-profile", "manage-account" ] + }, + "groups" : [ ] + } ], + "clientScopeMappings" : { + "realm-management" : [ { + "client" : "admin-cli", + "roles" : [ "realm-admin" ] + }, { + "client" : "security-admin-console", + "roles" : [ "realm-admin" ] + } ] + }, + "clients" : [ { + "id" : "6f27b0c3-9fc0-4e04-b69a-2031349acf04", + "clientId" : "account", + "name" : "${client_account}", + "baseUrl" : "/auth/realms/Migration/account", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "c34c6c4c-a208-415c-ac1a-f2b520a4c385", + "defaultRoles" : [ "view-profile", "manage-account" ], + "redirectUris" : [ "/auth/realms/Migration/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "f406f922-0aa5-44ab-83bd-fb3b596e9032", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "d3ffecae-3e6d-493e-a5ac-cb2d1446e9fc", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "e337e585-e509-49ec-a934-a01c5e7dfa34", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "cb5096d0-6c5f-4646-babc-33cdcfed387e", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "d78e393c-b5f3-4ea6-95e7-f3eaa5e83649", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "ed30dd8d-2624-46e0-b513-e799362ff0ba", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "a91baa2f-f6c3-4e5a-b321-3d951258d929", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "4cd9dafb-0ecd-4d46-a351-94abdb764f11", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "684b2fcf-50c1-471a-87c5-b88a6d4bd3a4", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "b8260206-b5dc-4fd9-af9e-8dfbd599dd55", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "4de30825-99a5-4226-a1d1-0c9421128aa4", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "10d97d1b-ddb7-4d42-ab70-0b17ecb3c75a", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "76c2ecb0-cf53-4364-99fb-36debf566350", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "53d115aa-c9f3-4006-b81f-5a9afdb25416", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "573d0751-2969-4060-b668-6c924f25e4f4", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "b84d8413-0fc8-4133-9f52-1b6fffa55b0f", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "0ebd920b-6629-4fc3-8e4d-690011b4d828", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "eeb47dd6-571b-4582-847e-d6b2961df00b", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "0c131188-9db1-464a-b006-20144cb543d4", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "848b7816-4255-4caf-9dd5-64900aab78e5", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "13e9c269-b218-4447-9b54-2adb5f974d08", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "80298431-9a86-42b1-9d52-432d20be88e5", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "1903b814-7b40-4bc0-a69c-fd1380cf1fb8", + "clientId" : "migration-test-client", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "75da9358-22e0-4ab5-9609-5c74c40dd70f", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "0252fc64-bf67-4042-be15-4bfcb7c234c9", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "281a803d-0a7e-4e5e-9404-26ef620d5d46", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "de4d240f-fdb8-414a-8eba-152343583b4c", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "8d98c2dd-d8b0-46e2-b590-0ab353e9259a", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "b8094177-3c42-4e6a-aa73-3528d5bdfc1d", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "4361cd9a-8322-42e1-a0d3-7a723a788dd3", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "c8204f6f-f8c2-4af8-9bac-c45c95b4673b", + "clientId" : "realm-management", + "name" : "${client_realm-management}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "7d239280-c0b5-4f8b-887f-f7b5ccd2cbf2", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "09617e7f-699a-4d40-bf4c-56295799ba60", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "82c2f928-331e-4ee4-be70-80490c26eb18", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "41b86180-eb0e-40bd-9406-34295c709a0a", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "10c7a9cc-6384-4e8d-9440-97ed3031dc5f", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "fecbea26-e22a-4fda-82ee-929d63d89116", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "b03d5572-f001-4ab0-98dd-f179e8167096", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "401e0c86-afd1-4f4f-8322-32b05222bd06", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "baseUrl" : "/auth/admin/Migration/console/index.html", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "57a4a548-5e72-414a-8fee-2f2d0bbc6b7c", + "redirectUris" : [ "/auth/admin/Migration/console/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "dd59269d-26ff-48ef-bf3a-b5a217411c4c", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "3e6b11ad-1c5a-4421-8d7b-8b3941f88ef3", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "fc9bc4bf-e08f-418a-b19a-f65ac98ab22e", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "56659148-b115-4557-80e5-9fd9f8597559", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "80a23415-9b70-48c8-8d3e-b74113f7cc02", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "04023632-7cfb-4d97-b3b2-dafbf1598e2b", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "b54ec0ff-9f7d-42c1-9f76-86047f65b4d7", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "consentText" : "${locale}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + } ], + "clientTemplates" : [ ], + "browserSecurityHeaders" : { + "xContentTypeOptions" : "nosniff", + "xFrameOptions" : "SAMEORIGIN", + "contentSecurityPolicy" : "frame-src 'self'" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "7bd729e2-9099-45b3-aa05-2ec43bc974e8", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "38c943ce-0bc1-4137-b80d-05d514e12ee5", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "136cc895-ace6-444a-b6ca-08158a0514ca", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "63d387da-fa95-46e5-9321-9780d4086ac6", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "73357d65-d98f-4ba8-b312-f93b1e5efb3b", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "8452e4a6-9bd1-4a13-bff5-e3cff94fbd6f", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "806417ec-a33a-4d40-969d-98fd8e1822e2", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "075b4dc9-2657-4243-b25f-921b245cdfcd", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "93c9cce7-c15f-4067-a790-d52d113bfa9f", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEAhiLZwTEe2nNLi/IqXHFziVVW8XXRUGMUnMhprvMu86K4Xz9MRfjYzpffo+I10V+VSdRimMPgyqaSZ9x+mRSl61029Bilq4LZbfHAitjk5nZw1J645dVTRwul9u8/NsgqpFoT1Z4s63KOrXI4dduvBqLcLjaPcqiXs2nN8npS7fSEygrvHWUN8YZHMEwr5NmPk77RaiBXokXljgjBJNsQK8VUS56ynqYs9aK3sM/Ms49m+kb7BmdWlXlSPQ0ctxc10kOGX8KpepE78kset/u/6KnEaYlSDC+uuPMLTnB7y6OY23fzhGUJNhav/Pqhr9WXPqxhy+vQnJd5j38i20iuiwIDAQABAoIBAB04Ej8nOBVV8Cr4AYpJnGVaFapbg9EDBEZy0bKufpfL5mW5ICBN6Mx4ANtuN1L4g0il3yRv5tO+HT5Kpbkq6kmu8H2TsOL/ieWNN+gG/zXErydhu9007wMW4nw7+YUxbTiH9rId1qMjPTlDHFFwHVxQta3LbMwJNaJ7dcVQKCh1PomPh5Z7THeN31eTSRajvd3vP9bAorxJW8kh6vD+FHG5P1r5aOiF6SacKySCVJ+RxUeJvn9/8KLSP4n4GyLt9HWxSOCoRAjMiZuXUkDRXP09Csb4L5tgqaSIjiWRXOEH3xMcrBUoovM9iBbuqmkGPEjvyUTabLxPvxKGUEipV6ECgYEAvFNykRIjKwH8KN1LUd+ZOwM+Oe85yeMACCZqyjIiD7O7lAs261kOlyiycimTF3SGlbw60SzGO9FmTh722e50Mktl/uR3+iG7WoYy8t41uphoReHw4i8kl+bU/4+O0faHoTFXMN+TFaHeHzY3XQbAekXKXaKsP978NkdKcfXZUacCgYEAtlZaFhBevYOLt14S/LPlXoE0PZFqOJasOHSkIcotdq5zLEVppTzcxf4xTFSR+SOpsJUScGivO5F0Ko9svvaqxXzdH97Urb/4oDfuUgIFLnBs9ixNpj3fUPirBD9tolRqFAQCN+M2FTjUcbWkVDsusmXoynrPNaryyHEQ/c7PsH0CgYAU84esYgMtlrPx6+SkQCbw7MRwd4/LSQjI31VEF124t3sn1jOO7UJ1SJ7Jmpx1oI4UfHNisAOBxiMGj+VQi3m72q2HNO2wEy6fvIxQfq4liy0WkTNWRn5gs9qAb/0omK+wHCgiFM1tO6vVdxejrsudDsSbtCxLksgmVboPgZViwwKBgEc+cE6ksM/twT6xhEu24s1NQKM52T4pKTuZ37PQMnln6lqG+KN2p3C5RHvlo2+sTpZPePfw/18QE0q55ayr5sfpZOEaCRGmq7e2gukKHwopJXn+j4yAKmyR7Qho3CaMQzJ06oT5w10BaojPh1jeEv3jsdTDrYjztY86FoCFOUNlAoGBALhragR4OTeW+XaQhu9zVaLs4MIJIGdfe7zRnkrdMsKpyqBL4RJ6SUqtVe8CwJoSbOCkoiH/mLkppZdgUatSDW57qG3Y3V4/z3jfg7IlthdbBCcDKRk8UqTwXOM+IWjmaCg1cU/kIW9ZAbNm99DPX36Rdk8d1pEUQU96kK259UVc" ], + "certificate" : [ "MIICoTCCAYkCBgFa3GvSnTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlNaWdyYXRpb24wHhcNMTcwMzE3MTMxNzE4WhcNMjcwMzE3MTMxODU4WjAUMRIwEAYDVQQDDAlNaWdyYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCGItnBMR7ac0uL8ipccXOJVVbxddFQYxScyGmu8y7zorhfP0xF+NjOl9+j4jXRX5VJ1GKYw+DKppJn3H6ZFKXrXTb0GKWrgtlt8cCK2OTmdnDUnrjl1VNHC6X27z82yCqkWhPVnizrco6tcjh1268GotwuNo9yqJezac3yelLt9ITKCu8dZQ3xhkcwTCvk2Y+TvtFqIFeiReWOCMEk2xArxVRLnrKepiz1orewz8yzj2b6RvsGZ1aVeVI9DRy3FzXSQ4Zfwql6kTvySx63+7/oqcRpiVIML6648wtOcHvLo5jbd/OEZQk2Fq/8+qGv1Zc+rGHL69Ccl3mPfyLbSK6LAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAHub1rD7Q3uCxBWDZsmg8are61BHsTiBHx8uFZ+dUlideGrIfZ9Cdw+4MY970fFG77hetTcyzJmA9Xob3aZxRxj6T83Ibu41FTVpAoSNiqzRcrdPTCka/ey+AtCaymWeF9QFVPXorL8lBCYtbvpZ/ueTjCVdN3HkX59za0ntE9H48mxbBYoIvX8QN2v91xy3uTK0H5fZsE0MfvtJqgwgvlKtb2xOn79Tpob8f92D7ZCBQVIaXwXw34BIZYRqFX9Rftpx+Hr7O3KjpmUBOmPiJNjLX2ce9MnQyag6SXqs+9RQqOBYwgieCUwtTzjkuOx2FYkXCDy7Nd2dxyrwq3CM0E=" ], + "priority" : [ "100" ] + } + }, { + "id" : "676c2a48-745c-477c-b8d0-93da72d7fa4e", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "3d84b2f9-a3f2-4521-9f28-5761e1fb7b1b" ], + "secret" : [ "cVfUcv4wf-uT6VFAaY5fOw1biyTgwr9W0ueDv--twKc" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "e601d1ab-d031-4b0d-8da6-b20975353906", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "idp-email-verification", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "00b46bc9-ab8a-4403-bec6-9fd7f3a3f14d", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "7ee834ed-414b-4b34-a480-7d7cb158482a", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-spnego", + "requirement" : "DISABLED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "identity-provider-redirector", + "requirement" : "ALTERNATIVE", + "priority" : 25, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "forms", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "cbcf873c-a965-4c42-90cf-0bca617803fe", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-jwt", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "59bc4c61-ce2b-4f80-8538-6ec4bd4e93d0", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-password", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "requirement" : "OPTIONAL", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "8ebafdee-ed12-43ed-979f-6bc5e0c3a6b6", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "13dff5d3-3f43-4d8d-a605-dd46751cb4cd", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "912947ec-29a1-4f82-838f-3e6f0cb92544", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "requirement" : "REQUIRED", + "priority" : 10, + "flowAlias" : "registration form", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "e312ae45-7a9a-4ecd-a29a-938797798207", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-profile-action", + "requirement" : "REQUIRED", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-password-action", + "requirement" : "REQUIRED", + "priority" : 50, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-recaptcha-action", + "requirement" : "DISABLED", + "priority" : 60, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "3c8d1428-d801-4f27-a96a-6835a40377d5", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-credential-email", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-password", + "requirement" : "REQUIRED", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-otp", + "requirement" : "OPTIONAL", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "e76a5616-d4d1-4b1d-98cb-0b45cfb8d361", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "17259498-3563-4313-8111-fb8c015b0666", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "6a3f26f7-b906-4786-bfc5-cea683cfddfb", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "terms_and_conditions", + "name" : "Terms and Conditions", + "providerId" : "terms_and_conditions", + "enabled" : false, + "defaultAction" : false, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "attributes" : { + "_browser_header.xFrameOptions" : "SAMEORIGIN", + "failureFactor" : "30", + "quickLoginCheckMilliSeconds" : "1000", + "maxDeltaTimeSeconds" : "43200", + "_browser_header.xContentTypeOptions" : "nosniff", + "bruteForceProtected" : "false", + "maxFailureWaitSeconds" : "900", + "_browser_header.contentSecurityPolicy" : "frame-src 'self'", + "minimumQuickLoginWaitSeconds" : "60", + "waitIncrementSeconds" : "60" + }, + "keycloakVersion" : "2.5.5.Final" +}, { + "id" : "Migration2", + "realm" : "Migration2", + "notBefore" : 0, + "revokeRefreshToken" : false, + "accessTokenLifespan" : 300, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "offlineSessionIdleTimeout" : 2592000, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "3ca75db0-3a8b-4ac5-b8f3-b145e9d97aa4", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : false, + "containerId" : "Migration2" + }, { + "id" : "8dfe45d2-489b-4751-8332-2ca8b1cc9486", + "name" : "offline_access", + "description" : "${role_offline-access}", + "scopeParamRequired" : true, + "composite" : false, + "clientRole" : false, + "containerId" : "Migration2" + } ], + "client" : { + "realm-management" : [ { + "id" : "25219cc0-8d01-467c-a504-534ac254bc5d", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "0ba6266a-3b91-4d34-993b-6877b36e4cce", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "cda51a8d-c757-4858-8d32-fcd7263186df", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "d14d3fa7-bcb6-4394-b6cb-4b9cc1bac68a", + "name" : "manage-users", + "description" : "${role_manage-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "9aabb672-6c26-4d0c-9c8d-b13e8367b772", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "scopeParamRequired" : false, + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "manage-authorization", "manage-clients", "view-identity-providers", "manage-users", "view-realm", "manage-events", "impersonation", "view-users", "view-authorization", "manage-realm", "manage-identity-providers", "view-clients", "create-client", "view-events" ] + } + }, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "54fa9d64-e184-40c5-aac0-7f7368e41067", + "name" : "view-realm", + "description" : "${role_view-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "f8baca32-6261-4fbd-8450-1a78453996da", + "name" : "manage-events", + "description" : "${role_manage-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "8eca12ea-1ada-43f2-b110-8ba4046ddcfa", + "name" : "impersonation", + "description" : "${role_impersonation}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "a0a808e0-e1fe-493d-a50a-dbb95fb6c8ad", + "name" : "view-users", + "description" : "${role_view-users}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "eeeb42e5-1fdc-422d-bfb8-c94b1c5dfb0f", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "a77e7f4e-e675-4f4f-8f0a-4cb3a9f2b674", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "d9880b2d-27fd-4eb0-86a4-cf27eaa85c59", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "65ec15f1-84de-4ec6-82da-cbde752faf2f", + "name" : "view-clients", + "description" : "${role_view-clients}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "3c63876e-ef7e-4166-831e-90d9e8e99cf0", + "name" : "create-client", + "description" : "${role_create-client}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + }, { + "id" : "5383cc58-3a84-43b1-a84b-59205cf14193", + "name" : "view-events", + "description" : "${role_view-events}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc" + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "broker" : [ { + "id" : "37b7f08f-f0e7-4dc7-aa3a-a339265bdf08", + "name" : "read-token", + "description" : "${role_read-token}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "1af6d357-8e4f-4ebd-b852-d4c584dffe8d" + } ], + "account" : [ { + "id" : "46862339-1c0c-460a-914d-46803ed5e172", + "name" : "manage-account", + "description" : "${role_manage-account}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "55b6e874-9df4-41a2-9efb-8168f4f9ef0f" + }, { + "id" : "612d66f0-5e22-438b-a5dc-c635f0c75578", + "name" : "view-profile", + "description" : "${role_view-profile}", + "scopeParamRequired" : false, + "composite" : false, + "clientRole" : true, + "containerId" : "55b6e874-9df4-41a2-9efb-8168f4f9ef0f" + } ] + } + }, + "groups" : [ ], + "defaultRoles" : [ "offline_access", "uma_authorization" ], + "requiredCredentials" : [ "password" ], + "passwordPolicy" : "hashIterations(20000)", + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "clientScopeMappings" : { + "realm-management" : [ { + "client" : "admin-cli", + "roles" : [ "realm-admin" ] + }, { + "client" : "security-admin-console", + "roles" : [ "realm-admin" ] + } ] + }, + "clients" : [ { + "id" : "55b6e874-9df4-41a2-9efb-8168f4f9ef0f", + "clientId" : "account", + "name" : "${client_account}", + "baseUrl" : "/auth/realms/Migration2/account", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8dfaceeb-2772-494c-bf6d-d49c34e55d42", + "defaultRoles" : [ "view-profile", "manage-account" ], + "redirectUris" : [ "/auth/realms/Migration2/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "6406e544-302b-4bee-8508-2bde135ca397", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "372005a1-b0b0-43d5-8ced-4bd8019243c9", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "defb4a33-1cbc-428c-abb1-39836e710fd8", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "75672101-7a90-4d9d-8613-e065bb7c0fa4", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "3a137c4b-4e5d-401c-8308-fdbc3a0c1f29", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "65b72f01-66bb-4420-840f-e105938096cd", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "25b38437-8a49-4ad8-8bde-ba36f444a014", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "f218b8da-83c5-48bd-af15-afe98ecc50c0", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "d9608107-9888-4162-a496-f4f21372db20", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "bf5ee69f-9fb0-4c91-93cd-6b82ae22b99b", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "1a2302cb-6edb-44f7-9d66-cbd8b6433ced", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "dde6a8e4-d574-4697-8132-5d43c43a298b", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "a1b36bef-1460-453a-affc-a931f8927e7b", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "3d7e0cbd-6f8e-4f70-a879-846211aef6d1", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "1af6d357-8e4f-4ebd-b852-d4c584dffe8d", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "8b879d60-4dfa-4aaf-bdd6-c56c803ea8d3", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "2520d2a5-490d-492e-92ae-558b1acf5852", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "5a43651a-10f5-4446-a7b2-bdb6ee97e75c", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "c251a13f-0f81-4367-b1c0-b495695fb4bb", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "3d4150f0-5c31-484b-8e5b-6ccdf56b430a", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "efae169e-2d9e-4aec-842f-35287ae9b993", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "1bbae8eb-5670-41b2-bf14-e5bcd5fcd578", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "7028079b-fe5c-4a3b-b4ff-1d81fab31dbc", + "clientId" : "realm-management", + "name" : "${client_realm-management}", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "882a040f-d7db-4417-99ac-0d9b77d34d94", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "f6c4f5b1-8d7b-4fb1-a68c-b05c4fe7a9b7", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "3c1bfffa-18d7-471e-87d0-bae7dd44caf3", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "4e779369-50ab-4a54-947c-ace45236a599", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + }, { + "id" : "73f458f7-3069-4189-bf1c-99fb12513899", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "d6c5f1cb-ccb9-4107-bfb6-0395c93a9d6a", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "be37a03e-c842-45a3-9cd1-ad63ce4e350e", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + }, { + "id" : "ee19c9a7-e7bd-47c6-a43e-bc6eff9bf0c2", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "baseUrl" : "/auth/admin/Migration2/console/index.html", + "surrogateAuthRequired" : false, + "enabled" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "4c4ce40d-dedd-4f77-b76f-319520516b4d", + "redirectUris" : [ "/auth/admin/Migration2/console/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "attributes" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "c10048b1-d3ed-463d-b85b-2acd04ee5c7d", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${email}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "52cfc1e8-d160-4276-a4bb-1d32c43ef65b", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${givenName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "60523a72-fb43-4fea-91f5-03b914c5020f", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${username}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "0498d224-0d99-4e79-baed-170f952ca7c7", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "consentText" : "${locale}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "c3407c64-7d39-4de5-aefd-c437fc5ee0f5", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : true, + "consentText" : "${familyName}", + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "010054c8-ebb9-4cf5-9b8f-3eab0ff00c38", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : true, + "consentText" : "${fullName}", + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "a94915a4-4061-4109-9cbb-4ea7930251aa", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ], + "useTemplateConfig" : false, + "useTemplateScope" : false, + "useTemplateMappers" : false + } ], + "clientTemplates" : [ ], + "browserSecurityHeaders" : { + "xContentTypeOptions" : "nosniff", + "xFrameOptions" : "SAMEORIGIN", + "contentSecurityPolicy" : "frame-src 'self'" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "29dc4ac1-7121-489e-a057-7155f05044a7", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "ef24941c-ab4a-4d50-8d3b-c0e17686e538", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "5ce2cf82-c2b2-4fd9-9262-c89e7bf31af4", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "5975bf2d-003b-4545-9c98-1fb3986c5f80", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "47fb230a-8c18-4e64-abf1-7d1ec326b567", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "c6face0b-df25-448f-b2d2-746b798dda85", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "6f3552ff-4b2e-4817-88b0-1dbb09a1b772", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ], + "consent-required-for-all-mappers" : [ "true" ] + } + }, { + "id" : "1bc070b4-f5af-49e8-b57d-d8fdd7e1cc5b", + "name" : "Allowed Client Templates", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "416d683a-254c-4f0c-b8ce-6290752573e7", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEoQIBAAKCAQEA0wexM5VrVeD4G0K3XXqvhomXds3k4GyOn5UWoEQ/BsAmWiA8tt6zF0TTdf6QUO6htGFMBOo1eESE0lDlhhEf7IbSmm6UlCk2hqoTWNvhQZgesiA8QLsq0cLmn1djqpj9vD1RMWBWt0wECwq3HzyViZEdtGUf2UrI/m/Lmb8hWKmhnucWcLSi0or/bnZIbvS2697KVMuKGEFxMTP89LygAKOI/MzqcdywXnITWzTekp5ecyB0CH2mihwX7gbPD5/xewPtuAC/xPpFVvYNJehucf6yG0FD1wo3Q3nuEMmTiHu/6jtzpK2l2QRf/DV0ZuLjiKFqNPUTdFSD029Dz8+7wQIDAQABAoIBADHAn4N019BwcK4kpYxxb059w+rrkeljTqDLCoGQdXeG98PJ0+adTIXQ4TXxZV7fU9puEfkaqq6HIPVgwyw/f1JJWv+z0G255bQMBvGtLUdEsP/335y3Q9oeZDbu6H2BAllN74V/nBIs5ssfpJrFss+zGdi8+qxFGGv8OXku+ZKoRejrRHcVSw/kMZ/bRBuQH54MRPj+nSqM3SxqhJ8MDSB4yKtCse8JjzhpokacMFv2tDEdCGsd2fNwQ/eWoQDoj/JI2YNNH/YQTKHRvXB8W2V5w0TPzEOYAq2zJyJnoPodsV0OyuVcYh9s3d5PN7irQmjXDKc3CxtKeQJ1gAi/4q0CgYEA7Dc5DMczYGLiIK+Q7+Gv4ALpMFm3899n41ZNsD7PXlL4plFkopypTCtLJsBeXFndGIFrIe5/fyMAWinIHJ0iVBPJOOYnxIHlbbBFLlwfZHeWJUTmCVf+/dkDKn9dlIkhmKxGhf8FGu3fKqusHbEXGXGoHy/F5ZvKT7CxxTBCFAcCgYEA5LR0kmEv+NX3R8GMdNqKZB7bzdG6dk7zozUN0J6nSO0+C2kpEYrRCVatZj8sWcJFxNypnVHwrr8ALl5a8//58oSoitUmlYL/lwxuk0xhtAHHXAAbnulXxCpUfIeVhunE1HhKuIajMxeQ0NtYk7vcRhY4eic804JCDzSkb1OOD/cCgYBaQ0PemSQNudt06AG3WINPU21uF2qOmxjkqy7moSm2fngbfdC5vqmGvKhr92hXW9N7sMCSZ8N6fpJ84ahhHr5maGUlA/XARm64OnpFG9i3GGdceHZ6rZB3yfxGugK1Zq1a3MHaJDf8MVdsw8ryUaBlDaRTvnqdoaluSDO2CRnG8wJ/AclnH72iok8Jn4XjkwYiDqYvEWySCFqVjLDdasPSir9PvMcViw2KlIgY0rOrpQffg6o1qQT63GKhnbse+skFKt/ecTc5FfHwDT4Lnxr5qG5bIFzf2l34UZADGPX2NReecgp+ivKCU+PbPcZ46q6NCf8icdHcp8pcucGvhy8f7QKBgQDMWjVt34tMRR6G/DM14QLDgKfjISiqrtGoouKaEQ7aME/wf8lOpCtfSZASzIPdpz5CC+vvi0N7OwsllNL93S7xLlJ2BLVubRb3DMCtQSz9EUVL6Pti6Pnkb84BmXhRcT8e+RG73WP1SmXxuIL8bZ+bXEwa65jl8p5C8BpRYIJFUQ==" ], + "certificate" : [ "MIICozCCAYsCBgFa3GxEqjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDApNaWdyYXRpb24yMB4XDTE3MDMxNzEzMTc0N1oXDTI3MDMxNzEzMTkyN1owFTETMBEGA1UEAwwKTWlncmF0aW9uMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMHsTOVa1Xg+BtCt116r4aJl3bN5OBsjp+VFqBEPwbAJlogPLbesxdE03X+kFDuobRhTATqNXhEhNJQ5YYRH+yG0ppulJQpNoaqE1jb4UGYHrIgPEC7KtHC5p9XY6qY/bw9UTFgVrdMBAsKtx88lYmRHbRlH9lKyP5vy5m/IVipoZ7nFnC0otKK/252SG70tuveylTLihhBcTEz/PS8oACjiPzM6nHcsF5yE1s03pKeXnMgdAh9poocF+4Gzw+f8XsD7bgAv8T6RVb2DSXobnH+shtBQ9cKN0N57hDJk4h7v+o7c6StpdkEX/w1dGbi44ihajT1E3RUg9NvQ8/Pu8ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAqPLouXjLeW2IJtGnVSCtV8GsCphzSV97aJeRymhEgMRfbjmfwenrB24+9mQt+sq78LNE5tgi50+/jxQhYS0lZ7U0hyvD2CL7nPo/08CrJfVWal0G5MIEGVVg3TQV+mMVnYObpB4OVy2BdLrUw4Hu3U+HfrdqjaWLeWDLlBVvY9+PPtN9rvPE6iGzHlZRLsLe0QrJqLXEY8TKy8iSJQTmZQDnoPQh6LYXxz9mP29AOReYDA17bl0dHo1trhurVTFRnZOOhSLnOdp2GMNBPCQ4pZUNKUBskF8Cj60C/667AnQ/5Dsn4TTLpPp2u01MIHxuv0H9RFzglQ+4GesWnDZIzg==" ], + "priority" : [ "100" ] + } + }, { + "id" : "d083afb9-70c2-403c-9807-2125c1e4442e", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "07d897f7-d1c4-4553-a46c-ca0dc2b6b5fd" ], + "secret" : [ "W70htWKvXRziLRgp6oMnDmtL28Ruf2Gc12x4vk3qiAg" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "6caba987-2390-43de-b1e8-d61b774353e6", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "idp-email-verification", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "44495202-5330-461d-b05f-0ca97c27c06c", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "8fcb72b6-5936-418c-b2db-a766de6c95dd", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-spnego", + "requirement" : "DISABLED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "identity-provider-redirector", + "requirement" : "ALTERNATIVE", + "priority" : 25, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "forms", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "0cca7264-b861-464a-a7a2-3e9528075005", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "requirement" : "ALTERNATIVE", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "client-jwt", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "a7c6cffc-e45c-4310-99b9-d372d385b15f", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-password", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "requirement" : "OPTIONAL", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "6aeb0c6e-7f76-4d9d-b028-2d9bbf878a73", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "requirement" : "ALTERNATIVE", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "requirement" : "ALTERNATIVE", + "priority" : 30, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "5a2cb584-2b10-4cc9-820e-b40ea8c7d4ee", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "auth-otp-form", + "requirement" : "OPTIONAL", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "d6f55560-23a4-4952-9967-58a409e7f1ac", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "requirement" : "REQUIRED", + "priority" : 10, + "flowAlias" : "registration form", + "userSetupAllowed" : false, + "autheticatorFlow" : true + } ] + }, { + "id" : "2f9827b8-589e-4ea7-ac2b-8ddb2d6dbf40", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-profile-action", + "requirement" : "REQUIRED", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-password-action", + "requirement" : "REQUIRED", + "priority" : 50, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "registration-recaptcha-action", + "requirement" : "DISABLED", + "priority" : 60, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "3cf05239-7f60-4303-a98b-9a09efda49a9", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-credential-email", + "requirement" : "REQUIRED", + "priority" : 20, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-password", + "requirement" : "REQUIRED", + "priority" : 30, + "userSetupAllowed" : false, + "autheticatorFlow" : false + }, { + "authenticator" : "reset-otp", + "requirement" : "OPTIONAL", + "priority" : 40, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + }, { + "id" : "8aef44c6-44b0-4aae-9754-100cfb6f9283", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "requirement" : "REQUIRED", + "priority" : 10, + "userSetupAllowed" : false, + "autheticatorFlow" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "c56cb058-5ff0-4531-aee1-99778fd8597b", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "cc75f878-02a9-44f0-953f-e9e8f2fb8b24", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "config" : { } + }, { + "alias" : "terms_and_conditions", + "name" : "Terms and Conditions", + "providerId" : "terms_and_conditions", + "enabled" : false, + "defaultAction" : false, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "attributes" : { + "_browser_header.xFrameOptions" : "SAMEORIGIN", + "failureFactor" : "30", + "quickLoginCheckMilliSeconds" : "1000", + "maxDeltaTimeSeconds" : "43200", + "_browser_header.xContentTypeOptions" : "nosniff", + "bruteForceProtected" : "false", + "maxFailureWaitSeconds" : "900", + "_browser_header.contentSecurityPolicy" : "frame-src 'self'", + "minimumQuickLoginWaitSeconds" : "60", + "waitIncrementSeconds" : "60" + }, + "keycloakVersion" : "2.5.5.Final" +} ] \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json index 6a090ced66..edb0f61585 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json @@ -13,7 +13,11 @@ "smtpServer": { "from": "auto@keycloak.org", "host": "localhost", - "port":"3025" + "port":"3025", + "fromDisplayName": "Keycloak SSO", + "replyTo":"reply-to@keycloak.org", + "replyToDisplayName": "Keycloak no-reply", + "envelopeFrom": "auto+bounces@keycloak.org" }, "users" : [ { diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPClientInitiatedAccountLinkTest.java new file mode 100644 index 0000000000..7cc7f21c06 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPClientInitiatedAccountLinkTest.java @@ -0,0 +1,29 @@ +/* + * 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.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * + * @author Vlastislav Ramik + */ +@AppServerContainer("app-server-eap") +public class EAPClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest { + +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6ClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6ClientInitiatedAccountLinkTest.java new file mode 100644 index 0000000000..4cff5d7730 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6ClientInitiatedAccountLinkTest.java @@ -0,0 +1,29 @@ +/* + * 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.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * + * @author Vlastislav Ramik + */ +@AppServerContainer("app-server-eap6") +public class EAP6ClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest { + +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyClientInitiatedAccountLinkTest.java new file mode 100644 index 0000000000..ddf70fc045 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyClientInitiatedAccountLinkTest.java @@ -0,0 +1,29 @@ +/* + * 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.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * + * @author Vlastislav Ramik + */ +@AppServerContainer("app-server-wildfly") +public class WildflyClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest { + +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/CreateExecutionForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/CreateExecutionForm.java index eef0389b3b..53622502f2 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/CreateExecutionForm.java +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/CreateExecutionForm.java @@ -28,20 +28,30 @@ import org.openqa.selenium.support.ui.Select; /** * * @author Vlastislav Ramik + * @author Peter Zaoral */ public class CreateExecutionForm extends Form { public enum ProviderOption { - DIRECT_GRANT_VALIDATE_USERNAME("direct-grant-validate-username"), - RESET_OTP("reset-otp"), - AUTH_COOKIE("auth-cookie"), - RESET_CREDENTIALS_CHOOSE_USER("reset-credentials-choose-user"), - DIRECT_GRANT_VALIDATE_PASSWORD("direct-grant-validate-password"), - AUTH_USERNAME_PASSWORD_FORM("auth-username-password-form"), - AUTH_OTP_FORM("auth-otp-form"), - AUTH_SPNEGO("auth-spnego"), - DIRECT_GRANT_VALIDATE_OPT("direct-grant-validate-otp"), - RESET_CREDENTIALS_EMAIL("reset-credential-email"), - RESET_PASSWORD("reset-password"); + IDENTITY_PROVIDER_REDIRECTOR("Identity Provider Redirector"), + USERNAME_VALIDATION("Username Validation"), + RESET_OTP("Reset OTP"), + COOKIE("Cookie"), + CHOOSE_USER("Choose User"), + PASSWORD("Password"), + REVIEW_PROFILE("Review Profile"), + CONFIRM_LINK_EXISTING_ACCOUNT("Confirm Link Existing Account"), + CONDITIONAL_OTP("Conditional OTP"), + USERNAME_PASSWORD("Username Password"), + KERBEROS("Kerberos"), + SEND_RESET_EMAIL("Send Reset Email"), + RESET_PASSWORD("Reset Password"), + HTTP_BASIC_AUTHETICATION("HTTP Basic Authentication"), + OTP_FORM("OTP Form"), + USERNAME_PASSWORD_FORM_FOR_IDENTITY_PROVIDER_REAUTH("Username Password For Identity Provider Reauthentication"), + VERIFY_EXISTING_ACCOUNT_BY_EMAIL("Verify Existing Account By Email"), + SCRIPT("Script"), + OTP("OTP"), + CREATE_USER_IF_UNIQUE("Create User If Unique"); private final String name; diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java index 63694cc408..262a834ea2 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java @@ -5,9 +5,13 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.ui.Select; +import java.util.List; +import java.util.stream.Collectors; + /** * @author tkyjovsk * @author mhajas + * @author pzaoral */ public class Flows extends Authentication { @@ -19,19 +23,19 @@ public class Flows extends Authentication { @FindBy(tagName = "select") private Select flowSelect; - @FindBy(xpath = "//button[text() = 'New']") + @FindBy(xpath = ".//button[@data-ng-click='createFlow()']") private WebElement newButton; - @FindBy(xpath = "//button[text() = 'Copy']") + @FindBy(xpath = ".//button[@data-ng-click='copyFlow()']") private WebElement copyButton; - @FindBy(xpath = "//button[text() = 'Delete']") + @FindBy(xpath = ".//button[@data-ng-click='deleteFlow()']") private WebElement deleteButton; - @FindBy(xpath = "//button[text() = 'Add Execution']") + @FindBy(xpath = ".//button[@data-ng-click='addExecution()']") private WebElement addExecutionButton; - @FindBy(xpath = "//button[text() = 'Add Flow']") + @FindBy(xpath = ".//button[@data-ng-click='addFlow()']") private WebElement addFlowButton; @FindBy(tagName = "table") @@ -39,10 +43,10 @@ public class Flows extends Authentication { public enum FlowOption { - DIRECT_GRANT("Direct grant"), + DIRECT_GRANT("Direct Grant"), REGISTRATION("Registration"), BROWSER("Browser"), - RESET_CREDENTIALS("Reset credentials"), + RESET_CREDENTIALS("Reset Credentials"), CLIENTS("Clients"); private final String name; @@ -64,6 +68,10 @@ public class Flows extends Authentication { return flowSelect.getFirstSelectedOption().getText(); } + public List getFlowAllValues() { + return flowSelect.getOptions().stream().map(WebElement::getText).collect(Collectors.toList()); + } + public FlowsTable table() { return flowsTable; } diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java index 1e3401b0a6..37579962b1 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java @@ -25,11 +25,16 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; /** * * @author Vlastislav Ramik + * @author Peter Zaoral */ public class FlowsTable { public enum RequirementOption { @@ -53,8 +58,8 @@ public class FlowsTable { public enum Action { DELETE("Delete"), - ADD_EXECUTION("Add Execution"), - ADD_FLOW("Add Flow"); + ADD_EXECUTION("Add execution"), + ADD_FLOW("Add flow"); private final String name; @@ -69,26 +74,51 @@ public class FlowsTable { @FindBy(tagName = "tbody") private WebElement tbody; - + private WebElement getRowByLabelText(String text) { WebElement row = tbody.findElement(By.xpath("//span[text() = '" + text + "']/../..")); + //tbody.findElement(By.xpath("//span[contains(text(),\"" + text + "\")]/../..")); waitUntilElement(row).is().present(); return row; } - + public void clickLevelUpButton(String rowLabel) { - getRowByLabelText(rowLabel).findElement(By.xpath("//i[contains(@class, 'up')]/..")).click(); + getRowByLabelText(rowLabel).findElement(By.xpath(".//button[@data-ng-click='raisePriority(execution)']")).click(); } - + public void clickLevelDownButton(String rowLabel) { - getRowByLabelText(rowLabel).findElement(By.xpath("//i[contains(@class, 'down')]/..")).click(); + getRowByLabelText(rowLabel).findElement(By.xpath(".//button[@data-ng-click='lowerPriority(execution)']")).click(); } - + public void changeRequirement(String rowLabel, RequirementOption option) { - getRowByLabelText(rowLabel).findElement(By.xpath("//input[@value = '" + option + "']")).click(); + getRowByLabelText(rowLabel).findElement(By.xpath(".//input[@value = '" + option + "']")).click(); } - + public void performAction(String rowLabel, Action action) { - + + getRowByLabelText(rowLabel).findElement( + By.xpath(".//div[@class = 'dropdown']/a[@class='dropdown-toggle ng-binding']")).click(); + WebElement currentAction = getRowByLabelText(rowLabel).findElement( + By.xpath("//div[@class = 'dropdown open']/ul[@class = 'dropdown-menu']/li/" + + "a[@class='ng-binding' and text()='" + action.getName() + "']")); + currentAction.click(); + } + + // Returns all aliases of flows (first "Auth Type" column in table) including the names of execution flows + // Each returned alias (key) has also the Requirement option (value) assigned in the Map + public Map getFlowsAliasesWithRequirements(){ + Map flows = new LinkedHashMap<>(); + List aliases = tbody.findElements(By.xpath("//span[@class='ng-binding']")); + + for(WebElement alias : aliases) + { + List requirementsOptions = alias.findElements(By.xpath(".//../parent::*//input[@type='radio']")); + for (WebElement requirement : requirementsOptions) { + if (requirement.isSelected()) { + flows.put(alias.getText(), requirement.getAttribute("value")); + } + } + } + return flows; } } diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java index ecf69e51f0..0b02193836 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java @@ -76,6 +76,12 @@ public abstract class AbstractConsoleTest extends AbstractAuthTest { } } + // TODO: Fix the tests so this workaround is not necessary + @Override + protected boolean isImportAfterEachMethod() { + return true; + } + public void loginToMasterRealmAdminConsoleAs(UserRepresentation user) { loginToAdminConsoleAs(adminConsolePage, loginPage, user); } diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/FlowsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/FlowsTest.java index d3dfb226fb..c35fae3800 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/FlowsTest.java +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/FlowsTest.java @@ -23,8 +23,9 @@ package org.keycloak.testsuite.console.authentication; import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; +import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.testsuite.console.AbstractConsoleTest; import org.keycloak.testsuite.console.page.authentication.flows.CreateExecution; import org.keycloak.testsuite.console.page.authentication.flows.CreateExecutionForm; @@ -33,18 +34,27 @@ import org.keycloak.testsuite.console.page.authentication.flows.CreateFlowForm; import org.keycloak.testsuite.console.page.authentication.flows.Flows; import org.keycloak.testsuite.console.page.authentication.flows.FlowsTable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.*; /** * * @author Vlastislav Ramik + * @author Peter Zaoral */ -@Ignore //waiting for KEYCLOAK-1967(KEYCLOAK-1966) + public class FlowsTest extends AbstractConsoleTest { @Page private Flows flowsPage; - + @Page private CreateFlow createFlowPage; @@ -58,53 +68,71 @@ public class FlowsTest extends AbstractConsoleTest { @Test public void createDeleteFlowTest() { - log.info("add new flow"); + // Adding new flow flowsPage.clickNew(); createFlowPage.form().setValues("testFlow", "testDesc", CreateFlowForm.FlowType.GENERIC); - assertEquals("Success! Flow Created.", createFlowPage.getSuccessMessage()); - log.debug("new flow created via UI"); + assertAlertSuccess(); + + // Checking if test flow is created via rest + AuthenticationFlowRepresentation testFlow = getFlowFromREST("testFlow"); + assertEquals("testFlow", testFlow.getAlias()); - log.info("check if test flow is created via rest"); - //rest: flow is present - log.debug("checked"); - - log.debug("check if testFlow is selected in UI"); + // Checking if testFlow is selected in UI assertEquals("TestFlow", flowsPage.getFlowSelectValue()); - log.info("add new execution flow within testFlow"); + // Adding new execution flow within testFlow flowsPage.clickAddFlow(); - createFlowPage.form().setValues("testExecutionFlow", "executionDesc", CreateFlowForm.FlowType.GENERIC); - assertEquals("Success! Flow Created.", createFlowPage.getSuccessMessage()); - log.debug("new execution flow created via UI"); + createFlowPage.form().setValues("testExecution", "executionDesc", CreateFlowForm.FlowType.GENERIC); + assertAlertSuccess(); - log.info("check if execution flow is created via rest"); - //rest: flow within nested flow is present - log.debug("checked"); + // Checking if execution flow is created via rest + testFlow = getFlowFromREST("testFlow"); + assertEquals("testExecution", testFlow.getAuthenticationExecutions().get(0).getFlowAlias()); - log.debug("check if testFlow is selected in UI"); + // Checking if testFlow is selected in UI assertEquals("TestFlow", flowsPage.getFlowSelectValue()); - log.info("delete test flow"); + // Deleting test flow flowsPage.clickDelete(); - assertEquals("Success! Flow removed", createFlowPage.getSuccessMessage()); - log.debug("test flow removed via UI"); - - log.info("check if both test flow and execution flow is removed via rest"); - //rest - log.debug("checked"); + modalDialog.confirmDeletion(); + assertAlertSuccess(); + + // Checking if both test flow and execution flow is removed via UI + assertThat(flowsPage.getFlowAllValues(), not(hasItem("TestFlow"))); + + // Checking if both test flow and execution flow is removed via rest + assertThat(testRealmResource().flows().getFlows(), not(hasItem(testFlow))); } - + + @Test + public void selectFlowOptionTest() { + flowsPage.selectFlowOption(Flows.FlowOption.DIRECT_GRANT); + assertEquals("Direct Grant", flowsPage.getFlowSelectValue()); + flowsPage.selectFlowOption(Flows.FlowOption.BROWSER); + assertEquals("Browser", flowsPage.getFlowSelectValue()); + flowsPage.selectFlowOption(Flows.FlowOption.CLIENTS); + assertEquals("Clients", flowsPage.getFlowSelectValue()); + } + @Test public void createFlowWithEmptyAliasTest() { flowsPage.clickNew(); createFlowPage.form().setValues("", "testDesc", CreateFlowForm.FlowType.GENERIC); - assertEquals("Error! Missing or invalid field(s). Please verify the fields in red.", createFlowPage.getErrorMessage()); + assertAlertDanger(); //rest:flow isn't present - - //best-efford: check empty alias in nested flow } - + + @Test + public void createNestedFlowWithEmptyAliasTest() { + //best-effort: check empty alias in nested flow + flowsPage.clickNew(); + createFlowPage.form().setValues("testFlow", "testDesc", CreateFlowForm.FlowType.GENERIC); + flowsPage.clickAddFlow(); + createFlowPage.form().setValues("", "executionDesc", CreateFlowForm.FlowType.GENERIC); + assertAlertDanger(); + } + @Test public void copyFlowTest() { flowsPage.selectFlowOption(Flows.FlowOption.BROWSER); @@ -112,86 +140,172 @@ public class FlowsTest extends AbstractConsoleTest { modalDialog.setName("test copy of browser"); modalDialog.ok(); - assertEquals("Success! Flow copied.", createFlowPage.getSuccessMessage()); + assertAlertSuccess(); + + //UI + assertEquals("Test Copy Of Browser", flowsPage.getFlowSelectValue()); + assertTrue(flowsPage.table().getFlowsAliasesWithRequirements().containsKey("Test Copy Of Browser Forms")); + assertEquals(6,flowsPage.table().getFlowsAliasesWithRequirements().size()); + //rest: copied flow present + assertThat(testRealmResource().flows().getFlows().stream() + .map(AuthenticationFlowRepresentation::getAlias). + collect(Collectors.toList()), hasItem(getFlowFromREST("test copy of browser").getAlias())); } @Test public void createDeleteExecutionTest() { - //rest: add new flow - - log.info("add new execution within testFlow"); + // Adding new execution within testFlow + + flowsPage.clickNew(); + createFlowPage.form().setValues("testFlow", "testDesc", CreateFlowForm.FlowType.GENERIC); + flowsPage.clickAddExecution(); createExecutionPage.form().selectProviderOption(CreateExecutionForm.ProviderOption.RESET_PASSWORD); createExecutionPage.form().save(); + assertAlertSuccess(); - assertEquals("Success! Execution Created.", createExecutionPage.getSuccessMessage()); - log.debug("new execution flow created via UI"); - - //rest:check new execution - - log.debug("check if testFlow is selected in UI"); + // REST + AuthenticationFlowRepresentation flowRest = getFlowFromREST("testFlow"); + assertEquals(1, flowRest.getAuthenticationExecutions().size()); + assertEquals("reset-password", flowRest.getAuthenticationExecutions().get(0).getAuthenticator()); + + // UI assertEquals("TestFlow", flowsPage.getFlowSelectValue()); - - log.info("delete test flow"); + assertEquals(1,flowsPage.table().getFlowsAliasesWithRequirements().size()); + assertTrue(flowsPage.table().getFlowsAliasesWithRequirements().keySet().contains("Reset Password")); + + // Deletion flowsPage.clickDelete(); - assertEquals("Success! Flow removed", createFlowPage.getSuccessMessage()); - log.debug("test flow removed via UI"); - - log.info("check if both test flow and execution flow is removed via rest"); - //rest - log.debug("checked"); + modalDialog.confirmDeletion(); + assertAlertSuccess(); + assertThat(flowsPage.getFlowAllValues(), not(hasItem("TestFlow"))); } @Test public void navigationTest() { - //rest: add or copy flow to test navigation (browser) + flowsPage.selectFlowOption(Flows.FlowOption.BROWSER); + flowsPage.clickCopy(); + modalDialog.ok(); - //rest: - log.debug("check if there is expected structure of the flow"); + //init order //first should be Cookie //second Kerberos - //third Test Copy Of Browser Forms + //third Identity provider redirector + //fourth Test Copy Of Browser Forms //a) Username Password Form //b) OTP Form flowsPage.table().clickLevelDownButton("Cookie"); - assertEquals("Success! Priority lowered", flowsPage.getSuccessMessage()); + assertAlertSuccess(); - flowsPage.table().clickLevelUpButton("Test Copy Of Browser Forms"); - assertEquals("Success! Priority raised", flowsPage.getSuccessMessage()); + flowsPage.table().clickLevelUpButton("Cookie"); + assertAlertSuccess(); - flowsPage.table().clickLevelUpButton("OTP Forms"); - assertEquals("Success! Priority raised", flowsPage.getSuccessMessage()); - - //rest:check if navigation was changed properly + flowsPage.table().clickLevelUpButton("Kerberos"); + assertAlertSuccess(); + + flowsPage.table().clickLevelDownButton("Identity Provider Redirector"); + assertAlertSuccess(); + + flowsPage.table().clickLevelUpButton("OTP Form"); + assertAlertSuccess(); + + List expectedOrder = new ArrayList<>(); + Collections.addAll(expectedOrder, "Kerberos", "Cookie", "Copy Of Browser Forms", "OTP Form", + "Username Password Form", "Identity Provider Redirector"); + + //UI + assertEquals(6,flowsPage.table().getFlowsAliasesWithRequirements().size()); + assertTrue(expectedOrder.containsAll(flowsPage.table().getFlowsAliasesWithRequirements().keySet())); + + //REST + List executionsRest = + getFlowFromREST("Copy of browser").getAuthenticationExecutions(); + assertEquals("auth-spnego", executionsRest.get(0).getAuthenticator()); + assertEquals("auth-cookie", executionsRest.get(1).getAuthenticator()); + assertEquals("Copy of browser forms", executionsRest.get(2).getFlowAlias()); + assertEquals("identity-provider-redirector", executionsRest.get(3).getAuthenticator()); + flowsPage.clickDelete(); + modalDialog.confirmDeletion(); } @Test public void requirementTest() { //rest: add or copy flow to test navigation (browser), add reset, password - + flowsPage.selectFlowOption(Flows.FlowOption.BROWSER); flowsPage.table().changeRequirement("Cookie", FlowsTable.RequirementOption.DISABLED); + assertAlertSuccess(); + flowsPage.table().changeRequirement("Kerberos", FlowsTable.RequirementOption.REQUIRED); + assertAlertSuccess(); flowsPage.table().changeRequirement("Kerberos", FlowsTable.RequirementOption.ALTERNATIVE); - flowsPage.table().changeRequirement("Copy Of Browser Forms", FlowsTable.RequirementOption.REQUIRED); - flowsPage.table().changeRequirement("Reset Password", FlowsTable.RequirementOption.REQUIRED); + assertAlertSuccess(); + flowsPage.table().changeRequirement("OTP Form", FlowsTable.RequirementOption.DISABLED); + assertAlertSuccess(); + flowsPage.table().changeRequirement("OTP Form", FlowsTable.RequirementOption.OPTIONAL); + assertAlertSuccess(); + + //UI + List expectedOrder = new ArrayList<>(); + Collections.addAll(expectedOrder,"DISABLED", "ALTERNATIVE", "ALTERNATIVE", + "ALTERNATIVE", "REQUIRED", "OPTIONAL"); + assertTrue(expectedOrder.containsAll(flowsPage.table().getFlowsAliasesWithRequirements().values())); - //rest:check + //REST: + List browserFlow = getFlowFromREST("browser").getAuthenticationExecutions(); + assertEquals("DISABLED", browserFlow.get(0).getRequirement()); + assertEquals("ALTERNATIVE", browserFlow.get(1).getRequirement()); + assertEquals("ALTERNATIVE", browserFlow.get(2).getRequirement()); } @Test public void actionsTest() { //rest: add or copy flow to test navigation (browser) - + flowsPage.selectFlowOption(Flows.FlowOption.BROWSER); + flowsPage.clickCopy(); + modalDialog.ok(); + + flowsPage.table().performAction("Cookie", FlowsTable.Action.DELETE); + modalDialog.confirmDeletion(); + assertAlertSuccess(); flowsPage.table().performAction("Kerberos", FlowsTable.Action.DELETE); + modalDialog.confirmDeletion(); + assertAlertSuccess(); flowsPage.table().performAction("Copy Of Browser Forms", FlowsTable.Action.ADD_FLOW); - - createFlowPage.form().setValues("nestedFlow", "", CreateFlowForm.FlowType.CLIENT); - - //todo: perform all remaining actions - - //rest: check + createFlowPage.form().setValues("nestedFlow", "testDesc", CreateFlowForm.FlowType.FORM); + assertAlertSuccess(); + flowsPage.table().performAction("Copy Of Browser Forms",FlowsTable.Action.ADD_EXECUTION); + createExecutionPage.form().selectProviderOption(CreateExecutionForm.ProviderOption.RESET_PASSWORD); + createExecutionPage.form().save(); + assertAlertSuccess(); + + //UI + List expectedOrder = new ArrayList<>(); + Collections.addAll(expectedOrder, "Identity Provider Redirector", "Copy Of Browser Forms", + "Username Password Form", "OTP Form", "NestedFlow", "Reset Password"); + + assertEquals(6,flowsPage.table().getFlowsAliasesWithRequirements().size()); + assertTrue(expectedOrder.containsAll(flowsPage.table().getFlowsAliasesWithRequirements().keySet())); + + //REST + List executionsRest = + getFlowFromREST("Copy of browser").getAuthenticationExecutions(); + assertEquals("identity-provider-redirector", executionsRest.get(0).getAuthenticator()); + String tmpFlowAlias = executionsRest.get(1).getFlowAlias(); + assertEquals("Copy of browser forms", tmpFlowAlias); + assertEquals("Username Password Form", testRealmResource().flows().getExecutions(tmpFlowAlias).get(0).getDisplayName()); + assertEquals("nestedFlow", testRealmResource().flows().getExecutions(tmpFlowAlias).get(2).getDisplayName()); + } + + private AuthenticationFlowRepresentation getFlowFromREST(String alias) { + Optional flow = testRealmResource() + .flows() + .getFlows() + .stream() + .filter(f -> f.getAlias().equals(alias)) + .findFirst(); + return flow.isPresent() ? flow.get() : null; } } diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java index 559ba28823..103f7130d4 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java @@ -87,7 +87,6 @@ public abstract class AbstractClientTest extends AbstractConsoleTest { attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA256"); attributes.put(SAML_FORCE_NAME_ID_FORMAT, "false"); attributes.put(SAML_NAME_ID_FORMAT, "username"); - attributes.put(SAML_ONETIMEUSE_CONDITION, "true"); return attributes; } diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/pom.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/pom.xml index 9c704d28b5..f0408758ea 100644 --- a/testsuite/integration-arquillian/tests/other/server-config-migration/pom.xml +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/pom.xml @@ -35,6 +35,7 @@ ${project.build.directory}/keycloak-${project.version} + 1.8.1 @@ -64,7 +65,7 @@ unpack - compile + process-resources unpack @@ -89,7 +90,7 @@ copy-standalone - generate-test-sources + compile copy-resources @@ -106,7 +107,7 @@ copy-domain - generate-test-sources + compile copy-resources @@ -124,6 +125,36 @@ + + com.coderplus.maven.plugins + copy-rename-maven-plugin + 1.0.1 + + + rename-keycloak-server-json-standalone + generate-test-sources + + rename + + + ${jbossHome}/standalone/configuration/keycloak-server-${migrated.version}.json + ${jbossHome}/standalone/configuration/keycloak-server.json + + + + rename-keycloak-server-json-domain + generate-test-sources + + rename + + + ${jbossHome}/domain/configuration/keycloak-server-${migrated.version}.json + ${jbossHome}/domain/configuration/keycloak-server.json + + + + + com.google.code.maven-replacer-plugin maven-replacer-plugin @@ -185,7 +216,7 @@ shutdown - standalone-1.8.1.xml + standalone-${migrated.version}.xml -Djboss.socket.binding.port-offset=1000 @@ -205,14 +236,14 @@ shutdown - standalone-1.8.1.xml + standalone-${migrated.version}.xml -Djboss.socket.binding.port-offset=1000 - echo Reading subsystems for migrated standalone-1.8.1.xml - /subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-standalone-1.8.1.txt + echo Reading subsystems for migrated standalone-${migrated.version}.xml + /subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-standalone-${migrated.version}.txt @@ -249,7 +280,7 @@ shutdown - standalone-ha-1.8.1.xml + standalone-ha-${migrated.version}.xml -Djboss.socket.binding.port-offset=1000 @@ -269,14 +300,14 @@ shutdown - standalone-ha-1.8.1.xml + standalone-ha-${migrated.version}.xml -Djboss.socket.binding.port-offset=1000 - echo Reading subsystems for migrated standalone-ha-1.8.1.xml - /subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-standalone-ha-1.8.1.txt + echo Reading subsystems for migrated standalone-ha-${migrated.version}.xml + /subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-standalone-ha-${migrated.version}.txt @@ -314,9 +345,9 @@ DOMAIN - domain-1.8.1.xml + domain-${migrated.version}.xml - --host-config=host-master-1.8.1.xml + --host-config=host-master-${migrated.version}.xml @@ -345,9 +376,9 @@ DOMAIN - domain-1.8.1.xml + domain-${migrated.version}.xml - --host-config=host-master-1.8.1.xml + --host-config=host-master-${migrated.version}.xml -Djboss.management.http.port=10990 @@ -355,9 +386,9 @@ - echo Reading subsystems for migrated domain-1.8.1.xml - /profile=auth-server-standalone/subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-domain-standalone-1.8.1.txt - /profile=auth-server-clustered/subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-domain-clustered-1.8.1.txt + echo Reading subsystems for migrated domain-${migrated.version}.xml + /profile=auth-server-standalone/subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-domain-standalone-${migrated.version}.txt + /profile=auth-server-clustered/subsystem=*/:read-resource(recursive=true)>${project.build.directory}/migrated-domain-clustered-${migrated.version}.txt @@ -394,7 +425,51 @@ maven-surefire-plugin + + + ${migrated.version} + + + + + + product + + ${project.build.directory}/rh-sso-7.1 + 1.9.8.Final-redhat-1 + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + compile + + unpack + + + + + org.keycloak + keycloak-server-dist + 2.5.4.Final-redhat-1 + zip + true + ${project.build.directory} + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/java/org/keycloak/test/config/migration/ConfigMigrationTest.java b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/java/org/keycloak/test/config/migration/ConfigMigrationTest.java index f4cda30b79..7f5ad34f02 100644 --- a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/java/org/keycloak/test/config/migration/ConfigMigrationTest.java +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/java/org/keycloak/test/config/migration/ConfigMigrationTest.java @@ -34,21 +34,22 @@ import org.junit.Test; public class ConfigMigrationTest { private static final File TARGET_DIR = new File("./target"); + private final String migratedVersion = System.getProperty("migrated.version"); @Test public void testStandalone() throws IOException { - compareConfigs("master-standalone.txt", "migrated-standalone-1.8.1.txt"); + compareConfigs("master-standalone.txt", "migrated-standalone-" + migratedVersion + ".txt"); } @Test public void testStandaloneHA() throws IOException { - compareConfigs("master-standalone-ha.txt", "migrated-standalone-ha-1.8.1.txt"); + compareConfigs("master-standalone-ha.txt", "migrated-standalone-ha-" + migratedVersion + ".txt"); } @Test public void testDomain() throws IOException { - compareConfigs("master-domain-standalone.txt", "migrated-domain-standalone-1.8.1.txt"); - compareConfigs("master-domain-clustered.txt", "migrated-domain-clustered-1.8.1.txt"); + compareConfigs("master-domain-standalone.txt", "migrated-domain-standalone-" + migratedVersion + ".txt"); + compareConfigs("master-domain-clustered.txt", "migrated-domain-clustered-" + migratedVersion + ".txt"); } private void compareConfigs(String masterConfig, String migratedConfig) throws IOException { diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-1.9.8.Final-redhat-1.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-1.9.8.Final-redhat-1.xml new file mode 100644 index 0000000000..2a011dccbf --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-1.9.8.Final-redhat-1.xml @@ -0,0 +1,896 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + jdbc:h2:${jboss.server.data.dir}/../../shared-database/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-1.9.8.Final-redhat-1.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-1.9.8.Final-redhat-1.xml new file mode 100644 index 0000000000..4af977da17 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-1.9.8.Final-redhat-1.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server.json b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server-1.8.1.json similarity index 100% rename from testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server.json rename to testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server-1.8.1.json diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server-1.9.8.Final-redhat-1.json b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server-1.9.8.Final-redhat-1.json new file mode 100644 index 0000000000..4c8e3f9cc9 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/keycloak-server-1.9.8.Final-redhat-1.json @@ -0,0 +1,75 @@ +{ + "admin": { + "realm": "master" + }, + + "eventsStore": { + "provider": "jpa", + "jpa": { + "exclude-events": [ "REFRESH_TOKEN" ] + } + }, + + "realm": { + "provider": "jpa" + }, + + "user": { + "provider": "jpa" + }, + + "userCache": { + "default" : { + "enabled": true + } + }, + + "userSessionPersister": { + "provider": "jpa" + }, + + "authorizationPersister": { + "provider": "jpa" + }, + + "timer": { + "provider": "basic" + }, + + "theme": { + "staticMaxAge": 2592000, + "cacheTemplates": true, + "cacheThemes": true, + "folder": { + "dir": "${jboss.home.dir}/themes" + } + }, + + "scheduled": { + "interval": 900 + }, + + "connectionsHttpClient": { + "default": {} + }, + + "connectionsJpa": { + "default": { + "dataSource": "java:jboss/datasources/KeycloakDS", + "databaseSchema": "update" + } + }, + + "realmCache": { + "default" : { + "enabled": true + } + }, + + "connectionsInfinispan": { + "provider": "default", + "default": { + "cacheContainer" : "java:comp/env/infinispan/Keycloak" + } + } +} diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server.json b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server-1.8.1.json similarity index 100% rename from testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server.json rename to testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server-1.8.1.json diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server-1.9.8.Final-redhat-1.json b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server-1.9.8.Final-redhat-1.json new file mode 100644 index 0000000000..6bcfffba74 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/keycloak-server-1.9.8.Final-redhat-1.json @@ -0,0 +1,75 @@ +{ + "admin": { + "realm": "master" + }, + + "eventsStore": { + "provider": "jpa", + "jpa": { + "exclude-events": [ "REFRESH_TOKEN" ] + } + }, + + "realm": { + "provider": "jpa" + }, + + "user": { + "provider": "jpa" + }, + + "userCache": { + "default" : { + "enabled": true + } + }, + + "userSessionPersister": { + "provider": "jpa" + }, + + "authorizationPersister": { + "provider": "jpa" + }, + + "timer": { + "provider": "basic" + }, + + "theme": { + "staticMaxAge": 2592000, + "cacheTemplates": true, + "cacheThemes": true, + "folder": { + "dir": "${jboss.home.dir}/themes" + } + }, + + "scheduled": { + "interval": 900 + }, + + "connectionsHttpClient": { + "default": {} + }, + + "connectionsJpa": { + "default": { + "dataSource": "java:jboss/datasources/KeycloakDS", + "databaseSchema": "update" + } + }, + + "realmCache": { + "default" : { + "enabled": true + } + }, + + "connectionsInfinispan": { + "provider": "default", + "default": { + "cacheContainer" : "java:comp/env/infinispan/Keycloak" + } + } +} diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-1.9.8.Final-redhat-1.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-1.9.8.Final-redhat-1.xml new file mode 100644 index 0000000000..7bcc5a656b --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-1.9.8.Final-redhat-1.xml @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-1.9.8.Final-redhat-1.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-1.9.8.Final-redhat-1.xml new file mode 100644 index 0000000000..46ab99906d --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-1.9.8.Final-redhat-1.xml @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + auth + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 228bc9e295..7d2edbe5f3 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -78,8 +78,6 @@ true true - off - ${project.build.directory}/dependency/test-constants.properties false @@ -217,8 +215,6 @@ ${firefox_binary} ${phantomjs.cli.args} - ${keycloak.logging.level} - ${project.version} ${migration.project.version} ${migration.product.version} @@ -237,7 +233,7 @@ listener - org.keycloak.testsuite.util.TestEventsLogger,org.keycloak.testsuite.util.junit.AggregateResultsReporter + org.keycloak.testsuite.util.TestEventsLogger,org.keycloak.testsuite.util.junit.AggregateResultsReporter,org.keycloak.testsuite.util.NonIDERunListener diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java index 0977d2dbc6..b047595f5d 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java @@ -433,6 +433,7 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent // Assert I am logged immediately to account management due to previously linked "test-user" identity loginPage.clickSocial(identityProviderModel.getAlias()); + this.loginPage.login("test-user", "password"); doAfterProviderAuthentication(); assertTrue(accountFederatedIdentityPage.isCurrent()); assertTrue(driver.getPageSource().contains("id=\"remove-" + identityProviderModel.getAlias() + "\"")); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java index 09ddb39a3a..1fb0a63090 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java @@ -37,6 +37,9 @@ import org.keycloak.social.google.GoogleIdentityProvider; import org.keycloak.social.google.GoogleIdentityProviderFactory; import org.keycloak.social.linkedin.LinkedInIdentityProvider; import org.keycloak.social.linkedin.LinkedInIdentityProviderFactory; +import org.keycloak.social.openshift.OpenshifV3IdentityProviderConfig; +import org.keycloak.social.openshift.OpenshiftV3IdentityProvider; +import org.keycloak.social.openshift.OpenshiftV3IdentityProviderFactory; import org.keycloak.social.stackoverflow.StackOverflowIdentityProviderConfig; import org.keycloak.social.stackoverflow.StackoverflowIdentityProvider; import org.keycloak.social.stackoverflow.StackoverflowIdentityProviderFactory; @@ -146,6 +149,8 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes assertLinkedInIdentityProviderConfig(identityProvider); } else if (StackoverflowIdentityProviderFactory.PROVIDER_ID.equals(providerId)) { assertStackoverflowIdentityProviderConfig(identityProvider); + } else if (OpenshiftV3IdentityProviderFactory.PROVIDER_ID.equals(providerId)) { + assertOpenshiftIdentityProviderConfig(identityProvider); } else { continue; } @@ -283,6 +288,21 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes assertEquals(StackoverflowIdentityProvider.PROFILE_URL, config.getUserInfoUrl()); } + private void assertOpenshiftIdentityProviderConfig(IdentityProviderModel identityProvider) { + OpenshiftV3IdentityProvider osoIdentityProvider = new OpenshiftV3IdentityProviderFactory().create(session, identityProvider); + OpenshifV3IdentityProviderConfig config = osoIdentityProvider.getConfig(); + + assertEquals("model-openshift-v3", config.getAlias()); + assertEquals(OpenshiftV3IdentityProviderFactory.PROVIDER_ID, config.getProviderId()); + assertEquals(true, config.isEnabled()); + assertEquals(false, config.isTrustEmail()); + assertEquals(false, config.isAuthenticateByDefault()); + assertEquals(true, config.isStoreToken()); + assertEquals(OpenshiftV3IdentityProvider.BASE_URL, config.getBaseUrl()); + assertEquals("clientId", config.getClientId()); + assertEquals("clientSecret", config.getClientSecret()); + } + private void assertTwitterIdentityProviderConfig(IdentityProviderModel identityProvider) { TwitterIdentityProvider twitterIdentityProvider = new TwitterIdentityProviderFactory().create(session, identityProvider); OAuth2IdentityProviderConfig config = twitterIdentityProvider.getConfig(); diff --git a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json index 1bfc295905..09fa373bbe 100755 --- a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json +++ b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json @@ -91,6 +91,20 @@ "clientSecret": "clientSecret" } }, + { + "alias" : "model-openshift-v3", + "providerId" : "openshift-v3", + "enabled": true, + "storeToken": true, + "config": { + "baseUrl": "https://api.preview.openshift.com", + "authorizationUrl": "authorizationUrl", + "tokenUrl": "tokenUrl", + "userInfoUrl": "userInfoUrl", + "clientId": "clientId", + "clientSecret": "clientSecret" + } + }, { "alias" : "model-saml-signed-idp", "providerId" : "saml", diff --git a/testsuite/pom.xml b/testsuite/pom.xml index fa9cb53076..843f3cf848 100755 --- a/testsuite/pom.xml +++ b/testsuite/pom.xml @@ -51,12 +51,25 @@ integration - proxy - tomcat6 - tomcat7 tomcat8 - jetty integration-arquillian + + + + community + + + !product + + + + jetty + proxy + tomcat6 + tomcat7 + + + diff --git a/themes/pom.xml b/themes/pom.xml index 73edd82256..e98bacbe18 100755 --- a/themes/pom.xml +++ b/themes/pom.xml @@ -1,15 +1,54 @@ - - keycloak-parent - org.keycloak - 3.1.0.CR1-SNAPSHOT - - 4.0.0 + + keycloak-parent + org.keycloak + 3.1.0.CR1-SNAPSHOT + + 4.0.0 - keycloak-themes - Keycloak Themes - + keycloak-themes + Keycloak Themes + + + + + community + + + !product + + + + + + src/main/resources + + + src/main/resources-community + + + + + + product + + + product + + + + + + src/main/resources + + + src/main/resources-product + + + + + diff --git a/themes/src/main/resources/META-INF/keycloak-themes.json b/themes/src/main/resources-community/META-INF/keycloak-themes.json similarity index 100% rename from themes/src/main/resources/META-INF/keycloak-themes.json rename to themes/src/main/resources-community/META-INF/keycloak-themes.json diff --git a/themes/src/main/resources/theme/base/account/messages/messages_ca.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_ca.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_ca.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_ca.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_de.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_de.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_de.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_de.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_es.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_es.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_es.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_es.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_fr.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_fr.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_fr.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_fr.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_it.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_it.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_it.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_it.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_ja.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_ja.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_ja.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_ja.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_lt.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_lt.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_no.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_no.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_no.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_no.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_pt_BR.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_pt_BR.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_ru.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_ru.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_ru.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_ru.properties diff --git a/themes/src/main/resources/theme/base/account/messages/messages_sv.properties b/themes/src/main/resources-community/theme/base/account/messages/messages_sv.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/messages/messages_sv.properties rename to themes/src/main/resources-community/theme/base/account/messages/messages_sv.properties diff --git a/themes/src/main/resources/theme/base/account/theme.properties b/themes/src/main/resources-community/theme/base/account/theme.properties similarity index 100% rename from themes/src/main/resources/theme/base/account/theme.properties rename to themes/src/main/resources-community/theme/base/account/theme.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_ca.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ca.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_ca.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ca.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_de.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_de.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_es.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_es.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_es.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_es.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_fr.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_fr.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_fr.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_fr.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_it.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_it.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_it.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_it.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_ja.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ja.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_ja.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ja.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_lt.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_lt.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_lt.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_lt.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_no.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_no.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_no.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_no.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_pt_BR.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_pt_BR.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_pt_BR.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_pt_BR.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_ru.properties b/themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ru.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/admin-messages_ru.properties rename to themes/src/main/resources-community/theme/base/admin/messages/admin-messages_ru.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_ca.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_ca.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_ca.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_ca.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_es.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_es.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_es.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_es.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_fr.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_fr.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_fr.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_fr.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_it.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_it.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_it.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_it.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_ja.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_ja.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_ja.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_ja.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_lt.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_lt.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_lt.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_lt.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_no.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_no.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_no.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_no.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_pt_BR.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_pt_BR.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_pt_BR.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_pt_BR.properties diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_ru.properties b/themes/src/main/resources-community/theme/base/admin/messages/messages_ru.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/messages/messages_ru.properties rename to themes/src/main/resources-community/theme/base/admin/messages/messages_ru.properties diff --git a/themes/src/main/resources/theme/base/admin/theme.properties b/themes/src/main/resources-community/theme/base/admin/theme.properties similarity index 100% rename from themes/src/main/resources/theme/base/admin/theme.properties rename to themes/src/main/resources-community/theme/base/admin/theme.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_ca.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_ca.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_ca.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_ca.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_de.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_de.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_de.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_de.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_es.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_es.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_es.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_es.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_fr.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_fr.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_fr.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_fr.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_it.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_it.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_it.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_it.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_ja.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_ja.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_ja.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_ja.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_lt.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_lt.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_no.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_no.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_no.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_no.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_pt_BR.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_pt_BR.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_pt_BR.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_pt_BR.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_ru.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_ru.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_ru.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_ru.properties diff --git a/themes/src/main/resources/theme/base/email/messages/messages_sv.properties b/themes/src/main/resources-community/theme/base/email/messages/messages_sv.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/messages/messages_sv.properties rename to themes/src/main/resources-community/theme/base/email/messages/messages_sv.properties diff --git a/themes/src/main/resources/theme/base/email/theme.properties b/themes/src/main/resources-community/theme/base/email/theme.properties similarity index 100% rename from themes/src/main/resources/theme/base/email/theme.properties rename to themes/src/main/resources-community/theme/base/email/theme.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_ca.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_ca.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_de.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_de.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_de.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_de.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_es.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_es.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_es.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_es.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_fr.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_fr.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_fr.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_fr.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_it.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_it.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_it.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_it.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_ja.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_ja.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_ja.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_ja.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_lt.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_lt.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_no.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_no.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_no.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_no.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_pt_BR.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_pt_BR.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_ru.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_ru.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_ru.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_ru.properties diff --git a/themes/src/main/resources/theme/base/login/messages/messages_sv.properties b/themes/src/main/resources-community/theme/base/login/messages/messages_sv.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/messages/messages_sv.properties rename to themes/src/main/resources-community/theme/base/login/messages/messages_sv.properties diff --git a/themes/src/main/resources/theme/base/login/theme.properties b/themes/src/main/resources-community/theme/base/login/theme.properties similarity index 100% rename from themes/src/main/resources/theme/base/login/theme.properties rename to themes/src/main/resources-community/theme/base/login/theme.properties diff --git a/themes/src/main/resources-product/META-INF/keycloak-themes.json b/themes/src/main/resources-product/META-INF/keycloak-themes.json new file mode 100755 index 0000000000..176bc779ee --- /dev/null +++ b/themes/src/main/resources-product/META-INF/keycloak-themes.json @@ -0,0 +1,12 @@ +{ + "themes": [{ + "name" : "base", + "types": [ "admin", "account", "login", "email" ] + }, { + "name" : "keycloak", + "types": [ "admin", "account", "login", "common", "email", "welcome" ] + }, { + "name" : "rh-sso", + "types": [ "admin", "account", "login", "common", "email", "welcome" ] + }] +} \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/base/account/theme.properties b/themes/src/main/resources-product/theme/base/account/theme.properties new file mode 100644 index 0000000000..41e974fb1c --- /dev/null +++ b/themes/src/main/resources-product/theme/base/account/theme.properties @@ -0,0 +1 @@ +locales=en \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/base/admin/theme.properties b/themes/src/main/resources-product/theme/base/admin/theme.properties new file mode 100644 index 0000000000..a479a13545 --- /dev/null +++ b/themes/src/main/resources-product/theme/base/admin/theme.properties @@ -0,0 +1,2 @@ +import=common/keycloak +locales=en \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/base/email/theme.properties b/themes/src/main/resources-product/theme/base/email/theme.properties new file mode 100644 index 0000000000..41e974fb1c --- /dev/null +++ b/themes/src/main/resources-product/theme/base/email/theme.properties @@ -0,0 +1 @@ +locales=en \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/base/login/theme.properties b/themes/src/main/resources-product/theme/base/login/theme.properties new file mode 100644 index 0000000000..41e974fb1c --- /dev/null +++ b/themes/src/main/resources-product/theme/base/login/theme.properties @@ -0,0 +1 @@ +locales=en \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/rh-sso/account/messages/messages_en.properties b/themes/src/main/resources-product/theme/rh-sso/account/messages/messages_en.properties new file mode 100644 index 0000000000..dfe4ef623c --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/account/messages/messages_en.properties @@ -0,0 +1 @@ +accountManagementTitle=RH-SSO Account Management diff --git a/themes/src/main/resources-product/theme/rh-sso/account/resources/css/account.css b/themes/src/main/resources-product/theme/rh-sso/account/resources/css/account.css new file mode 100644 index 0000000000..f95d014ec5 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/account/resources/css/account.css @@ -0,0 +1,267 @@ +html { + height: 100%; +} + +body { + background-color: #F9F9F9; + margin: 0; + padding: 0; + height: 100%; +} + +header .navbar { + margin-bottom: 0; + min-height: inherit; +} + +.header .container { + position: relative; +} + +.navbar-title { + background-image: url('../img/brand.svg'); + height: 25px; + background-repeat: no-repeat; + width: 172px; + margin: 3px 10px 5px; + text-indent: -99999px; + position: relative; + top: 8px; +} + +.navbar-pf .navbar-utility { + right: 20px; + top: -34px; + font-size: 12px; +} + +.navbar-pf .navbar-utility > li > a { + color: #fff !important; + padding-bottom: 12px; + padding-top: 11px; + border-left: medium none; +} + +.container { + height: 100%; +} + +.content-area { + background-color: #fff; + border-color: #CECECE; + border-style: solid; + border-width: 0 1px; + height: 100%; + padding: 0 30px; +} + +/* Sidebar */ + +.bs-sidebar { + background-color: #f9f9f9; + padding-top: 44px; + padding-right: 0; + padding-left: 0; + z-index: 20; +} +.bs-sidebar ul { + list-style: none; + padding-left: 12px; +} + +.bs-sidebar ul li { + margin-bottom: 0.5em; + margin-left: -1em; +} +.bs-sidebar ul li a { + font-size: 14px; + padding-left: 25px; + color: #4d5258; + line-height: 28px; + display: block; + border-width: 1px 0 1px 1px; + border-style: solid; + border-color: #f9f9f9; +} +.bs-sidebar ul li a:hover, +.bs-sidebar ul li a:focus { + text-decoration: none; + color: #777777; + border-right: 2px solid #aaa; +} +.bs-sidebar ul li.active a { + background-color: #c7e5f0; + border-color: #56bae0; + font-weight: bold; + background-image: url(../img/icon-sidebar-active.png); + background-repeat: no-repeat; + background-position: right center; +} + +.bs-sidebar ul li.active a:hover { + border-right: none; +} + + +.content-area h2 { + font-family: "Open Sans", sans-serif; + font-weight: 100; + font-size: 24px; + margin-bottom: 25px; + margin-top: 25px; +} + +.subtitle { + text-align: right; + margin-top: 30px; + color: #909090; +} + +.required { + color: #CB2915; +} + + +.alert { + margin-top: 30px; + margin-bottom: 0; +} + +.feedback-aligner .alert { + background-position: 1.27273em center; + background-repeat: no-repeat; + border-radius: 2px; + border-width: 1px; + color: #4D5258; + display: inline-block; + font-size: 1.1em; + line-height: 1.4em; + margin: 0; + padding: 0.909091em 3.63636em; + position: relative; + text-align: left; +} +.alert.alert-success { + background-color: #E4F1E1; + border-color: #4B9E39; +} +.alert.alert-error { + background-color: #F8E7E7; + border-color: #B91415; +} +.alert.alert-warning { + background-color: #FEF1E9; + border-color: #F17528; +} +.alert.alert-info { + background-color: #E4F3FA; + border-color: #5994B2; +} + +.form-horizontal { + border-top: 1px solid #E9E8E8; + padding-top: 23px; +} + +.form-horizontal .control-label { + color: #909090; + line-height: 1.4em; + padding-top: 5px; + position: relative; + text-align: right; + width: 100%; +} + +.form-group { + position: relative; +} + +.control-label + .required { + position: absolute; + right: -2px; + top: 0; +} + +#kc-form-buttons { + text-align: right; + margin-top: 10px; +} + +#kc-form-buttons .btn-primary { + float: right; + margin-left: 8px; +} + +/* Authenticator page */ + +ol { + padding-left: 40px; +} + +ol li { + font-size: 13px; + margin-bottom: 10px; + position: relative; +} + +ol li img { + margin-top: 15px; + margin-bottom: 5px; + border: 1px solid #eee; +} + +hr + .form-horizontal { + border: none; + padding-top: 0; +} + +.kc-dropdown{ + position: relative; +} +.kc-dropdown > a{ + display:block; + padding: 11px 10px 12px; + line-height: 12px; + font-size: 12px; + color: #fff !important; + text-decoration: none; +} +.kc-dropdown > a::after{ + content: "\2c5"; + margin-left: 4px; +} +.kc-dropdown:hover > a{ + background-color: rgba(0,0,0,0.2); +} +.kc-dropdown ul li a{ + padding: 1px 11px; + font-size: 12px; + color: #000 !important; + border: 1px solid #fff; + text-decoration: none; + display:block; + line-height: 20px; +} +.kc-dropdown ul li a:hover{ + color: #4d5258; + background-color: #d4edfa; + border-color: #b3d3e7; +} +.kc-dropdown ul{ + position: absolute; + z-index: 2000; + list-style:none; + display:none; + padding: 5px 0px; + margin: 0px; + background-color: #fff !important; + border: 1px solid #b6b6b6; + border-radius: 1px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; + min-width: 100px; +} +.kc-dropdown:hover ul{ + display:block; +} diff --git a/themes/src/main/resources-product/theme/rh-sso/account/resources/img/icon-sidebar-active.png b/themes/src/main/resources-product/theme/rh-sso/account/resources/img/icon-sidebar-active.png new file mode 100644 index 0000000000..e7b9b08283 Binary files /dev/null and b/themes/src/main/resources-product/theme/rh-sso/account/resources/img/icon-sidebar-active.png differ diff --git a/themes/src/main/resources-product/theme/rh-sso/account/theme.properties b/themes/src/main/resources-product/theme/rh-sso/account/theme.properties new file mode 100644 index 0000000000..8a3c6129a3 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/account/theme.properties @@ -0,0 +1,4 @@ +parent=keycloak +import=common/rh-sso + +styles=lib/rcue/css/rcue.min.css lib/rcue/css/rcue-additions.min.css css/account.css diff --git a/themes/src/main/resources-product/theme/rh-sso/admin/messages/admin-messages_en.properties b/themes/src/main/resources-product/theme/rh-sso/admin/messages/admin-messages_en.properties new file mode 100644 index 0000000000..24d6e16a33 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/admin/messages/admin-messages_en.properties @@ -0,0 +1 @@ +consoleTitle=RH-SSO Admin Console diff --git a/themes/src/main/resources-product/theme/rh-sso/admin/resources/css/styles.css b/themes/src/main/resources-product/theme/rh-sso/admin/resources/css/styles.css new file mode 100644 index 0000000000..a1960ed2b9 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/admin/resources/css/styles.css @@ -0,0 +1,411 @@ +html,body { + height: 100%; +} + +form { + margin-top: 20px; +} + +table { + margin-top: 20px; +} + +.required { + color: #f00; +} + +.tooltip-inner { + min-width: 200px; +} + +.margin-top { + margin-top: 20px; +} + +.no-margin-top { + margin-top: 0px !important; +} + +table { + max-width: 100%; +} + +td.clip { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 0; +} + +th.w-10 { + width: 10%; +} + +th.w-15 { + width: 15%; +} + +th.w-20 { + width: 20%; +} + + +th.w-25 { + width: 25%; +} + +th.w-30 { + width: 30%; +} + + +th.w-35 { + width: 35%; +} + +th.w-40 { + width: 40%; +} + +/*********** Loading ***********/ + +.loading { + background-color: #f5f5f5; + border: 1px solid #eee; + position: absolute; + bottom: 0px; + left: 0px; + padding: 2px 200px 2px 5px; +} + +/*********** Feedback ***********/ + +.feedback-aligner { + position: fixed; + top: 15px; + text-align: center; + width: 100%; + height: 0; + z-index: 100; +} +.feedback-aligner .alert { + border-radius: 2px; + border-width: 1px; + display: inline-block; + position: relative; +} + +/*********** On-Off Switch ***********/ + +.onoffswitch { + -moz-user-select: none; + height: 26px; + position: relative; + width: 62px; +} +.onoffswitch .onoffswitch-checkbox { + display: none; +} +.onoffswitch .onoffswitch-label { + border: 1px solid #bbb; + border-radius: 2px; + cursor: pointer; + display: block; + overflow: hidden; + width: 62px; +} +.onoffswitch .onoffswitch-inner { + display: block; + margin-left: -100%; + transition: margin 0.3s ease-in 0s; + width: 200%; +} +.onoffswitch .onoffswitch-inner > span { + -moz-box-sizing: border-box; + color: white; + float: left; + font-size: 11px; + font-family: "Open Sans", sans-serif; + font-weight: bold; + height: 24px; + line-height: 24px; + padding: 0; + width: 50%; +} +.onoffswitch .onoffswitch-switch { + background-image: linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -o-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -moz-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -webkit-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -ms-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fafafa), color-stop(1, 0, #ededed)); + border: 1px solid #aaa; + border-radius: 2px; + bottom: 0; + margin: 0; + position: absolute; + right: 39px; + top: 0; + transition: all 0.3s ease-in 0s; + -webkit-transition: all 0.3s ease-in 0s; + width: 23px; +} +.onoffswitch .onoffswitch-inner .onoffswitch-active { + background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%); + background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%); + background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%); + background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%); + background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3)); + color: #FFFFFF; + padding-left: 10px; +} +.onoffswitch-checkbox:disabled + .onoffswitch-label .onoffswitch-inner .onoffswitch-active, +.onoffswitch-checkbox:disabled + .onoffswitch-label .onoffswitch-inner .onoffswitch-inactive { + background-image: none; + background-color: #e5e5e5; + color: #9d9fa1; +} +.onoffswitch .onoffswitch-inner .onoffswitch-inactive { + background: linear-gradient(#fefefe, #e8e8e8) repeat scroll 0 0 transparent; + color: #4d5258; + padding-right: 10px; + text-align: right; +} +.onoffswitch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { + margin-left: 0; +} +.onoffswitch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { + right: 0; +} + + +/*********** Select 2 ***********/ + +.select2-container { + width: 100%; +} + +.select2-container-multi .select2-choices .select2-search-field { + height: 26px; +} + + +/*********** New Menu ***********/ + + +.sidebar-pf-left{ + background: #292e34; +} + +.sidebar-pf .nav-pills > li a i, .sidebar-pf .nav-pills > li a span{ + color: #72767b; + display: inline-block; + margin-right: 10px; +} +.sidebar-pf .nav-pills > li > a{ + color: #dbdada; + padding: 0px 20px 0 30px!important; + line-height: 30px; + border-left-width: 12px; + border-left-style: solid; + border-left-color: #292e34; + margin-left: -6px; +} + +.sidebar-pf .nav-pills > li > a:hover{ + background: #393f44; + border-color:#292e34; + border-left-color: #393f44; + color: #fff; +} + +.sidebar-pf .nav-pills > li > a:after{ + display: none!important; +} + + +.sidebar-pf .nav-pills > li.active > a { + color: #fff; + background: #393f44!important; + border-bottom: 1px solid #000!important; + border-top: 1px solid #000!important; + border-left-color: #39a5dc!important; +} + +.sidebar-pf .nav-pills > li.active a i, .sidebar-pf .nav-pills > li.active a span{ + color: #39a5dc; +} + +/*********** Realm selector ***********/ + +.realm-selector{ + color: #fff; + margin: 0 -20px; + position: relative; +} + +.realm-dropmenu{ + display: none; + cursor: pointer; + position: absolute; + top: 60px; + left: 0; + right: 0; + z-index: 999; + background: #fff; +} + +.realm-selector:hover .realm-dropmenu{ + display: block; +} + +.realm-add{ + padding: 10px; +} + +.realm-selector h2{ + font-size: 16px; + line-height: 60px; + padding: 0 20px; + margin: 0; + border-bottom: 1px solid #d5d5d6; +} + +.realm-selector h2 i{ + display: inline-block; + float: right; + line-height: 60px; +} + + +.realm-selector ul{ + padding-left: 0; + margin: 0; + list-style: none; + max-height: 200px; + overflow-y:auto; +} + + +.realm-selector ul li a{ + line-height: 60px; + padding: 0 20px; + border-bottom: 1px solid #d5d5d6; + line-height: 39px; + display: block; + font-size: 14px; +} + + +/*********** Overwrites header defaults ***********/ + +.navbar-pf{ + border-top: none!important; +} + +.navbar-pf .navbar-header { + height: 56px; +} + +.navbar-pf .navbar-brand { + padding: 0; + height: 56px; + line-height: 56px; + background-position: center center; + background-image: url('../img/brand.svg'); + background-size: 172px 10px; + background-repeat: no-repeat; + width: 176px; + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} + +.navbar-pf .navbar-utility > li > a{ + padding: 22px 30px 23px 40px!important; +} +/* @media (min-width: 768px) */ +.navbar-pf .navbar-utility li.dropdown > .dropdown-toggle .pficon-user { + top: 22px; + left:20px; +} + +.clickable { + cursor: pointer; +} + +h1 i { + color: #999999; + font-size: 18px; + margin-left: 10px; +} + +/* Action cell */ +.kc-action-cell { + background-color: #eeeeee; + background-image: linear-gradient(to bottom, #fafafa 0%, #ededed 100%); + background-repeat: repeat-x; + + text-align: center; + vertical-align: middle; + + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + cursor:pointer; +} + +.kc-action-cell:hover { + background-color: #eeeeee; + background-image: none; +} + +.kc-sorter span { + margin-left: 10px; +} + + +/* Time selector */ + +.time-selector input { + display: inline-block; + width: 120px; + padding-right: 0; + margin-right: 0; +} + +.time-selector select { + display: inline-block; + width: 80px; + margin-left: 0; + padding-left: 0; +} + +.ace_editor { + height: 600px; + width: 100%; +} + +.kc-button-input-file input { + float: left; + width: 73%; +} + +.kc-button-input-file label { + float: left; + margin-left: 2%; + width: 25%; +} + +table.kc-authz-table-expanded { + margin-top: 0px !important; +} + +.no-gutter > [class*='col-'] { + padding-right:0!important; + padding-left:0!important; +} diff --git a/themes/src/main/resources-product/theme/rh-sso/admin/resources/img/select-arrow.png b/themes/src/main/resources-product/theme/rh-sso/admin/resources/img/select-arrow.png new file mode 100644 index 0000000000..a865a6fa73 Binary files /dev/null and b/themes/src/main/resources-product/theme/rh-sso/admin/resources/img/select-arrow.png differ diff --git a/themes/src/main/resources-product/theme/rh-sso/admin/theme.properties b/themes/src/main/resources-product/theme/rh-sso/admin/theme.properties new file mode 100755 index 0000000000..009f980712 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/admin/theme.properties @@ -0,0 +1,3 @@ +parent=keycloak +import=common/rh-sso +styles=lib/rcue/css/rcue.min.css lib/rcue/css/rcue-additions.min.css lib/select2-3.4.1/select2.css css/styles.css lib/angular/treeview/css/angular.treeview.css diff --git a/themes/src/main/resources-product/theme/rh-sso/common/resources/img/brand.svg b/themes/src/main/resources-product/theme/rh-sso/common/resources/img/brand.svg new file mode 100644 index 0000000000..a908d8c006 --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/common/resources/img/brand.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/src/main/resources-product/theme/rh-sso/common/resources/img/favicon.ico b/themes/src/main/resources-product/theme/rh-sso/common/resources/img/favicon.ico new file mode 100644 index 0000000000..dad490b8d5 Binary files /dev/null and b/themes/src/main/resources-product/theme/rh-sso/common/resources/img/favicon.ico differ diff --git a/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css b/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css new file mode 100644 index 0000000000..5d505764da --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css @@ -0,0 +1,5699 @@ +/* PatternFly additions to Bootstrap */ +.form-search .combobox-container, +.form-inline .combobox-container { + display: inline-block; + margin-bottom: 0; + vertical-align: top; +} +.form-search .combobox-container .input-group-addon, +.form-inline .combobox-container .input-group-addon { + width: auto; +} +.combobox-selected .caret { + display: none; +} +/* :not doesn't work in IE8 */ +.combobox-container:not(.combobox-selected) .glyphicon-remove { + display: none; +} +.typeahead-long { + max-height: 300px; + overflow-y: auto; +} +.control-group.error .combobox-container .add-on { + color: #B94A48; + border-color: #B94A48; +} +.control-group.error .combobox-container .caret { + border-top-color: #B94A48; +} +.control-group.warning .combobox-container .add-on { + color: #C09853; + border-color: #C09853; +} +.control-group.warning .combobox-container .caret { + border-top-color: #C09853; +} +.control-group.success .combobox-container .add-on { + color: #468847; + border-color: #468847; +} +.control-group.success .combobox-container .caret { + border-top-color: #468847; +} +.datepicker { + padding: 4px; + border-radius: 4px; + direction: ltr; +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-top: 0; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-top: 0; + position: absolute; +} +.datepicker-dropdown.datepicker-orient-left:before { + left: 6px; +} +.datepicker-dropdown.datepicker-orient-left:after { + left: 7px; +} +.datepicker-dropdown.datepicker-orient-right:before { + right: 6px; +} +.datepicker-dropdown.datepicker-orient-right:after { + right: 7px; +} +.datepicker-dropdown.datepicker-orient-top:before { + top: -7px; +} +.datepicker-dropdown.datepicker-orient-top:after { + top: -6px; +} +.datepicker-dropdown.datepicker-orient-bottom:before { + bottom: -7px; + border-bottom: 0; + border-top: 7px solid #999; +} +.datepicker-dropdown.datepicker-orient-bottom:after { + bottom: -6px; + border-bottom: 0; + border-top: 6px solid #fff; +} +.datepicker > div { + display: none; +} +.datepicker.days .datepicker-days, +.datepicker.months .datepicker-months, +.datepicker.years .datepicker-years { + display: block; +} +.datepicker table { + margin: 0; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.datepicker table tr td, +.datepicker table tr th { + text-align: center; + width: 30px; + height: 30px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover, +.datepicker table tr td.day.focused { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + color: #000; + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today:focus, +.datepicker table tr td.today:hover:focus, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today.focus, +.datepicker table tr td.today:hover.focus, +.datepicker table tr td.today.disabled.focus, +.datepicker table tr td.today.disabled:hover.focus { + color: #000; + background-color: #ffc966; + border-color: #b37400; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover { + color: #000; + background-color: #ffc966; + border-color: #f59e00; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.today, +.open > .dropdown-toggle.datepicker table tr td.today:hover, +.open > .dropdown-toggle.datepicker table tr td.today.disabled, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover { + color: #000; + background-color: #ffc966; + border-color: #f59e00; +} +.datepicker table tr td.today:active:hover, +.datepicker table tr td.today:hover:active:hover, +.datepicker table tr td.today.disabled:active:hover, +.datepicker table tr td.today.disabled:hover:active:hover, +.datepicker table tr td.today.active:hover, +.datepicker table tr td.today:hover.active:hover, +.datepicker table tr td.today.disabled.active:hover, +.datepicker table tr td.today.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td.today:hover, +.open > .dropdown-toggle.datepicker table tr td.today:hover:hover, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:active:focus, +.datepicker table tr td.today:hover:active:focus, +.datepicker table tr td.today.disabled:active:focus, +.datepicker table tr td.today.disabled:hover:active:focus, +.datepicker table tr td.today.active:focus, +.datepicker table tr td.today:hover.active:focus, +.datepicker table tr td.today.disabled.active:focus, +.datepicker table tr td.today.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td.today:focus, +.open > .dropdown-toggle.datepicker table tr td.today:hover:focus, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today:active.focus, +.datepicker table tr td.today:hover:active.focus, +.datepicker table tr td.today.disabled:active.focus, +.datepicker table tr td.today.disabled:hover:active.focus, +.datepicker table tr td.today.active.focus, +.datepicker table tr td.today:hover.active.focus, +.datepicker table tr td.today.disabled.active.focus, +.datepicker table tr td.today.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td.today.focus, +.open > .dropdown-toggle.datepicker table tr td.today:hover.focus, +.open > .dropdown-toggle.datepicker table tr td.today.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover.focus { + color: #000; + background-color: #ffbc42; + border-color: #b37400; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.today, +.open > .dropdown-toggle.datepicker table tr td.today:hover, +.open > .dropdown-toggle.datepicker table tr td.today.disabled, +.open > .dropdown-toggle.datepicker table tr td.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today:hover.disabled:hover, +.datepicker table tr td.today.disabled.disabled:hover, +.datepicker table tr td.today.disabled:hover.disabled:hover, +.datepicker table tr td.today[disabled]:hover, +.datepicker table tr td.today:hover[disabled]:hover, +.datepicker table tr td.today.disabled[disabled]:hover, +.datepicker table tr td.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.today:hover, +fieldset[disabled] .datepicker table tr td.today:hover:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today:hover.disabled:focus, +.datepicker table tr td.today.disabled.disabled:focus, +.datepicker table tr td.today.disabled:hover.disabled:focus, +.datepicker table tr td.today[disabled]:focus, +.datepicker table tr td.today:hover[disabled]:focus, +.datepicker table tr td.today.disabled[disabled]:focus, +.datepicker table tr td.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.today:focus, +fieldset[disabled] .datepicker table tr td.today:hover:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today.disabled.focus, +.datepicker table tr td.today:hover.disabled.focus, +.datepicker table tr td.today.disabled.disabled.focus, +.datepicker table tr td.today.disabled:hover.disabled.focus, +.datepicker table tr td.today[disabled].focus, +.datepicker table tr td.today:hover[disabled].focus, +.datepicker table tr td.today.disabled[disabled].focus, +.datepicker table tr td.today.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td.today.focus, +fieldset[disabled] .datepicker table tr td.today:hover.focus, +fieldset[disabled] .datepicker table tr td.today.disabled.focus, +fieldset[disabled] .datepicker table tr td.today.disabled:hover.focus { + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today .badge, +.datepicker table tr td.today:hover .badge, +.datepicker table tr td.today.disabled .badge, +.datepicker table tr td.today.disabled:hover .badge { + color: #ffdb99; + background-color: #000; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + color: #000; + background-color: #f7ca77; + border-color: #f1a417; + border-radius: 0; +} +.datepicker table tr td.range.today:focus, +.datepicker table tr td.range.today:hover:focus, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today.focus, +.datepicker table tr td.range.today:hover.focus, +.datepicker table tr td.range.today.disabled.focus, +.datepicker table tr td.range.today.disabled:hover.focus { + color: #000; + background-color: #f4b747; + border-color: #815608; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover { + color: #000; + background-color: #f4b747; + border-color: #bf800c; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.range.today, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + color: #000; + background-color: #f4b747; + border-color: #bf800c; +} +.datepicker table tr td.range.today:active:hover, +.datepicker table tr td.range.today:hover:active:hover, +.datepicker table tr td.range.today.disabled:active:hover, +.datepicker table tr td.range.today.disabled:hover:active:hover, +.datepicker table tr td.range.today.active:hover, +.datepicker table tr td.range.today:hover.active:hover, +.datepicker table tr td.range.today.disabled.active:hover, +.datepicker table tr td.range.today.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:active:focus, +.datepicker table tr td.range.today:hover:active:focus, +.datepicker table tr td.range.today.disabled:active:focus, +.datepicker table tr td.range.today.disabled:hover:active:focus, +.datepicker table tr td.range.today.active:focus, +.datepicker table tr td.range.today:hover.active:focus, +.datepicker table tr td.range.today.disabled.active:focus, +.datepicker table tr td.range.today.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td.range.today:focus, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover:focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today:active.focus, +.datepicker table tr td.range.today:hover:active.focus, +.datepicker table tr td.range.today.disabled:active.focus, +.datepicker table tr td.range.today.disabled:hover:active.focus, +.datepicker table tr td.range.today.active.focus, +.datepicker table tr td.range.today:hover.active.focus, +.datepicker table tr td.range.today.disabled.active.focus, +.datepicker table tr td.range.today.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.focus, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover.focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover.focus { + color: #000; + background-color: #f2aa25; + border-color: #815608; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.range.today, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open > .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today:hover.disabled:hover, +.datepicker table tr td.range.today.disabled.disabled:hover, +.datepicker table tr td.range.today.disabled:hover.disabled:hover, +.datepicker table tr td.range.today[disabled]:hover, +.datepicker table tr td.range.today:hover[disabled]:hover, +.datepicker table tr td.range.today.disabled[disabled]:hover, +.datepicker table tr td.range.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today:hover.disabled:focus, +.datepicker table tr td.range.today.disabled.disabled:focus, +.datepicker table tr td.range.today.disabled:hover.disabled:focus, +.datepicker table tr td.range.today[disabled]:focus, +.datepicker table tr td.range.today:hover[disabled]:focus, +.datepicker table tr td.range.today.disabled[disabled]:focus, +.datepicker table tr td.range.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.range.today:focus, +fieldset[disabled] .datepicker table tr td.range.today:hover:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today.disabled.focus, +.datepicker table tr td.range.today:hover.disabled.focus, +.datepicker table tr td.range.today.disabled.disabled.focus, +.datepicker table tr td.range.today.disabled:hover.disabled.focus, +.datepicker table tr td.range.today[disabled].focus, +.datepicker table tr td.range.today:hover[disabled].focus, +.datepicker table tr td.range.today.disabled[disabled].focus, +.datepicker table tr td.range.today.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td.range.today.focus, +fieldset[disabled] .datepicker table tr td.range.today:hover.focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled.focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.focus { + background-color: #f7ca77; + border-color: #f1a417; +} +.datepicker table tr td.range.today .badge, +.datepicker table tr td.range.today:hover .badge, +.datepicker table tr td.range.today.disabled .badge, +.datepicker table tr td.range.today.disabled:hover .badge { + color: #f7ca77; + background-color: #000; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + color: #fff; + background-color: #999999; + border-color: #555555; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:focus, +.datepicker table tr td.selected:hover:focus, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected.focus, +.datepicker table tr td.selected:hover.focus, +.datepicker table tr td.selected.disabled.focus, +.datepicker table tr td.selected.disabled:hover.focus { + color: #fff; + background-color: #808080; + border-color: #161616; +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover { + color: #fff; + background-color: #808080; + border-color: #373737; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.selected, +.open > .dropdown-toggle.datepicker table tr td.selected:hover, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + color: #fff; + background-color: #808080; + border-color: #373737; +} +.datepicker table tr td.selected:active:hover, +.datepicker table tr td.selected:hover:active:hover, +.datepicker table tr td.selected.disabled:active:hover, +.datepicker table tr td.selected.disabled:hover:active:hover, +.datepicker table tr td.selected.active:hover, +.datepicker table tr td.selected:hover.active:hover, +.datepicker table tr td.selected.disabled.active:hover, +.datepicker table tr td.selected.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td.selected:hover, +.open > .dropdown-toggle.datepicker table tr td.selected:hover:hover, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:active:focus, +.datepicker table tr td.selected:hover:active:focus, +.datepicker table tr td.selected.disabled:active:focus, +.datepicker table tr td.selected.disabled:hover:active:focus, +.datepicker table tr td.selected.active:focus, +.datepicker table tr td.selected:hover.active:focus, +.datepicker table tr td.selected.disabled.active:focus, +.datepicker table tr td.selected.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td.selected:focus, +.open > .dropdown-toggle.datepicker table tr td.selected:hover:focus, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected:active.focus, +.datepicker table tr td.selected:hover:active.focus, +.datepicker table tr td.selected.disabled:active.focus, +.datepicker table tr td.selected.disabled:hover:active.focus, +.datepicker table tr td.selected.active.focus, +.datepicker table tr td.selected:hover.active.focus, +.datepicker table tr td.selected.disabled.active.focus, +.datepicker table tr td.selected.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td.selected.focus, +.open > .dropdown-toggle.datepicker table tr td.selected:hover.focus, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover.focus { + color: #fff; + background-color: #6e6e6e; + border-color: #161616; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.selected, +.open > .dropdown-toggle.datepicker table tr td.selected:hover, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled, +.open > .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + background-image: none; +} +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected:hover.disabled:hover, +.datepicker table tr td.selected.disabled.disabled:hover, +.datepicker table tr td.selected.disabled:hover.disabled:hover, +.datepicker table tr td.selected[disabled]:hover, +.datepicker table tr td.selected:hover[disabled]:hover, +.datepicker table tr td.selected.disabled[disabled]:hover, +.datepicker table tr td.selected.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.selected:hover, +fieldset[disabled] .datepicker table tr td.selected:hover:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected:hover.disabled:focus, +.datepicker table tr td.selected.disabled.disabled:focus, +.datepicker table tr td.selected.disabled:hover.disabled:focus, +.datepicker table tr td.selected[disabled]:focus, +.datepicker table tr td.selected:hover[disabled]:focus, +.datepicker table tr td.selected.disabled[disabled]:focus, +.datepicker table tr td.selected.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.selected:focus, +fieldset[disabled] .datepicker table tr td.selected:hover:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected.disabled.focus, +.datepicker table tr td.selected:hover.disabled.focus, +.datepicker table tr td.selected.disabled.disabled.focus, +.datepicker table tr td.selected.disabled:hover.disabled.focus, +.datepicker table tr td.selected[disabled].focus, +.datepicker table tr td.selected:hover[disabled].focus, +.datepicker table tr td.selected.disabled[disabled].focus, +.datepicker table tr td.selected.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td.selected.focus, +fieldset[disabled] .datepicker table tr td.selected:hover.focus, +fieldset[disabled] .datepicker table tr td.selected.disabled.focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover.focus { + background-color: #999999; + border-color: #555555; +} +.datepicker table tr td.selected .badge, +.datepicker table tr td.selected:hover .badge, +.datepicker table tr td.selected.disabled .badge, +.datepicker table tr td.selected.disabled:hover .badge { + color: #999999; + background-color: #fff; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + color: #fff; + background-color: #0085cf; + border-color: #006e9c; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:focus, +.datepicker table tr td.active:hover:focus, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active.focus, +.datepicker table tr td.active:hover.focus, +.datepicker table tr td.active.disabled.focus, +.datepicker table tr td.active.disabled:hover.focus { + color: #fff; + background-color: #00649c; + border-color: #00141d; +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover { + color: #fff; + background-color: #00649c; + border-color: #00435f; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.active, +.open > .dropdown-toggle.datepicker table tr td.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active.disabled, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover { + color: #fff; + background-color: #00649c; + border-color: #00435f; +} +.datepicker table tr td.active:active:hover, +.datepicker table tr td.active:hover:active:hover, +.datepicker table tr td.active.disabled:active:hover, +.datepicker table tr td.active.disabled:hover:active:hover, +.datepicker table tr td.active.active:hover, +.datepicker table tr td.active:hover.active:hover, +.datepicker table tr td.active.disabled.active:hover, +.datepicker table tr td.active.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active:hover:hover, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:active:focus, +.datepicker table tr td.active:hover:active:focus, +.datepicker table tr td.active.disabled:active:focus, +.datepicker table tr td.active.disabled:hover:active:focus, +.datepicker table tr td.active.active:focus, +.datepicker table tr td.active:hover.active:focus, +.datepicker table tr td.active.disabled.active:focus, +.datepicker table tr td.active.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td.active:focus, +.open > .dropdown-toggle.datepicker table tr td.active:hover:focus, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active:active.focus, +.datepicker table tr td.active:hover:active.focus, +.datepicker table tr td.active.disabled:active.focus, +.datepicker table tr td.active.disabled:hover:active.focus, +.datepicker table tr td.active.active.focus, +.datepicker table tr td.active:hover.active.focus, +.datepicker table tr td.active.disabled.active.focus, +.datepicker table tr td.active.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td.active.focus, +.open > .dropdown-toggle.datepicker table tr td.active:hover.focus, +.open > .dropdown-toggle.datepicker table tr td.active.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover.focus { + color: #fff; + background-color: #004d78; + border-color: #00141d; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td.active, +.open > .dropdown-toggle.datepicker table tr td.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active.disabled, +.open > .dropdown-toggle.datepicker table tr td.active.disabled:hover { + background-image: none; +} +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active:hover.disabled:hover, +.datepicker table tr td.active.disabled.disabled:hover, +.datepicker table tr td.active.disabled:hover.disabled:hover, +.datepicker table tr td.active[disabled]:hover, +.datepicker table tr td.active:hover[disabled]:hover, +.datepicker table tr td.active.disabled[disabled]:hover, +.datepicker table tr td.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.active:hover, +fieldset[disabled] .datepicker table tr td.active:hover:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active:hover.disabled:focus, +.datepicker table tr td.active.disabled.disabled:focus, +.datepicker table tr td.active.disabled:hover.disabled:focus, +.datepicker table tr td.active[disabled]:focus, +.datepicker table tr td.active:hover[disabled]:focus, +.datepicker table tr td.active.disabled[disabled]:focus, +.datepicker table tr td.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.active:focus, +fieldset[disabled] .datepicker table tr td.active:hover:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active.disabled.focus, +.datepicker table tr td.active:hover.disabled.focus, +.datepicker table tr td.active.disabled.disabled.focus, +.datepicker table tr td.active.disabled:hover.disabled.focus, +.datepicker table tr td.active[disabled].focus, +.datepicker table tr td.active:hover[disabled].focus, +.datepicker table tr td.active.disabled[disabled].focus, +.datepicker table tr td.active.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td.active.focus, +fieldset[disabled] .datepicker table tr td.active:hover.focus, +fieldset[disabled] .datepicker table tr td.active.disabled.focus, +fieldset[disabled] .datepicker table tr td.active.disabled:hover.focus { + background-color: #0085cf; + border-color: #006e9c; +} +.datepicker table tr td.active .badge, +.datepicker table tr td.active:hover .badge, +.datepicker table tr td.active.disabled .badge, +.datepicker table tr td.active.disabled:hover .badge { + color: #0085cf; + background-color: #fff; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + color: #fff; + background-color: #0085cf; + border-color: #006e9c; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:focus, +.datepicker table tr td span.active:hover:focus, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active.focus, +.datepicker table tr td span.active:hover.focus, +.datepicker table tr td span.active.disabled.focus, +.datepicker table tr td span.active.disabled:hover.focus { + color: #fff; + background-color: #00649c; + border-color: #00141d; +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover { + color: #fff; + background-color: #00649c; + border-color: #00435f; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td span.active, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + color: #fff; + background-color: #00649c; + border-color: #00435f; +} +.datepicker table tr td span.active:active:hover, +.datepicker table tr td span.active:hover:active:hover, +.datepicker table tr td span.active.disabled:active:hover, +.datepicker table tr td span.active.disabled:hover:active:hover, +.datepicker table tr td span.active.active:hover, +.datepicker table tr td span.active:hover.active:hover, +.datepicker table tr td span.active.disabled.active:hover, +.datepicker table tr td span.active.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active:hover:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active:focus, +.datepicker table tr td span.active:hover:active:focus, +.datepicker table tr td span.active.disabled:active:focus, +.datepicker table tr td span.active.disabled:hover:active:focus, +.datepicker table tr td span.active.active:focus, +.datepicker table tr td span.active:hover.active:focus, +.datepicker table tr td span.active.disabled.active:focus, +.datepicker table tr td span.active.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td span.active:focus, +.open > .dropdown-toggle.datepicker table tr td span.active:hover:focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active:active.focus, +.datepicker table tr td span.active:hover:active.focus, +.datepicker table tr td span.active.disabled:active.focus, +.datepicker table tr td span.active.disabled:hover:active.focus, +.datepicker table tr td span.active.active.focus, +.datepicker table tr td span.active:hover.active.focus, +.datepicker table tr td span.active.disabled.active.focus, +.datepicker table tr td span.active.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.focus, +.open > .dropdown-toggle.datepicker table tr td span.active:hover.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover.focus { + color: #fff; + background-color: #004d78; + border-color: #00141d; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td span.active, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + background-image: none; +} +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active:hover.disabled:hover, +.datepicker table tr td span.active.disabled.disabled:hover, +.datepicker table tr td span.active.disabled:hover.disabled:hover, +.datepicker table tr td span.active[disabled]:hover, +.datepicker table tr td span.active:hover[disabled]:hover, +.datepicker table tr td span.active.disabled[disabled]:hover, +.datepicker table tr td span.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td span.active:hover, +fieldset[disabled] .datepicker table tr td span.active:hover:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active:hover.disabled:focus, +.datepicker table tr td span.active.disabled.disabled:focus, +.datepicker table tr td span.active.disabled:hover.disabled:focus, +.datepicker table tr td span.active[disabled]:focus, +.datepicker table tr td span.active:hover[disabled]:focus, +.datepicker table tr td span.active.disabled[disabled]:focus, +.datepicker table tr td span.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td span.active:focus, +fieldset[disabled] .datepicker table tr td span.active:hover:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active.disabled.focus, +.datepicker table tr td span.active:hover.disabled.focus, +.datepicker table tr td span.active.disabled.disabled.focus, +.datepicker table tr td span.active.disabled:hover.disabled.focus, +.datepicker table tr td span.active[disabled].focus, +.datepicker table tr td span.active:hover[disabled].focus, +.datepicker table tr td span.active.disabled[disabled].focus, +.datepicker table tr td span.active.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td span.active.focus, +fieldset[disabled] .datepicker table tr td span.active:hover.focus, +fieldset[disabled] .datepicker table tr td span.active.disabled.focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus { + background-color: #0085cf; + border-color: #006e9c; +} +.datepicker table tr td span.active .badge, +.datepicker table tr td span.active:hover .badge, +.datepicker table tr td span.active.disabled .badge, +.datepicker table tr td span.active.disabled:hover .badge { + color: #0085cf; + background-color: #fff; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker .datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child .cw { + cursor: default; + background-color: transparent; +} +.input-group.date .input-group-addon { + cursor: pointer; +} +.input-daterange { + width: 100%; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + border-radius: 0 3px 3px 0; +} +.input-daterange .input-group-addon { + width: auto; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 1.66666667; + text-align: center; + text-shadow: 0 1px 0 #fff; + vertical-align: middle; + background-color: #eeeeee; + border: solid #BABABA; + border-width: 1px 0; + margin-left: -5px; + margin-right: -5px; +} +.bootstrap-select { + width: 220px \0; + /*IE9 and below*/ +} +.bootstrap-select > .dropdown-toggle { + width: 100%; + padding-right: 25px; +} +.has-error .bootstrap-select .dropdown-toggle, +.error .bootstrap-select .dropdown-toggle { + border-color: #b94a48; +} +.bootstrap-select.fit-width { + width: auto !important; +} +.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 220px; +} +.bootstrap-select .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; +} +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; +} +.bootstrap-select.form-control:not([class*="col-"]) { + width: 100%; +} +.bootstrap-select.form-control.input-group-btn { + z-index: auto; +} +.bootstrap-select.btn-group:not(.input-group-btn), +.bootstrap-select.btn-group[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; +} +.bootstrap-select.btn-group.dropdown-menu-right, +.bootstrap-select.btn-group[class*="col-"].dropdown-menu-right, +.row .bootstrap-select.btn-group[class*="col-"].dropdown-menu-right { + float: right; +} +.form-inline .bootstrap-select.btn-group, +.form-horizontal .bootstrap-select.btn-group, +.form-group .bootstrap-select.btn-group { + margin-bottom: 0; +} +.form-group-lg .bootstrap-select.btn-group.form-control, +.form-group-sm .bootstrap-select.btn-group.form-control { + padding: 0; +} +.form-inline .bootstrap-select.btn-group .form-control { + width: 100%; +} +.bootstrap-select.btn-group.disabled, +.bootstrap-select.btn-group > .disabled { + cursor: not-allowed; +} +.bootstrap-select.btn-group.disabled:focus, +.bootstrap-select.btn-group > .disabled:focus { + outline: none !important; +} +.bootstrap-select.btn-group .dropdown-toggle .filter-option { + display: inline-block; + overflow: hidden; + width: 100%; + text-align: left; +} +.bootstrap-select.btn-group .dropdown-toggle .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; +} +.bootstrap-select.btn-group[class*="col-"] .dropdown-toggle { + width: 100%; +} +.bootstrap-select.btn-group .dropdown-menu { + min-width: 100%; + z-index: 1035; + box-sizing: border-box; +} +.bootstrap-select.btn-group .dropdown-menu.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + box-shadow: none; +} +.bootstrap-select.btn-group .dropdown-menu li { + position: relative; +} +.bootstrap-select.btn-group .dropdown-menu li.active small { + color: #fff; +} +.bootstrap-select.btn-group .dropdown-menu li.disabled a { + cursor: not-allowed; +} +.bootstrap-select.btn-group .dropdown-menu li a { + cursor: pointer; +} +.bootstrap-select.btn-group .dropdown-menu li a.opt { + position: relative; + padding-left: 2.25em; +} +.bootstrap-select.btn-group .dropdown-menu li a span.check-mark { + display: none; +} +.bootstrap-select.btn-group .dropdown-menu li a span.text { + display: inline-block; +} +.bootstrap-select.btn-group .dropdown-menu li small { + padding-left: 0.5em; +} +.bootstrap-select.btn-group .dropdown-menu .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: #f5f5f5; + border: 1px solid #e3e3e3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + pointer-events: none; + opacity: 0.9; + box-sizing: border-box; +} +.bootstrap-select.btn-group .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; +} +.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option { + position: static; +} +.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret { + position: static; + top: auto; + margin-top: -1px; +} +.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + margin-top: 5px; +} +.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text { + margin-right: 34px; +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle { + z-index: 1036; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(204, 204, 204, 0.2); + position: absolute; + bottom: -4px; + left: 9px; + display: none; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before { + bottom: auto; + top: -3px; + border-top: 7px solid rgba(204, 204, 204, 0.2); + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after { + bottom: auto; + top: -3px; + border-top: 6px solid white; + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before { + right: 12px; + left: auto; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after { + right: 13px; + left: auto; +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before, +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after { + display: block; +} +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} +.bs-actionsbox { + float: left; + width: 100%; + box-sizing: border-box; +} +.bs-actionsbox .btn-group button { + width: 50%; +} +.bs-donebutton { + float: left; + width: 100%; + box-sizing: border-box; +} +.bs-donebutton .btn-group button { + width: 100%; +} +.bs-searchbox + .bs-actionsbox { + padding: 0 8px 4px; +} +.bs-searchbox .form-control { + margin-bottom: 0; + width: 100%; +} +select.bs-select-hidden, +select.selectpicker { + display: none !important; +} +select.mobile-device { + position: absolute !important; + top: 0; + left: 0; + display: block !important; + width: 100%; + height: 100% !important; + opacity: 0; +} +.bootstrap-switch { + display: inline-block; + direction: ltr; + cursor: pointer; + border-radius: 1px; + border: 1px solid; + border-color: #b7b7b7; + position: relative; + text-align: left; + overflow: hidden; + line-height: 8px; + z-index: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.bootstrap-switch .bootstrap-switch-container { + display: inline-block; + top: 0; + border-radius: 1px; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off, +.bootstrap-switch .bootstrap-switch-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + display: inline-block !important; + height: 100%; + padding: 2px 6px; + font-size: 12px; + line-height: 20px; +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off { + text-align: center; + z-index: 1; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary { + color: #fff; + background: #0085cf; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info { + color: #fff; + background: #006e9c; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success { + color: #fff; + background: #3f9c35; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning { + background: #ec7a08; + color: #fff; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger { + color: #fff; + background: #a30000; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default { + color: #000; + background: #eeeeee; +} +.bootstrap-switch .bootstrap-switch-label { + text-align: center; + margin-top: -1px; + margin-bottom: -1px; + z-index: 100; + color: #4d5258; + background: #eeeeee; +} +.bootstrap-switch .bootstrap-switch-handle-on { + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +.bootstrap-switch .bootstrap-switch-handle-off { + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.bootstrap-switch input[type='radio'], +.bootstrap-switch input[type='checkbox'] { + position: absolute !important; + top: 0; + left: 0; + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; +} +.bootstrap-switch input[type='radio'].form-control, +.bootstrap-switch input[type='checkbox'].form-control { + height: auto; +} +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label { + padding: 1px 5px; + font-size: 11px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label { + padding: 2px 6px; + font-size: 11px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label { + padding: 2px 10px; + font-size: 14px; + line-height: 1.3333333; +} +.bootstrap-switch.bootstrap-switch-disabled, +.bootstrap-switch.bootstrap-switch-readonly, +.bootstrap-switch.bootstrap-switch-indeterminate { + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container { + -webkit-transition: margin-left 0.5s; + -o-transition: margin-left 0.5s; + transition: margin-left 0.5s; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +.bootstrap-switch.bootstrap-switch-focused { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label { + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; +} +.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label { + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; +} +/* + * Bootstrap TouchSpin - v3.0.1 + * A mobile and touch friendly input spinner component for Bootstrap 3. + * http://www.virtuosoft.eu/code/bootstrap-touchspin/ + * + * Made by István Ujj-Mészáros + * Under Apache License v2.0 License + */ +.bootstrap-touchspin .input-group-btn-vertical { + position: relative; + white-space: nowrap; + width: 1%; + vertical-align: middle; + display: table-cell; +} +.bootstrap-touchspin .input-group-btn-vertical > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + padding: 8px 10px; + margin-left: -1px; + position: relative; +} +.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up { + border-radius: 0; + border-top-right-radius: 4px; +} +.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down { + margin-top: -2px; + border-radius: 0; + border-bottom-right-radius: 4px; +} +.bootstrap-touchspin .input-group-btn-vertical i { + position: absolute; + top: 3px; + left: 5px; + font-size: 9px; + font-weight: normal; +} +/*-- Chart --*/ +.c3 svg { + font: 10px sans-serif; +} +.c3 path, +.c3 line { + fill: none; + stroke: #000; +} +.c3 text { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +.c3-legend-item-tile, +.c3-xgrid-focus, +.c3-ygrid, +.c3-event-rect, +.c3-bars path { + shape-rendering: crispEdges; +} +.c3-chart-arc path { + stroke: #fff; +} +.c3-chart-arc text { + fill: #fff; + font-size: 13px; +} +/*-- Axis --*/ +/*-- Grid --*/ +.c3-grid line { + stroke: #aaa; +} +.c3-grid text { + fill: #aaa; +} +.c3-xgrid, +.c3-ygrid { + stroke-dasharray: 3 3; +} +/*-- Text on Chart --*/ +.c3-text.c3-empty { + fill: #808080; + font-size: 2em; +} +/*-- Line --*/ +.c3-line { + stroke-width: 1px; +} +/*-- Point --*/ +.c3-circle._expanded_ { + stroke-width: 1px; + stroke: white; +} +.c3-selected-circle { + fill: white; + stroke-width: 2px; +} +/*-- Bar --*/ +.c3-bar { + stroke-width: 0; +} +.c3-bar._expanded_ { + fill-opacity: 0.75; +} +/*-- Focus --*/ +.c3-target.c3-focused { + opacity: 1; +} +.c3-target.c3-focused path.c3-line, +.c3-target.c3-focused path.c3-step { + stroke-width: 2px; +} +.c3-target.c3-defocused { + opacity: 0.3 !important; +} +/*-- Region --*/ +.c3-region { + fill: steelblue; + fill-opacity: 0.1; +} +/*-- Brush --*/ +.c3-brush .extent { + fill-opacity: 0.1; +} +/*-- Select - Drag --*/ +/*-- Legend --*/ +.c3-legend-item { + font-size: 12px; +} +.c3-legend-item-hidden { + opacity: 0.15; +} +.c3-legend-background { + opacity: 0.75; + fill: white; + stroke: lightgray; + stroke-width: 1; +} +/*-- Tooltip --*/ +.c3-tooltip-container { + z-index: 10; +} +.c3-tooltip { + border-collapse: collapse; + border-spacing: 0; + background-color: #fff; + empty-cells: show; + -webkit-box-shadow: 7px 7px 12px -9px #777777; + -moz-box-shadow: 7px 7px 12px -9px #777777; + box-shadow: 7px 7px 12px -9px #777777; + opacity: 0.9; +} +.c3-tooltip tr { + border: 1px solid #CCC; +} +.c3-tooltip th { + background-color: #aaa; + font-size: 14px; + padding: 2px 5px; + text-align: left; + color: #FFF; +} +.c3-tooltip td { + font-size: 13px; + padding: 3px 6px; + background-color: #fff; + border-left: 1px dotted #999; +} +.c3-tooltip td > span { + display: inline-block; + width: 10px; + height: 10px; + margin-right: 6px; +} +.c3-tooltip td.value { + text-align: right; +} +/*-- Area --*/ +.c3-area { + stroke-width: 0; + opacity: 0.2; +} +/*-- Arc --*/ +.c3-chart-arcs-title { + dominant-baseline: middle; + font-size: 1.3em; +} +.c3-chart-arcs .c3-chart-arcs-background { + fill: #e0e0e0; + stroke: none; +} +.c3-chart-arcs .c3-chart-arcs-gauge-unit { + fill: #000; + font-size: 16px; +} +.c3-chart-arcs .c3-chart-arcs-gauge-max { + fill: #777; +} +.c3-chart-arcs .c3-chart-arcs-gauge-min { + fill: #777; +} +.c3-chart-arc .c3-gauge-value { + fill: #000; + /* font-size: 28px !important;*/ +} +/*! + * Datetimepicker for Bootstrap 3 + * version : 4.17.37 + * https://github.com/Eonasdan/bootstrap-datetimepicker/ + */ +.bootstrap-datetimepicker-widget { + list-style: none; +} +.bootstrap-datetimepicker-widget.dropdown-menu { + margin: 2px 0; + padding: 4px; + width: 19em; +} +@media (min-width: 768px) { + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } +} +@media (min-width: 992px) { + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } +} +@media (min-width: 1200px) { + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } +} +.bootstrap-datetimepicker-widget.dropdown-menu:before, +.bootstrap-datetimepicker-widget.dropdown-menu:after { + content: ''; + display: inline-block; + position: absolute; +} +.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before { + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + top: -7px; + left: 7px; +} +.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after { + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + top: -6px; + left: 8px; +} +.bootstrap-datetimepicker-widget.dropdown-menu.top:before { + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + bottom: -7px; + left: 6px; +} +.bootstrap-datetimepicker-widget.dropdown-menu.top:after { + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid white; + bottom: -6px; + left: 7px; +} +.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before { + left: auto; + right: 6px; +} +.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after { + left: auto; + right: 7px; +} +.bootstrap-datetimepicker-widget .list-unstyled { + margin: 0; +} +.bootstrap-datetimepicker-widget a[data-action] { + padding: 6px 0; +} +.bootstrap-datetimepicker-widget a[data-action]:active { + box-shadow: none; +} +.bootstrap-datetimepicker-widget .timepicker-hour, +.bootstrap-datetimepicker-widget .timepicker-minute, +.bootstrap-datetimepicker-widget .timepicker-second { + width: 54px; + font-weight: bold; + font-size: 1em; + margin: 0; +} +.bootstrap-datetimepicker-widget button[data-action] { + padding: 6px; +} +.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Increment Hours"; +} +.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Increment Minutes"; +} +.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Decrement Hours"; +} +.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Decrement Minutes"; +} +.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Show Hours"; +} +.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Show Minutes"; +} +.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Toggle AM/PM"; +} +.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Clear the picker"; +} +.bootstrap-datetimepicker-widget .btn[data-action="today"]::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Set the date to today"; +} +.bootstrap-datetimepicker-widget .picker-switch { + text-align: center; +} +.bootstrap-datetimepicker-widget .picker-switch::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Toggle Date and Time Screens"; +} +.bootstrap-datetimepicker-widget .picker-switch td { + padding: 0; + margin: 0; + height: auto; + width: auto; + line-height: inherit; +} +.bootstrap-datetimepicker-widget .picker-switch td span { + line-height: 2.5; + height: 2.5em; + width: 100%; +} +.bootstrap-datetimepicker-widget table { + width: 100%; + margin: 0; +} +.bootstrap-datetimepicker-widget table td, +.bootstrap-datetimepicker-widget table th { + text-align: center; + border-radius: 1px; +} +.bootstrap-datetimepicker-widget table th { + height: 20px; + line-height: 20px; + width: 20px; +} +.bootstrap-datetimepicker-widget table th.picker-switch { + width: 145px; +} +.bootstrap-datetimepicker-widget table th.disabled, +.bootstrap-datetimepicker-widget table th.disabled:hover { + background: none; + color: #999999; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget table th.prev::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Previous Month"; +} +.bootstrap-datetimepicker-widget table th.next::after { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Next Month"; +} +.bootstrap-datetimepicker-widget table thead tr:first-child th { + cursor: pointer; +} +.bootstrap-datetimepicker-widget table thead tr:first-child th:hover { + background: transparent; +} +.bootstrap-datetimepicker-widget table td { + height: 54px; + line-height: 54px; + width: 54px; +} +.bootstrap-datetimepicker-widget table td.cw { + font-size: .8em; + height: 20px; + line-height: 20px; + color: #999999; +} +.bootstrap-datetimepicker-widget table td.day { + height: 20px; + line-height: 20px; + width: 20px; +} +.bootstrap-datetimepicker-widget table td.day:hover, +.bootstrap-datetimepicker-widget table td.hour:hover, +.bootstrap-datetimepicker-widget table td.minute:hover, +.bootstrap-datetimepicker-widget table td.second:hover { + background: transparent; + cursor: pointer; +} +.bootstrap-datetimepicker-widget table td.old, +.bootstrap-datetimepicker-widget table td.new { + color: #999999; +} +.bootstrap-datetimepicker-widget table td.today { + position: relative; +} +.bootstrap-datetimepicker-widget table td.today:before { + content: ''; + display: inline-block; + border: solid transparent; + border-width: 0 0 7px 7px; + border-bottom-color: #0085cf; + border-top-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: 4px; + right: 4px; +} +.bootstrap-datetimepicker-widget table td.active, +.bootstrap-datetimepicker-widget table td.active:hover { + background-color: #0085cf; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.bootstrap-datetimepicker-widget table td.active.today:before { + border-bottom-color: #fff; +} +.bootstrap-datetimepicker-widget table td.disabled, +.bootstrap-datetimepicker-widget table td.disabled:hover { + background: none; + color: #999999; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget table td span { + display: inline-block; + width: 54px; + height: 54px; + line-height: 54px; + margin: 2px 1.5px; + cursor: pointer; + border-radius: 1px; +} +.bootstrap-datetimepicker-widget table td span:hover { + background: transparent; +} +.bootstrap-datetimepicker-widget table td span.active { + background-color: #0085cf; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.bootstrap-datetimepicker-widget table td span.old { + color: #999999; +} +.bootstrap-datetimepicker-widget table td span.disabled, +.bootstrap-datetimepicker-widget table td span.disabled:hover { + background: none; + color: #999999; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget.usetwentyfour td.hour { + height: 27px; + line-height: 27px; +} +.bootstrap-datetimepicker-widget.wider { + width: 21em; +} +.bootstrap-datetimepicker-widget .datepicker-decades .decade { + line-height: 1.8em !important; +} +.input-group.date .input-group-addon { + cursor: pointer; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.blank-slate-pf { + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 1px; + margin-bottom: 20px; + padding: 30px; + text-align: center; +} +@media (min-width: 768px) { + .blank-slate-pf { + padding: 60px 60px; + } +} +@media (min-width: 992px) { + .blank-slate-pf { + padding: 90px 120px; + } +} +.blank-slate-pf .blank-slate-pf-icon { + color: #999999; + font-size: 57.6px; + line-height: 57.6px; +} +.blank-slate-pf .blank-slate-pf-main-action { + margin-top: 20px; +} +.blank-slate-pf .blank-slate-pf-secondary-action { + margin-top: 20px; +} +.combobox-container.combobox-selected .glyphicon-remove { + display: inline-block; +} +.combobox-container .caret { + margin-left: 0; +} +.combobox-container .combobox::-ms-clear { + display: none; +} +.combobox-container .dropdown-menu { + margin-top: -1px; + width: 100%; +} +.combobox-container .glyphicon-remove { + display: none; + top: auto; + width: 12px; +} +.combobox-container .glyphicon-remove:before { + content: "\e60b"; + font-family: "PatternFlyIcons-webfont"; +} +.combobox-container .input-group-addon { + background-color: #eeeeee; + background-image: -webkit-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -o-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: linear-gradient(to bottom, #fafafa 0%, #ededed 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0); + border-color: #b7b7b7; + color: #4d5258; + position: relative; +} +.combobox-container .input-group-addon:hover, +.combobox-container .input-group-addon:focus, +.combobox-container .input-group-addon:active, +.combobox-container .input-group-addon.active, +.open .dropdown-toggle.combobox-container .input-group-addon { + background-color: #eeeeee; + background-image: none; + border-color: #b7b7b7; + color: #4d5258; +} +.combobox-container .input-group-addon:active, +.combobox-container .input-group-addon.active, +.open .dropdown-toggle.combobox-container .input-group-addon { + background-image: none; +} +.combobox-container .input-group-addon:active:hover, +.combobox-container .input-group-addon.active:hover, +.open .dropdown-toggle.combobox-container .input-group-addon:hover, +.combobox-container .input-group-addon:active:focus, +.combobox-container .input-group-addon.active:focus, +.open .dropdown-toggle.combobox-container .input-group-addon:focus, +.combobox-container .input-group-addon:active.focus, +.combobox-container .input-group-addon.active.focus, +.open .dropdown-toggle.combobox-container .input-group-addon.focus { + background-color: #e2e2e2; + border-color: #a5a5a5; +} +.combobox-container .input-group-addon.disabled, +.combobox-container .input-group-addon[disabled], +fieldset[disabled] .combobox-container .input-group-addon, +.combobox-container .input-group-addon.disabled:hover, +.combobox-container .input-group-addon[disabled]:hover, +fieldset[disabled] .combobox-container .input-group-addon:hover, +.combobox-container .input-group-addon.disabled:focus, +.combobox-container .input-group-addon[disabled]:focus, +fieldset[disabled] .combobox-container .input-group-addon:focus, +.combobox-container .input-group-addon.disabled:active, +.combobox-container .input-group-addon[disabled]:active, +fieldset[disabled] .combobox-container .input-group-addon:active, +.combobox-container .input-group-addon.disabled.active, +.combobox-container .input-group-addon[disabled].active, +fieldset[disabled] .combobox-container .input-group-addon.active { + background-color: #eeeeee; + border-color: #b7b7b7; +} +.combobox-container .input-group-addon:active { + -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2); + box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2); +} +.bootstrap-datepicker.form-control[readonly] { + background-color: #fff; + border-color: #BABABA !important; + color: #333333; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.bootstrap-datepicker.form-control[readonly]:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.bootstrap-datepicker.form-control[readonly]:focus { + border-color: #66afe9 !important; +} +.has-error .bootstrap-datepicker.form-control[readonly]:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-success .bootstrap-datepicker.form-control[readonly]:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-warning .bootstrap-datepicker.form-control[readonly]:focus { + border-color: #bb6106; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #faad60; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #faad60; +} +.bootstrap-datepicker.form-control[readonly]:hover { + border-color: #7BB2DD !important; +} +.has-error .bootstrap-datepicker.form-control[readonly]:hover { + border-color: #843534 !important; +} +.has-success .bootstrap-datepicker.form-control[readonly]:hover { + border-color: #2b542c !important; +} +.has-warning .bootstrap-datepicker.form-control[readonly]:hover { + border-color: #bb6106 !important; +} +.has-error .bootstrap-datepicker.form-control[readonly] { + border-color: #a94442 !important; +} +.has-success .bootstrap-datepicker.form-control[readonly] { + border-color: #3c763d !important; +} +.has-warning .bootstrap-datepicker.form-control[readonly] { + border-color: #ec7a08 !important; +} +.datepicker { + border-radius: 1px; +} +.datepicker .datepicker-switch, +.datepicker tfoot .clear, +.datepicker tfoot .today { + font-size: 14px; + font-weight: 500; +} +.datepicker .next, +.datepicker .prev { + font-weight: 500; +} +.datepicker table tr td, +.datepicker table tr th { + border-radius: 1px; +} +.datepicker table tr td.active.active, +.datepicker table tr td.active.active:hover, +.datepicker table tr td.active.active.disabled, +.datepicker table tr td.active.active.disabled:hover { + background: #0099d3 !important; + color: #fff !important; + text-shadow: none; +} +.datepicker table tr td.day:hover, +.datepicker table tr td.day.focused { + background: #d4edfa; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + text-shadow: none; +} +.datepicker table tr td span { + border-radius: 1px; +} +.datepicker table tr td span.active.active, +.datepicker table tr td span.active.active:hover, +.datepicker table tr td span.active.active.disabled, +.datepicker table tr td span.active.active.disabled:hover { + background: #0099d3; + text-shadow: none; +} +.datepicker table tr td span:hover { + background: #d4edfa; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #d4edfa; +} +.input-daterange input:first-child { + border-radius: 1px 0 0 1px; +} +.input-daterange input:last-child { + border-radius: 0 1px 1px 0; +} +.input-daterange .input-group-addon { + background-color: #eeeeee; + border-color: #BABABA; + line-height: 1.66666667; + padding: 2px 6px; +} +.bootstrap-select.btn-group.form-control { + margin-bottom: 0; +} +.bootstrap-select.btn-group .btn { + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.bootstrap-select.btn-group .btn:hover { + border-color: #7BB2DD; +} +.bootstrap-select.btn-group .btn .caret { + margin-top: -4px; +} +.bootstrap-select.btn-group .btn:focus { + border-color: #66afe9; + outline: 0 !important; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.has-error .bootstrap-select.btn-group .btn { + border-color: #a94442; +} +.has-error .bootstrap-select.btn-group .btn:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-success .bootstrap-select.btn-group .btn { + border-color: #3c763d; +} +.has-success .bootstrap-select.btn-group .btn:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-warning .bootstrap-select.btn-group .btn { + border-color: #ec7a08; +} +.has-warning .bootstrap-select.btn-group .btn:focus { + border-color: #bb6106; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #faad60; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #faad60; +} +.bootstrap-select.btn-group .dropdown-menu > .active > a, +.bootstrap-select.btn-group .dropdown-menu > .active > a:active { + background-color: #d4edfa !important; + border-color: #b3d3e7 !important; + color: #333333 !important; +} +.bootstrap-select.btn-group .dropdown-menu > .active > a small, +.bootstrap-select.btn-group .dropdown-menu > .active > a:active small { + color: #999999 !important; +} +.bootstrap-select.btn-group .dropdown-menu > .disabled > a { + color: #999999 !important; +} +.bootstrap-select.btn-group .dropdown-menu > .selected > a { + background-color: #0099d3 !important; + border-color: #0076b7 !important; + color: #fff !important; +} +.bootstrap-select.btn-group .dropdown-menu > .selected > a small { + color: #70c8e7 !important; + color: rgba(225, 255, 255, 0.5) !important; +} +.bootstrap-select.btn-group .dropdown-menu .divider { + background: #e5e5e5 !important; + margin: 4px 1px !important; +} +.bootstrap-select.btn-group .dropdown-menu dt { + color: #969696; + font-weight: normal; + padding: 1px 10px; +} +.bootstrap-select.btn-group .dropdown-menu li > a.opt { + padding: 1px 10px; +} +.bootstrap-select.btn-group .dropdown-menu li a:active small { + color: #70c8e7 !important; + color: rgba(225, 255, 255, 0.5) !important; +} +.bootstrap-select.btn-group .dropdown-menu li a:hover small, +.bootstrap-select.btn-group .dropdown-menu li a:focus small { + color: #999999; +} +.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:hover small, +.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:focus small { + color: #999999; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default { + background: #fbfbfb; +} +.bootstrap-switch .bootstrap-switch-label { + background: #eeeeee; + box-shadow: 0 0 2px rgba(0, 0, 0, 0.4); + background-image: -webkit-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: -o-linear-gradient(top, #fafafa 0%, #ededed 100%); + background-image: linear-gradient(to bottom, #fafafa 0%, #ededed 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0); + position: relative; + z-index: 9; +} +.bootstrap-touchspin .input-group-btn-vertical > .btn { + padding-bottom: 6px; + padding-top: 6px; +} +.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down { + border-bottom-right-radius: 1px; +} +.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up { + border-top-right-radius: 1px; +} +.bootstrap-touchspin .input-group-btn-vertical i { + font-size: 8px; + left: 6px; + top: 2px; +} +.bootstrap-touchspin .input-group-btn-vertical i.fa-angle-down, +.bootstrap-touchspin .input-group-btn-vertical i.fa-angle-up { + font-size: 12px; + line-height: 12px; + top: 0; +} +.bootstrap-touchspin .input-group-btn-vertical i.fa-angle-down, +.bootstrap-touchspin .input-group-btn-vertical i.fa-angle-up { + left: 7px; +} +.treeview .list-group { + border-top: 0; +} +.treeview .list-group-item { + background: transparent; + border-bottom: 1px solid transparent !important; + border-top: 1px solid transparent !important; + margin-bottom: 0; + padding: 0 10px; +} +.treeview .list-group-item:hover { + background: #d4edfa !important; + border-color: #b3d3e7 !important; +} +.treeview .list-group-item.node-selected { + background: #0099d3 !important; + border-color: #0076b7 !important; + color: #fff !important; +} +.treeview span.icon { + display: inline-block; + font-size: 13px; + min-width: 10px; + text-align: center; +} +.treeview span.icon > [class*="fa-angle"] { + font-size: 15px; +} +.treeview span.indent { + margin-right: 5px; +} +.card-pf { + background: #fff; + border-top: 2px solid transparent; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.175); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.175); + margin: 0 -10px 20px; + padding: 0 20px; +} +.card-pf.card-pf-accented { + border-top-color: #39a5dc; +} +.card-pf.card-pf-aggregate-status .card-pf-aggregate-status-notifications a, +.card-pf.card-pf-aggregate-status .card-pf-title a { + color: #333333; +} +.card-pf.card-pf-aggregate-status .card-pf-aggregate-status-notifications a.add, +.card-pf.card-pf-aggregate-status .card-pf-title a.add { + color: #0099d3; +} +.card-pf.card-pf-aggregate-status .card-pf-aggregate-status-notifications a.add:hover, +.card-pf.card-pf-aggregate-status .card-pf-title a.add:hover { + color: #00618a; +} +.card-pf.card-pf-aggregate-status .card-pf-aggregate-status-notifications a:hover, +.card-pf.card-pf-aggregate-status .card-pf-title a:hover { + color: #00618a; +} +.card-pf.card-pf-aggregate-status { + padding: 0 10px; + text-align: center; +} +.card-pf.card-pf-aggregate-status-mini { + padding-bottom: 10px; + position: relative; +} +@media (min-width: 768px) { + .card-pf.card-pf-bleed-left { + margin-left: -20px; + } + .card-pf.card-pf-bleed-right { + border-right: 1px solid #d1d1d1; + margin-right: -20px; + } +} +.card-pf-aggregate-status-notifications { + font-size: 24px; + font-weight: 300; +} +.card-pf-aggregate-status-mini .card-pf-aggregate-status-notifications { + line-height: 1; +} +.card-pf-aggregate-status-notifications .card-pf-aggregate-status-notification + .card-pf-aggregate-status-notification { + border-left: 1px solid #d1d1d1; + margin-left: 3px; + padding-left: 10px; +} +.card-pf-aggregate-status-notifications .fa, +.card-pf-aggregate-status-notifications .pficon { + font-size: 18px; + margin-right: 7px; +} +.card-pf-body { + margin: 20px 0; + padding: 0 0 20px; +} +.card-pf-aggregate-status .card-pf-body { + margin-top: 10px; + padding-bottom: 10px; +} +.card-pf-aggregate-status-mini .card-pf-body { + margin-bottom: 0; + margin-top: 0; + padding-bottom: 0; + position: absolute; + right: 20px; + top: 15px; +} +.card-pf-utilization .card-pf-title + .card-pf-body { + margin-top: -8px; +} +.card-pf-body > *:last-child { + margin-bottom: 0; +} +.card-pf-footer { + background-color: #fafafa; + border-top: 1px solid #d1d1d1; + margin: 0 -20px !important; + padding: 20px 20px 10px; +} +.card-pf-footer a .fa, +.card-pf-footer a .pficon { + margin-right: 5px; +} +.card-pf-footer .card-pf-time-frame-filter { + margin-top: -2px; +} +.card-pf-link-with-icon { + padding-left: 21px; + position: relative; +} +.card-pf-link-with-icon .fa, +.card-pf-link-with-icon .pficon { + font-size: 16px; + left: 0; + position: absolute; + top: 0; +} +.card-pf-heading .card-pf-time-frame-filter, +.card-pf-footer .card-pf-time-frame-filter { + float: right; + margin-left: 20px; +} +.card-pf-heading { + border-bottom: 1px solid #d1d1d1; + margin: 0 -20px 20px; + padding: 0 20px 0; +} +.card-pf-heading .card-pf-time-frame-filter { + margin-top: -5px; +} +.card-pf-heading-details { + float: right; + font-size: 10px; +} +.card-pf-subtitle { + font-size: 16px; + margin-top: 20px; + margin-bottom: 10px; +} +[class^='col'] .card-pf-subtitle { + margin-top: 0; +} +@media (max-width: 767px) { + .card-pf-body [class^='col'] + [class^='col'] > .card-pf-subtitle { + margin-top: 40px; + } +} +.card-pf-title { + font-size: 16px; + font-weight: 400; + margin: 20px 0; + padding: 0; +} +.card-pf-aggregate-status .card-pf-title { + font-size: 14px; + margin: 10px 0 0; +} +.card-pf-aggregate-status .card-pf-title .fa, +.card-pf-aggregate-status .card-pf-title .pficon { + color: #333; + font-size: 16px; + margin-right: 7px; +} +.card-pf-title .card-pf-aggregate-status-count { + font-size: 16px; +} +.card-pf-aggregate-status-mini .card-pf-title .card-pf-aggregate-status-count { + display: block; + font-size: 24px; + font-weight: 300; + margin-bottom: 3px; +} +.card-pf-aggregate-status-mini .card-pf-title { + font-size: 12px; + margin-top: 5px; +} +.card-pf-aggregate-status-mini .card-pf-title a { + display: inline-block; +} +.card-pf-aggregate-status-mini .card-pf-title .fa, +.card-pf-aggregate-status-mini .card-pf-title .pficon { + font-size: 26px; + margin-right: 0; + min-width: 26px; + position: absolute; + left: 20px; + text-align: center; + top: 15px; +} +.card-pf-utilization-details { + border-bottom: 1px solid #d1d1d1; + display: table; + margin: 12px 0 15px; + padding: 0 0 15px; + width: 100%; +} +.card-pf-utilization-details .card-pf-utilization-card-details-count, +.card-pf-utilization-details .card-pf-utilization-card-details-description { + display: table-cell; + float: left; + line-height: 1; + vertical-align: middle; +} +.card-pf-utilization-details .card-pf-utilization-card-details-count { + font-size: 26px; + font-weight: 300; + margin-right: 10px; +} +.card-pf-utilization-details .card-pf-utilization-card-details-line-1, +.card-pf-utilization-details .card-pf-utilization-card-details-line-2 { + display: block; +} +.card-pf-utilization-details .card-pf-utilization-card-details-line-1 { + font-size: 10px; + margin-bottom: 2px; +} +.cards-pf { + background: #f5f5f5; +} +.container-cards-pf { + margin-top: 20px; +} +.row-cards-pf { + margin-left: -10px; + margin-right: -10px; +} +.c3 path { + stroke: #d1d1d1; +} +.c3 svg { + font-family: "Open Sans", Helvetica, Arial, sans-serif; +} +.c3-axis-x .tick line { + stroke: #d1d1d1; +} +.c3-axis-y .tick line { + display: none; +} +.c3-chart-arc path { + stroke: #fff; +} +.c3-grid line { + stroke: #d1d1d1; +} +.c3-line { + stroke-width: 2px; +} +.c3-tooltip { + background: #434343; + -webkit-box-shadow: none; + box-shadow: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.c3-tooltip td { + background: transparent; + border: 0; + color: #fff; + font-size: 12px; + padding: 5px 10px; +} +.c3-tooltip th { + background: transparent; + font-size: 12px; + padding: 5px 10px 0; + border-bottom: solid 2px #030303; +} +.c3-tooltip tr { + border: 0; +} +.c3-tooltip tr + tr > td { + padding-top: 0; +} +.c3-tooltip-sparkline, +.donut-tooltip-pf { + background: #434343; + color: #fff; + opacity: 0.9; + filter: alpha(opacity=90); + padding: 2px 6px; +} +.c3-xgrid, +.c3-ygrid { + stroke-dasharray: 0 0; +} +.chart-pf-sparkline { + margin-left: -5px; + margin-right: -5px; +} +.donut-title-big-pf { + font-size: 30px; + font-weight: 300; +} +.donut-title-small-pf { + font-size: 12px; + font-weight: 400; +} +.line-chart-pf .c3-zoom-rect { + opacity: 1.0 !important; + fill: #fafafa; + stroke: #d1d1d1; + stroke-width: 1px; +} +.close { + text-shadow: none; + opacity: 0.6; + filter: alpha(opacity=60); +} +.close:hover, +.close:focus { + opacity: 0.9; + filter: alpha(opacity=90); +} +.ColVis_Button:active:focus { + outline: none; +} +.ColVis_catcher { + position: absolute; + z-index: 999; +} +.ColVis_collection { + background-color: #fff; + border: 1px solid #b6b6b6; + border-radius: 1px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; + list-style: none; + margin: -1px 0 0 0; + padding: 5px 10px; + width: 150px; + z-index: 1000; +} +.ColVis_collection label { + font-weight: normal; + margin-bottom: 5px; + margin-top: 5px; + padding-left: 20px; +} +.ColVis_collectionBackground { + background-color: #fff; + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 998; +} +.dataTables_header { + background-color: #f6f6f6; + border: 1px solid #d1d1d1; + border-bottom: none; + padding: 5px; + position: relative; + text-align: center; +} +.dataTables_header .btn { + -webkit-box-shadow: none; + box-shadow: none; +} +.dataTables_header .ColVis { + position: absolute; + right: 5px; + text-align: left; + top: 5px; +} +.dataTables_header .ColVis + .dataTables_info { + padding-right: 30px; +} +.dataTables_header .dataTables_filter { + position: absolute; +} +.dataTables_header .dataTables_filter input { + border: 1px solid #bbbbbb; + height: 24px; +} +@media (max-width: 767px) { + .dataTables_header .dataTables_filter input { + width: 100px; + } +} +.dataTables_header .dataTables_info { + padding: 2px 0; +} +@media (max-width: 480px) { + .dataTables_header .dataTables_info { + text-align: right; + } +} +.dataTables_header .dataTables_info b { + font-weight: bold; +} +.dataTables_footer { + background-color: #fff; + border: 1px solid #d1d1d1; + border-top: none; + overflow: hidden; +} +.dataTables_paginate { + background: #fafafa; + float: right; + margin: 0; +} +.dataTables_paginate .pagination { + float: left; + margin: 0; +} +.dataTables_paginate .pagination > li > span { + border-color: #ffffff #e1e1e1 #f4f4f4; + border-width: 0 1px; + font-size: 16px; + font-weight: normal; + padding: 0; + text-align: center; + width: 31px; +} +.dataTables_paginate .pagination > li > span:hover, +.dataTables_paginate .pagination > li > span:focus { + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.dataTables_paginate .pagination > li.last > span { + border-right: none; +} +.dataTables_paginate .pagination > li.disabled > span { + background: #f5f5f5; + border-left-color: #ececec; + border-right-color: #ececec; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.dataTables_paginate .pagination-input { + float: left; + font-size: 12px; + line-height: 1em; + padding: 4px 15px 0; + text-align: right; +} +.dataTables_paginate .pagination-input .paginate_input { + border: 1px solid #d3d3d3; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + font-size: 12px; + font-weight: 600; + height: 19px; + margin-right: 8px; + padding-right: 3px; + text-align: right; + width: 30px; +} +.dataTables_paginate .pagination-input .paginate_of { + position: relative; +} +.dataTables_paginate .pagination-input .paginate_of b { + margin-left: 3px; +} +.dataTables_wrapper { + margin: 20px 0; +} +@media (max-width: 767px) { + .dataTables_wrapper .table-responsive { + margin-bottom: 0; + } +} +.DTCR_clonedTable { + background-color: rgba(255, 255, 255, 0.7); + z-index: 202; +} +.DTCR_pointer { + background-color: #0099d3; + width: 1px; + z-index: 201; +} +table.datatable { + margin-bottom: 0; + max-width: none !important; +} +table.datatable thead .sorting, +table.datatable thead .sorting_asc, +table.datatable thead .sorting_desc, +table.datatable thead .sorting_asc_disabled, +table.datatable thead .sorting_desc_disabled { + cursor: pointer; + *cursor: hand; +} +table.datatable thead .sorting_asc, +table.datatable thead .sorting_desc { + color: #0099d3 !important; + position: relative; +} +table.datatable thead .sorting_asc:after, +table.datatable thead .sorting_desc:after { + content: "\f107"; + font-family: "FontAwesome"; + font-size: 10px; + font-weight: normal; + height: 9px; + left: 7px; + line-height: 12px; + position: relative; + top: 2px; + vertical-align: baseline; + width: 12px; +} +table.datatable thead .sorting_asc:before, +table.datatable thead .sorting_desc:before { + background: #0099d3; + content: ''; + height: 2px; + position: absolute; + left: 0; + top: 0; + width: 100%; +} +table.datatable thead .sorting_asc:after { + content: "\f106"; + top: -3px; +} +table.datatable th:active { + outline: none; +} +.footer-pf-alt, +.footer-pf { + background-color: #030303; + color: #999999; + font-size: 11px; + line-height: 17px; + padding-left: 25px; + padding-top: 10px; +} +.layout-pf-alt-fixed-with-footer .footer-pf-alt, +.layout-pf-alt-fixed-with-footer .footer-pf, +.layout-pf-fixed-with-footer .footer-pf-alt, +.layout-pf-fixed-with-footer .footer-pf { + bottom: 0; + left: 0; + position: fixed; + right: 0; + z-index: 1030; +} +@font-face { + font-family: 'PatternFlyIcons-webfont'; + src: url('../fonts/PatternFlyIcons-webfont.eot'); + src: url('../fonts/PatternFlyIcons-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/PatternFlyIcons-webfont.ttf') format('truetype'), url('../fonts/PatternFlyIcons-webfont.woff') format('woff'), url('../fonts/PatternFlyIcons-webfont.svg#PatternFlyIcons-webfont') format('svg'); + font-weight: normal; + font-style: normal; +} +[class^="pficon-"], +[class*=" pficon-"] { + display: inline-block; + font-family: 'PatternFlyIcons-webfont'; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + speak: none; + text-transform: none; + /* Better Font Rendering =========== */ + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} +.pficon-add-circle-o:before { + content: "\e61b"; +} +.pficon-build:before { + content: "\e902"; +} +.pficon-builder-image:before { + content: "\e800"; +} +.pficon-close:before { + content: "\e60b"; +} +.pficon-cloud-security:before { + content: "\e903"; +} +.pficon-cloud-tenant:before { + content: "\e904"; +} +.pficon-cluster:before { + content: "\e620"; +} +.pficon-container-node:before { + content: "\e621"; +} +.pficon-cpu:before { + content: "\e905"; +} +.pficon-delete:before { + content: "\e611"; +} +.pficon-edit:before { + content: "\e60a"; +} +.pficon-enterprise:before { + content: "\e906"; +} +.pficon-error-circle-o:before { + color: #cc0000; + content: "\e61d"; +} +.pficon-export:before { + content: "\e616"; +} +.pficon-flag:before, +.pficon-messages:before { + content: "\e603"; +} +.pficon-flavor:before { + content: "\e907"; +} +.pficon-folder-close:before { + content: "\e607"; +} +.pficon-folder-open:before { + content: "\e606"; +} +.pficon-help:before { + content: "\e605"; +} +.pficon-history:before { + content: "\e617"; +} +.pficon-home:before { + content: "\e618"; +} +.pficon-image:before { + content: "\e61f"; +} +.pficon-import:before { + content: "\e615"; +} +.pficon-info:before { + content: "\e604"; +} +.pficon-memory:before { + content: "\e908"; +} +.pficon-network:before { + content: "\e909"; +} +.pficon-ok:before { + color: #3f9c35; + content: "\e602"; +} +.pficon-print:before { + content: "\e612"; +} +.pficon-project:before { + content: "\e622"; +} +.pficon-refresh:before, +.pficon-restart:before { + content: "\e613"; +} +.pficon-regions:before { + content: "\e90a"; +} +.pficon-registry:before { + content: "\e623"; +} +.pficon-replicator:before { + content: "\e624"; +} +.pficon-repository:before { + content: "\e90b"; +} +.pficon-resource-pool:before { + content: "\e90c"; +} +.pficon-resources-almost-full:before { + content: "\e912"; +} +.pficon-resources-full:before { + content: "\e913"; +} +.pficon-route:before { + content: "\e625"; +} +.pficon-running:before { + content: "\e614"; +} +.pficon-save:before { + content: "\e601"; +} +.pficon-screen:before { + content: "\e600"; +} +.pficon-server:before { + content: "\e90d"; +} +.pficon-service:before { + content: "\e61e"; +} +.pficon-settings:before { + content: "\e610"; +} +.pficon-storage-domain:before { + content: "\e90e"; +} +.pficon-thumb-tack-o:before { + content: "\e609"; +} +.pficon-topology:before { + content: "\e608"; +} +.pficon-trend-down:before { + content: "\e900"; +} +.pficon-trend-up:before { + content: "\e901"; +} +.pficon-user:before { + content: "\e60e"; +} +.pficon-users:before { + content: "\e60f"; +} +.pficon-virtual-machine:before { + content: "\e90f"; +} +.pficon-volume:before { + content: "\e910"; +} +.pficon-warning-triangle-o:before { + color: #ec7a08; + content: "\e61c"; +} +.pficon-zone:before { + content: "\e911"; +} +.navbar-nav > li > .dropdown-menu.infotip { + border-top-width: 1px !important; + margin-top: 10px; +} +@media (max-width: 767px) { + .navbar-pf .navbar-nav .open .dropdown-menu.infotip { + background-color: #fff !important; + margin-top: 0; + } +} +.infotip { + min-width: 235px; + padding: 0; +} +.infotip .list-group { + border-top: 0; + margin: 0; + padding: 8px 0; +} +.infotip .list-group .list-group-item { + border: none; + margin: 0 15px 0 34px; + padding: 5px 0; +} +.infotip .list-group .list-group-item > .i { + color: #4d5258; + font-size: 13px; + left: -20px; + position: absolute; + top: 8px; +} +.infotip .list-group .list-group-item > a { + color: #4d5258; + line-height: 13px; +} +.infotip .list-group .list-group-item > .close { + float: right; +} +.infotip .footer { + background-color: #f5f5f5; + padding: 6px 15px; +} +.infotip .footer a:hover { + color: #0099d3; +} +.infotip .arrow, +.infotip .arrow:after { + border-color: transparent; + border-style: solid; + display: block; + height: 0; + position: absolute; + width: 0; +} +.infotip .arrow { + border-width: 11px; +} +.infotip .arrow:after { + border-width: 10px; + content: ""; +} +.infotip.bottom .arrow, +.infotip.bottom-left .arrow, +.infotip.bottom-right .arrow { + border-bottom-color: #999999; + border-bottom-color: #bbbbbb; + border-top-width: 0; + left: 50%; + margin-left: -11px; + top: -11px; +} +.infotip.bottom .arrow:after, +.infotip.bottom-left .arrow:after, +.infotip.bottom-right .arrow:after { + border-top-width: 0; + border-bottom-color: #fff; + content: " "; + margin-left: -10px; + top: 1px; +} +.infotip.bottom-left .arrow { + left: 20%; +} +.infotip.bottom-right .arrow { + left: 80%; +} +.infotip.top .arrow { + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: #bbbbbb; + bottom: -11px; + left: 50%; + margin-left: -11px; +} +.infotip.top .arrow:after { + border-bottom-width: 0; + border-top-color: #f5f5f5; + bottom: 1px; + content: " "; + margin-left: -10px; +} +.infotip.right .arrow { + border-left-width: 0; + border-right-color: #999999; + border-right-color: #bbbbbb; + left: -11px; + margin-top: -11px; + top: 50%; +} +.infotip.right .arrow:after { + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; + content: " "; + left: 1px; +} +.infotip.left .arrow { + border-left-color: #999999; + border-left-color: #bbbbbb; + border-right-width: 0; + margin-top: -11px; + right: -11px; + top: 50%; +} +.infotip.left .arrow:after { + border-left-color: #fff; + border-right-width: 0; + bottom: -10px; + content: " "; + right: 1px; +} +.layout-pf, +.layout-pf body { + min-height: 100%; +} +.layout-pf.layout-pf-fixed.transitions .container-pf-nav-pf-vertical { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf.layout-pf-fixed body { + padding-top: 60px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical { + margin-left: 200px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.hidden-icons-pf { + margin-left: 176px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.collapsed-nav { + margin-left: 0; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.hidden-nav { + margin-left: 0; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.collapsed-nav { + margin-left: 75px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.collapsed-nav.hidden-icons-pf { + margin-left: 0; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.collapsed-secondary-nav-pf, +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-secondary-nav-pf { + margin-left: 250px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf { + margin-left: 200px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.hidden-icons-pf { + margin-left: 176px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.hidden-nav { + margin-left: 0; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-nav { + margin-left: 75px; +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-nav.hidden-icons-pf { + margin-left: 0; +} +@media (min-width: 1200px) { + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf { + margin-left: 450px; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.hidden-icons-pf { + margin-left: 426px; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.hidden-nav { + margin-left: 0; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-secondary-nav-pf { + margin-left: 250px; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-nav { + margin-left: 325px; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-nav.collapsed-secondary-nav-pf { + margin-left: 250px; + } + .layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.secondary-visible-pf.collapsed-nav.hidden-icons-pf { + margin-left: 0; + } +} +.layout-pf.layout-pf-fixed .container-pf-nav-pf-vertical.container-pf-nav-pf-vertical-with-secondary.hidden-nav { + margin-left: 0; +} +.layout-pf.layout-pf-fixed-with-footer body { + padding-bottom: 37px; +} +.layout-pf-alt, +.layout-pf-alt body { + min-height: 100%; +} +.layout-pf-alt.layout-pf-alt-fixed.layout-pf-alt-fixed-inner-scroll, +.layout-pf-alt.layout-pf-alt-fixed.layout-pf-alt-fixed-inner-scroll body { + height: 100%; + min-height: 0; +} +.layout-pf-alt.layout-pf-alt-fixed.layout-pf-alt-fixed-inner-scroll .container-pf-alt-nav-pf-vertical-alt { + height: 100%; + overflow: auto; +} +.layout-pf-alt.layout-pf-alt-fixed.layout-pf-alt-fixed-inner-scroll .container-pf-alt-nav-pf-vertical-alt.container-cards-pf { + margin-top: 0; + padding-top: 20px; +} +.layout-pf-alt.layout-pf-alt-fixed.transitions .container-pf-alt-nav-pf-vertical-alt { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf-alt.layout-pf-alt-fixed body { + padding-top: 60px; +} +.layout-pf-alt.layout-pf-alt-fixed .container-pf-alt-nav-pf-vertical-alt { + margin-left: 250px; +} +.layout-pf-alt.layout-pf-alt-fixed .container-pf-alt-nav-pf-vertical-alt.collapsed-nav { + margin-left: 75px; +} +.layout-pf-alt.layout-pf-alt-fixed .container-pf-alt-nav-pf-vertical-alt.hidden-nav { + margin-left: 0; +} +.layout-pf-alt.layout-pf-alt-fixed-with-footer body { + padding-bottom: 37px; +} +.list-view-pf .list-group-item { + align-items: flex-start; + display: -ms-flexbox; + display: flex; + padding-bottom: 0; + padding-top: 0; +} +.list-view-pf .list-group-item:before, +.list-view-pf .list-group-item:after { + content: " "; + display: table; +} +.list-view-pf .list-group-item:after { + clear: both; +} +.list-view-pf .list-group-item.active { + color: #555; + background-color: #def3ff; +} +.list-view-pf .list-group-item:hover { + background-color: #ededed; +} +@media (min-width: 992px) { + .list-view-pf .list-group-item { + align-items: center; + } +} +.list-view-pf .list-group-item-heading { + font-size: 16px; +} +.list-view-pf .list-group-item-heading small { + display: block; + font-size: 9.6px; + font-weight: 400; +} +@media (min-width: 992px) { + .list-view-pf .list-group-item-heading { + -ms-flex: 1 0 calc(25% - 20px); + flex: 1 0 calc(25% - 20px); + float: left; + font-size: 12px; + margin: 0 20px 0 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: calc(25% - 20px); + } +} +.list-view-pf .list-group-item-text { + color: currentColor !important; + margin-bottom: 10px; +} +@media (min-width: 992px) { + .list-view-pf .list-group-item-text { + -ms-flex: 1 0 auto; + flex: 1 0 auto; + float: left; + margin: 0 40px 0 0; + width: calc(75% - 40px); + } +} +.list-view-pf-actions { + float: right; + margin-bottom: 20px; + margin-left: 20px; + margin-top: 20px; + -ms-flex-order: 2; + order: 2; +} +.list-view-pf-actions button, +.list-view-pf-actions > a { + margin-left: 10px; +} +.list-view-pf-top-align .list-view-pf-actions { + align-self: flex-start; +} +.list-view-pf-additional-info { + align-items: center; + display: flex; + flex-wrap: wrap; +} +@media (min-width: 992px) { + .list-view-pf-additional-info { + flex: 1 0 auto; + float: left; + width: 50%; + } +} +.list-view-pf-additional-info-item { + align-items: center; + display: inline-block; + display: flex; + margin-right: 20px; + max-width: 100%; + text-align: center; +} +.list-view-pf-additional-info-item.list-view-pf-additional-info-item-stacked { + text-align: center; + flex-direction: column; +} +.list-view-pf-additional-info-item.list-view-pf-additional-info-item-stacked strong { + font-size: 13px; + line-height: 1em; +} +.list-view-pf-additional-info-item .pficon, +.list-view-pf-additional-info-item .fa { + font-size: 16px; + margin-right: 10px; +} +.list-view-pf-additional-info-item strong { + font-size: 16px; + font-weight: 600; + margin-right: 5px; +} +.list-view-pf-additional-info-item:last-child { + margin-right: 0; +} +.list-view-pf-additional-info-item-donut-chart { + width: 60px; +} +.list-view-pf-body { + align-items: center; + display: table-cell; + -ms-flex: 1; + flex: 1; + vertical-align: top; + width: 100%; +} +@media (min-width: 992px) { + .list-view-pf-body { + align-items: center; + display: -ms-flexbox; + display: flex; + flex-direction: row; + } +} +.list-view-pf-checkbox { + border-right: 1px solid #d1d1d1; + float: left; + margin-bottom: 20px; + margin-right: 15px; + margin-top: 20px; + padding: 3px 10px 3px 0; +} +.list-view-pf-top-align .list-view-pf-checkbox { + align-self: flex-start; +} +.list-view-pf-description { + -ms-flex: 1 0 50%; + flex: 1 0 50%; +} +.list-view-pf-stacked .list-view-pf-description { + display: block; +} +@media (min-width: 992px) { + .list-view-pf-description { + align-items: center; + display: flex; + float: left; + width: 50%; + } +} +.list-view-pf-left { + display: table-cell; + padding-right: 20px; + text-align: center; + vertical-align: top; +} +.list-view-pf-left .list-view-pf-calendar { + font-size: 11px; + line-height: 1em; +} +.list-view-pf-left .list-view-pf-calendar strong { + display: block; + font-size: 44px; + font-weight: 300; + line-height: 1em; +} +.list-view-pf-left .pficon, +.list-view-pf-left .fa { + border-radius: 50%; + font-size: 2em; +} +.list-view-pf-left .pficon.list-view-pf-icon-md, +.list-view-pf-left .fa.list-view-pf-icon-md { + background-color: #f2f2f2; + height: 50px; + line-height: 50px; + width: 50px; +} +.list-view-pf-left .pficon.list-view-pf-icon-danger, +.list-view-pf-left .fa.list-view-pf-icon-danger { + background-color: #fbe7e7; + color: #cc0000; +} +.list-view-pf-left .pficon.list-view-pf-icon-info, +.list-view-pf-left .fa.list-view-pf-icon-info { + color: #8b8d8f; +} +.list-view-pf-left .pficon.list-view-pf-icon-lg, +.list-view-pf-left .fa.list-view-pf-icon-lg { + background-color: #f2f2f2; + height: 60px; + line-height: 60px; + width: 60px; +} +.list-view-pf-left .pficon.list-view-pf-icon-sm, +.list-view-pf-left .fa.list-view-pf-icon-sm { + border: 2px solid #39a5dc; + font-size: 1.4em; + height: 30px; + line-height: 30px; + width: 30px; +} +.list-view-pf-left .pficon.list-view-pf-icon-success, +.list-view-pf-left .fa.list-view-pf-icon-success { + background-color: #e8f9e7; + color: #3f9c35; +} +.list-view-pf-left .pficon.list-view-pf-icon-warning, +.list-view-pf-left .fa.list-view-pf-icon-warning { + background-color: #fdf4ea; + color: #ec7a08; +} +.list-view-pf-main-info { + align-items: flex-start; + display: -ms-flexbox; + display: flex; + -ms-flex: 1; + flex: 1; + padding-bottom: 20px; + padding-top: 20px; +} +@media (min-width: 992px) { + .list-view-pf-main-info { + align-items: center; + } + .list-view-pf-top-align .list-view-pf-main-info { + align-items: flex-start; + } +} +.list-view-pf-stacked .list-group-item-heading { + float: none; + font-size: 16px; + line-height: 1.2em; + margin-bottom: 5px; + margin-right: 40px; + width: auto; +} +.list-view-pf-stacked .list-group-item-text { + float: none; + width: auto; +} +.login-pf { + height: 100%; +} +.login-pf #brand { + position: relative; + top: -70px; +} +.login-pf #brand img { + display: block; + height: 18px; + margin: 0 auto; + max-width: 100%; +} +@media (min-width: 768px) { + .login-pf #brand img { + margin: 0; + text-align: left; + } +} +.login-pf #badge { + display: block; + margin: 20px auto 70px; + position: relative; + text-align: center; +} +@media (min-width: 768px) { + .login-pf #badge { + float: right; + margin-right: 64px; + margin-top: 50px; + } +} +.login-pf body { + background: #1a1a1a url("../img/bg-login.png") repeat-x 50% 0; + background-size: auto; +} +@media (min-width: 768px) { + .login-pf body { + background-size: 100% auto; + } +} +.login-pf .container { + background-color: transparent; + clear: right; + color: #fff; + padding-bottom: 40px; + padding-top: 20px; + width: auto; +} +@media (min-width: 768px) { + .login-pf .container { + bottom: 13%; + padding-left: 80px; + position: absolute; + width: 100%; + } +} +.login-pf .container [class^='alert'] { + background: transparent; + color: #fff; +} +.login-pf .container .details p:first-child { + border-top: 1px solid #474747; + padding-top: 25px; + margin-top: 25px; +} +@media (min-width: 768px) { + .login-pf .container .details { + border-left: 1px solid #474747; + padding-left: 40px; + } + .login-pf .container .details p:first-child { + border-top: 0; + padding-top: 0; + margin-top: 0; + } +} +.login-pf .container .details p { + margin-bottom: 2px; +} +.login-pf .container .form-horizontal .control-label { + font-size: 13px; + font-weight: 400; + text-align: left; +} +.login-pf .container .form-horizontal .form-group:last-child, +.login-pf .container .form-horizontal .form-group:last-child .help-block:last-child { + margin-bottom: 0; +} +.login-pf .container .help-block { + color: #fff; +} +@media (min-width: 768px) { + .login-pf .container .login { + padding-right: 40px; + } +} +.login-pf .container .submit { + text-align: right; +} +.navbar-pf { + background: #393F45; + border: 0; + border-radius: 0; + border-top: 3px solid #cc0000; + margin-bottom: 0; + min-height: 0; +} +.navbar-pf .navbar-brand { + color: #fff; + height: auto; + padding: 12px 0; + margin: 0 0 0 20px; +} +.navbar-pf .navbar-brand img { + display: block; +} +.navbar-pf .navbar-collapse { + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + padding: 0; +} +.navbar-pf .navbar-header { + border-bottom: 1px solid #53565b; + float: none; +} +.navbar-pf .navbar-nav { + margin: 0; +} +.navbar-pf .navbar-nav > .active > a, +.navbar-pf .navbar-nav > .active > a:hover, +.navbar-pf .navbar-nav > .active > a:focus { + background-color: #454C53; + color: #fff; +} +.navbar-pf .navbar-nav > li > a { + color: #dbdada; + line-height: 1; + padding: 10px 20px; + text-shadow: none; +} +.navbar-pf .navbar-nav > li > a:hover, +.navbar-pf .navbar-nav > li > a:focus { + color: #fff; +} +.navbar-pf .navbar-nav > .open > a, +.navbar-pf .navbar-nav > .open > a:hover, +.navbar-pf .navbar-nav > .open > a:focus { + background-color: #454C53; + color: #fff; +} +@media (max-width: 767px) { + .navbar-pf .navbar-nav .active .dropdown-menu, + .navbar-pf .navbar-nav .active .navbar-persistent, + .navbar-pf .navbar-nav .open .dropdown-menu { + background-color: #3c434a !important; + margin-left: 0; + padding-bottom: 0; + padding-top: 0; + } + .navbar-pf .navbar-nav .active .dropdown-menu > .active > a, + .navbar-pf .navbar-nav .active .navbar-persistent > .active > a, + .navbar-pf .navbar-nav .open .dropdown-menu > .active > a, + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu.open > a, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.open > a, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu.open > a, + .navbar-pf .navbar-nav .active .dropdown-menu > .active > a:hover, + .navbar-pf .navbar-nav .active .navbar-persistent > .active > a:hover, + .navbar-pf .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu.open > a:hover, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.open > a:hover, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu.open > a:hover, + .navbar-pf .navbar-nav .active .dropdown-menu > .active > a:focus, + .navbar-pf .navbar-nav .active .navbar-persistent > .active > a:focus, + .navbar-pf .navbar-nav .open .dropdown-menu > .active > a:focus, + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu.open > a:focus, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.open > a:focus, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu.open > a:focus { + background-color: #424950 !important; + color: #fff; + } + .navbar-pf .navbar-nav .active .dropdown-menu > li > a, + .navbar-pf .navbar-nav .active .navbar-persistent > li > a, + .navbar-pf .navbar-nav .open .dropdown-menu > li > a { + background-color: transparent; + border: 0; + color: #dbdada; + outline: none; + padding-left: 30px; + } + .navbar-pf .navbar-nav .active .dropdown-menu > li > a:hover, + .navbar-pf .navbar-nav .active .navbar-persistent > li > a:hover, + .navbar-pf .navbar-nav .open .dropdown-menu > li > a:hover { + color: #fff; + } + .navbar-pf .navbar-nav .active .dropdown-menu .divider, + .navbar-pf .navbar-nav .active .navbar-persistent .divider, + .navbar-pf .navbar-nav .open .dropdown-menu .divider { + background-color: #53565b; + margin: 0 1px; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-header, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-header, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-header { + padding-bottom: 0; + padding-left: 30px; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu.open .dropdown-toggle, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.open .dropdown-toggle, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu.open .dropdown-toggle { + color: #fff; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu.pull-left, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.pull-left, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu.pull-left { + float: none !important; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu > a:after, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu > a:after, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu > a:after { + display: none; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu .dropdown-header, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-header, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu .dropdown-header { + padding-left: 45px; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu .dropdown-menu, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-menu, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu .dropdown-menu { + border: 0; + bottom: auto; + -webkit-box-shadow: none; + box-shadow: none; + display: block; + float: none; + margin: 0; + min-width: 0; + padding: 0; + position: relative; + left: auto; + right: auto; + top: auto; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu .dropdown-menu > li > a, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-menu > li > a, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu .dropdown-menu > li > a { + padding: 5px 15px 5px 45px; + line-height: 20px; + } + .navbar-pf .navbar-nav .active .dropdown-menu .dropdown-submenu .dropdown-menu .dropdown-menu > li > a, + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-menu .dropdown-menu > li > a, + .navbar-pf .navbar-nav .open .dropdown-menu .dropdown-submenu .dropdown-menu .dropdown-menu > li > a { + padding-left: 60px; + } + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu.open .dropdown-menu { + display: block; + } + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu > a:after { + display: inline-block !important; + position: relative; + right: auto; + top: 1px; + } + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-menu { + display: none; + } + .navbar-pf .navbar-nav .active .navbar-persistent .dropdown-submenu .dropdown-submenu > a:after { + display: none !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu { + background-color: #fff !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .active > a, + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .active > a:active { + background-color: #d4edfa !important; + border-color: #b3d3e7 !important; + color: #333333 !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .active > a small, + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .active > a:active small { + color: #999999 !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .disabled > a { + color: #999999 !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .selected > a, + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .selected > a:active { + background-color: #0099d3 !important; + border-color: #0076b7 !important; + color: #fff !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .selected > a small, + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu > .selected > a:active small { + color: #70c8e7 !important; + color: rgba(225, 255, 255, 0.5) !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu li > a.opt { + border-bottom: 1px solid transparent; + border-top: 1px solid transparent; + color: #333333; + padding-left: 10px; + padding-right: 10px; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu li a:active small { + color: #70c8e7 !important; + color: rgba(225, 255, 255, 0.5) !important; + } + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu li a:hover small, + .navbar-pf .navbar-nav .context-bootstrap-select .open > .dropdown-menu li a:focus small { + color: #999999; + } + .navbar-pf .navbar-nav .context-bootstrap-select > .open > .dropdown-menu { + padding-bottom: 5px; + padding-top: 5px; + } +} +.navbar-pf .navbar-persistent { + display: none; +} +.navbar-pf .active > .navbar-persistent { + display: block; +} +.navbar-pf .navbar-primary { + float: none; +} +.navbar-pf .navbar-primary .context { + border-bottom: 1px solid #53565b; +} +.navbar-pf .navbar-primary .context.context-bootstrap-select .bootstrap-select.btn-group, +.navbar-pf .navbar-primary .context.context-bootstrap-select .bootstrap-select.btn-group[class*="span"] { + margin: 8px 20px 9px; + width: auto; +} +.navbar-pf .navbar-primary > li > .navbar-persistent > .dropdown-submenu > a { + position: relative; +} +.navbar-pf .navbar-primary > li > .navbar-persistent > .dropdown-submenu > a:after { + content: "\f107"; + display: inline-block; + font-family: "FontAwesome"; + font-weight: normal; +} +@media (max-width: 767px) { + .navbar-pf .navbar-primary > li > .navbar-persistent > .dropdown-submenu > a:after { + height: 10px; + margin-left: 4px; + vertical-align: baseline; + } +} +.navbar-pf .navbar-toggle { + border: 0; + margin: 0; + padding: 10px 20px; +} +.navbar-pf .navbar-toggle:hover, +.navbar-pf .navbar-toggle:focus { + background-color: transparent; + outline: none; +} +.navbar-pf .navbar-toggle:hover .icon-bar, +.navbar-pf .navbar-toggle:focus .icon-bar { + -webkit-box-shadow: 0 0 3px #ffffff; + box-shadow: 0 0 3px #ffffff; +} +.navbar-pf .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-pf .navbar-utility { + border-bottom: 1px solid #53565b; +} +.navbar-pf .navbar-utility li.dropdown > .dropdown-toggle { + padding-left: 36px; + position: relative; +} +.navbar-pf .navbar-utility li.dropdown > .dropdown-toggle .pficon-user { + left: 20px; + position: absolute; + top: 10px; +} +@media (max-width: 767px) { + .navbar-pf .navbar-utility > li + li { + border-top: 1px solid #53565b; + } +} +@media (min-width: 768px) { + .navbar-pf .navbar-brand { + padding: 7px 0 8px; + } + .navbar-pf .navbar-nav > li > a { + padding-bottom: 14px; + padding-top: 14px; + } + .navbar-pf .navbar-persistent { + font-size: 14px; + } + .navbar-pf .navbar-primary { + font-size: 14px; + background-image: -webkit-linear-gradient(top, #474c50 0%, #383f43 100%); + background-image: -o-linear-gradient(top, #474c50 0%, #383f43 100%); + background-image: linear-gradient(to bottom, #474c50 0%, #383f43 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff474c50', endColorstr='#ff383f43', GradientType=0); + } + .navbar-pf .navbar-primary.persistent-secondary .context .dropdown-menu { + top: auto; + } + .navbar-pf .navbar-primary.persistent-secondary .dropup .dropdown-menu { + bottom: -5px; + top: auto; + } + .navbar-pf .navbar-primary.persistent-secondary > li { + position: static; + } + .navbar-pf .navbar-primary.persistent-secondary > li.active { + margin-bottom: 32px; + } + .navbar-pf .navbar-primary.persistent-secondary > li.active > .navbar-persistent { + display: block; + left: 0; + position: absolute; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent { + background: #f6f6f6; + border-bottom: 1px solid #cecdcd; + padding: 0; + width: 100%; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent a { + text-decoration: none !important; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active:before, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active:hover:before { + background: #0099d3; + bottom: -1px; + content: ''; + display: block; + height: 2px; + left: 20px; + position: absolute; + right: 20px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active > a, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active > a:hover, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active:hover > a { + color: #0099d3 !important; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.active .active > a { + color: #fff; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu:hover > .dropdown-menu { + display: none; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu.open > .dropdown-menu { + display: block; + left: 20px; + margin-top: 1px; + top: 100%; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle { + color: #222222; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle:after { + border-top-color: #222222; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu > .dropdown-toggle { + padding-right: 35px !important; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.dropdown-submenu > .dropdown-toggle:after { + position: absolute; + right: 20px; + top: 10px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li:hover:before, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.open:before { + background: #aaa; + bottom: -1px; + content: ''; + display: block; + height: 2px; + left: 20px; + position: absolute; + right: 20px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li:hover > a, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.open > a { + color: #222222; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li:hover > a:after, + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li.open > a:after { + border-top-color: #222222; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li > a { + background-color: transparent; + display: block; + line-height: 1; + padding: 9px 20px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li > a.dropdown-toggle { + padding-right: 35px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li > a.dropdown-toggle:after { + font-size: 15px; + position: absolute; + right: 20px; + top: 9px; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li > a:hover { + color: #222222; + } + .navbar-pf .navbar-primary.persistent-secondary > li > .navbar-persistent > li a { + color: #4d5258; + } + .navbar-pf .navbar-primary > li > a { + border-bottom: 1px solid transparent; + border-top: 1px solid transparent; + position: relative; + margin: -1px 0 0; + } + .navbar-pf .navbar-primary > li > a:hover { + background-color: #4b5053; + border-top-color: #949699; + color: #dbdada; + background-image: -webkit-linear-gradient(top, #5c6165 0%, #4b5053 100%); + background-image: -o-linear-gradient(top, #5c6165 0%, #4b5053 100%); + background-image: linear-gradient(to bottom, #5c6165 0%, #4b5053 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5c6165', endColorstr='#ff4b5053', GradientType=0); + } + .navbar-pf .navbar-primary > .active > a, + .navbar-pf .navbar-primary > .active > a:hover, + .navbar-pf .navbar-primary > .active > a:focus, + .navbar-pf .navbar-primary > .open > a, + .navbar-pf .navbar-primary > .open > a:hover, + .navbar-pf .navbar-primary > .open > a:focus { + background-color: #64686c; + border-bottom-color: #64686c; + border-top-color: #949699; + -webkit-box-shadow: none; + box-shadow: none; + color: #fff; + background-image: -webkit-linear-gradient(top, #72757a 0%, #64686c 100%); + background-image: -o-linear-gradient(top, #72757a 0%, #64686c 100%); + background-image: linear-gradient(to bottom, #72757a 0%, #64686c 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff72757a', endColorstr='#ff64686c', GradientType=0); + } + .navbar-pf .navbar-primary li.context.context-bootstrap-select .filter-option { + max-width: 160px; + text-overflow: ellipsis; + } + .navbar-pf .navbar-primary li.context.dropdown { + border-bottom: 0; + } + .navbar-pf .navbar-primary li.context > a, + .navbar-pf .navbar-primary li.context.context-bootstrap-select { + background-color: #505458; + border-bottom-color: #65696d; + border-right: 1px solid #65696d; + border-top-color: #64696d; + font-weight: 600; + background-image: -webkit-linear-gradient(top, #585d61 0%, #505458 100%); + background-image: -o-linear-gradient(top, #585d61 0%, #505458 100%); + background-image: linear-gradient(to bottom, #585d61 0%, #505458 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff585d61', endColorstr='#ff505458', GradientType=0); + } + .navbar-pf .navbar-primary li.context > a:hover, + .navbar-pf .navbar-primary li.context.context-bootstrap-select:hover { + background-color: #5a5e62; + border-bottom-color: #6e7276; + border-right-color: #6e7276; + border-top-color: #6c7276; + background-image: -webkit-linear-gradient(top, #62676b 0%, #5a5e62 100%); + background-image: -o-linear-gradient(top, #62676b 0%, #5a5e62 100%); + background-image: linear-gradient(to bottom, #62676b 0%, #5a5e62 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62676b', endColorstr='#ff5a5e62', GradientType=0); + } + .navbar-pf .navbar-primary li.context.open > a { + background-color: #65696d; + border-bottom-color: #6e7276; + border-right-color: #777a7e; + border-top-color: #767a7e; + background-image: -webkit-linear-gradient(top, #6b7175 0%, #65696d 100%); + background-image: -o-linear-gradient(top, #6b7175 0%, #65696d 100%); + background-image: linear-gradient(to bottom, #6b7175 0%, #65696d 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6b7175', endColorstr='#ff65696d', GradientType=0); + } + .navbar-pf .navbar-utility { + border-bottom: 0; + font-size: 11px; + position: absolute; + right: 0; + top: 0; + } + .navbar-pf .navbar-utility > .active > a, + .navbar-pf .navbar-utility > .active > a:hover, + .navbar-pf .navbar-utility > .active > a:focus, + .navbar-pf .navbar-utility > .open > a, + .navbar-pf .navbar-utility > .open > a:hover, + .navbar-pf .navbar-utility > .open > a:focus { + background: #5b6165; + color: #fff; + } + .navbar-pf .navbar-utility > li > a { + border-left: 1px solid #53565b; + color: #fff !important; + padding: 7px 10px; + } + .navbar-pf .navbar-utility > li > a:hover { + background: #4a5053; + border-left-color: #636466; + } + .navbar-pf .navbar-utility > li.open > a { + border-left-color: #6c6e70; + color: #fff !important; + } + .navbar-pf .navbar-utility li.dropdown > .dropdown-toggle { + padding-left: 26px; + } + .navbar-pf .navbar-utility li.dropdown > .dropdown-toggle .pficon-user { + left: 10px; + top: 7px; + } + .navbar-pf .navbar-utility .open .dropdown-menu { + left: auto; + right: 0; + } + .navbar-pf .navbar-utility .open .dropdown-menu .dropdown-menu { + left: auto; + right: 100%; + } + .navbar-pf .open .dropdown-menu { + border-top-width: 0 !important; + } + .navbar-pf .open.bootstrap-select .dropdown-menu, + .navbar-pf .open .dropdown-submenu > .dropdown-menu { + border-top-width: 1px !important; + } +} +@media (max-width: 360px) { + .navbar-pf .navbar-brand { + margin-left: 10px; + width: 75%; + } + .navbar-pf .navbar-brand img { + height: auto; + max-width: 100%; + } + .navbar-pf .navbar-toggle { + padding-left: 0; + } +} +.navbar-pf-alt { + background-color: #030303; + background-image: url("../img/bg-navbar-pf-alt.svg"); + background-repeat: no-repeat; + background-size: auto 100%; + border: none; + border-radius: 0; + border-top: 0 solid #199dde; + margin-bottom: 0; +} +.navbar-pf-alt .infotip.bottom-right .arrow { + left: 90%; +} +.layout-pf-alt-fixed .navbar-pf-alt { + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 1030; +} +.navbar-pf-alt .nav.navbar-nav > li > .dropdown-menu.infotip { + margin-top: 0; +} +.navbar-pf-alt .nav .nav-item-iconic { + cursor: pointer; + line-height: 1; + max-height: 60px; + padding: 22px 12px; + position: relative; +} +.navbar-pf-alt .nav .nav-item-iconic:hover, +.navbar-pf-alt .nav .nav-item-iconic:focus { + background-color: transparent; +} +.navbar-pf-alt .nav .nav-item-iconic:hover .caret, +.navbar-pf-alt .nav .nav-item-iconic:focus .caret, +.navbar-pf-alt .nav .nav-item-iconic:hover .fa, +.navbar-pf-alt .nav .nav-item-iconic:focus .fa, +.navbar-pf-alt .nav .nav-item-iconic:hover .glyphicon, +.navbar-pf-alt .nav .nav-item-iconic:focus .glyphicon, +.navbar-pf-alt .nav .nav-item-iconic:hover .pf-icon, +.navbar-pf-alt .nav .nav-item-iconic:focus .pf-icon { + color: #fff; +} +.navbar-pf-alt .nav .nav-item-iconic .badge { + background-color: #cc0000; + border-radius: 20px; + color: #fff; + cursor: pointer; + font-size: 9px; + font-weight: 700; + margin: 0 0 -11px -12px; + min-width: 0; + padding: 2px 4px; +} +.navbar-pf-alt .nav .nav-item-iconic .caret, +.navbar-pf-alt .nav .nav-item-iconic .fa, +.navbar-pf-alt .nav .nav-item-iconic .pf-icon { + color: #cfcfcf; + font-size: 16px; +} +.navbar-pf-alt .nav .nav-item-iconic .caret { + font-size: 12px; + width: auto; +} +.navbar-pf-alt .nav .open > .nav-item-iconic, +.navbar-pf-alt .nav .open > .nav-item-iconic:hover, +.navbar-pf-alt .nav .open > .nav-item-iconic:focus { + background: transparent; +} +.navbar-pf-alt .nav .open > .nav-item-iconic .caret, +.navbar-pf-alt .nav .open > .nav-item-iconic:hover .caret, +.navbar-pf-alt .nav .open > .nav-item-iconic:focus .caret, +.navbar-pf-alt .nav .open > .nav-item-iconic .fa, +.navbar-pf-alt .nav .open > .nav-item-iconic:hover .fa, +.navbar-pf-alt .nav .open > .nav-item-iconic:focus .fa, +.navbar-pf-alt .nav .open > .nav-item-iconic .pf-icon, +.navbar-pf-alt .nav .open > .nav-item-iconic:hover .pf-icon, +.navbar-pf-alt .nav .open > .nav-item-iconic:focus .pf-icon { + color: #fff; +} +.navbar-pf-alt .navbar-brand { + color: #fff; + height: auto; + margin: 0 0 0 25px; + min-height: 35px; + padding: 18px 0 22px; +} +.navbar-pf-alt .navbar-brand .navbar-brand-name { + display: inline; + margin: 0 15px 0 0; +} +@media (max-width: 355px) { + .navbar-pf-alt .navbar-brand .navbar-brand-name { + display: none; + } +} +.navbar-pf-alt .navbar-brand .navbar-brand-icon { + display: inline; + margin: 0 15px 0 0; +} +.navbar-pf-alt .navbar-iconic { + margin-right: 0; +} +.navbar-pf-alt .navbar-toggle { + border: 0; + display: block; + float: left; + margin: 14px 15px; +} +.navbar-pf-alt .navbar-toggle:hover .icon-bar, +.navbar-pf-alt .navbar-toggle:focus .icon-bar { + background: #fff; +} +.navbar-pf-alt .navbar-toggle + .navbar-brand { + margin-left: 0; +} +.navbar-pf-alt .navbar-toggle .icon-bar { + background: #cfcfcf; +} +.navbar-pf-vertical { + background-color: #1d1d1d; + border: none; + border-radius: 0; + border-top: 2px solid #199dde; + margin-bottom: 0; +} +.navbar-pf-vertical .infotip.bottom-right .arrow { + left: 90%; +} +.layout-pf-fixed .navbar-pf-vertical { + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 1030; +} +.navbar-pf-vertical .nav.navbar-nav > li > .dropdown-menu.infotip { + margin-top: 0; +} +.navbar-pf-vertical .nav .nav-item-iconic { + cursor: pointer; + line-height: 1; + max-height: 58px; + padding: 21px 12px; + position: relative; +} +.navbar-pf-vertical .nav .nav-item-iconic:hover, +.navbar-pf-vertical .nav .nav-item-iconic:focus { + background-color: transparent; +} +.navbar-pf-vertical .nav .nav-item-iconic:hover .caret, +.navbar-pf-vertical .nav .nav-item-iconic:focus .caret, +.navbar-pf-vertical .nav .nav-item-iconic:hover .fa, +.navbar-pf-vertical .nav .nav-item-iconic:focus .fa, +.navbar-pf-vertical .nav .nav-item-iconic:hover .glyphicon, +.navbar-pf-vertical .nav .nav-item-iconic:focus .glyphicon, +.navbar-pf-vertical .nav .nav-item-iconic:hover .pf-icon, +.navbar-pf-vertical .nav .nav-item-iconic:focus .pf-icon { + color: #fff; +} +.navbar-pf-vertical .nav .nav-item-iconic .badge { + background-color: #cc0000; + border-radius: 20px; + color: #fff; + cursor: pointer; + font-size: 9px; + font-weight: 700; + margin: 0 0 -11px -12px; + min-width: 0; + padding: 2px 4px; +} +.navbar-pf-vertical .nav .nav-item-iconic .caret, +.navbar-pf-vertical .nav .nav-item-iconic .fa, +.navbar-pf-vertical .nav .nav-item-iconic .pf-icon { + color: #cfcfcf; + font-size: 16px; +} +.navbar-pf-vertical .nav .nav-item-iconic .caret { + font-size: 12px; + width: auto; +} +.navbar-pf-vertical .nav .open > .nav-item-iconic, +.navbar-pf-vertical .nav .open > .nav-item-iconic:hover, +.navbar-pf-vertical .nav .open > .nav-item-iconic:focus { + background: transparent; +} +.navbar-pf-vertical .nav .open > .nav-item-iconic .caret, +.navbar-pf-vertical .nav .open > .nav-item-iconic:hover .caret, +.navbar-pf-vertical .nav .open > .nav-item-iconic:focus .caret, +.navbar-pf-vertical .nav .open > .nav-item-iconic .fa, +.navbar-pf-vertical .nav .open > .nav-item-iconic:hover .fa, +.navbar-pf-vertical .nav .open > .nav-item-iconic:focus .fa, +.navbar-pf-vertical .nav .open > .nav-item-iconic .pf-icon, +.navbar-pf-vertical .nav .open > .nav-item-iconic:hover .pf-icon, +.navbar-pf-vertical .nav .open > .nav-item-iconic:focus .pf-icon { + color: #fff; +} +.navbar-pf-vertical .navbar-brand { + color: #fff; + height: auto; + margin: 0 0 0 25px; + min-height: 35px; + padding: 11px 0 12px; +} +.navbar-pf-vertical .navbar-brand .navbar-brand-name { + display: inline; + margin: 0 15px 0 0; +} +@media (max-width: 480px) { + .navbar-pf-vertical .navbar-brand .navbar-brand-name { + display: none; + } +} +.navbar-pf-vertical .navbar-brand .navbar-brand-icon { + display: inline; + margin: 0 15px 0 0; +} +.navbar-pf-vertical .navbar-iconic { + margin-right: 0; +} +.navbar-pf-vertical .navbar-toggle { + border: 0; + display: block; + float: left; + margin: 13px 15px; +} +.navbar-pf-vertical .navbar-toggle:hover .icon-bar, +.navbar-pf-vertical .navbar-toggle:focus .icon-bar { + background: #fff; +} +.navbar-pf-vertical .navbar-toggle + .navbar-brand { + margin-left: 0; +} +.navbar-pf-vertical .navbar-toggle .icon-bar { + background: #cfcfcf; +} +.layout-pf-alt-fixed.transitions .nav-pf-vertical-alt { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf-alt-fixed.transitions .nav-pf-vertical-alt.collapsed .list-group-item .list-group-item-value { + transition: opacity 0s .1s, opacity .1s linear; +} +.layout-pf-alt-fixed.transitions .nav-pf-vertical-alt .list-group-item .badge { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf-alt-fixed.transitions .nav-pf-vertical-alt .list-group-item .list-group-item-value { + transition: opacity 0.5s ease-out; + transition-delay: .15s; +} +.nav-pf-vertical-alt { + background: #fff; +} +.ie9.layout-pf-alt-fixed .nav-pf-vertical-alt { + box-sizing: content-box; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt { + border-right: 1px solid #d0d0d0; + bottom: 0; + overflow-x: hidden; + overflow-y: auto; + left: 0; + position: fixed; + top: 60px; + width: 250px; + z-index: 1030; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt.collapsed { + width: 75px !important; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt.collapsed .list-group-item .badge { + padding: 2px 3px; + right: 21px; + top: 36px; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt.collapsed .list-group-item .list-group-item-value { + opacity: 0; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt.hidden { + display: none; +} +.layout-pf-alt-fixed .nav-pf-vertical-alt.hidden.show-mobile-nav { + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + display: block !important; +} +.layout-pf-alt-fixed-with-footer .nav-pf-vertical-alt { + bottom: 37px; +} +.nav-pf-vertical-alt .list-group { + border-top: 0; + margin-bottom: 0; +} +.nav-pf-vertical-alt .list-group-item { + padding: 0; +} +.nav-pf-vertical-alt .list-group-item a { + color: #333333; + display: block; + font-size: 14px; + height: 63px; + padding: 17px 20px 17px 25px; + position: relative; + white-space: nowrap; +} +.nav-pf-vertical-alt .list-group-item a:focus { + color: #333333; + text-decoration: none; +} +.nav-pf-vertical-alt .list-group-item a:hover { + color: #39a5dc; + text-decoration: none; +} +.nav-pf-vertical-alt .list-group-item.active { + background-color: #fff; + border-color: #f2f2f2; +} +.nav-pf-vertical-alt .list-group-item.active:before { + background: #39a5dc; + content: " "; + display: block; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 5px; +} +.nav-pf-vertical-alt .list-group-item.active a { + color: #39a5dc; +} +.nav-pf-vertical-alt .list-group-item .badge { + background: #333333; + border: 1px solid #fff; + border-radius: 3px; + color: #fff; + font-weight: 700; + font-size: 9px; + padding: 5px; + position: absolute; + right: 15px; + text-align: center; + top: 21px; +} +.nav-pf-vertical-alt .list-group-item .badge.notifications { + background: #cc0000; +} +.nav-pf-vertical-alt .list-group-item .fa, +.nav-pf-vertical-alt .list-group-item .glyphicon, +.nav-pf-vertical-alt .list-group-item .pficon { + float: left; + font-size: 18px; + line-height: 30px; + margin-right: 10px; + text-align: center; + width: 18px; +} +.nav-pf-vertical-alt .list-group-item .list-group-item-value { + display: inline-block; + line-height: 30px; + opacity: 1; + overflow: hidden; + text-overflow: ellipsis; + width: 140px; +} +.nav-pf-vertical-alt .list-group-item-separator { + border-top-width: 5px; +} +.sidebar-pf .nav-pf-vertical-alt { + margin-left: -20px; + margin-right: -20px; +} +.search-pf.has-button { + border-collapse: separate; + display: table; +} +.search-pf.has-button .form-group { + display: table-cell; + width: 100%; +} +.search-pf.has-button .form-group .btn { + -webkit-box-shadow: none; + box-shadow: none; + float: left; + margin-left: -1px; +} +.search-pf.has-button .form-group .btn.btn-lg { + font-size: 14.5px; +} +.search-pf.has-button .form-group .btn.btn-sm { + font-size: 10.7px; +} +.search-pf.has-button .form-group .form-control { + float: left; +} +.search-pf .has-clear .clear { + background: transparent; + background: rgba(255, 255, 255, 0); + border: 0; + height: 25px; + line-height: 1; + padding: 0; + position: absolute; + right: 1px; + top: 1px; + width: 28px; +} +.search-pf .has-clear .clear:focus { + outline: none; +} +.search-pf .has-clear .form-control { + padding-right: 30px; +} +.search-pf .has-clear .form-control::-ms-clear { + display: none; +} +.search-pf .has-clear .input-lg + .clear { + height: 31px; + width: 28px; +} +.search-pf .has-clear .input-sm + .clear { + height: 20px; + width: 28px; +} +.search-pf .has-clear .input-sm + .clear span { + font-size: 10px; +} +.search-pf .has-clear .search-pf-input-group { + position: relative; +} +.sidebar-header { + border-bottom: 1px solid #e9e9e9; + padding-bottom: 11px; + margin: 50px 0 20px; +} +.sidebar-header .actions { + margin-top: -2px; +} +.sidebar-pf .sidebar-header + .list-group { + border-top: 0; + margin-top: -10px; +} +.sidebar-pf .sidebar-header + .list-group .list-group-item { + background: transparent; + border-color: #e9e9e9; + padding-left: 0; +} +.sidebar-pf .sidebar-header + .list-group .list-group-item-heading { + font-size: 12px; +} +.sidebar-pf .nav-category h2 { + color: #999999; + font-size: 12px; + font-weight: 400; + line-height: 21px; + margin: 0; + padding: 8px 0; +} +.sidebar-pf .nav-category + .nav-category { + margin-top: 10px; +} +.sidebar-pf .nav-pills > li.active > a { + background: #0099d3 !important; + border-color: #0076b7 !important; + color: #fff; +} +@media (min-width: 768px) { + .sidebar-pf .nav-pills > li.active > a:after { + content: "\f105"; + font-family: "FontAwesome"; + display: block; + position: absolute; + right: 10px; + top: 1px; + } +} +.sidebar-pf .nav-pills > li.active > a .fa { + color: #fff; +} +.sidebar-pf .nav-pills > li > a { + border-bottom: 1px solid transparent; + border-radius: 0; + border-top: 1px solid transparent; + color: #333333; + font-size: 13px; + line-height: 21px; + padding: 1px 20px; +} +.sidebar-pf .nav-pills > li > a:hover { + background: #d4edfa; + border-color: #b3d3e7; +} +.sidebar-pf .nav-pills > li > a .fa { + color: #6a7079; + font-size: 15px; + margin-right: 10px; + text-align: center; + vertical-align: middle; + width: 15px; +} +.sidebar-pf .nav-stacked { + margin-left: -20px; + margin-right: -20px; +} +.sidebar-pf .nav-stacked li + li { + margin-top: 0; +} +.sidebar-pf .panel { + background: transparent; +} +.sidebar-pf .panel-body { + padding: 6px 20px; +} +.sidebar-pf .panel-body .nav-pills > li > a { + padding-left: 37px; +} +.sidebar-pf .panel-heading { + padding: 9px 20px; +} +.sidebar-pf .panel-title { + font-size: 12px; +} +.sidebar-pf .panel-title > a:before { + display: inline-block; + margin-left: 1px; + margin-right: 4px; + width: 9px; +} +.sidebar-pf .panel-title > a.collapsed:before { + margin-left: 3px; + margin-right: 2px; +} +@media (min-width: 767px) { + .sidebar-header-bleed-left { + margin-left: -20px; + } + .sidebar-header-bleed-left > h2 { + margin-left: 20px; + } + .sidebar-header-bleed-right { + margin-right: -20px; + } + .sidebar-header-bleed-right .actions { + margin-right: 20px; + } + .sidebar-header-bleed-right > h2 { + margin-right: 20px; + } + .sidebar-header-bleed-right + .list-group { + margin-right: -20px; + } + .sidebar-pf .panel-group .panel-default, + .sidebar-pf .treeview { + border-left: 0; + border-right: 0; + margin-left: -20px; + margin-right: -20px; + } + .sidebar-pf .treeview { + margin-top: 5px; + } + .sidebar-pf .treeview .list-group-item { + padding-left: 20px; + padding-right: 20px; + } + .sidebar-pf .treeview .list-group-item.node-selected:after { + content: "\f105"; + font-family: "FontAwesome"; + display: block; + position: absolute; + right: 10px; + top: 1px; + } +} +@media (min-width: 768px) { + .sidebar-pf { + background: #fafafa; + } + .sidebar-pf.sidebar-pf-left { + border-right: 1px solid #d0d0d0; + } + .sidebar-pf.sidebar-pf-right { + border-left: 1px solid #d0d0d0; + } + .sidebar-pf > .nav-category, + .sidebar-pf > .nav-stacked { + margin-top: 5px; + } +} +@-webkit-keyframes rotation { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(359deg); + } +} +@keyframes rotation { + from { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} +.spinner { + -webkit-animation: rotation .6s infinite linear; + animation: rotation .6s infinite linear; + border-bottom: 4px solid rgba(0, 0, 0, 0.25); + border-left: 4px solid rgba(0, 0, 0, 0.25); + border-right: 4px solid rgba(0, 0, 0, 0.25); + border-radius: 100%; + border-top: 4px solid rgba(0, 0, 0, 0.75); + height: 24px; + margin: 0 auto; + position: relative; + width: 24px; +} +.spinner.spinner-inline { + display: inline-block; + margin-right: 3px; +} +.spinner.spinner-lg { + border-width: 5px; + height: 30px; + width: 30px; +} +.spinner.spinner-sm { + border-width: 3px; + height: 18px; + width: 18px; +} +.spinner.spinner-xs { + border-width: 2px; + height: 12px; + width: 12px; +} +.spinner.spinner-inverse { + border-bottom-color: rgba(255, 255, 255, 0.25); + border-left-color: rgba(255, 255, 255, 0.25); + border-right-color: rgba(255, 255, 255, 0.25); + border-top-color: rgba(255, 255, 255, 0.75); +} +.ie9 .spinner { + background: url("../img/spinner.gif") no-repeat; + border: 0; +} +.ie9 .spinner.spinner-inverse { + background-image: url("../img/spinner-inverse.gif"); +} +.ie9 .spinner.spinner-inverse-lg { + background-image: url("../img/spinner-inverse-lg.gif"); +} +.ie9 .spinner.spinner-inverse-sm { + background-image: url("../img/spinner-inverse-sm.gif"); +} +.ie9 .spinner.spinner-inverse-xs { + background-image: url("../img/spinner-inverse-xs.gif"); +} +.ie9 .spinner.spinner-lg { + background-image: url("../img/spinner-lg.gif"); +} +.ie9 .spinner.spinner-sm { + background-image: url("../img/spinner-sm.gif"); +} +.ie9 .spinner.spinner-xs { + background-image: url("../img/spinner-xs.gif"); +} +.prettyprint .atn, +.prettyprint .com, +.prettyprint .fun, +.prettyprint .var { + color: #3f9c35; +} +.prettyprint .atv, +.prettyprint .str { + color: #a30000; +} +.prettyprint .clo, +.prettyprint .dec, +.prettyprint .kwd, +.prettyprint .opn, +.prettyprint .pln, +.prettyprint .pun { + color: #333333; +} +.prettyprint .lit, +.prettyprint .tag, +.prettyprint .typ { + color: #006e9c; +} +.prettyprint ol.linenums { + margin-bottom: 0; +} +.bootstrap-datetimepicker-widget a[data-action] { + border: 0; + box-shadow: none; + color: #333333; + display: block; + padding-bottom: 4px; + padding-top: 4px; +} +.bootstrap-datetimepicker-widget a[data-action]:hover { + color: #0099d3; +} +.bootstrap-datetimepicker-widget.dropdown-menu { + left: 0!important; + padding: 0; + top: 23px!important; + width: calc(100% - 25px); +} +.bootstrap-datetimepicker-widget.dropdown-menu:before, +.bootstrap-datetimepicker-widget.dropdown-menu:after { + content: none; +} +.bootstrap-datetimepicker-widget .timepicker-hour { + width: 100%; +} +.bootstrap-datetimepicker-widget .timepicker-hour:after { + content: ":"; + float: right; +} +.timepicker-hours table td, +.timepicker-minutes table td { + font-weight: bold; + line-height: 30px; + height: 30px; +} +.timepicker-hours table td:hover, +.timepicker-minutes table td:hover { + color: #0099d3; +} +.timepicker-hours .table-condensed > tbody > tr > td, +.timepicker-minutes .table-condensed > tbody > tr > td { + padding: 0; +} +.time-picker-pf .input-group-addon .fa, +.time-picker-pf .input-group-addon .pficon { + width: 12px; +} +.time-picker-pf .input-group-addon:not(.active) { + box-shadow: none; +} +.timepicker-picker table td span, +.timepicker-picker table td a span { + height: 24px; + line-height: 24px; + margin: 0; + width: 100%; +} +.timepicker-picker .table-condensed > tbody > tr > td { + height: 25px; + line-height: 18px; + padding: 0; +} +.timepicker-picker button[data-action] { + padding-bottom: 0; + padding-top: 0; +} +.timepicker-picker .separator { + display: none; +} +.timepicker-picker tr:nth-child(2) td { + background-color: #d4edfa; + border-color: #b3d3e7; + border-style: solid; + border-width: 1px; + border-left: 0; + border-right: 0; +} +.toast-pf { + background-color: rgba(255, 255, 255, 0.94); + border-color: #b1b1b1; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); + padding-left: 68px; + /* Medium devices (desktops, 992px and up) */ +} +.toast-pf.alert-danger > .pficon { + background-color: #cc0000; +} +.toast-pf.alert-info > .pficon { + background-color: #8b8d8f; +} +.toast-pf.alert-success > .pficon { + background-color: #3f9c35; +} +.toast-pf.alert-warning > .pficon { + background-color: #ec7a08; +} +.toast-pf .dropdown-kebab-pf { + margin-left: 10px; +} +.toast-pf > .pficon { + background-color: #4d5258; + bottom: -1px; + box-shadow: 2px 0 5px -2px rgba(0, 0, 0, 0.2); + left: -1px; + padding-top: 10px; + text-align: center; + top: -1px; + width: 53px; +} +.toast-pf > .pficon:before { + color: rgba(255, 255, 255, 0.74); +} +.toast-pf .toast-pf-action { + margin-left: 15px; +} +@media (min-width: 992px) { + .toast-pf { + display: inline-block; + } +} +@media (min-width: 992px) { + .toast-pf-max-width { + max-width: 31.1% ; + } +} +.toast-pf-top-right { + left: 20px; + position: absolute; + right: 20px; + top: 12px; + z-index: 1035; + /* Medium devices (desktops, 992px and up) */ +} +@media (min-width: 992px) { + .toast-pf-top-right { + left: auto; + } +} +.toolbar-pf { + background: #fff; + border-bottom: 1px solid #d0d0d0; + box-shadow: 0 1px 0px rgba(0, 0, 0, 0.045); + padding-top: 10px; +} +.toolbar-pf .form-group { + margin-bottom: 10px; +} +@media (min-width: 768px) { + .toolbar-pf .form-group { + border-right: 1px solid #d0d0d0; + display: table-cell; + float: left; + margin-bottom: 0; + padding-left: 20px; + padding-right: 20px; + } +} +.toolbar-pf .form-group:last-child { + margin-bottom: 0; +} +.toolbar-pf .form-group .btn + .btn, +.toolbar-pf .form-group .btn-group + .btn, +.toolbar-pf .form-group .btn + .btn-group, +.toolbar-pf .form-group .btn-group + .btn-group { + margin-left: 5px; +} +.toolbar-pf .form-group .btn + .btn-link, +.toolbar-pf .form-group .btn-group + .btn-link, +.toolbar-pf .form-group .btn + .dropdown, +.toolbar-pf .form-group .btn-group + .dropdown { + margin-left: 10px; +} +.toolbar-pf .form-group .btn-link { + color: #222222; + font-size: 16px; + line-height: 1; + padding: 4px 0; +} +.toolbar-pf .form-group .btn-link:active, +.toolbar-pf .form-group .btn-link:focus, +.toolbar-pf .form-group .btn-link:hover { + color: #0099d3; +} +.toolbar-pf-actions { + display: table; + width: 100%; +} +@media (min-width: 768px) { + .toolbar-pf-actions .toolbar-pf-filter { + padding-left: 0; + width: 25%; + } +} +.toolbar-pf-actions .toolbar-pf-view-selector { + font-size: 16px; +} +@media (min-width: 768px) { + .toolbar-pf-actions .toolbar-pf-view-selector { + border-right: 0; + float: right; + padding-right: 0; + } +} +.toolbar-pf-actions .toolbar-pf-view-selector .active a { + color: #0099d3; + cursor: default; +} +.toolbar-pf-actions .toolbar-pf-view-selector a { + color: #222222; +} +.toolbar-pf-actions .toolbar-pf-view-selector a:hover { + color: #0099d3; +} +.toolbar-pf-actions .toolbar-pf-view-selector .list-inline { + margin-bottom: 0; +} +.toolbar-pf-results { + border-top: 1px solid #d0d0d0; + margin-top: 10px; +} +.toolbar-pf-results h5, +.toolbar-pf-results p, +.toolbar-pf-results ul { + display: inline-block; + line-height: 26.66666667px; + margin-bottom: 0; + margin-top: 0; +} +@media (min-width: 768px) { + .toolbar-pf-results h5, + .toolbar-pf-results p, + .toolbar-pf-results ul { + line-height: 40px; + } +} +.toolbar-pf-results h5 { + font-weight: 700; + margin-right: 20px; +} +.toolbar-pf-results .label { + font-size: 11px; +} +.toolbar-pf-results .label a { + color: #fff; + display: inline-block; + margin-left: 5px; +} +.toolbar-pf-results .list-inline { + margin: 0 10px 0 5px; +} +.toolbar-pf-results .list-inline li { + padding-left: 0; + padding-right: 0; +} +.layout-pf-fixedafdaf.transitions .nav-pf-vertical { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf-fixedafdaf.transitions .nav-pf-vertical.collapsed .list-group-item .list-group-item-value { + transition: opacity 0s .1s, opacity .1s linear; +} +.layout-pf-fixedafdaf.transitions .nav-pf-vertical .list-group-item .badge { + transition: all 0.2s cubic-bezier(0.35, 0, 0.25, 1); +} +.layout-pf-fixedafdaf.transitions .nav-pf-vertical .list-group-item .list-group-item-value { + transition: opacity 0.5s ease-out; + transition-delay: .15s; +} +.nav-pf-vertical { + background: #292e34; + border-right: 1px solid #262626; + bottom: 0; + overflow-x: hidden; + overflow-y: auto; + left: 0; + position: fixed; + top: 60px; + width: 200px; + z-index: 1030; +} +.layout-pf-fixed-with-footer .nav-pf-vertical { + bottom: 37px; +} +.ie9.layout-pf-fixed .nav-pf-vertical { + box-sizing: content-box; +} +.nav-pf-vertical.collapsed:not(.nav-pf-vertical-with-secondary-nav) { + display: none; +} +.nav-pf-vertical.collapsed { + width: 75px; +} +.nav-pf-vertical.collapsed.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item > a { + margin-right: 0; + width: 75px; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item > a > .list-group-item-value { + display: none; + width: 0; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary.active > a, +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary > a { + width: 75px; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary.active > a:after, +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary > a:after { + right: 10px; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary:hover > a { + width: 76px; + z-index: 1032; +} +.nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary:hover > a:after { + right: 11px; +} +@media (min-width: 1200px) { + .nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary.active > a, + .nav-pf-vertical.collapsed > .list-group > .list-group-item.persistent-secondary > a { + width: 76px; + } +} +.nav-pf-vertical.hidden-icons-pf { + width: 176px; +} +.nav-pf-vertical.hidden-icons-pf.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item > a { + width: 176px; +} +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item > a .fa, +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item > a .glyphicon, +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item > a .pficon { + display: none; +} +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item.persistent-secondary.active > a, +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item.persistent-secondary:hover > a { + width: 177px; + z-index: 1032; +} +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item.persistent-secondary.active > a:after, +.nav-pf-vertical.hidden-icons-pf > .list-group > .list-group-item.persistent-secondary:hover > a:after { + right: 21px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav .nav-pf-persistent-secondary { + left: 176px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav .nav-pf-persistent-secondary.collapsed-secondary-nav-pf { + left: 0; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.collapsed { + display: none; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf { + width: 426px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf.show-mobile-nav { + width: 176px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.secondary-visible-pf { + width: 426px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.hidden-icons-pf.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.show-mobile-nav { + width: 250px; +} +.nav-pf-vertical.hidden.show-mobile-nav { + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + display: block !important; +} +.nav-pf-vertical.hidden > .list-group > .list-group-item.persistent-secondary:hover > a { + z-index: 1030; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.collapsed.hover-secondary-nav-pf { + width: 325px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.collapsed.hover-secondary-nav-pf.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf { + width: 450px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf.collapsed-secondary-nav-pf { + width: 250px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.hover-secondary-nav-pf.show-mobile-nav { + width: 200px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf { + width: 200px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed { + width: 75px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.show-mobile-nav { + width: 250px; +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed-secondary-nav-pf { + width: 250px; +} +@media (min-width: 1200px) { + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf { + width: 450px; + } + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed-secondary-nav-pf { + width: 250px; + } + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed { + width: 75px; + } + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed.hover-secondary-nav-pf, + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed.secondary-visible-pf { + width: 325px; + } + .nav-pf-vertical.nav-pf-vertical-with-secondary-nav.secondary-visible-pf.collapsed.collapsed-secondary-nav-pf { + width: 250px; + } +} +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.collapsed-secondary-nav-pf > .list-group > .list-group-item.persistent-secondary.active > a, +.nav-pf-vertical.nav-pf-vertical-with-secondary-nav.collapsed-secondary-nav-pf > .list-group > .list-group-item.persistent-secondary:hover > a { + z-index: 1030; +} +.layout-pf-fixed-with-footer .nav-pf-vertical { + bottom: 37px; +} +.nav-pf-vertical > .list-group { + border-top: 0; + margin-bottom: 0; +} +.nav-pf-vertical > .list-group > .list-group-item { + background-color: transparent; + border-color: #000000; + padding: 0; +} +.nav-pf-vertical > .list-group > .list-group-item > a { + background-color: transparent; + color: #dbdada; + display: block; + font-size: 14px; + font-weight: 400; + height: 63px; + outline: 0; + padding: 17px 20px 17px 25px; + position: relative; + white-space: nowrap; + width: 200px; +} +.nav-pf-vertical > .list-group > .list-group-item > a .fa, +.nav-pf-vertical > .list-group > .list-group-item > a .glyphicon, +.nav-pf-vertical > .list-group > .list-group-item > a .pficon { + color: #72767b; + float: left; + font-size: 14px; + line-height: 30px; + margin-right: 10px; + text-align: center; + width: 24px; +} +.nav-pf-vertical > .list-group > .list-group-item > a:hover, +.nav-pf-vertical > .list-group > .list-group-item > a:focus { + text-decoration: none; +} +.nav-pf-vertical > .list-group > .list-group-item.active > a, +.nav-pf-vertical > .list-group > .list-group-item:hover > a { + background-color: #393f44; + color: #fff; + font-weight: 600; +} +.nav-pf-vertical > .list-group > .list-group-item.active > a .fa, +.nav-pf-vertical > .list-group > .list-group-item:hover > a .fa, +.nav-pf-vertical > .list-group > .list-group-item.active > a .glyphicon, +.nav-pf-vertical > .list-group > .list-group-item:hover > a .glyphicon, +.nav-pf-vertical > .list-group > .list-group-item.active > a .pficon, +.nav-pf-vertical > .list-group > .list-group-item:hover > a .pficon { + color: #199dde; +} +.show-mobile-nav .nav-pf-vertical > .list-group > .list-group-item.active > a { + z-index: 1030; +} +.nav-pf-vertical > .list-group > .list-group-item.active > a:before { + background: #199dde; + content: " "; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 3px; +} +.nav-pf-vertical > .list-group > .list-group-item .list-group-item-value { + display: block; + line-height: 30px; + max-width: 120px; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; +} +.nav-pf-vertical > .list-group > .list-group-item.persistent-secondary > a:after { + color: #72767b; + content: "\f105"; + display: block; + font-family: "FontAwesome"; + font-size: 24px; + line-height: 30px; + padding: 17px 0; + position: absolute; + right: 20px; + top: 0; +} +.nav-pf-vertical > .list-group > .list-group-item.persistent-secondary.active > a, +.nav-pf-vertical > .list-group > .list-group-item.persistent-secondary:hover > a { + width: 201px; + z-index: 1032; +} +.nav-pf-vertical > .list-group > .list-group-item.persistent-secondary.active > a:after, +.nav-pf-vertical > .list-group > .list-group-item.persistent-secondary:hover > a:after { + right: 21px; +} +.collapsed-secondary-nav-pf .nav-pf-vertical > .list-group > .list-group-item.persistent-secondary.active > a, +.collapsed-secondary-nav-pf .nav-pf-vertical > .list-group > .list-group-item.persistent-secondary:hover > a { + z-index: 1030; +} +.nav-pf-vertical .list-group-item-separator { + border-top-width: 2px; + border-top-color: #000000; +} +.nav-pf-persistent-secondary { + background: #393f44; + border: 1px solid #262626; + border-bottom: none; + border-top: none; + bottom: 0; + display: none; + left: 200px; + overflow-x: hidden; + overflow-y: auto; + position: fixed; + top: 60px; + width: 250px; + z-index: 1030; +} +.secondary-visible-pf .persistent-secondary.active .nav-pf-persistent-secondary, +.secondary-visible-pf .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + display: block; +} +.secondary-visible-pf.collapsed .persistent-secondary.active .nav-pf-persistent-secondary, +.secondary-visible-pf.collapsed .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + display: none; +} +@media (min-width: 1200px) { + .secondary-visible-pf.collapsed .persistent-secondary.active .nav-pf-persistent-secondary, + .secondary-visible-pf.collapsed .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + display: block; + left: 75px; + } + .collapsed-secondary-nav-pf .secondary-visible-pf.collapsed .persistent-secondary.active .nav-pf-persistent-secondary, + .collapsed-secondary-nav-pf .secondary-visible-pf.collapsed .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + left: 0; + } +} +@media (min-width: 1200px) { + .secondary-visible-pf.collapsed.collapsed-secondary-nav-pf .persistent-secondary.active .nav-pf-persistent-secondary, + .secondary-visible-pf.collapsed.collapsed-secondary-nav-pf .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + left: 0; + } +} +.show-mobile-nav .persistent-secondary.active .nav-pf-persistent-secondary, +.show-mobile-nav .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + left: 0; + z-index: 1032; +} +.collapsed-secondary-nav-pf .persistent-secondary.active .nav-pf-persistent-secondary, +.collapsed-secondary-nav-pf .persistent-secondary.mobile-nav-item-pf .nav-pf-persistent-secondary { + display: block; + left: 0; +} +.persistent-secondary:hover .nav-pf-persistent-secondary { + display: block; + z-index: 1031; +} +.collapsed .persistent-secondary:hover .nav-pf-persistent-secondary { + left: 75px; +} +.collapsed.collapsed-secondary-nav-pf .persistent-secondary:hover .nav-pf-persistent-secondary { + left: 0; +} +@media (min-width: 1200px) { + .collapsed.collapsed-secondary-nav-pf .persistent-secondary:hover .nav-pf-persistent-secondary { + left: 0; + } + .hidden-icons-pf .collapsed.collapsed-secondary-nav-pf .persistent-secondary:hover .nav-pf-persistent-secondary { + left: 0; + } +} +.secondary-visible-pf.collapsed .persistent-secondary:hover .nav-pf-persistent-secondary { + display: block; +} +.ie9.layout-pf-fixed .nav-pf-persistent-secondary { + box-sizing: content-box; +} +.layout-pf-fixed-with-footer .nav-pf-persistent-secondary { + bottom: 37px; +} +.nav-pf-persistent-secondary .persistent-secondary-header { + color: #fff; + font-size: 16px; + margin: 18px 20px 10px 20px; +} +.nav-pf-persistent-secondary .persistent-secondary-header > a { + margin-right: 7px; +} +.nav-pf-persistent-secondary .persistent-secondary-header > a:hover, +.nav-pf-persistent-secondary .persistent-secondary-header > a:focus { + text-decoration: none; + color: #0099d3; +} +.nav-pf-persistent-secondary h5 { + color: #fff; + cursor: default; + font-size: 13px; + font-weight: 600; + margin: 30px 20px 10px 20px; +} +.nav-pf-persistent-secondary > .list-group { + border-top: 0; + margin-bottom: 0; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item { + background-color: transparent; + border: none; + padding: 0 0 5px 0; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item > a { + background-color: transparent; + color: #dbdada; + display: block; + font-size: 12px; + outline: 0; + padding: 0 15px 0 20px; + position: relative; + white-space: nowrap; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item > a:hover > .list-group-item-value { + color: #fff; + text-decoration: underline; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item.active .list-group-item-value { + background-color: #4d5258; + color: #fff; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item.active .fa, +.nav-pf-persistent-secondary > .list-group > .list-group-item.active .glyphicon, +.nav-pf-persistent-secondary > .list-group > .list-group-item.active .pficon { + color: #199dde; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item .badge-container-pf { + background-color: #292e34; + position: absolute; + right: 15px; + top: 0; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item .badge-container-pf .badge { + background: #292e34; + color: #fff; + font-size: 12px; + font-weight: 700; + float: left; + line-height: 1.66666667; + margin: 0; + padding: 0 7px; + text-align: center; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item .badge-container-pf .badge .pficon, +.nav-pf-persistent-secondary > .list-group > .list-group-item .badge-container-pf .badge .fa { + font-size: 14px; + height: 20px; + line-height: 1.66666667; + margin-right: 3px; + margin-top: -1px; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item .fa, +.nav-pf-persistent-secondary > .list-group > .list-group-item .glyphicon, +.nav-pf-persistent-secondary > .list-group > .list-group-item .pficon { + float: left; + font-size: 18px; + line-height: 30px; + margin-right: 10px; + text-align: center; + width: 18px; +} +.nav-pf-persistent-secondary > .list-group > .list-group-item .list-group-item-value { + display: inline-block; + line-height: 20px; + max-width: none; + opacity: 1; + overflow: hidden; + padding-left: 5px; + text-overflow: ellipsis; +} +.nav-pf-persistent-secondary .secondary-collapse-toggle-pf { + display: inline-block; + font-family: "FontAwesome"; + font-size: inherit; + -webkit-font-smoothing: antialiased; +} +.nav-pf-persistent-secondary .secondary-collapse-toggle-pf:before { + content: '\f190'; +} +.nav-pf-persistent-secondary .secondary-collapse-toggle-pf.collapsed:before { + content: '\f18e'; +} +.show-mobile-nav .persistent-secondary:hover .nav-pf-persistent-secondary { + display: none; +} +.show-mobile-nav .persistent-secondary.mobile-nav-item-pf:hover .nav-pf-persistent-secondary { + display: block; +} +.force-hide-secondary-nav-pf .persistent-secondary .nav-pf-persistent-secondary { + display: none !important; +} +/* RCUE-specific */ +.login-pf { + background-color: #1a1a1a; +} +@media (min-width: 768px) { + .login-pf { + background-image: url("../img/bg-login-2.png"); + background-position: 100% 100%; + background-repeat: no-repeat; + background-size: 30%; + } +} +@media (min-width: 992px) { + .login-pf { + background-size: auto; + } +} +.login-pf #badge { + margin-bottom: 50px; +} +.login-pf body { + background: transparent; +} +@media (min-width: 768px) { + .login-pf body { + background-image: url("../img/bg-login.png"); + background-repeat: no-repeat; + background-size: 30%; + height: 100%; + } +} +@media (min-width: 992px) { + .login-pf body { + background-size: auto; + } +} +.login-pf #brand { + top: -30px; +} +@media (min-width: 768px) { + .login-pf #brand { + top: -40px; + } + .login-pf #brand + .alert { + margin-top: -20px; + } +} +.login-pf .container { + padding-top: 0; +} +@media (min-width: 992px) { + .login-pf .container { + bottom: 20%; + padding-right: 120px; + } +} +/*# sourceMappingURL=rcue-additions.css.map */ \ No newline at end of file diff --git a/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css.map b/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css.map new file mode 100644 index 0000000000..d9d973355e --- /dev/null +++ b/themes/src/main/resources-product/theme/rh-sso/common/resources/lib/rcue/css/rcue-additions.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["components/patternfly/less/lib/bootstrap-combobox/combobox.less","components/patternfly/less/lib/bootstrap-datepicker/datepicker3.less","components/patternfly/less/lib/bootstrap/mixins/buttons.less","components/patternfly/less/lib/bootstrap-select/bootstrap-select.less","components/patternfly/less/lib/bootstrap-switch/bootstrap-switch.less","components/patternfly/less/lib/bootstrap/mixins/vendor-prefixes.less","components/patternfly/less/lib/bootstrap/mixins/border-radius.less","components/patternfly/less/lib/bootstrap/mixins/opacity.less","components/patternfly/less/lib/bootstrap-touchspin/jquery.bootstrap-touchspin.css","components/patternfly/less/lib/c3/c3.css","components/patternfly/less/lib/eonasdan-bootstrap-datetimepicker/_bootstrap-datetimepicker.less","components/patternfly/less/lib/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker-build.less","components/patternfly/less/blank-slate.less","components/patternfly/less/bootstrap-combobox.less","components/patternfly/less/variables.less","components/patternfly/less/mixins.less","components/patternfly/less/lib/bootstrap/mixins/gradients.less","components/patternfly/less/bootstrap-datepicker.less","components/patternfly/less/lib/bootstrap/mixins/forms.less","components/patternfly/less/bootstrap-select.less","components/patternfly/less/bootstrap-switch.less","components/patternfly/less/bootstrap-touchspin.less","components/patternfly/less/bootstrap-treeview.less","components/patternfly/less/cards.less","components/patternfly/less/charts.less","components/patternfly/less/close.less","components/patternfly/less/datatables.less","components/patternfly/less/lib/bootstrap/mixins/reset-filter.less","components/patternfly/less/lib/font-awesome/variables.less","components/patternfly/less/footer.less","components/patternfly/less/icons.less","components/patternfly/less/infotip.less","components/patternfly/less/layouts.less","components/patternfly/less/list-view.less","components/patternfly/less/lib/bootstrap/mixins/clearfix.less","components/patternfly/less/login.less","components/patternfly/less/navbar.less","components/patternfly/less/navbar-alt.less","components/patternfly/less/navbar-vertical.less","components/patternfly/less/nav-vertical-alt.less","components/patternfly/less/search.less","components/patternfly/less/sidebar.less","components/patternfly/less/spinner.less","components/patternfly/less/syntax-highlighting.less","components/patternfly/less/time-picker.less","components/patternfly/less/toast.less","components/patternfly/less/toolbar.less","components/patternfly/less/vertical-nav.less","less/login.less"],"names":[],"mappings":"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","sourcesContent":[".form-search,\n.form-inline {\n .combobox-container {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: top;\n .input-group-addon{\n width: auto;\n }\n }\n}\n\n.combobox-selected .caret {\n display: none;\n}\n\n/* :not doesn't work in IE8 */\n.combobox-container:not(.combobox-selected) .glyphicon-remove {\n display: none;\n}\n\n.typeahead-long {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.control-group.error .combobox-container{\n .add-on {\n color: #B94A48;\n border-color: #B94A48;\n }\n .caret {\n border-top-color: #B94A48;\n }\n}\n\n.control-group.warning .combobox-container {\n .add-on {\n color: #C09853;\n border-color: #C09853;\n }\n .caret {\n border-top-color: #C09853;\n }\n}\n\n.control-group.success .combobox-container{\n .add-on {\n color: #468847;\n border-color: #468847;\n }\n .caret {\n border-top-color: #468847;\n }\n}\n",".datepicker {\n\tpadding: 4px;\n\tborder-radius: 4px;\n\t&-inline {\n\t\twidth: 220px;\n\t}\n\tdirection: ltr;\n\t&&-rtl {\n\t\tdirection: rtl;\n\t\ttable tr td span {\n\t\t\tfloat: right;\n\t\t}\n\t}\n\t&-dropdown {\n\t\ttop: 0;\n\t\tleft: 0;\n\t\t&:before {\n\t\t\tcontent: '';\n\t\t\tdisplay: inline-block;\n\t\t\tborder-left: 7px solid transparent;\n\t\t\tborder-right: 7px solid transparent;\n\t\t\tborder-bottom: 7px solid #ccc;\n\t\t\tborder-top: 0;\n\t\t\tborder-bottom-color: rgba(0,0,0,.2);\n\t\t\tposition: absolute;\n\t\t}\n\t\t&:after {\n\t\t\tcontent: '';\n\t\t\tdisplay: inline-block;\n\t\t\tborder-left: 6px solid transparent;\n\t\t\tborder-right: 6px solid transparent;\n\t\t\tborder-bottom: 6px solid #fff;\n\t\t\tborder-top: 0;\n\t\t\tposition: absolute;\n\t\t}\n\t\t&.datepicker-orient-left:before { left: 6px; }\n\t\t&.datepicker-orient-left:after { left: 7px; }\n\t\t&.datepicker-orient-right:before { right: 6px; }\n\t\t&.datepicker-orient-right:after { right: 7px; }\n\t\t&.datepicker-orient-top:before { top: -7px; }\n\t\t&.datepicker-orient-top:after { top: -6px; }\n\t\t&.datepicker-orient-bottom:before {\n\t\t\tbottom: -7px;\n\t\t\tborder-bottom: 0;\n\t\t\tborder-top: 7px solid #999;\n\t\t}\n\t\t&.datepicker-orient-bottom:after {\n\t\t\tbottom: -6px;\n\t\t\tborder-bottom: 0;\n\t\t\tborder-top: 6px solid #fff;\n\t\t}\n\t}\n\t> div {\n\t\tdisplay: none;\n\t}\n\t&.days .datepicker-days,\n\t&.months .datepicker-months,\n\t&.years .datepicker-years {\n\t\tdisplay: block;\n\t}\n\ttable {\n\t\tmargin: 0;\n\t\t-webkit-touch-callout: none;\n\t\t-webkit-user-select: none;\n\t\t-khtml-user-select: none;\n\t\t-moz-user-select: none;\n\t\t-ms-user-select: none;\n\t\tuser-select: none;\n\t\ttr {\n\t\t\ttd, th {\n\t\t\t\ttext-align: center;\n\t\t\t\twidth: 30px;\n\t\t\t\theight: 30px;\n\t\t\t\tborder-radius: 4px;\n\n\t\t\t\tborder: none;\n\t\t\t}\n\t\t}\n\t}\n\t// Inline display inside a table presents some problems with\n\t// border and background colors.\n\t.table-striped & table tr {\n\t\ttd, th {\n\t\t\tbackground-color:transparent;\n\t\t}\n\t}\n\ttable tr td {\n\t\t&.day:hover, &.day.focused {\n\t\t\tbackground: @gray-lighter;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t&.old,\n\t\t&.new {\n\t\t\tcolor: @btn-link-disabled-color;\n\t\t}\n\t\t&.disabled,\n\t\t&.disabled:hover {\n\t\t\tbackground: none;\n\t\t\tcolor: @btn-link-disabled-color;\n\t\t\tcursor: default;\n\t\t}\n\t\t&.today,\n\t\t&.today:hover,\n\t\t&.today.disabled,\n\t\t&.today.disabled:hover {\n\t\t\t@today-bg: lighten(orange, 30%);\n\t\t\t.button-variant(#000, @today-bg, darken(@today-bg, 20%));\n\t\t}\n\t\t&.today:hover:hover { // Thank bootstrap 2.0 for this selector...\n\t\t\t// TODO: Bump min BS to 2.1, use @textColor in buttonBackground above\n\t\t\tcolor: #000;\n\t\t}\n\t\t&.today.active:hover {\n\t\t\tcolor: #fff;\n\t\t}\n\t\t&.range,\n\t\t&.range:hover,\n\t\t&.range.disabled,\n\t\t&.range.disabled:hover {\n\t\t\tbackground:@gray-lighter;\n\t\t\tborder-radius: 0;\n\t\t}\n\t\t&.range.today,\n\t\t&.range.today:hover,\n\t\t&.range.today.disabled,\n\t\t&.range.today.disabled:hover {\n\t\t\t@today-bg: mix(orange, @gray-lighter, 50%);\n\t\t\t.button-variant(#000, @today-bg, darken(@today-bg, 20%));\n\t\t\tborder-radius: 0;\n\t\t}\n\t\t&.selected,\n\t\t&.selected:hover,\n\t\t&.selected.disabled,\n\t\t&.selected.disabled:hover {\n\t\t\t.button-variant(#fff, @gray-light, @gray);\n\t\t\ttext-shadow: 0 -1px 0 rgba(0,0,0,.25);\n\t\t}\n\t\t&.active,\n\t\t&.active:hover,\n\t\t&.active.disabled,\n\t\t&.active.disabled:hover {\n\t\t\t.button-variant(@btn-primary-color, @btn-primary-bg, @btn-primary-border);\n\t\t\ttext-shadow: 0 -1px 0 rgba(0,0,0,.25);\n\t\t}\n\t\tspan {\n\t\t\tdisplay: block;\n\t\t\twidth: 23%;\n\t\t\theight: 54px;\n\t\t\tline-height: 54px;\n\t\t\tfloat: left;\n\t\t\tmargin: 1%;\n\t\t\tcursor: pointer;\n\t\t\tborder-radius: 4px;\n\t\t\t&:hover {\n\t\t\t\tbackground: @gray-lighter;\n\t\t\t}\n\t\t\t&.disabled,\n\t\t\t&.disabled:hover {\n\t\t\t\tbackground: none;\n\t\t\t\tcolor: @btn-link-disabled-color;\n\t\t\t\tcursor: default;\n\t\t\t}\n\t\t\t&.active,\n\t\t\t&.active:hover,\n\t\t\t&.active.disabled,\n\t\t\t&.active.disabled:hover {\n\t\t\t\t.button-variant(@btn-primary-color, @btn-primary-bg, @btn-primary-border);\n\t\t\t\ttext-shadow: 0 -1px 0 rgba(0,0,0,.25);\n\t\t\t}\n\t\t\t&.old,\n\t\t\t&.new {\n\t\t\t\tcolor: @btn-link-disabled-color;\n\t\t\t}\n\t\t}\n\t}\n\n\t.datepicker-switch {\n\t\twidth: 145px;\n\t}\n\n\tthead tr:first-child th,\n\ttfoot tr th {\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tbackground: @gray-lighter;\n\t\t}\n\t}\n\n\t// Basic styling for calendar-week cells\n\t.cw {\n\t\tfont-size: 10px;\n\t\twidth: 12px;\n\t\tpadding: 0 2px 0 5px;\n\t\tvertical-align: middle;\n\t}\n\tthead tr:first-child .cw {\n\t\tcursor: default;\n\t\tbackground-color: transparent;\n\t}\n}\n.input-group.date .input-group-addon {\n\tcursor: pointer;\n}\n.input-daterange {\n\twidth: 100%;\n\tinput {\n\t\ttext-align:center;\n\t}\n\tinput:first-child {\n\t\tborder-radius: 3px 0 0 3px;\n\t}\n\tinput:last-child {\n\t\tborder-radius: 0 3px 3px 0;\n\t}\n\t.input-group-addon {\n\t\twidth: auto;\n\t\tmin-width: 16px;\n\t\tpadding: 4px 5px;\n\t\tfont-weight: normal;\n\t\tline-height: @line-height-base;\n\t\ttext-align: center;\n\t\ttext-shadow: 0 1px 0 #fff;\n\t\tvertical-align: middle;\n\t\tbackground-color: @input-group-addon-bg;\n\t\tborder: solid @input-group-addon-border-color;\n\t\tborder-width: 1px 0;\n\t\tmargin-left:-5px;\n\t\tmargin-right:-5px;\n\t}\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","@import \"variables\";\n\n// Mixins\n.cursor-disabled() {\n cursor: not-allowed;\n}\n\n// Rules\n.bootstrap-select {\n width: 220px \\0; /*IE9 and below*/\n\n // The selectpicker button\n > .dropdown-toggle {\n width: 100%;\n padding-right: 25px;\n }\n\n // Error display\n .has-error & .dropdown-toggle,\n .error & .dropdown-toggle {\n border-color: @color-red-error;\n }\n\n &.fit-width {\n width: auto !important;\n }\n\n &:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n width: @width-default;\n }\n\n .dropdown-toggle:focus {\n outline: thin dotted #333333 !important;\n outline: 5px auto -webkit-focus-ring-color !important;\n outline-offset: -2px;\n }\n}\n\n.bootstrap-select.form-control {\n margin-bottom: 0;\n padding: 0;\n border: none;\n\n &:not([class*=\"col-\"]) {\n width: 100%;\n }\n\n &.input-group-btn {\n z-index: auto;\n }\n}\n\n// The selectpicker components\n.bootstrap-select.btn-group {\n &:not(.input-group-btn),\n &[class*=\"col-\"] {\n float: none;\n display: inline-block;\n margin-left: 0;\n }\n\n // Forces the pull to the right, if necessary\n &,\n &[class*=\"col-\"],\n .row &[class*=\"col-\"] {\n &.dropdown-menu-right {\n float: right;\n }\n }\n\n .form-inline &,\n .form-horizontal &,\n .form-group & {\n margin-bottom: 0;\n }\n\n .form-group-lg &.form-control,\n .form-group-sm &.form-control {\n padding: 0;\n }\n\n // Set the width of the live search (and any other form control within an inline form)\n // see https://github.com/silviomoreto/bootstrap-select/issues/685\n .form-inline & .form-control {\n width: 100%;\n }\n\n &.disabled,\n > .disabled {\n .cursor-disabled();\n\n &:focus {\n outline: none !important;\n }\n }\n\n // The selectpicker button\n .dropdown-toggle {\n .filter-option {\n display: inline-block;\n overflow: hidden;\n width: 100%;\n text-align: left;\n }\n\n .caret {\n position: absolute;\n top: 50%;\n right: 12px;\n margin-top: -2px;\n vertical-align: middle;\n }\n }\n\n &[class*=\"col-\"] .dropdown-toggle {\n width: 100%;\n }\n\n // The selectpicker dropdown\n .dropdown-menu {\n min-width: 100%;\n z-index: @zindex-select-dropdown;\n box-sizing: border-box;\n\n &.inner {\n position: static;\n float: none;\n border: 0;\n padding: 0;\n margin: 0;\n border-radius: 0;\n box-shadow: none;\n }\n\n li {\n position: relative;\n\n &.active small {\n color: #fff;\n }\n\n &.disabled a {\n .cursor-disabled();\n }\n\n a {\n cursor: pointer;\n\n &.opt {\n position: relative;\n padding-left: 2.25em;\n }\n\n span.check-mark {\n display: none;\n }\n\n span.text {\n display: inline-block;\n }\n }\n\n small {\n padding-left: 0.5em;\n }\n }\n\n .notify {\n position: absolute;\n bottom: 5px;\n width: 96%;\n margin: 0 2%;\n min-height: 26px;\n padding: 3px 5px;\n background: rgb(245, 245, 245);\n border: 1px solid rgb(227, 227, 227);\n box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%);\n pointer-events: none;\n opacity: 0.9;\n box-sizing: border-box;\n }\n }\n\n .no-results {\n padding: 3px;\n background: #f5f5f5;\n margin: 0 5px;\n white-space: nowrap;\n }\n\n &.fit-width .dropdown-toggle {\n .filter-option {\n position: static;\n }\n\n .caret {\n position: static;\n top: auto;\n margin-top: -1px;\n }\n }\n\n &.show-tick .dropdown-menu li {\n &.selected a span.check-mark {\n position: absolute;\n display: inline-block;\n right: 15px;\n margin-top: 5px;\n }\n\n a span.text {\n margin-right: 34px;\n }\n }\n}\n\n.bootstrap-select.show-menu-arrow {\n &.open > .dropdown-toggle {\n z-index: (@zindex-select-dropdown + 1);\n }\n\n .dropdown-toggle {\n &:before {\n content: '';\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-bottom: 7px solid @color-grey-arrow;\n position: absolute;\n bottom: -4px;\n left: 9px;\n display: none;\n }\n\n &:after {\n content: '';\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid white;\n position: absolute;\n bottom: -4px;\n left: 10px;\n display: none;\n }\n }\n\n &.dropup .dropdown-toggle {\n &:before {\n bottom: auto;\n top: -3px;\n border-top: 7px solid @color-grey-arrow;\n border-bottom: 0;\n }\n\n &:after {\n bottom: auto;\n top: -3px;\n border-top: 6px solid white;\n border-bottom: 0;\n }\n }\n\n &.pull-right .dropdown-toggle {\n &:before {\n right: 12px;\n left: auto;\n }\n\n &:after {\n right: 13px;\n left: auto;\n }\n }\n\n &.open > .dropdown-toggle {\n &:before,\n &:after {\n display: block;\n }\n }\n}\n\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n padding: 4px 8px;\n}\n\n.bs-actionsbox {\n float: left;\n width: 100%;\n box-sizing: border-box;\n\n & .btn-group button {\n width: 50%;\n }\n}\n\n.bs-donebutton {\n float: left;\n width: 100%;\n box-sizing: border-box;\n\n & .btn-group button {\n width: 100%;\n }\n}\n\n.bs-searchbox {\n & + .bs-actionsbox {\n padding: 0 8px 4px;\n }\n\n & .form-control {\n margin-bottom: 0;\n width: 100%;\n }\n}\n\nselect.bs-select-hidden,\nselect.selectpicker {\n display: none !important;\n}\n\nselect.mobile-device {\n position: absolute !important;\n top: 0;\n left: 0;\n display: block !important;\n width: 100%;\n height: 100% !important;\n opacity: 0;\n}\n","@bootstrap-switch-base: bootstrap-switch;\n\n.@{bootstrap-switch-base} {\n display: inline-block;\n direction: ltr;\n cursor: pointer;\n border-radius: @border-radius-base;\n border: 1px solid;\n border-color: @btn-default-border;\n position: relative;\n text-align: left;\n overflow: hidden;\n line-height: 8px;\n z-index: 0;\n .user-select(none);\n vertical-align: middle;\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n .@{bootstrap-switch-base}-container {\n display: inline-block;\n top: 0;\n border-radius: @border-radius-base;\n .translate3d(0, 0, 0);\n }\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off,\n .@{bootstrap-switch-base}-label {\n .box-sizing(border-box);\n cursor: pointer;\n display: inline-block !important;\n height: 100%;\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-computed;\n }\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off {\n text-align: center;\n z-index: 1;\n\n &.@{bootstrap-switch-base}-primary {\n color: #fff;\n background: @btn-primary-bg;\n }\n\n &.@{bootstrap-switch-base}-info {\n color: #fff;\n background: @btn-info-bg;\n }\n\n &.@{bootstrap-switch-base}-success {\n color: #fff;\n background: @btn-success-bg;\n }\n\n &.@{bootstrap-switch-base}-warning {\n background: @btn-warning-bg;\n color: #fff;\n }\n\n &.@{bootstrap-switch-base}-danger {\n color: #fff;\n background: @btn-danger-bg;\n }\n\n &.@{bootstrap-switch-base}-default {\n color: #000;\n background: @gray-lighter;\n }\n }\n\n .@{bootstrap-switch-base}-label {\n text-align: center;\n margin-top: -1px;\n margin-bottom: -1px;\n z-index: 100;\n color: @btn-default-color;\n background: @btn-default-bg;\n }\n\n .@{bootstrap-switch-base}-handle-on {\n .border-left-radius((@border-radius-base - 1));\n }\n\n .@{bootstrap-switch-base}-handle-off {\n .border-right-radius((@border-radius-base - 1));\n }\n\n input[type='radio'],\n input[type='checkbox'] {\n position: absolute !important;\n top: 0;\n left: 0;\n .opacity(0);\n z-index: -1;\n\n &.form-control {\n height: auto;\n }\n }\n\n &.@{bootstrap-switch-base}-mini {\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off,\n .@{bootstrap-switch-base}-label {\n padding: @padding-xs-vertical @padding-xs-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n }\n\n &.@{bootstrap-switch-base}-small {\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off,\n .@{bootstrap-switch-base}-label {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n }\n\n &.@{bootstrap-switch-base}-large {\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off,\n .@{bootstrap-switch-base}-label {\n padding: @padding-base-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n }\n }\n\n &.@{bootstrap-switch-base}-disabled,\n &.@{bootstrap-switch-base}-readonly,\n &.@{bootstrap-switch-base}-indeterminate {\n cursor: default !important;\n\n .@{bootstrap-switch-base}-handle-on,\n .@{bootstrap-switch-base}-handle-off,\n .@{bootstrap-switch-base}-label {\n .opacity(.5);\n cursor: default !important;\n }\n }\n\n &.@{bootstrap-switch-base}-animate {\n\n .@{bootstrap-switch-base}-container {\n .transition(margin-left .5s);\n }\n }\n\n &.@{bootstrap-switch-base}-inverse {\n\n .@{bootstrap-switch-base}-handle-on {\n .border-left-radius(0);\n .border-right-radius((@border-radius-base - 1));\n }\n\n .@{bootstrap-switch-base}-handle-off {\n .border-right-radius(0);\n .border-left-radius((@border-radius-base - 1));\n }\n }\n\n &.@{bootstrap-switch-base}-focused {\n @color-rgba: rgba(red(@input-border-focus), green(@input-border-focus), blue(@input-border-focus), .6);\n border-color: @input-border-focus;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n\n &.@{bootstrap-switch-base}-on,\n &.@{bootstrap-switch-base}-inverse.@{bootstrap-switch-base}-off {\n\n .@{bootstrap-switch-base}-label {\n .border-right-radius((@border-radius-base - 1));\n }\n }\n\n &.@{bootstrap-switch-base}-off,\n &.@{bootstrap-switch-base}-inverse.@{bootstrap-switch-base}-on {\n\n\n .@{bootstrap-switch-base}-label {\n .border-left-radius((@border-radius-base - 1));\n }\n }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","/*\n * Bootstrap TouchSpin - v3.0.1\n * A mobile and touch friendly input spinner component for Bootstrap 3.\n * http://www.virtuosoft.eu/code/bootstrap-touchspin/\n *\n * Made by István Ujj-Mészáros\n * Under Apache License v2.0 License\n */\n\n.bootstrap-touchspin .input-group-btn-vertical {\n position: relative;\n white-space: nowrap;\n width: 1%;\n vertical-align: middle;\n display: table-cell;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n padding: 8px 10px;\n margin-left: -1px;\n position: relative;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {\n border-radius: 0;\n border-top-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {\n margin-top: -2px;\n border-radius: 0;\n border-bottom-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical i {\n position: absolute;\n top: 3px;\n left: 5px;\n font-size: 9px;\n font-weight: normal;\n}\n","/*-- Chart --*/\n.c3 svg {\n font: 10px sans-serif; }\n\n.c3 path, .c3 line {\n fill: none;\n stroke: #000; }\n\n.c3 text {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none; }\n\n.c3-legend-item-tile, .c3-xgrid-focus, .c3-ygrid, .c3-event-rect, .c3-bars path {\n shape-rendering: crispEdges; }\n\n.c3-chart-arc path {\n stroke: #fff; }\n\n.c3-chart-arc text {\n fill: #fff;\n font-size: 13px; }\n\n/*-- Axis --*/\n/*-- Grid --*/\n.c3-grid line {\n stroke: #aaa; }\n\n.c3-grid text {\n fill: #aaa; }\n\n.c3-xgrid, .c3-ygrid {\n stroke-dasharray: 3 3; }\n\n/*-- Text on Chart --*/\n.c3-text.c3-empty {\n fill: #808080;\n font-size: 2em; }\n\n/*-- Line --*/\n.c3-line {\n stroke-width: 1px; }\n\n/*-- Point --*/\n.c3-circle._expanded_ {\n stroke-width: 1px;\n stroke: white; }\n\n.c3-selected-circle {\n fill: white;\n stroke-width: 2px; }\n\n/*-- Bar --*/\n.c3-bar {\n stroke-width: 0; }\n\n.c3-bar._expanded_ {\n fill-opacity: 0.75; }\n\n/*-- Focus --*/\n.c3-target.c3-focused {\n opacity: 1; }\n\n.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {\n stroke-width: 2px; }\n\n.c3-target.c3-defocused {\n opacity: 0.3 !important; }\n\n/*-- Region --*/\n.c3-region {\n fill: steelblue;\n fill-opacity: 0.1; }\n\n/*-- Brush --*/\n.c3-brush .extent {\n fill-opacity: 0.1; }\n\n/*-- Select - Drag --*/\n/*-- Legend --*/\n.c3-legend-item {\n font-size: 12px; }\n\n.c3-legend-item-hidden {\n opacity: 0.15; }\n\n.c3-legend-background {\n opacity: 0.75;\n fill: white;\n stroke: lightgray;\n stroke-width: 1; }\n\n/*-- Tooltip --*/\n.c3-tooltip-container {\n z-index: 10; }\n\n.c3-tooltip {\n border-collapse: collapse;\n border-spacing: 0;\n background-color: #fff;\n empty-cells: show;\n -webkit-box-shadow: 7px 7px 12px -9px #777777;\n -moz-box-shadow: 7px 7px 12px -9px #777777;\n box-shadow: 7px 7px 12px -9px #777777;\n opacity: 0.9; }\n\n.c3-tooltip tr {\n border: 1px solid #CCC; }\n\n.c3-tooltip th {\n background-color: #aaa;\n font-size: 14px;\n padding: 2px 5px;\n text-align: left;\n color: #FFF; }\n\n.c3-tooltip td {\n font-size: 13px;\n padding: 3px 6px;\n background-color: #fff;\n border-left: 1px dotted #999; }\n\n.c3-tooltip td > span {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin-right: 6px; }\n\n.c3-tooltip td.value {\n text-align: right; }\n\n/*-- Area --*/\n.c3-area {\n stroke-width: 0;\n opacity: 0.2; }\n\n/*-- Arc --*/\n.c3-chart-arcs-title {\n dominant-baseline: middle;\n font-size: 1.3em; }\n\n.c3-chart-arcs .c3-chart-arcs-background {\n fill: #e0e0e0;\n stroke: none; }\n\n.c3-chart-arcs .c3-chart-arcs-gauge-unit {\n fill: #000;\n font-size: 16px; }\n\n.c3-chart-arcs .c3-chart-arcs-gauge-max {\n fill: #777; }\n\n.c3-chart-arcs .c3-chart-arcs-gauge-min {\n fill: #777; }\n\n.c3-chart-arc .c3-gauge-value {\n fill: #000;\n /* font-size: 28px !important;*/ }\n","/*!\n * Datetimepicker for Bootstrap 3\n * version : 4.17.37\n * https://github.com/Eonasdan/bootstrap-datetimepicker/\n */\n@bs-datetimepicker-timepicker-font-size: 1.2em;\n@bs-datetimepicker-active-bg: @btn-primary-bg;\n@bs-datetimepicker-active-color: @btn-primary-color;\n@bs-datetimepicker-border-radius: @border-radius-base;\n@bs-datetimepicker-btn-hover-bg: @gray-lighter;\n@bs-datetimepicker-disabled-color: @gray-light;\n@bs-datetimepicker-alternate-color: @gray-light;\n@bs-datetimepicker-secondary-border-color: #ccc;\n@bs-datetimepicker-secondary-border-color-rgba: rgba(0, 0, 0, 0.2);\n@bs-datetimepicker-primary-border-color: white;\n@bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n\n.bootstrap-datetimepicker-widget {\n list-style: none;\n\n &.dropdown-menu {\n margin: 2px 0;\n padding: 4px;\n width: 19em;\n\n &.timepicker-sbs {\n @media (min-width: @screen-sm-min) {\n width: 38em;\n }\n\n @media (min-width: @screen-md-min) {\n width: 38em;\n }\n\n @media (min-width: @screen-lg-min) {\n width: 38em;\n }\n }\n\n &:before, &:after {\n content: '';\n display: inline-block;\n position: absolute;\n }\n\n &.bottom {\n &:before {\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-bottom: 7px solid @bs-datetimepicker-secondary-border-color;\n border-bottom-color: @bs-datetimepicker-secondary-border-color-rgba;\n top: -7px;\n left: 7px;\n }\n\n &:after {\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid @bs-datetimepicker-primary-border-color;\n top: -6px;\n left: 8px;\n }\n }\n\n &.top {\n &:before {\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid @bs-datetimepicker-secondary-border-color;\n border-top-color: @bs-datetimepicker-secondary-border-color-rgba;\n bottom: -7px;\n left: 6px;\n }\n\n &:after {\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-top: 6px solid @bs-datetimepicker-primary-border-color;\n bottom: -6px;\n left: 7px;\n }\n }\n\n &.pull-right {\n &:before {\n left: auto;\n right: 6px;\n }\n\n &:after {\n left: auto;\n right: 7px;\n }\n }\n }\n\n .list-unstyled {\n margin: 0;\n }\n\n a[data-action] {\n padding: 6px 0;\n }\n\n a[data-action]:active {\n box-shadow: none;\n }\n\n .timepicker-hour, .timepicker-minute, .timepicker-second {\n width: 54px;\n font-weight: bold;\n font-size: @bs-datetimepicker-timepicker-font-size;\n margin: 0;\n }\n\n button[data-action] {\n padding: 6px;\n }\n\n .btn[data-action=\"incrementHours\"]::after {\n .sr-only();\n content: \"Increment Hours\";\n }\n\n .btn[data-action=\"incrementMinutes\"]::after {\n .sr-only();\n content: \"Increment Minutes\";\n }\n\n .btn[data-action=\"decrementHours\"]::after {\n .sr-only();\n content: \"Decrement Hours\";\n }\n\n .btn[data-action=\"decrementMinutes\"]::after {\n .sr-only();\n content: \"Decrement Minutes\";\n }\n\n .btn[data-action=\"showHours\"]::after {\n .sr-only();\n content: \"Show Hours\";\n }\n\n .btn[data-action=\"showMinutes\"]::after {\n .sr-only();\n content: \"Show Minutes\";\n }\n\n .btn[data-action=\"togglePeriod\"]::after {\n .sr-only();\n content: \"Toggle AM/PM\";\n }\n\n .btn[data-action=\"clear\"]::after {\n .sr-only();\n content: \"Clear the picker\";\n }\n\n .btn[data-action=\"today\"]::after {\n .sr-only();\n content: \"Set the date to today\";\n }\n\n .picker-switch {\n text-align: center;\n\n &::after {\n .sr-only();\n content: \"Toggle Date and Time Screens\";\n }\n\n td {\n padding: 0;\n margin: 0;\n height: auto;\n width: auto;\n line-height: inherit;\n\n span {\n line-height: 2.5;\n height: 2.5em;\n width: 100%;\n }\n }\n }\n\n table {\n width: 100%;\n margin: 0;\n\n\n & td,\n & th {\n text-align: center;\n border-radius: @bs-datetimepicker-border-radius;\n }\n\n & th {\n height: 20px;\n line-height: 20px;\n width: 20px;\n\n &.picker-switch {\n width: 145px;\n }\n\n &.disabled,\n &.disabled:hover {\n background: none;\n color: @bs-datetimepicker-disabled-color;\n cursor: not-allowed;\n }\n\n &.prev::after {\n .sr-only();\n content: \"Previous Month\";\n }\n\n &.next::after {\n .sr-only();\n content: \"Next Month\";\n }\n }\n\n & thead tr:first-child th {\n cursor: pointer;\n\n &:hover {\n background: @bs-datetimepicker-btn-hover-bg;\n }\n }\n\n & td {\n height: 54px;\n line-height: 54px;\n width: 54px;\n\n &.cw {\n font-size: .8em;\n height: 20px;\n line-height: 20px;\n color: @bs-datetimepicker-alternate-color;\n }\n\n &.day {\n height: 20px;\n line-height: 20px;\n width: 20px;\n }\n\n &.day:hover,\n &.hour:hover,\n &.minute:hover,\n &.second:hover {\n background: @bs-datetimepicker-btn-hover-bg;\n cursor: pointer;\n }\n\n &.old,\n &.new {\n color: @bs-datetimepicker-alternate-color;\n }\n\n &.today {\n position: relative;\n\n &:before {\n content: '';\n display: inline-block;\n border: solid transparent;\n border-width: 0 0 7px 7px;\n border-bottom-color: @bs-datetimepicker-active-bg;\n border-top-color: @bs-datetimepicker-secondary-border-color-rgba;\n position: absolute;\n bottom: 4px;\n right: 4px;\n }\n }\n\n &.active,\n &.active:hover {\n background-color: @bs-datetimepicker-active-bg;\n color: @bs-datetimepicker-active-color;\n text-shadow: @bs-datetimepicker-text-shadow;\n }\n\n &.active.today:before {\n border-bottom-color: #fff;\n }\n\n &.disabled,\n &.disabled:hover {\n background: none;\n color: @bs-datetimepicker-disabled-color;\n cursor: not-allowed;\n }\n\n span {\n display: inline-block;\n width: 54px;\n height: 54px;\n line-height: 54px;\n margin: 2px 1.5px;\n cursor: pointer;\n border-radius: @bs-datetimepicker-border-radius;\n\n &:hover {\n background: @bs-datetimepicker-btn-hover-bg;\n }\n\n &.active {\n background-color: @bs-datetimepicker-active-bg;\n color: @bs-datetimepicker-active-color;\n text-shadow: @bs-datetimepicker-text-shadow;\n }\n\n &.old {\n color: @bs-datetimepicker-alternate-color;\n }\n\n &.disabled,\n &.disabled:hover {\n background: none;\n color: @bs-datetimepicker-disabled-color;\n cursor: not-allowed;\n }\n }\n }\n }\n\n &.usetwentyfour {\n td.hour {\n height: 27px;\n line-height: 27px;\n }\n }\n\t\n\t&.wider {\n\t\twidth: 21em;\n\t}\n\n\t& .datepicker-decades .decade {\n line-height: 1.8em !important;\n }\n}\n\n.input-group.date {\n & .input-group-addon {\n cursor: pointer;\n }\n}\n","// Import bootstrap variables including default color palette and fonts\n// @import \"bootstrap/less/variables.less\"; commented this line because it is already being imported\n\n// Import datepicker component\n@import \"_bootstrap-datetimepicker.less\";\n\n//this is here so the compiler doesn't complain about a missing bootstrap mixin\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n","//\n// Blank Slate\n// --------------------------------------------------\n\n.blank-slate-pf{\n @media (min-width: @screen-sm-min) {\n padding: (@jumbotron-padding * 2) (@jumbotron-padding * 2);\n }\n @media (min-width: @screen-md-min) {\n padding: (@jumbotron-padding * 3) (@jumbotron-padding * 4);\n }\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n margin-bottom: 20px;\n padding: @jumbotron-padding;\n text-align: center;\n .blank-slate-pf-icon{\n color: @gray-light;\n font-size: (@font-size-h1 * 2.4);\n line-height: (@font-size-h1 * 2.4);\n }\n .blank-slate-pf-main-action{\n margin-top: @line-height-computed;\n }\n .blank-slate-pf-secondary-action{\n margin-top: @line-height-computed;\n }\n}\n","//\n// Bootstrap-Combobox\n// --------------------------------------------------\n\n.combobox-container {\n &.combobox-selected .glyphicon-remove {\n display: inline-block;\n }\n .caret {\n margin-left: 0;\n }\n .combobox::-ms-clear {\n display: none;\n }\n .dropdown-menu {\n margin-top: -1px;\n width: 100%;\n }\n .glyphicon-remove {\n display: none;\n top: auto;\n width: 12px;\n &:before {\n content: \"\\e60b\";\n font-family: @icon-font-name-pf;\n }\n }\n .input-group-addon {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-bg-img-start; @btn-default-bg-img-stop; @btn-default-border);\n position: relative; // IE8\n &:active {\n .box-shadow(inset 0 2px 8px rgba(0,0,0,.2));\n }\n }\n}\n","//\n// Variables\n// --------------------------------------------------\n// Bootstrap overrides and PatternFly-specific variables\n\n// PatternFly-specific\n// -------------------\n@import \"color-variables.less\";\n\n@bootstrap-switch-handle-default-bg-color: #fbfbfb;\n@btn-default-bg-img-start: @color-pf-black-100;\n@btn-default-bg-img-stop: #ededed;\n@btn-xs-font-weight: 400;\n@card-pf-accented-border-top-color: @color-pf-blue-300;\n@card-pf-aggregate-status-title-icon-color: #333;\n@card-pf-bg-color: #fff;\n@card-pf-border-color: @color-pf-black-300;\n@card-pf-border-top-color: transparent;\n@card-pf-container-bg-color: #f5f5f5;\n@card-pf-footer-bg-color: @color-pf-black-100;\n@donut-font-size-big: 30px;\n@dropdown-divider-margin: 4px 1px;\n@dropdown-link-active-border-color: #0076b7;\n@dropdown-link-hover-border-color: #b3d3e7;\n@dropdown-link-focus-color: #fff;\n@flyout-transition-pf: all .2s cubic-bezier(.35,0,.25,1);\n@font-family-monospace: Menlo, Monaco, Consolas, monospace;\n@font-path: \"../fonts\";\n@footer-pf-bg-color: @color-pf-black;\n@footer-pf-padding-left: 25px;\n@footer-pf-padding-top: 10px;\n@footer-pf-height: 37px;\n@gray-light-pf: #aaa;\n@gray-pf: @color-pf-black-700;\n@icon-font-name-fa: \"FontAwesome\";\n@icon-font-name-pf: \"PatternFlyIcons-webfont\";\n@icon-prefix: pficon;\n@img-bg-login: \"bg-login.jpg\";\n@img-path: \"../img\";\n@img-spinner: \"spinner.gif\";\n@img-spinner-inverse: \"spinner-inverse.gif\";\n@img-spinner-inverse-lg: \"spinner-inverse-lg.gif\";\n@img-spinner-inverse-sm: \"spinner-inverse-sm.gif\";\n@img-spinner-inverse-xs: \"spinner-inverse-xs.gif\";\n@img-spinner-lg: \"spinner-lg.gif\";\n@img-spinner-sm: \"spinner-sm.gif\";\n@img-spinner-xs: \"spinner-xs.gif\";\n@input-border-disabled: #d4d4d4;\n@input-border-hover: #7BB2DD;\n@list-view-accented-border: @color-pf-blue-300;\n@list-view-active-bg: #def3ff;\n@list-view-divider: @color-pf-black-300;\n@list-view-hover-bg: #ededed;\n@list-group-top-border: #e9e8e8;\n@login-bg-color: #080808;\n@login-container-bg-color: #181818;\n@login-container-bg-color-rgba: rgba(255, 255, 255, 0.055);\n@modal-title-padding-horizontal: 18px;\n@modal-title-padding-vertical: 10px;\n@navbar-pf-active-color: #f1f1f1;\n@navbar-pf-alt-active-color: #fff;\n@navbar-pf-alt-bg-color: @color-pf-black;\n@navbar-pf-alt-bg-img: url(\"../img/bg-navbar-pf-alt.svg\");\n@navbar-pf-bg-color: @color-pf-black;\n@navbar-pf-border-color: #199dde;\n@navbar-pf-color: #cfcfcf;\n@navbar-pf-height: 60px;\n@navbar-pf-icon-bar-bg-color: #fff;\n@navbar-pf-navbar-navbar-brand-min-width: 270px;\n@navbar-pf-navbar-navbar-brand-padding: 8px 0 7px;\n@navbar-pf-navbar-navbar-persistent-bg-color: #f6f6f6;\n@navbar-pf-navbar-navbar-persistent-border-color: #cecdcd;\n@navbar-pf-vertical-active-color: #fff;\n@navbar-pf-vertical-bg-color: #1d1d1d;\n@navbar-pf-vertical-bg-repeat: no-repeat;\n@navbar-pf-vertical-bg-size: auto 100%;\n@navbar-pf-vertical-border-color: #199dde;\n@navbar-pf-vertical-border-style: solid;\n@navbar-pf-vertical-border-width: 2px;\n@navbar-pf-vertical-color: #cfcfcf;\n@navbar-pf-vertical-height: 60px;\n@navbar-pf-vertical-icon-bar-bg-color: #fff;\n@navbar-pf-vertical-navbar-brand-color: #fff;\n@navbar-pf-vertical-navbar-brand-icon-margin: 0 15px 0 0;\n@navbar-pf-vertical-navbar-brand-margin: 0 0 0 25px;\n@navbar-pf-vertical-navbar-brand-min-height: 35px;\n@navbar-pf-vertical-navbar-brand-name-breakpoint: 480px;\n@navbar-pf-vertical-navbar-brand-name-margin: 0 15px 0 0;\n@navbar-pf-vertical-navbar-brand-padding: 11px 0 12px;\n@navbar-pf-vertical-navbar-toggle-margin: 13px 15px;\n@navbar-pf-vertical-navbar-toggle-icon-bar-hover-bg: #fff;\n@navbar-pf-vertical-nav-item-iconic-padding: 21px 12px;\n@nav-pf-vertical-active-color: #fff;\n@nav-pf-vertical-active-before-color: #199dde;\n@nav-pf-vertical-active-bg-color: @color-pf-black-800;\n@nav-pf-vertical-active-border-color: #303030;\n@nav-pf-vertical-active-font-weight: 600;\n@nav-pf-vertical-active-icon-color: #199dde;\n@nav-pf-vertical-badge-color: #fff;\n@nav-pf-vertical-bg-color: @color-pf-black-900;\n@nav-pf-vertical-border-color: #262626;\n@nav-pf-vertical-collapsed-width: 75px;\n@nav-pf-vertical-color: #dbdada;\n@nav-pf-vertical-font-weight: 400;\n@nav-pf-vertical-icon-color: @color-pf-black-600;\n@nav-pf-vertical-icon-width: 24px;\n@nav-pf-vertical-item-border-color: #000000;\n@nav-pf-vertical-link-height: 63px;\n@nav-pf-vertical-link-padding: 17px 20px 17px 25px;\n@nav-pf-vertical-secondary-active-color: #fff;\n@nav-pf-vertical-secondary-active-bg-color: @color-pf-black-700;\n@nav-pf-vertical-secondary-active-icon-color: #199dde;\n@nav-pf-vertical-secondary-badge-color: #fff;\n@nav-pf-vertical-secondary-badge-bg-color: @color-pf-black-900;\n@nav-pf-vertical-secondary-border-color: #199dde;\n@nav-pf-vertical-secondary-color: #fff;\n@nav-pf-vertical-secondary-header-margin: 18px 20px 10px 20px;\n@nav-pf-vertical-secondary-indicator-color: @color-pf-black-600;\n@nav-pf-vertical-secondayr-indicator-padding: 17px 0;\n@nav-pf-vertical-secondary-item-color: #dbdada;\n@nav-pf-vertical-secondary-item-padding: 0 0 5px 0;\n@nav-pf-vertical-secondary-link-height: 63px;\n@nav-pf-vertical-secondary-link-padding: 0 15px 0 20px;\n@nav-pf-vertical-secondary-list-header-margin: 30px 20px 10px 20px;\n@nav-pf-vertical-secondary-width: 250px;\n@nav-pf-vertical-width: 200px;\n@pagination-padding-small-vertical: 0;\n@panel-default-border-color: #bebdbd;\n@pficon-var-add-circle-o: \"\\e61b\";\n@pficon-var-build: \"\\e902\";\n@pficon-var-builder-image: \"\\e800\";\n@pficon-var-close: \"\\e60b\";\n@pficon-var-cloud-security: \"\\e903\";\n@pficon-var-cloud-tenant: \"\\e904\";\n@pficon-var-cluster: \"\\e620\";\n@pficon-var-container-node: \"\\e621\";\n@pficon-var-cpu: \"\\e905\";\n@pficon-var-delete: \"\\e611\";\n@pficon-var-edit: \"\\e60a\";\n@pficon-var-enterprise: \"\\e906\";\n@pficon-var-error-circle-o: \"\\e61d\";\n@pficon-var-export: \"\\e616\";\n@pficon-var-flag: \"\\e603\";\n@pficon-var-flavor: \"\\e907\";\n@pficon-var-folder-close: \"\\e607\";\n@pficon-var-folder-open: \"\\e606\";\n@pficon-var-help: \"\\e605\";\n@pficon-var-history: \"\\e617\";\n@pficon-var-home: \"\\e618\";\n@pficon-var-image: \"\\e61f\";\n@pficon-var-import: \"\\e615\";\n@pficon-var-info: \"\\e604\";\n@pficon-var-kubernetes: \"\\e627\";\n@pficon-var-memory: \"\\e908\";\n@pficon-var-network: \"\\e909\";\n@pficon-var-ok: \"\\e602\";\n@pficon-var-openshift: \"\\e626\";\n@pficon-var-print: \"\\e612\";\n@pficon-var-project: \"\\e622\";\n@pficon-var-regions: \"\\e90a\";\n@pficon-var-registry: \"\\e623\";\n@pficon-var-replicator: \"\\e624\";\n@pficon-var-repository: \"\\e90b\";\n@pficon-var-resource-pool: \"\\e90c\";\n@pficon-var-resources-almost-full: \"\\e912\";\n@pficon-var-resources-full: \"\\e913\";\n@pficon-var-restart: \"\\e613\";\n@pficon-var-route: \"\\e625\";\n@pficon-var-running: \"\\e614\";\n@pficon-var-save: \"\\e601\";\n@pficon-var-screen: \"\\e600\";\n@pficon-var-server: \"\\e90d\";\n@pficon-var-service: \"\\e61e\";\n@pficon-var-settings: \"\\e610\";\n@pficon-var-storage-domain: \"\\e90e\";\n@pficon-var-thumb-tack-o: \"\\e609\";\n@pficon-var-topology: \"\\e608\";\n@pficon-var-trend-down: \"\\e900\";\n@pficon-var-trend-up: \"\\e901\";\n@pficon-var-user: \"\\e60e\";\n@pficon-var-users: \"\\e60f\";\n@pficon-var-virtual-machine: \"\\e90f\";\n@pficon-var-volume: \"\\e910\";\n@pficon-var-warning-triangle-o: \"\\e61c\";\n@pficon-var-zone: \"\\e911\";\n@progress-description-label-width: 85px;\n@sidebar-pf-bg: @color-pf-black-100;\n@sidebar-pf-border-color: #d0d0d0;\n@table-border-hover: #a7cadf;\n@table-cell-padding-bottom: 3px;\n@table-cell-padding-top: 2px;\n// Reference variables declared in block above\n@bootstrap-switch-bg-color-start: @btn-default-bg-img-start;\n@bootstrap-switch-bg-color-stop: @btn-default-bg-img-stop;\n@fa-font-path: @font-path;\n@navbar-pf-navbar-header-border-color: lighten(@navbar-pf-bg-color, 15%);\n@navbar-pf-navbar-nav-active-active-bg-color: lighten(@navbar-pf-bg-color, 8%);\n@navbar-pf-navbar-nav-active-active-open-bg-color: lighten(@navbar-pf-bg-color, 11%);\n@navbar-pf-navbar-nav-active-bg-color: lighten(@navbar-pf-bg-color, 12.5%);\n@navbar-pf-navbar-primary-bg-color-start: lighten(@navbar-pf-bg-color, 10%); // #474C50;\n@navbar-pf-navbar-primary-bg-color-stop: @navbar-pf-bg-color; // #383F43;\n@navbar-pf-navbar-utility-border-color: lighten(@navbar-pf-bg-color, 15.5%);\n@navbar-pf-navbar-utility-color: @navbar-pf-color;\n@navbar-pf-navbar-utility-hover-bg-color: lighten(@navbar-pf-bg-color, 12.5%);\n@nav-pf-vertical-hidden-icons-width: (@nav-pf-vertical-width - @nav-pf-vertical-icon-width);\n@nav-pf-vertical-secondary-bg-color: @nav-pf-vertical-active-bg-color;\n@nav-tabs-color: @gray-pf;\n// Reference variables declared in block above\n@navbar-pf-navbar-primary-context-bg-color-start: lighten(@navbar-pf-navbar-primary-bg-color-start, 8.5%);\n@navbar-pf-navbar-primary-context-bg-color-stop: lighten(@navbar-pf-navbar-primary-bg-color-stop, 11%);\n@navbar-pf-navbar-primary-hover-bg-color-start: lighten(@navbar-pf-navbar-primary-bg-color-start, 10%);\n@navbar-pf-navbar-primary-hover-bg-color-stop: lighten(@navbar-pf-navbar-primary-bg-color-stop, 10%);\n@navbar-pf-navbar-primary-hover-border-color: lighten(@navbar-pf-navbar-header-border-color, 20%);\n@navbar-pf-navbar-primary-context-border-color: lighten(@navbar-pf-navbar-header-border-color, 8%);\n@navbar-pf-navbar-primary-context-border-top-color: lighten(@navbar-pf-navbar-header-border-color, 7%);\n@navbar-pf-navbar-utility-hover-border-color: lighten(@navbar-pf-navbar-utility-border-color, 5%);\n@navbar-pf-navbar-utility-open-bg-color: lighten(@navbar-pf-navbar-utility-hover-bg-color, 7.5%);\n@navbar-pf-navbar-utility-open-border-color: lighten(@navbar-pf-navbar-utility-hover-border-color, 5%);\n// Reference variables declared in block above\n@navbar-pf-navbar-primary-active-bg-color-start: lighten(@navbar-pf-navbar-primary-hover-bg-color-start, 5%);\n@navbar-pf-navbar-primary-active-bg-color-stop: lighten(@navbar-pf-navbar-primary-hover-bg-color-stop, 7.5%);\n@navbar-pf-navbar-primary-active-border-color: lighten(@navbar-pf-navbar-primary-hover-border-color, 5%);\n@navbar-pf-navbar-primary-context-hover-bg-color-start: lighten(@navbar-pf-navbar-primary-context-bg-color-start, 5%);\n@navbar-pf-navbar-primary-context-hover-bg-color-stop: lighten(@navbar-pf-navbar-primary-context-bg-color-stop, 7.5%);\n@navbar-pf-navbar-primary-context-hover-border-color: lighten(@navbar-pf-navbar-primary-context-border-color, 5%);\n@navbar-pf-navbar-primary-context-hover-border-top-color: lighten(@navbar-pf-navbar-primary-context-border-top-color, 6%);\n// Reference variables declared in block above\n@navbar-pf-navbar-primary-context-active-bg-color-start: lighten(@navbar-pf-navbar-primary-context-hover-bg-color-start, 5%);\n@navbar-pf-navbar-primary-context-active-bg-color-stop: lighten(@navbar-pf-navbar-primary-context-hover-bg-color-stop, 7.5%);\n@navbar-pf-navbar-primary-context-active-border-color: lighten(@navbar-pf-navbar-primary-context-hover-border-color, 5%);\n@navbar-pf-navbar-primary-context-active-border-top-color: lighten(@navbar-pf-navbar-primary-context-hover-border-top-color, 6%);\n// References variable declared in block above\n@navbar-pf-navbar-primary-context-active-border-right-color: @navbar-pf-navbar-primary-context-active-border-color;\n\n// Alternate navigation layout - Kept for backwards compatibility\n// --------------------------------------------------------------\n@footer-pf-alt-bg-color: @footer-pf-bg-color;\n@footer-pf-alt-padding-left: @footer-pf-padding-left;\n@footer-pf-alt-padding-top: @footer-pf-padding-top;\n@footer-pf-alt-height: @footer-pf-height;\n@img-path-alt: @img-path;\n@nav-pf-vertical-alt-active-color: @color-pf-blue-300;\n@nav-pf-vertical-alt-bg-color: #fff;\n@nav-pf-vertical-alt-badge-color: #fff;\n@nav-pf-vertical-alt-border-color: @sidebar-pf-border-color;\n@nav-pf-vertical-alt-collapsed-width: 75px;\n@nav-pf-vertical-alt-color: #464952;\n@nav-pf-vertical-alt-link-height: 63px;\n@nav-pf-vertical-alt-link-padding: 17px 20px 17px 25px;\n@nav-pf-vertical-alt-width: 250px;\n@navbar-pf-alt-bg-repeat: @navbar-pf-vertical-bg-repeat;\n@navbar-pf-alt-bg-size: @navbar-pf-vertical-bg-size;\n@navbar-pf-alt-border-color: @navbar-pf-vertical-border-color;\n@navbar-pf-alt-border-style: @navbar-pf-vertical-border-style;\n@navbar-pf-alt-border-width: @navbar-pf-vertical-border-width;\n@navbar-pf-alt-color: @navbar-pf-vertical-color;\n@navbar-pf-alt-height: @navbar-pf-vertical-height;\n@navbar-pf-alt-nav-item-iconic-padding: @navbar-pf-vertical-nav-item-iconic-padding;\n@navbar-pf-alt-navbar-brand-color: @navbar-pf-vertical-navbar-brand-color;\n@navbar-pf-alt-navbar-brand-icon-margin: @navbar-pf-vertical-navbar-brand-icon-margin;\n@navbar-pf-alt-navbar-brand-margin: @navbar-pf-vertical-navbar-brand-margin;\n@navbar-pf-alt-navbar-brand-min-height: @navbar-pf-vertical-navbar-brand-min-height;\n@navbar-pf-alt-navbar-brand-name-breakpoint: @navbar-pf-vertical-navbar-brand-name-breakpoint;\n@navbar-pf-alt-navbar-brand-name-margin: @navbar-pf-vertical-navbar-brand-name-margin;\n@navbar-pf-alt-navbar-brand-padding: @navbar-pf-vertical-navbar-brand-padding;\n@navbar-pf-alt-navbar-toggle-margin: @navbar-pf-vertical-navbar-toggle-margin;\n@navbar-pf-alt-navbar-toggle-icon-bar-hover-bg: @navbar-pf-vertical-navbar-toggle-icon-bar-hover-bg;\n\n// Bootstrap overrides\n// -------------------\n@alert-info-border: @color-pf-black-500;\n@alert-link-font-weight: 500;\n@alert-padding: 11px;\n@body-bg: #ffffff;\n@border-radius-base: 1px;\n@brand-danger: @color-pf-red;\n@brand-info: #006e9c;\n@brand-primary: #00a8e1;\n@brand-success: @color-pf-green;\n@brand-warning: @color-pf-orange;\n@breadcrumb-bg: transparent;\n@breadcrumb-separator: \"\\f105\";\n@btn-danger-bg: @color-pf-red-200;\n@btn-danger-border: #781919;\n@btn-default-border: #b7b7b7;\n@btn-font-weight: 600;\n@btn-primary-bg: #0085cf;\n@btn-primary-border: #006e9c;\n@caret-width-base: 0;\n@dropdown-border: #b6b6b6;\n@dropdown-divider-bg: #e5e5e5;\n@dropdown-link-active-color: #fff;\n@dropdown-link-hover-bg: #d4edfa;\n@font-family-base: \"Open Sans\", Helvetica, Arial, sans-serif;\n@font-size-base: 12px;\n@gray-dark: lighten(#000, 20%); // #333\n@gray-darker: lighten(#000, 13.5%); // #222\n@gray-light: lighten(#000, 60%); // #999\n@gray-lighter: lighten(#000, 93.5%); // #eee\n@grid-gutter-width: 40px;\n@icon-font-path: \"../fonts/\";\n@input-bg-disabled: #F8F8F8;\n@input-border: #BABABA;\n@line-height-base: 1.66666667; // 20/12\n@link-color: #0099d3;\n@list-group-border: #f2f2f2;\n@list-group-border-radius: 0;\n@list-group-hover-bg: #d4edfa;\n@link-hover-color: #00618a;\n@nav-tabs-border-color: #e9e8e8;\n@nav-tabs-link-hover-border-color: transparent;\n@padding-large-horizontal: 10px;\n@padding-base-horizontal: 6px;\n@padding-base-vertical: 2px;\n@padding-large-vertical: 6px;\n@pager-border-radius: 0;\n@pager-disabled-color: #969696;\n@pagination-bg: #f5f5f5;\n@pagination-border: @color-pf-black-400;\n@pagination-hover-bg: #ededed;\n@panel-inner-border: #cecdcd;\n@popover-arrow-color: #fff;\n@popover-arrow-outer-color: @color-pf-black-400;\n@popover-border-color: @color-pf-black-400;\n@popover-max-width: 220px;\n@popover-title-bg: #f5f5f5;\n@pre-bg: #fcfcfc;\n@progress-bg: #ededed;\n@table-bg-accent: #f5f5f5;\n@table-bg-hover: #d5ecf9;\n@table-border-color: @color-pf-black-300;\n@table-cell-padding: 10px;\n@tooltip-arrow-width: 8px;\n@tooltip-bg: #434343;\n@tooltip-max-width: 220px;\n// Reference variables declared in block above\n@alert-danger-bg: #fbe7e7;\n@alert-danger-border: @brand-danger;\n@alert-danger-text: @gray-dark;\n@alert-info-bg: #f2f2f2;\n@alert-info-text: @gray-dark;\n@alert-success-bg: #e8f9e7;\n@alert-success-border: @brand-success;\n@alert-success-text: @gray-dark;\n@alert-warning-bg: #fdf4ea;\n@alert-warning-border: @brand-warning;\n@alert-warning-text: @gray-dark;\n@badge-border-radius: @border-radius-base;\n@border-radius-large: @border-radius-base;\n@border-radius-small: @border-radius-base;\n@breadcrumb-active-color: @gray-pf;\n@breadcrumb-color: @gray-pf;\n@btn-default-bg: @gray-lighter;\n@btn-default-color: @gray-pf;\n@caret-width-large: @caret-width-base;\n@dropdown-fallback-border: @dropdown-border;\n@dropdown-link-active-bg: @link-color;\n@dropdown-link-hover-color: @gray-pf;\n@font-size-h1: ceil((@font-size-base * 2)); // ~24px\n@font-size-h2: ceil((@font-size-base * 1.8333)); // ~22px\n@font-size-h3: ceil((@font-size-base * 1.3333)); // ~16px\n@font-size-h5: ceil((@font-size-base * 1.0833)); // ~13px\n@font-size-large: ceil((@font-size-base * 1.1666)); // ~14px\n@font-size-small: ceil((@font-size-base * .9166)); // ~11px\n@input-color: @gray-dark;\n@nav-tabs-active-link-hover-color: @link-color;\n@nav-tabs-justified-link-border-color: @nav-tabs-border-color;\n@padding-small-horizontal: @padding-base-horizontal;\n@padding-small-vertical: @padding-base-vertical;\n@panel-danger-border: @brand-danger;\n@panel-danger-heading-bg: @brand-danger;\n@panel-info-border: @brand-info;\n@panel-info-heading-bg: @brand-info;\n@panel-primary-text: @body-bg;\n@panel-success-border: @brand-success;\n@panel-success-heading-bg: @brand-success;\n@panel-warning-border: @brand-warning;\n@panel-warning-heading-bg: @brand-warning;\n@state-warning-text: @brand-warning;\n// Reference variable declared in block above\n@panel-danger-text: @panel-primary-text;\n@panel-info-text: @panel-primary-text;\n@panel-success-text: @panel-primary-text;\n@panel-warning-text: @panel-primary-text;\n\n// PatternFly-specific variables based on Bootstrap overides\n// ---------------------------------------------------------\n@bootstrap-switch-bg-color: @btn-default-bg;\n@btn-danger-bg-img-start: @brand-danger;\n@btn-danger-bg-img-stop: @btn-danger-bg;\n@btn-primary-bg-img-start: @brand-primary;\n@btn-primary-bg-img-stop: @btn-primary-bg;\n@dropdown-link-focus-bg: @link-color;\n@line-height-computed: floor((@font-size-base * @line-height-base));\n@notification-badge-color: @brand-danger;\n@progress-sm: (@line-height-computed - 6);\n@progress-xs: (@line-height-computed - 14);\n@syntax-1: @btn-danger-bg;\n@syntax-2: @gray-dark;\n@syntax-3: @brand-success;\n@syntax-4: @brand-info;\n@tooltip-font-size: @font-size-base;\n","//\n// Mixins\n// --------------------------------------------------\n// Bootstrap overrides and PatternFly-specific mixins\n\n// Bootstrap overrides\n// -------------------\n\n// Button variants\n.button-variant(@color; @background; @background-image-start; @background-image-stop; @border) {\n background-color: @background;\n #gradient > .vertical(@background-image-start, @background-image-stop);\n border-color: @border;\n color: @color;\n\n &:hover,\n &:focus,\n &:active,\n &.active,\n .open .dropdown-toggle& {\n background-color: @background;\n background-image: none;\n border-color: @border;\n color: @color;\n }\n &:active,\n &.active,\n .open .dropdown-toggle& {\n background-image: none;\n &:hover,\n &:focus,\n &.focus {\n background-color: darken(@background, 5%);\n border-color: darken(@border, 7%);\n }\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border\n }\n }\n}\n\n// Form control outline\n.form-control-outline(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0 !important;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Gradients\n#gradient {\n .striped(@color: rgba(0,0,0,.15); @angle: -45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, @color 26%, transparent 27%, transparent 49%, @color 50%, @color 51%, transparent 52%, transparent 74%, @color 75%, @color 76%, transparent 77%);\n background-image: linear-gradient(@angle, @color 25%, @color 26%, transparent 27%, transparent 49%, @color 50%, @color 51%, transparent 52%, transparent 74%, @color 75%, @color 76%, transparent 77%);\n }\n}\n\n// Horizontal dividers\n.nav-divider(@color: #e5e5e5, @margin: 4px 1px) {\n background-color: @color;\n height: 1px;\n margin: @margin;\n overflow: hidden;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &:-moz-placeholder { color: @color; font-style: italic; } // Firefox 4-18\n &::-moz-placeholder { color: @color; font-style: italic; opacity: 1; } // Firefox 19+\n &:-ms-input-placeholder { color: @color; font-style: italic; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; font-style: italic; } // Safari and Chrome\n}\n\n// PatternFly-specific\n// -------------------\n\n.tab-indicator(@background: @gray-light-pf, @left: 15px, @right: 15px) {\n &:before {\n background: @background;\n bottom: -1px;\n content: '';\n display: block;\n height: 2px;\n left: @left;\n position: absolute;\n right: @right;\n }\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","//\n// Bootstrap-Datepicker\n// --------------------------------------------------\n\n.bootstrap-datepicker.form-control[readonly] {\n background-color: @input-bg;\n border-color: @input-border !important;\n color: @input-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .form-control-focus();\n &:focus {\n border-color: @input-border-focus !important;\n .has-error & {\n border-color: darken(@state-danger-text, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@state-danger-text, 20%);\n .box-shadow(@shadow);\n }\n .has-success & {\n border-color: darken(@state-success-text, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@state-success-text, 20%);\n .box-shadow(@shadow);\n }\n .has-warning & {\n border-color: darken(@state-warning-text, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@state-warning-text, 20%);\n .box-shadow(@shadow);\n }\n }\n &:hover {\n border-color: @input-border-hover !important;\n .has-error & {\n border-color: darken(@state-danger-text, 10%) !important;\n }\n .has-success & {\n border-color: darken(@state-success-text, 10%) !important;\n }\n .has-warning & {\n border-color: darken(@state-warning-text, 10%) !important;\n }\n }\n .has-error & {\n border-color: @state-danger-text !important;\n }\n .has-success & {\n border-color: @state-success-text !important;\n }\n .has-warning & {\n border-color: @state-warning-text !important;\n }\n}\n\n.datepicker {\n border-radius: @border-radius-base;\n .datepicker-switch,\n tfoot .clear,\n tfoot .today {\n font-size: @font-size-large;\n font-weight: 500;\n }\n .next,\n .prev {\n font-weight: 500;\n }\n table tr {\n td,\n th {\n border-radius: @border-radius-base;\n }\n td {\n &.active.active,\n &.active.active:hover,\n &.active.active.disabled,\n &.active.active.disabled:hover {\n background: @dropdown-link-active-bg !important;\n color: #fff !important;\n text-shadow: none;\n }\n &.day:hover,\n &.day.focused {\n background: @dropdown-link-hover-bg;\n }\n &.selected,\n &.selected:hover,\n &.selected.disabled,\n &.selected.disabled:hover {\n text-shadow: none;\n }\n span {\n border-radius: @border-radius-base;\n &.active.active,\n &.active.active:hover,\n &.active.active.disabled,\n &.active.active.disabled:hover {\n background: @dropdown-link-active-bg;\n text-shadow: none;\n }\n &:hover {\n background: @dropdown-link-hover-bg;\n }\n }\n }\n }\n thead tr:first-child th,\n tfoot tr th {\n &:hover {\n background: @dropdown-link-hover-bg;\n }\n }\n}\n\n.input-daterange {\n input:first-child {\n border-radius: @border-radius-base 0 0 @border-radius-base;\n }\n input:last-child {\n border-radius: 0 @border-radius-base @border-radius-base 0;\n }\n .input-group-addon {\n background-color: @input-group-addon-bg;\n border-color: @input-group-addon-border-color;\n line-height: @line-height-base;\n padding: @padding-base-vertical @padding-base-horizontal;\n }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `s in some browsers, due to the limited stylability of `s in IE10+.\n &::-ms-expand {\n border: 0;\n background-color: transparent;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 8.3, iOS doesn't support `datetime` or `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n &.form-control {\n line-height: @input-height-base;\n }\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because