diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 3864ea8adc..1dde85034e 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -35,7 +35,6 @@ import org.eclipse.che.api.factory.server.FactoryCreateValidator; import org.eclipse.che.api.factory.server.FactoryEditValidator; import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.machine.shared.Constants; -import org.eclipse.che.api.user.server.TokenValidator; import org.eclipse.che.api.workspace.server.WorkspaceConfigMessageBodyAdapter; import org.eclipse.che.api.workspace.server.WorkspaceMessageBodyAdapter; import org.eclipse.che.api.workspace.server.stack.StackMessageBodyAdapter; @@ -86,8 +85,6 @@ public class WsMasterModule extends AbstractModule { bind(org.eclipse.che.api.user.server.CheUserCreator.class); - bind(TokenValidator.class).to(org.eclipse.che.api.local.DummyTokenValidator.class); - bind(org.eclipse.che.api.core.rest.ApiInfoService.class); bind(org.eclipse.che.api.project.server.template.ProjectTemplateDescriptionLoader.class).asEagerSingleton(); bind(org.eclipse.che.api.project.server.template.ProjectTemplateRegistry.class); diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java index 8a6e3d9892..9a201f27d4 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java @@ -48,7 +48,6 @@ public class WsMasterServletModule extends ServletModule { filter("/*").through(CorsFilter.class, corsFilterParams); - filter("/api/*").through(org.eclipse.che.api.local.filters.EnvironmentInitializationFilter.class); serveRegex("^/api((?!(/(ws|eventbus)($|/.*)))/.*)").with(GuiceEverrestServlet.class); install(new org.eclipse.che.swagger.deploy.BasicSwaggerConfigurationModule()); } diff --git a/assembly2/assembly-ide-war/src/main/patches/src/main/webapp/IDE.jsp.patch b/assembly2/assembly-ide-war/src/main/patches/src/main/webapp/IDE.jsp.patch index 87fc7eb693..1b46d7a87b 100644 --- a/assembly2/assembly-ide-war/src/main/patches/src/main/webapp/IDE.jsp.patch +++ b/assembly2/assembly-ide-war/src/main/patches/src/main/webapp/IDE.jsp.patch @@ -7,8 +7,8 @@ + + - \ No newline at end of file + diff --git a/assembly2/assembly-ide-war/src/main/webapp/WEB-INF/keycloak.json b/assembly2/assembly-ide-war/src/main/webapp/WEB-INF/keycloak.json index 54de3dc50c..93ab8c0a65 100644 --- a/assembly2/assembly-ide-war/src/main/webapp/WEB-INF/keycloak.json +++ b/assembly2/assembly-ide-war/src/main/webapp/WEB-INF/keycloak.json @@ -1,7 +1,7 @@ { - "realm" : "Che", + "realm" : "che", "resource" : "che-public", - "auth-server-url" : "http://172.19.20.18:5050/auth", + "auth-server-url" : "http://172.17.0.1:5050/auth", "ssl-required" : "external", "enable-cors" : true, "bearer-only" : false, diff --git a/assembly2/assembly-wsagent-war/pom.xml b/assembly2/assembly-wsagent-war/pom.xml index 303a95364c..c52fcab9f5 100644 --- a/assembly2/assembly-wsagent-war/pom.xml +++ b/assembly2/assembly-wsagent-war/pom.xml @@ -80,15 +80,15 @@ WEB-INF/lib/*gwt*.jar, WEB-INF/lib/gin-*.jar, WEB-INF/lib/jsr305*.jar - - - ${basedir}/src/main/webapp/WEB-INF - WEB-INF - - **/* - - - + + + ${basedir}/src/main/webapp/WEB-INF + WEB-INF + + **/* + + + diff --git a/assembly2/assembly-wsagent-war/src/main/webapp/WEB-INF/keycloak.json b/assembly2/assembly-wsagent-war/src/main/webapp/WEB-INF/keycloak.json index 22f7c39af4..3766b69899 100644 --- a/assembly2/assembly-wsagent-war/src/main/webapp/WEB-INF/keycloak.json +++ b/assembly2/assembly-wsagent-war/src/main/webapp/WEB-INF/keycloak.json @@ -1,7 +1,7 @@ { - "realm" : "Che", + "realm" : "che", "resource" : "che-public", - "auth-server-url" : "http://172.19.20.18:5050/auth", + "auth-server-url" : "http://172.17.0.1:5050/auth", "ssl-required" : "external", "enable-cors" : true, "bearer-only" : true, diff --git a/assembly2/assembly-wsmaster-war/pom.xml b/assembly2/assembly-wsmaster-war/pom.xml index b953783664..448af0f4d9 100644 --- a/assembly2/assembly-wsmaster-war/pom.xml +++ b/assembly2/assembly-wsmaster-war/pom.xml @@ -80,6 +80,9 @@ + + WEB-INF/lib/wsmaster-local*.jar, + diff --git a/assembly2/assembly-wsmaster-war/src/main/webapp/WEB-INF/keycloak.json b/assembly2/assembly-wsmaster-war/src/main/webapp/WEB-INF/keycloak.json index 9db5fb8356..badd19b1fc 100644 --- a/assembly2/assembly-wsmaster-war/src/main/webapp/WEB-INF/keycloak.json +++ b/assembly2/assembly-wsmaster-war/src/main/webapp/WEB-INF/keycloak.json @@ -1,9 +1,9 @@ { - "realm": "Che", - "auth-server-url": "http://172.19.20.18:5050/auth", + "realm": "che", + "auth-server-url": "http://172.17.0.1:5050/auth", "ssl-required": "external", "resource": "che", "credentials": { - "secret": "f5967907-9a29-4713-971a-9776b830caa2" + "secret": "7be16729-d151-46d4-97cd-5e6d5205b567" } -} \ No newline at end of file +} diff --git a/assembly2/dashboard/src/main/patches/src/app/index.module.ts.patch b/assembly2/dashboard/src/main/patches/src/app/index.module.ts.patch index 3dd71704e9..9b91d4bbe9 100644 --- a/assembly2/dashboard/src/main/patches/src/app/index.module.ts.patch +++ b/assembly2/dashboard/src/main/patches/src/app/index.module.ts.patch @@ -8,8 +8,8 @@ + + +let keycloakConfig = { -+ "url": "http://172.19.20.18:5050/auth", -+ "realm": "Che", ++ "url": "http://172.17.0.1:5050/auth", ++ "realm": "che", + "clientId": "che-public", +}; diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/pom.xml b/plugins/plugin-keycloak/che-plugin-keycloak-server/pom.xml index 6c39777bb9..74b892214b 100644 --- a/plugins/plugin-keycloak/che-plugin-keycloak-server/pom.xml +++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/pom.xml @@ -42,10 +42,22 @@ org.eclipse.che.core che-core-api-core + + org.eclipse.che.core + che-core-api-model + + + org.eclipse.che.core + che-core-api-user + org.eclipse.che.core che-core-commons-inject + + org.keycloak + keycloak-core + org.keycloak keycloak-servlet-filter-adapter diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java new file mode 100644 index 0000000000..1371c3c97e --- /dev/null +++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.keycloak.server; + +import org.eclipse.che.api.core.ConflictException; +import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.core.model.user.User; +import org.eclipse.che.api.user.server.UserManager; +import org.eclipse.che.api.user.server.model.impl.UserImpl; +import org.eclipse.che.commons.env.EnvironmentContext; +import org.eclipse.che.commons.subject.Subject; +import org.eclipse.che.commons.subject.SubjectImpl; +import org.keycloak.KeycloakSecurityContext; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.security.Principal; + +import static java.util.Collections.emptyList; + +/** + * @author Max Shaposhnik (mshaposhnik@redhat.com) + */ +@Singleton +public class KeycloakEnvironmentInitalizationFilter implements Filter { + + @Inject + private UserManager userManager; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws IOException, ServletException { + + final HttpServletRequest httpRequest = (HttpServletRequest)request; + final HttpSession session = httpRequest.getSession(); + final KeycloakSecurityContext context = (KeycloakSecurityContext)session.getAttribute(KeycloakSecurityContext.class.getName()); + + User user; + + try { + user = userManager.getById(context.getIdToken().getSubject()); + } catch (NotFoundException ex) { + try { + final UserImpl cheUser = new UserImpl(context.getIdToken().getSubject(), + context.getIdToken().getEmail(), + context.getIdToken().getPreferredUsername(), + "secret", + emptyList()); + user = userManager.create(cheUser, false); + } catch (ServerException | ConflictException e) { + throw new ServletException("Unable to create new user"); + } + } catch (ServerException e) { + throw new ServletException("Unable to get user"); + } + final Subject subject = + new SubjectImpl(user.getName(), user.getId(), context.getTokenString(), false); + session.setAttribute("codenvy_user", subject); + + final EnvironmentContext environmentContext = EnvironmentContext.getCurrent(); + try { + environmentContext.setSubject(subject); + filterChain.doFilter(addUserInRequest(httpRequest, subject), response); + } finally { + EnvironmentContext.reset(); + } + } + + private HttpServletRequest addUserInRequest(final HttpServletRequest httpRequest, final Subject subject) { + return new HttpServletRequestWrapper(httpRequest) { + @Override + public String getRemoteUser() { + return subject.getUserName(); + } + + @Override + public Principal getUserPrincipal() { + return subject::getUserName; + } + }; + } + + @Override + public void destroy() { + } +} diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakTokenValidator.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakTokenValidator.java new file mode 100644 index 0000000000..250d4352f1 --- /dev/null +++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakTokenValidator.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.keycloak.server; + +import org.eclipse.che.api.core.ConflictException; +import org.eclipse.che.api.core.model.user.User; +import org.eclipse.che.api.user.server.TokenValidator; +import org.eclipse.che.api.user.server.model.impl.UserImpl; +import org.eclipse.che.commons.env.EnvironmentContext; +import org.eclipse.che.commons.subject.Subject; + +/** + * @author Max Shaposhnik (mshaposhnik@redhat.com) + */ +public class KeycloakTokenValidator implements TokenValidator { + @Override + public User validateToken(String token) throws ConflictException { + final Subject subject = EnvironmentContext.getCurrent().getSubject(); + return new UserImpl(subject.getUserId(), "", subject.getUserName()); + } +} diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakModule.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakModule.java index 1fa66be3b5..c507479c41 100644 --- a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakModule.java +++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakModule.java @@ -13,7 +13,9 @@ package org.eclipse.che.keycloak.server.deploy; import com.google.inject.AbstractModule; import org.eclipse.che.api.core.rest.HttpJsonRequestFactory; +import org.eclipse.che.api.user.server.TokenValidator; import org.eclipse.che.inject.DynaModule; +import org.eclipse.che.keycloak.server.KeycloakTokenValidator; @DynaModule @@ -21,6 +23,6 @@ public class KeycloakModule extends AbstractModule { @Override protected void configure() { bind(HttpJsonRequestFactory.class).to(org.eclipse.che.keycloak.server.KeycloakHttpJsonRequestFactory.class); - + bind(TokenValidator.class).to(KeycloakTokenValidator.class); } } diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java index 79df5bd3c9..f75ca14ca8 100644 --- a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java +++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java @@ -14,6 +14,7 @@ import com.google.inject.servlet.ServletModule; import org.eclipse.che.inject.DynaModule; import org.eclipse.che.keycloak.server.KeycloakAuthenticationFilter; +import org.eclipse.che.keycloak.server.KeycloakEnvironmentInitalizationFilter; import javax.inject.Singleton; @@ -24,5 +25,6 @@ public class KeycloakServletModule extends ServletModule { protected void configureServlets() { bind(KeycloakAuthenticationFilter.class).in(Singleton.class); filter("/*").through(KeycloakAuthenticationFilter.class); + filter("/*").through(KeycloakEnvironmentInitalizationFilter.class); } } diff --git a/pom.xml b/pom.xml index 8436591451..7ddbbdb66c 100644 --- a/pom.xml +++ b/pom.xml @@ -1174,6 +1174,11 @@ che-sample-plugin-wizard-shared ${che.version} + + org.keycloak + keycloak-core + ${org.keycloak.version} + org.keycloak keycloak-servlet-filter-adapter diff --git a/wsmaster/wsmaster-local/pom.xml b/wsmaster/wsmaster-local/pom.xml index f7d8acbd88..173f3f4520 100644 --- a/wsmaster/wsmaster-local/pom.xml +++ b/wsmaster/wsmaster-local/pom.xml @@ -24,6 +24,14 @@ false + + com.google.inject + guice + + + com.google.inject.extensions + guice-servlet + javax.inject javax.inject @@ -40,6 +48,10 @@ org.eclipse.che.core che-core-api-user + + org.eclipse.che.core + che-core-commons-inject + javax.servlet javax.servlet-api diff --git a/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalModule.java b/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalModule.java new file mode 100644 index 0000000000..f10194c530 --- /dev/null +++ b/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalModule.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.api.local; + +import com.google.inject.AbstractModule; + +import org.eclipse.che.api.user.server.TokenValidator; +import org.eclipse.che.inject.DynaModule; + +/** + * @author Max Shaposhnik (mshaposhnik@redhat.com) + */ +@DynaModule +public class LocalModule extends AbstractModule { + @Override + protected void configure() { + bind(TokenValidator.class).to(org.eclipse.che.api.local.DummyTokenValidator.class); + } +} diff --git a/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalServletModule.java b/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalServletModule.java new file mode 100644 index 0000000000..8493eb2276 --- /dev/null +++ b/wsmaster/wsmaster-local/src/main/java/org/eclipse/che/api/local/LocalServletModule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.api.local; + +import com.google.inject.servlet.ServletModule; + +import org.eclipse.che.inject.DynaModule; + +/** + * @author Max Shaposhnik (mshaposhnik@redhat.com) + */ +@DynaModule +public class LocalServletModule extends ServletModule { + @Override + protected void configureServlets() { + filter("/api/*").through(org.eclipse.che.api.local.filters.EnvironmentInitializationFilter.class); + } +}