diff --git a/api/src/main/java/io/sentrius/sso/controllers/api/ZeroTrustATApiController.java b/api/src/main/java/io/sentrius/sso/controllers/api/ZeroTrustATApiController.java index a82edc5e..37949df8 100644 --- a/api/src/main/java/io/sentrius/sso/controllers/api/ZeroTrustATApiController.java +++ b/api/src/main/java/io/sentrius/sso/controllers/api/ZeroTrustATApiController.java @@ -33,6 +33,7 @@ import io.sentrius.sso.core.services.security.KeycloakService; import io.sentrius.sso.core.services.security.ZeroTrustAccessTokenService; import io.sentrius.sso.core.services.security.ZtatTokenService; +import io.sentrius.sso.core.utils.AccessUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -273,28 +274,27 @@ public ResponseEntity getRequest(HttpServletRequest request, HttpServletRespo @GetMapping("/list/{type}") @LimitAccess(ztatAccess = {ZeroTrustAccessTokenEnum.CAN_VIEW_ZTATS}) - public ResponseEntity listZtatRequests(@RequestHeader("Authorization") String token, + public ResponseEntity listZtatRequests(@RequestHeader(name= "Authorization", required=false) String token, @PathVariable("type") String type, HttpServletRequest request, HttpServletResponse response) { - String compactJwt = token.startsWith("Bearer ") ? token.substring(7) : token; + var operatingUser = getOperatingUser(request, response ); + if (null != token) { + String compactJwt = token.startsWith("Bearer ") ? token.substring(7) : token; - log.info("Received ZTAT request from agent: {}", compactJwt); - if (!keycloakService.validateJwt(compactJwt)) { - log.warn("Invalid Keycloak token"); - return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED).body("Invalid Keycloak token"); - } - - // Extract agent identity from the JWT - var operatingUser = getOperatingUser(request, response ); + log.info("Received ZTAT request from agent: {}", compactJwt); + if (!keycloakService.validateJwt(compactJwt)) { + log.warn("Invalid Keycloak token"); + return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED).body("Invalid Keycloak token"); + } + String agentId = keycloakService.extractAgentId(compactJwt); - // Extract agent identity from the JWT - String agentId = keycloakService.extractAgentId(compactJwt); + if (null == operatingUser) { + log.warn("No operating user found for agent: {}", agentId); + var username = keycloakService.extractUsername(compactJwt); + operatingUser = userService.getUserByUsername(username); - if (null == operatingUser) { - log.warn("No operating user found for agent: {}", agentId); - var username = keycloakService.extractUsername(compactJwt); - operatingUser = userService.getUserByUsername(username); + } } List ztatTracker = new ArrayList(); @@ -324,6 +324,88 @@ public ResponseEntity listZtatRequests(@RequestHeader("Authorization") String default: log.warn("Invalid type: {}", type); } + ztatTracker = decorateTats(ztatTracker, operatingUser); + return ResponseEntity.ok(ztatTracker); + } + + @GetMapping("/list/{state}/{type}") + @LimitAccess(ztatAccess = {ZeroTrustAccessTokenEnum.CAN_VIEW_ZTATS}) + public ResponseEntity listTypedZtatRequests(@RequestHeader(name= "Authorization", required=false) String token, + @PathVariable("type") String type, + @PathVariable("state") String state, + HttpServletRequest request, HttpServletResponse response) { + + var operatingUser = getOperatingUser(request, response ); + if (null != token) { + String compactJwt = token.startsWith("Bearer ") ? token.substring(7) : token; + + + log.info("Received ZTAT request from agent: {}", compactJwt); + if (!keycloakService.validateJwt(compactJwt)) { + log.warn("Invalid Keycloak token"); + return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED).body("Invalid Keycloak token"); + } + String agentId = keycloakService.extractAgentId(compactJwt); + + if (null == operatingUser) { + log.warn("No operating user found for agent: {}", agentId); + var username = keycloakService.extractUsername(compactJwt); + operatingUser = userService.getUserByUsername(username); + + } + + } + // Extract agent identity from the JWT + + + // Extract agent identity from the JWT + + List ztatTracker = new ArrayList(); + switch(type){ + case "terminal": + if ("denied".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getDeniedJITRequests(operatingUser); + } else if ("approved".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getApprovedJITRequests(operatingUser); + } else { + ztatTracker = ztatService.getOpenJITRequests(operatingUser); + } + break; + case "ops": + if ("denied".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getDeniedOpsJITRequests(operatingUser); + } else if ("approved".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getApprovedOpsJITRequests(operatingUser); + } else { + ztatTracker = ztatService.getOpenOpsRequests(operatingUser); + } + break; + case "atat": + if ("denied".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getDeniedOpsJITRequests(operatingUser); + } else if ("approved".equalsIgnoreCase(state)) { + ztatTracker = ztatService.getApprovedOpsJITRequests(operatingUser); + } else { + ztatTracker = ztatService.getOpenOpsRequests(operatingUser); + } + ztatTracker = ztatTracker.stream().filter(dto -> { + if (dto.getCommand().equals("register")) { + return false; + } + try { + if (userService.isNPE(dto.getUserName())){ + return true; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return false; + }).toList(); + break; + default: + log.warn("Invalid type: {}", type); + } + ztatTracker = decorateTats(ztatTracker, operatingUser); return ResponseEntity.ok(ztatTracker); } @@ -364,4 +446,29 @@ public ResponseEntity verifyZtat(@RequestBody ZtatChallengeRequest requ } } + List decorateTats(List tats, User operatingUser){ + boolean canApprove = AccessUtil.canAccess(operatingUser, ZeroTrustAccessTokenEnum.CAN_APPROVE_ZTATS); + boolean canDeny = AccessUtil.canAccess(operatingUser, ZeroTrustAccessTokenEnum.CAN_DENY_ZTATS); + if (canApprove || canDeny) { + for (var tat : tats) { + + if (tat.getUserName().equals(operatingUser.getUsername())) { + tat.setCurrentUser(true); + if (systemOptions.getCanApproveOwnZtat()) { + if (tat.getUsesRemaining() > 0) { + tat.setCanApprove(canApprove); + } + tat.setCanDeny(canDeny); + } + } + else { + if (tat.getUsesRemaining() > 0) { + tat.setCanApprove(canApprove); + } + tat.setCanDeny(canDeny); + } + } + } + return tats; + } } diff --git a/api/src/main/resources/templates/sso/ztats/view_ztats.html b/api/src/main/resources/templates/sso/ztats/view_ztats.html index 2d326382..ed02eb0b 100755 --- a/api/src/main/resources/templates/sso/ztats/view_ztats.html +++ b/api/src/main/resources/templates/sso/ztats/view_ztats.html @@ -86,6 +86,7 @@

Trust AT (TAT) Management

OperationUserSystemActions + @@ -110,6 +112,7 @@

Trust AT (TAT) Management

OperationUserActions + @@ -150,6 +154,7 @@

Trust AT (TAT) Management

RemainingActions + @@ -172,6 +178,7 @@

Trust AT (TAT) Management

+ @@ -189,8 +197,8 @@

Trust AT (TAT) Management

- - + +
@@ -207,6 +215,7 @@

Trust AT (TAT) Management

OperationUserSystemActions +
@@ -227,6 +237,7 @@

Trust AT (TAT) Management

OperationUserActions + @@ -247,46 +259,285 @@

Trust AT (TAT) Management

+ + - - diff --git a/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustAccessTokenService.java b/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustAccessTokenService.java index 907f5762..aeb7d19f 100644 --- a/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustAccessTokenService.java +++ b/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustAccessTokenService.java @@ -277,10 +277,25 @@ public boolean hasJITRequest(String command, User user, HostSystem system) { return ztatRequestService.hasJITRequest(command, user.getId(), system.getId()); } - public List getOpenJITRequests(User operatingUser) { - return ztatRequestService.getOpenAccessTokenRequests(operatingUser); - } + public List getOpenJITRequests(User operatingUser) { + return ztatRequestService.getOpenAccessTokenRequests(operatingUser); + } + public List getDeniedJITRequests(User operatingUser) { + return ztatRequestService.getDeniedTerminalAccessTokenRequests(operatingUser); + } + + public List getDeniedOpsJITRequests(User operatingUser) { + return ztatRequestService.getDeniedOpsAccessTokenRequests(operatingUser); + } + + public List getApprovedJITRequests(User operatingUser) { + return ztatRequestService.getApprovedTerminalAccessTokenRequests(operatingUser); + } + + public List getApprovedOpsJITRequests(User operatingUser) { + return ztatRequestService.getApprovedOpsAccessTokenRequests(operatingUser); + } public List getOpenOpsRequests(User operatingUser) { return ztatRequestService.getOpenOpsRequests(operatingUser); } diff --git a/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustRequestService.java b/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustRequestService.java index bbc95b09..47a6f0f7 100644 --- a/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustRequestService.java +++ b/dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustRequestService.java @@ -269,8 +269,12 @@ public List getOpenAccessTokenRequests(@NonNull User currentUser) { for (ZeroTrustAccessTokenRequest request : openRequests) { var dto = convertToDTO(request); if (Objects.equals(currentUser.getId(), request.getUser().getId())) { + log.info("Current user matches request user: {}", request.getUser().getUsername()); dto.setCurrentUser(true); } + else { + log.info("Current user does not match request user: {} vs {}", currentUser.getUsername(), request.getUser().getUsername()); + } ztatTrackerList.add(dto); } @@ -384,7 +388,8 @@ private Integer getUsesRemaining(ZeroTrustAccessTokenRequest request) { List approval = request.getApprovals(); if (!approval.isEmpty()) { var uses = ztatUseRepository.getUses(approval.get(0)); - return systemOptions.maxJitUses - uses.size(); + var usesRemaining = systemOptions.maxJitUses - uses.size(); + return Math.max(usesRemaining, 0); } return systemOptions.maxJitUses; // Update as needed based on your logic diff --git a/ops-scripts/local/deploy-helm.sh b/ops-scripts/local/deploy-helm.sh index ecada310..3a3bb5c7 100755 --- a/ops-scripts/local/deploy-helm.sh +++ b/ops-scripts/local/deploy-helm.sh @@ -14,6 +14,8 @@ ENABLE_TLS=false INSTALL_CERT_MANAGER=false ENV_TARGET="local" # default mode CERT_DIR="${SCRIPT_DIR}/../../docker/dev-certs" +# set default to false +DEPLOY_ADMINER=${DEPLOY_ADMINER:-false} # --- Load and back up environment file --- ENV_FILE="${SCRIPT_DIR}/../../.$ENV_TARGET.env" @@ -208,7 +210,7 @@ if [[ -z "$KEYCLOAK_CLIENT_SECRET" ]]; then fi helm upgrade --install sentrius ./sentrius-chart --namespace ${TENANT} \ - --set adminer.enabled=true \ + --set adminer.enabled=${DEPLOY_ADMINER} \ --set tenant=${TENANT} \ --set environment=${ENVIRONMENT} \ --set subdomain="${SUBDOMAIN}" \