diff --git a/cygnus-lib/src/main/java/lib/models/CasePunching.java b/cygnus-lib/src/main/java/lib/models/CasePunching.java index c0a40bc..d561e2b 100644 --- a/cygnus-lib/src/main/java/lib/models/CasePunching.java +++ b/cygnus-lib/src/main/java/lib/models/CasePunching.java @@ -13,7 +13,7 @@ public class CasePunching { private Map optionsl; private Map> options; private List visibleSections; - private Integer portfolioId; + private Short portfolioId; private Integer formMode; private String userId; private String dynamicFields; diff --git a/cygnus-lib/src/main/java/lib/models/UserSession.java b/cygnus-lib/src/main/java/lib/models/UserSession.java new file mode 100644 index 0000000..d9268df --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/UserSession.java @@ -0,0 +1,29 @@ +package lib.models; + +import java.io.Serial; +import java.io.Serializable; +import lombok.Builder; +import lombok.Value; + +/** Immutable, type-safe representation of an authenticated Cygnus user. */ +@Value +@Builder +public class UserSession implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + Short companyId; + String companyName; + String companyCode; + Short branchId; + String branchName; + String branchCode; + String branchLocation; + Short userId; + String username; + String userDisplayName; + Short userGroupId; + String userGroupName; + String loginTime; + String menuHtml; +} diff --git a/cygnus-lib/target/classes/lib/constants/ApplicationError.class b/cygnus-lib/target/classes/lib/constants/ApplicationError.class index 859f4fa..71c961f 100644 Binary files a/cygnus-lib/target/classes/lib/constants/ApplicationError.class and b/cygnus-lib/target/classes/lib/constants/ApplicationError.class differ diff --git a/cygnus-lib/target/classes/lib/models/CasePunching.class b/cygnus-lib/target/classes/lib/models/CasePunching.class index 079128b..4a094cf 100644 Binary files a/cygnus-lib/target/classes/lib/models/CasePunching.class and b/cygnus-lib/target/classes/lib/models/CasePunching.class differ diff --git a/cygnus-lib/target/classes/lib/models/Option.class b/cygnus-lib/target/classes/lib/models/Option.class index 0b26128..2df6df0 100644 Binary files a/cygnus-lib/target/classes/lib/models/Option.class and b/cygnus-lib/target/classes/lib/models/Option.class differ diff --git a/cygnus-lib/target/classes/lib/models/UserSession$UserSessionBuilder.class b/cygnus-lib/target/classes/lib/models/UserSession$UserSessionBuilder.class new file mode 100644 index 0000000..af44226 Binary files /dev/null and b/cygnus-lib/target/classes/lib/models/UserSession$UserSessionBuilder.class differ diff --git a/cygnus-lib/target/classes/lib/models/UserSession.class b/cygnus-lib/target/classes/lib/models/UserSession.class new file mode 100644 index 0000000..5fb4f06 Binary files /dev/null and b/cygnus-lib/target/classes/lib/models/UserSession.class differ diff --git a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index 588215f..7251d26 100644 --- a/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/cygnus-lib/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -2,3 +2,4 @@ /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CasePunching.java /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ErrorDetails.java /Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/Option.java +/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/UserSession.java diff --git a/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml index 07aa669..0ea63ab 100644 --- a/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml +++ b/cygnus-lib/target/surefire-reports/TEST-lib.models.ErrorDetailsTest.xml @@ -1,18 +1,18 @@ - + - + - + - + - + - - + + @@ -20,8 +20,8 @@ - - + + @@ -29,10 +29,10 @@ - + - + @@ -40,11 +40,11 @@ - + - + - + @@ -52,13 +52,12 @@ - - - + + - + - + \ No newline at end of file diff --git a/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt index c838cbc..18dfcf8 100644 --- a/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt +++ b/cygnus-lib/target/surefire-reports/lib.models.ErrorDetailsTest.txt @@ -1,4 +1,4 @@ ------------------------------------------------------------------------------- Test set: lib.models.ErrorDetailsTest ------------------------------------------------------------------------------- -Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s -- in lib.models.ErrorDetailsTest +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.028 s -- in lib.models.ErrorDetailsTest diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp index ef74d95..6a7f76e 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/edp/punching/initcase.jsp @@ -53,7 +53,7 @@ @@ -133,9 +133,9 @@ - - - + + + @@ -152,7 +152,7 @@ @@ -184,7 +184,7 @@ @@ -200,7 +200,7 @@ @@ -311,7 +311,7 @@ - + @@ -429,7 +429,7 @@ - + @@ -556,7 +556,7 @@ - + @@ -689,8 +689,8 @@ - - + + diff --git a/cygnus-onprem-app/build/WebContent/WEB-INF/app/fragments/app-title.jspf b/cygnus-onprem-app/build/WebContent/WEB-INF/app/fragments/app-title.jspf index 648c45b..662c5ab 100644 --- a/cygnus-onprem-app/build/WebContent/WEB-INF/app/fragments/app-title.jspf +++ b/cygnus-onprem-app/build/WebContent/WEB-INF/app/fragments/app-title.jspf @@ -6,8 +6,8 @@ Cygnus 1.0
- () - () + () + ()
diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudAuthenticationGateway.java b/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudAuthenticationGateway.java index d510989..5916d71 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudAuthenticationGateway.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudAuthenticationGateway.java @@ -5,7 +5,7 @@ import com.cygnus.client.CloudIdentityClient; import java.time.Duration; import java.util.logging.Level; import java.util.logging.Logger; -import matrix.nimble.model.Session; +import lib.models.UserSession; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -28,7 +28,7 @@ public class CloudAuthenticationGateway { this.sessionMapper = sessionMapper; } - public Session authenticate(String loginId, String password) { + public UserSession authenticate(String loginId, String password) { try { Duration blockingTimeout = properties.requestTimeout().plusSeconds(1); return sessionMapper.map(client.authenticate(loginId, password).block(blockingTimeout)); diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudSessionMapper.java b/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudSessionMapper.java index fc47fbe..f297ee6 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudSessionMapper.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/cloud/identity/CloudSessionMapper.java @@ -5,6 +5,7 @@ import com.cygnus.client.model.CloudMenuItem; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.List; +import lib.models.UserSession; import matrix.nimble.model.Session; import org.springframework.stereotype.Component; @@ -20,22 +21,42 @@ public class CloudSessionMapper { this.menuRenderer = menuRenderer; } - public Session map(CloudIdentitySession source) { + public UserSession map(CloudIdentitySession source) { + return UserSession.builder() + .userId(source.userId()) + .username(source.loginId()) + .userDisplayName(source.displayName()) + .userGroupId(source.groupId()) + .userGroupName(source.groupName()) + .branchId(source.branchId()) + .branchName(source.branchName()) + .branchCode(source.branchCode()) + .branchLocation(source.branchLocation()) + .companyId(source.companyId()) + .companyName(source.companyName()) + .companyCode(source.companyCode()) + .loginTime(LEGACY_LOGIN_TIME.format(source.loginTime())) + .menuHtml(menuRenderer.render(toLegacyMenu(source.menu()))) + .build(); + } + + /** Temporary projection used by controllers that have not migrated to UserSession yet. */ + public Session toLegacy(UserSession source) { Session target = new Session(); - target.setUserID(Short.toString(source.userId())); - target.setUsername(source.loginId()); - target.setUserDisplayName(source.displayName()); - target.setUserGroupID(Short.toString(source.groupId())); - target.setUserGroupName(source.groupName()); - target.setBranchID(Short.toString(source.branchId())); - target.setBranchName(source.branchName()); - target.setBranchCode(source.branchCode()); - target.setBranchLocation(source.branchLocation()); - target.setCompanyID(Short.toString(source.companyId())); - target.setCompanyName(source.companyName()); - target.setCompanyCode(source.companyCode()); - target.setLoginTime(LEGACY_LOGIN_TIME.format(source.loginTime())); - target.setMenuHtml(menuRenderer.render(toLegacyMenu(source.menu()))); + target.setUserID(Short.toString(source.getUserId())); + target.setUsername(source.getUsername()); + target.setUserDisplayName(source.getUserDisplayName()); + target.setUserGroupID(Short.toString(source.getUserGroupId())); + target.setUserGroupName(source.getUserGroupName()); + target.setBranchID(Short.toString(source.getBranchId())); + target.setBranchName(source.getBranchName()); + target.setBranchCode(source.getBranchCode()); + target.setBranchLocation(source.getBranchLocation()); + target.setCompanyID(Short.toString(source.getCompanyId())); + target.setCompanyName(source.getCompanyName()); + target.setCompanyCode(source.getCompanyCode()); + target.setLoginTime(source.getLoginTime()); + target.setMenuHtml(source.getMenuHtml()); return target; } diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java index d522876..1d1c1fd 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/AbstractAuthenticatedController.java @@ -4,7 +4,7 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import lib.constants.ApplicationError; import lib.models.ErrorDetails; -import matrix.nimble.model.Session; +import lib.models.UserSession; import matrix.services.commons.CommonErrorService; import matrix.services.commons.CommonService; import org.springframework.ui.ModelMap; @@ -26,14 +26,14 @@ public abstract class AbstractAuthenticatedController { ModelMap model, HttpSession httpSession, HttpServletResponse response) { - Session session = commonService.getSession(httpSession); + UserSession session = commonService.getUserSession(httpSession); if (session == null) { return denied(model, response, httpSession, ApplicationError.SESSION_REQUIRED); } if (!commonService.hasPageAccess(session, pageRoute)) { return denied(model, response, httpSession, ApplicationError.ACCESS_DENIED); } - model.addAttribute(CommonService.SESSION_ATTRIBUTE, session); + model.addAttribute(CommonService.USER_SESSION_ATTRIBUTE, session); return PageAuthorization.granted(session); } @@ -47,8 +47,8 @@ public abstract class AbstractAuthenticatedController { return PageAuthorization.denied(viewName); } - protected record PageAuthorization(Session session, String viewName) { - private static PageAuthorization granted(Session session) { + protected record PageAuthorization(UserSession session, String viewName) { + private static PageAuthorization granted(UserSession session) { return new PageAuthorization(session, null); } diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java index 82be155..08a25b7 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/controller/SessionController.java @@ -2,9 +2,11 @@ package matrix.nimble.controller; import matrix.nimble.cloud.identity.CloudAuthenticationException; import matrix.nimble.cloud.identity.CloudAuthenticationGateway; +import matrix.nimble.cloud.identity.CloudSessionMapper; import matrix.nimble.model.Login; import matrix.nimble.model.Session; import matrix.services.commons.CommonService; +import lib.models.UserSession; //servlet libraries import jakarta.servlet.http.HttpServletRequest; @@ -23,12 +25,15 @@ import org.springframework.web.bind.annotation.SessionAttributes; public class SessionController { private final CloudAuthenticationGateway cloudAuthenticationGateway; private final CommonService commonService; + private final CloudSessionMapper cloudSessionMapper; public SessionController( CloudAuthenticationGateway cloudAuthenticationGateway, - CommonService commonService) { + CommonService commonService, + CloudSessionMapper cloudSessionMapper) { this.cloudAuthenticationGateway = cloudAuthenticationGateway; this.commonService = commonService; + this.cloudSessionMapper = cloudSessionMapper; } @RequestMapping(value="login", method={RequestMethod.GET, RequestMethod.POST}) public String LoginPage(ModelMap model) @@ -53,10 +58,12 @@ public class SessionController { HttpSession httpSession) { try { - Session cloudSession = cloudAuthenticationGateway.authenticate( + UserSession userSession = cloudAuthenticationGateway.authenticate( login.getLoginid(), login.getPassword()); + Session cloudSession = cloudSessionMapper.toLegacy(userSession); model.remove("login"); model.addAttribute("Sessvals", cloudSession); + commonService.storeUserSession(httpSession, userSession); commonService.storeSession(httpSession, cloudSession); return "home"; } catch (CloudAuthenticationException exception) { diff --git a/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/PunchingController.java b/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/PunchingController.java index b4850cc..b48b940 100644 --- a/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/PunchingController.java +++ b/cygnus-onprem-app/src/main/java/matrix/nimble/edp/punching/controllers/PunchingController.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestParam; import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpServletResponse; import matrix.nimble.controller.AbstractAuthenticatedController; -import matrix.nimble.model.Session; +import lib.models.UserSession; import matrix.services.commons.CommonService; import matrix.services.edp.PunchingService; import matrix.services.commons.CommonErrorService; @@ -38,11 +38,10 @@ public class PunchingController extends AbstractAuthenticatedController { if (!authorization.isGranted()) { return authorization.viewName(); } - Session Sessvals = authorization.session(); + UserSession userSession = authorization.session(); model.addAttribute("model", punchingService.init( - Sessvals.getBranchID(), Sessvals.getUserID(), null, "xxx")); - model.addAttribute("Sessvals", Sessvals); + userSession.getBranchId(), userSession.getUserId(), null, null)); return "edp/punching/initcase"; } @@ -58,16 +57,15 @@ public class PunchingController extends AbstractAuthenticatedController { return authorization.viewName(); } - Session session = authorization.session(); + UserSession session = authorization.session(); model.addAttribute("model", punchingService.addCase( - submitted, session.getBranchID(), session.getUserID())); - model.addAttribute("Sessvals", session); + submitted, session.getBranchId(), session.getCompanyId(), session.getUserId())); return "edp/punching/initcase"; } @RequestMapping(value = "caseedit", method = RequestMethod.POST) public String editCase( - @RequestParam("PortfolioId") Integer portfolioId, + @RequestParam("PortfolioId") Short portfolioId, @RequestParam("uuid") String documentCaseId, ModelMap model, HttpSession httpSession, @@ -78,10 +76,10 @@ public class PunchingController extends AbstractAuthenticatedController { return authorization.viewName(); } - Session session = authorization.session(); + UserSession session = authorization.session(); model.addAttribute("model", punchingService.editCase( - portfolioId, documentCaseId, session.getBranchID(), session.getUserID())); - model.addAttribute("Sessvals", session); + portfolioId, documentCaseId, session.getBranchId(), + session.getCompanyId(), session.getUserId())); return "edp/punching/initcase"; } } diff --git a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java index a13c4b8..a0e2720 100644 --- a/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java +++ b/cygnus-onprem-app/src/main/java/matrix/services/commons/CommonService.java @@ -3,6 +3,7 @@ package matrix.services.commons; import com.cygnus.db.CygnusDbExecutor; import jakarta.servlet.http.HttpSession; import lib.models.Option; +import lib.models.UserSession; import java.util.List; import java.util.Objects; @@ -15,6 +16,7 @@ import org.springframework.stereotype.Service; @Service public class CommonService { public static final String SESSION_ATTRIBUTE = "Sessvals"; + public static final String USER_SESSION_ATTRIBUTE = "userSession"; private static final Pattern MENU_COMMAND = Pattern.compile( "SubmitMenuCommand\\(\\s*'([^']+)'\\s*,", @@ -46,6 +48,20 @@ public class CommonService { httpSession.setAttribute(SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session")); } + public UserSession getUserSession(HttpSession httpSession) { + if (httpSession == null) { + return null; + } + Object value = httpSession.getAttribute(USER_SESSION_ATTRIBUTE); + return value instanceof UserSession session ? session : null; + } + + public void storeUserSession(HttpSession httpSession, UserSession session) { + Objects.requireNonNull(httpSession, "httpSession"); + httpSession.setAttribute( + USER_SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session")); + } + public boolean hasPageAccess(HttpSession httpSession, String pageRoute) { return hasPageAccess(getSession(httpSession), pageRoute); } @@ -69,6 +85,29 @@ public class CommonService { return false; } + public boolean hasPageAccess(UserSession session, String pageRoute) { + return session != null && hasPageAccess(session.getMenuHtml(), pageRoute); + } + + private boolean hasPageAccess(String menuHtml, String pageRoute) { + if (menuHtml == null) { + return false; + } + + String requiredRoute = normalizeRoute(pageRoute); + if (requiredRoute.isEmpty()) { + return false; + } + + Matcher matcher = MENU_COMMAND.matcher(menuHtml); + while (matcher.find()) { + if (normalizeRoute(matcher.group(1)).equals(requiredRoute)) { + return true; + } + } + return false; + } + private String normalizeRoute(String route) { if (route == null) { return ""; diff --git a/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java b/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java index 30acdd0..c2e06e5 100644 --- a/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java +++ b/cygnus-onprem-app/src/main/java/matrix/services/edp/PunchingService.java @@ -1,5 +1,6 @@ package matrix.services.edp; +import com.cygnus.db.SqlArrayParameter; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -13,7 +14,6 @@ import lib.models.ErrorDetails; import lib.models.Option; import lib.constants.ApplicationError; import matrix.nimble.edp.punching.model.PunchingHandler; -import matrix.nimble.utilities.CommonFunctions; import matrix.nimble.utilities.GlobalClass; import matrix.services.commons.CommonService; @@ -25,8 +25,15 @@ public class PunchingService { private static final String PRODUCT = "product."; private static final String CITY = "city."; private static final String APPLICATION_TYPE = "applicationType."; + private static final String DATABASE_APPLICATION_TYPE = "apptype."; private static final String CATEGORY = "category."; + private static final Short ACTIVE = Short.valueOf((short) 1); + private static final SqlArrayParameter GENERAL_OPTION_TYPES = + SqlArrayParameter.text("CITY", "APPTYPE"); + private static final SqlArrayParameter PORTFOLIO_OPTION_TYPES = + SqlArrayParameter.text("CATEGORY", "PRODUCT"); + private final CommonService commonService; public PunchingService(CommonService commonService) { @@ -34,8 +41,8 @@ public class PunchingService { } public CasePunching init( - String branchId, - String userId, + Short branchId, + Short userId, String verificationCaseId, String documentCaseId) { PunchingHandler punchingHandler = new PunchingHandler(); @@ -43,16 +50,15 @@ public class PunchingService { CasePunching casePunching = new CasePunching(); Map> options = new LinkedHashMap<>(); - Short databaseBranchId = Short.valueOf(branchId.trim()); List