From 64126dc5dfec53b6d183976101ab84a4fc76927e Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Mon, 19 Dec 2022 18:25:04 -0500 Subject: [PATCH 1/2] feat(CK Board): Log out of CK Board when user logs out of SCORE #7 --- .../service/session/SessionService.java | 6 ++ .../session/impl/SessionServiceImpl.java | 63 +++++++++++++++++-- .../portal/spring/impl/WISELogoutHandler.java | 9 ++- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/wise/portal/service/session/SessionService.java b/src/main/java/org/wise/portal/service/session/SessionService.java index ad1f0f9b78..5f716f1c8f 100644 --- a/src/main/java/org/wise/portal/service/session/SessionService.java +++ b/src/main/java/org/wise/portal/service/session/SessionService.java @@ -3,6 +3,8 @@ import java.io.Serializable; import java.util.Set; +import javax.servlet.http.HttpServletRequest; + import org.springframework.security.core.userdetails.UserDetails; public interface SessionService { @@ -28,4 +30,8 @@ public interface SessionService { void removeCurrentAuthor(Serializable projectdId, String authorUsername); void removeUser(UserDetails user); + + boolean isCkBoardAvailable(); + + void signOutOfCkBoard(HttpServletRequest request); } diff --git a/src/main/java/org/wise/portal/service/session/impl/SessionServiceImpl.java b/src/main/java/org/wise/portal/service/session/impl/SessionServiceImpl.java index 0b434b8f25..8ab212aac8 100644 --- a/src/main/java/org/wise/portal/service/session/impl/SessionServiceImpl.java +++ b/src/main/java/org/wise/portal/service/session/impl/SessionServiceImpl.java @@ -1,9 +1,17 @@ package org.wise.portal.service.session.impl; +import java.io.IOException; import java.io.Serializable; import java.util.Set; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.HttpClientBuilder; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.session.Session; @@ -15,6 +23,9 @@ @Service public class SessionServiceImpl implements SessionService { + @Autowired + private Environment appProperties; + @Autowired private StringRedisTemplate stringRedisTemplate; @@ -63,8 +74,8 @@ public void addCurrentAuthor(Serializable projectId, String authorUsername) { @Override public void removeCurrentAuthor(UserDetails author) { - Set currentlyAuthoredProjects = - stringRedisTemplate.opsForSet().members("currentlyAuthoredProjects"); + Set currentlyAuthoredProjects = stringRedisTemplate.opsForSet() + .members("currentlyAuthoredProjects"); for (String projectId : currentlyAuthoredProjects) { removeCurrentAuthor(projectId, author.getUsername()); } @@ -72,8 +83,8 @@ public void removeCurrentAuthor(UserDetails author) { public void removeCurrentAuthor(Serializable projectId, String authorUsername) { stringRedisTemplate.opsForSet().remove("currentAuthors:" + projectId, authorUsername); - Long numCurrentAuthorsForProject = - stringRedisTemplate.opsForSet().size("currentAuthors:" + projectId); + Long numCurrentAuthorsForProject = stringRedisTemplate.opsForSet() + .size("currentAuthors:" + projectId); if (numCurrentAuthorsForProject == 0) { stringRedisTemplate.opsForSet().remove("currentlyAuthoredProjects", projectId.toString()); } @@ -90,4 +101,48 @@ public void removeUser(UserDetails user) { public Set getCurrentAuthors(Serializable projectId) { return stringRedisTemplate.opsForSet().members("currentAuthors:" + projectId); } + + public boolean isCkBoardAvailable() { + String ckBoardUrl = appProperties.getProperty("ck_board_url"); + return ckBoardUrl != null && !ckBoardUrl.equals(""); + } + + public void signOutOfCkBoard(HttpServletRequest request) { + String ckSessionCookie = getCkSessionCookie(request); + HttpClient client = HttpClientBuilder.create().build(); + HttpPost ckBoardLogoutRequest = new HttpPost(getCkBoardLogoutUrl()); + ckBoardLogoutRequest.setHeader("Authorization", "Bearer " + ckSessionCookie); + try { + client.execute(ckBoardLogoutRequest); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String getCkBoardLogoutUrl() { + String ckBoardUrl = appProperties.getProperty("ck_board_url"); + + // The CK Board local backend url is only used for local development and should only be set in + // local development environments. When we are running locally, we need the local IP and port of + // the CK Board backend because the SCORE API is served using Docker. If the SCORE API makes a + // request to localhost:8001, it won't be able to access the CK Board backend. This is because + // the SCORE API expects localhost to be within the container but the CK Board backend is not in + // the container. + String ckBoardLocalBackendUrl = appProperties.getProperty("ck_board_local_backend_url"); + if (ckBoardLocalBackendUrl != null && !ckBoardLocalBackendUrl.equals("")) { + ckBoardUrl = ckBoardLocalBackendUrl; + } + return ckBoardUrl + "/api/auth/logout"; + } + + private String getCkSessionCookie(HttpServletRequest request) { + Cookie[] cookies = request.getCookies(); + for (Cookie cookie : cookies) { + if (cookie.getName().equals("CK_SESSION")) { + return cookie.getValue(); + } + } + return null; + } + } diff --git a/src/main/java/org/wise/portal/spring/impl/WISELogoutHandler.java b/src/main/java/org/wise/portal/spring/impl/WISELogoutHandler.java index dff46617c0..a9b703a450 100644 --- a/src/main/java/org/wise/portal/spring/impl/WISELogoutHandler.java +++ b/src/main/java/org/wise/portal/spring/impl/WISELogoutHandler.java @@ -38,17 +38,20 @@ import org.springframework.session.Session; import org.wise.portal.service.session.SessionService; -public class WISELogoutHandler implements LogoutHandler, - ApplicationListener { +public class WISELogoutHandler + implements LogoutHandler, ApplicationListener { @Autowired protected SessionService sessionService; @Override - public void logout(HttpServletRequest request, HttpServletResponse response, + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { if (authentication != null) { sessionService.removeUser((UserDetails) authentication.getPrincipal()); + if (sessionService.isCkBoardAvailable()) { + sessionService.signOutOfCkBoard(request); + } } } From d23f8ba3e8c9dcfff1bddd2d0c714c0051815a54 Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Mon, 19 Dec 2022 18:42:23 -0500 Subject: [PATCH 2/2] chore(CK Board): Add application property variable #7 --- .project | 4 ++-- src/main/resources/application-dockerdev.properties | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.project b/.project index 850f83f876..b9691b3ba1 100644 --- a/.project +++ b/.project @@ -47,12 +47,12 @@ - 1598983010649 + 1671208548449 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ diff --git a/src/main/resources/application-dockerdev.properties b/src/main/resources/application-dockerdev.properties index 8405fe37d0..73f7b9491e 100644 --- a/src/main/resources/application-dockerdev.properties +++ b/src/main/resources/application-dockerdev.properties @@ -193,5 +193,8 @@ google.tokens.dir= ck_board_url= ck_board_sso_secret_key= +# Only set this when in local development environment +#ck_board_local_backend_url= + # backwards compatibility purpose only. system-wide-salt=secret