Skip to content

Commit

Permalink
Hazelcast session store (#694)
Browse files Browse the repository at this point in the history
* Moving pac4j bundle registration

* Fixing enforcer

* Fixing enforcer

* First pass SessionProvider

* Getting OidcProfile from Mongo

* Handling null pointer profile

* Hazelcast session store in abstract base module

* Update SessionProvider

* Setting localhost member

* Passing Hazelcast config yaml file

* Formatting fix

* Updating Hazelcast config file

* Fixing style

* Removing unneeded conditional

* Adding license header

* Removing guava

* Updating legend versions

* Fixing legend versions
  • Loading branch information
ivan-kyosev-gs authored Aug 23, 2023
1 parent 07e86c0 commit a9fe514
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 13 deletions.
15 changes: 15 additions & 0 deletions legend-sdlc-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@
<!-- ENGINE -->

<!-- SHARED -->
<dependency>
<groupId>org.finos.legend.shared</groupId>
<artifactId>legend-shared-pac4j</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.finos.legend.shared</groupId>
<artifactId>legend-shared-pac4j-kerberos</artifactId>
Expand Down Expand Up @@ -177,6 +187,11 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.pac4j.jax-rs</groupId>
<artifactId>core</artifactId>
</dependency>

<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import java.time.Instant;
import java.util.Objects;

class GitLabSessionBuilder extends SessionBuilder<GitLabSession>
public class GitLabSessionBuilder extends SessionBuilder<GitLabSession>
{
private final GitLabTokenManager tokenManager;

Expand Down Expand Up @@ -130,7 +130,7 @@ static boolean isSupportedProfile(CommonProfile profile)
return (profile instanceof KerberosProfile) || (profile instanceof OidcProfile) || (profile instanceof GitlabPersonalAccessTokenProfile);
}

static GitLabSessionBuilder newBuilder(GitLabAppInfo appInfo)
public static GitLabSessionBuilder newBuilder(GitLabAppInfo appInfo)
{
return new GitLabSessionBuilder(GitLabTokenManager.newTokenManager(appInfo));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.finos.legend.sdlc.server.gitlab.auth.GitLabSession;
import org.finos.legend.sdlc.server.gitlab.auth.GitLabUserContext;
import org.finos.legend.sdlc.server.resources.BaseResource;
import org.finos.legend.sdlc.server.tools.SessionUtil;
import org.finos.legend.sdlc.server.tools.SessionProvider;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -31,23 +31,30 @@
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import static org.finos.legend.sdlc.server.auth.LegendSDLCWebFilter.SESSION_ATTRIBUTE;

@Path("/auth")
public class GitLabAuthCheckResource extends BaseResource
{

private final HttpServletRequest httpRequest;
private final HttpServletResponse httpResponse;
private final GitLabAuthorizerManager authorizerManager;
private final GitLabAppInfo appInfo;
private final SessionProvider sessionProvider;

@Inject
public GitLabAuthCheckResource(HttpServletRequest httpRequest, HttpServletResponse httpResponse, GitLabAuthorizerManager authorizerManager, GitLabAppInfo appInfo)
public GitLabAuthCheckResource(HttpServletRequest httpRequest,
HttpServletResponse httpResponse,
GitLabAuthorizerManager authorizerManager,
GitLabAppInfo appInfo,
SessionProvider sessionProvider)
{
super();
this.httpRequest = httpRequest;
this.httpResponse = httpResponse;
this.authorizerManager = authorizerManager;
this.appInfo = appInfo;
this.sessionProvider = sessionProvider;
}

@GET
Expand All @@ -57,7 +64,13 @@ public boolean isAuthorized()
{
return executeWithLogging("checking authorization", () ->
{
Session session = SessionUtil.findSession(httpRequest);
Session session = SessionProvider.findSession(httpRequest);

if (session == null)
{
session = sessionProvider.getSessionFromSessionStore(httpRequest, httpResponse, appInfo);
httpRequest.setAttribute(SESSION_ATTRIBUTE, session);
}

if (session instanceof GitLabSession)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.inject.Binder;
import com.google.inject.Provides;
import com.hubspot.dropwizard.guicier.DropwizardAwareModule;
import org.eclipse.collections.api.factory.Maps;
import org.finos.legend.sdlc.server.BaseLegendSDLCServer;
import org.finos.legend.sdlc.server.BaseServer.ServerInfo;
import org.finos.legend.sdlc.server.config.LegendSDLCServerConfiguration;
Expand Down Expand Up @@ -224,6 +225,14 @@
import org.finos.legend.sdlc.server.resources.workflow.project.user.WorkspaceWorkflowsResource;
import org.finos.legend.sdlc.server.resources.workspace.project.user.WorkspacesResource;
import org.finos.legend.sdlc.server.tools.BackgroundTaskProcessor;
import org.finos.legend.sdlc.server.tools.SessionProvider;
import org.finos.legend.server.pac4j.LegendPac4jConfiguration;
import org.finos.legend.server.pac4j.hazelcaststore.HazelcastSessionStore;
import org.pac4j.core.context.J2EContext;
import org.pac4j.core.context.session.J2ESessionStore;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.jax.rs.pac4j.JaxRsContext;
import org.pac4j.jax.rs.servlet.pac4j.ServletSessionStore;

import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -257,6 +266,7 @@ public void configure(Binder binder)
binder.bind(LegendSDLCServerFeaturesConfiguration.class).toProvider(this::getFeaturesConfiguration);
binder.bind(BackgroundTaskProcessor.class).toProvider(this.server::getBackgroundTaskProcessor);
binder.bind(ProjectStructurePlatformExtensions.class).toInstance(buildProjectStructurePlatformExtensions());
binder.bind(SessionProvider.class).toProvider(this::getSessionProvider);

bindResources(binder);
}
Expand Down Expand Up @@ -539,6 +549,25 @@ private AuthClientInjector resolveAuthClientInjector()
return builder -> builder;
}

private SessionProvider getSessionProvider()
{
LegendPac4jConfiguration config = getConfiguration().getPac4jConfiguration();
return new SessionProvider(getSessionStoreFromConfig(config));
}

private SessionStore getSessionStoreFromConfig(LegendPac4jConfiguration config)
{
if (config.getHazelcastSession() != null && config.getHazelcastSession().isEnabled())
{
return new HazelcastSessionStore(
config.getHazelcastSession().getConfigFilePath(),
Maps.immutable.with(
J2EContext.class, new J2ESessionStore(),
JaxRsContext.class, new ServletSessionStore()).castToMap());
}
return null;
}

@Provides
@Named("applicationName")
public String provideApplicationName(LegendSDLCServerConfiguration configuration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
import com.google.inject.servlet.RequestScoped;
import org.finos.legend.sdlc.server.auth.Session;
import org.finos.legend.sdlc.server.error.LegendSDLCServerException;
import org.finos.legend.sdlc.server.tools.SessionUtil;
import org.finos.legend.sdlc.server.tools.SessionProvider;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@RequestScoped
public class UserContext
{
Expand All @@ -37,7 +36,7 @@ public UserContext(HttpServletRequest httpRequest, HttpServletResponse httpRespo
{
this.httpRequest = httpRequest;
this.httpResponse = httpResponse;
this.session = LegendSDLCServerException.validateNonNull(SessionUtil.findSession(httpRequest), "Invalid request");
this.session = LegendSDLCServerException.validateNonNull(SessionProvider.findSession(httpRequest), "Invalid request");
}

public String getCurrentUser()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,56 @@

import org.finos.legend.sdlc.server.auth.LegendSDLCWebFilter;
import org.finos.legend.sdlc.server.auth.Session;
import org.finos.legend.sdlc.server.gitlab.GitLabAppInfo;
import org.finos.legend.sdlc.server.gitlab.auth.GitLabSessionBuilder;
import org.finos.legend.server.pac4j.gitlab.GitlabClient;
import org.pac4j.core.context.J2EContext;
import org.pac4j.core.context.Pac4jConstants;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.profile.CommonProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;

public class SessionUtil
public class SessionProvider
{

private static final Logger LOGGER = LoggerFactory.getLogger(SessionUtil.class);
private static final Logger LOGGER = LoggerFactory.getLogger(SessionProvider.class);

private final SessionStore sessionStore;

public SessionProvider(SessionStore sessionStore)
{
this.sessionStore = sessionStore;
}

public Session getSessionFromSessionStore(HttpServletRequest httpRequest, HttpServletResponse httpResponse, GitLabAppInfo appInfo)
{
if (sessionStore != null)
{
WebContext context = new J2EContext(httpRequest, httpResponse);
Map<String, CommonProfile> profileMap =
(Map<String, CommonProfile>) sessionStore.get(context, Pac4jConstants.USER_PROFILES);

if (profileMap != null)
{
CommonProfile profile = profileMap.get(GitlabClient.GITLAB_CLIENT_NAME);
if (profile != null)
{
return GitLabSessionBuilder.newBuilder(appInfo).withProfile(profile).build();
}
}
}

return null;
}

public static Session findSession(ServletRequest request)
{
Expand Down
3 changes: 3 additions & 0 deletions legend-sdlc-server/src/test/resources/config-sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ pac4j:
secret: $APP_SECRET
discoveryUri: https://$GITLAB_HOST/.well-known/openid-configuration
scope: openid profile api
# hazelcastSession:
# enabled: true
# configFilePath: legend-sdlc-server/src/test/resources/hazelcast.yaml
bypassPaths:
- /api/info
- /api/server/info
Expand Down
31 changes: 31 additions & 0 deletions legend-sdlc-server/src/test/resources/hazelcast.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2023 Goldman Sachs
#
# 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.

hazelcast:
cluster-name: legend-hazelcast-session-store-cluster
instance-name: legend-hazelcast-session-store
network:
port:
port: 5701
auto-increment: false
join:
multicast:
enabled: false
tcp-ip:
enabled: true
member-list:
- localhost
map:
session-store:
time-to-live-seconds: 7200
9 changes: 7 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@
<java.version.range>[11,12),[17,18)</java.version.range>

<!-- Legend dependency versions -->
<legend.engine.version>4.24.0</legend.engine.version>
<legend.engine.version>4.25.0</legend.engine.version>
<legend.pure.version>4.5.11</legend.pure.version>
<legend.shared.version>0.23.8</legend.shared.version>
<legend.shared.version>0.24.0</legend.shared.version>

<!-- Dependency versions -->
<commons-codec.version>1.15</commons-codec.version>
Expand Down Expand Up @@ -1379,6 +1379,11 @@
<artifactId>pac4j-oidc</artifactId>
<version>${pac4j.version}</version>
</dependency>
<dependency>
<groupId>org.pac4j.jax-rs</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
Expand Down

0 comments on commit a9fe514

Please sign in to comment.