22
33import java .lang .reflect .Field ;
44import java .security .GeneralSecurityException ;
5+ import java .util .ArrayList ;
56import java .util .HashMap ;
67import java .util .List ;
78import java .util .Map ;
1415import io .sentrius .sso .core .annotations .LimitAccess ;
1516import io .sentrius .sso .core .config .SystemOptions ;
1617import io .sentrius .sso .core .controllers .BaseController ;
18+ import io .sentrius .sso .core .exceptions .ZtatException ;
1719import io .sentrius .sso .core .model .security .UserType ;
1820import io .sentrius .sso .core .model .security .enums .UserAccessEnum ;
1921import io .sentrius .sso .core .model .users .User ;
2729import io .sentrius .sso .core .services .UserCustomizationService ;
2830import io .sentrius .sso .core .services .UserService ;
2931import io .sentrius .sso .core .services .agents .AgentService ;
32+ import io .sentrius .sso .core .services .agents .ZeroTrustClientService ;
3033import io .sentrius .sso .core .services .security .CryptoService ;
3134import io .sentrius .sso .core .services .security .ZeroTrustAccessTokenService ;
3235import io .sentrius .sso .core .services .security .ZeroTrustRequestService ;
3538import jakarta .servlet .http .HttpServletRequest ;
3639import jakarta .servlet .http .HttpServletResponse ;
3740import lombok .extern .slf4j .Slf4j ;
41+ import org .springframework .beans .factory .annotation .Value ;
42+ import org .springframework .core .ParameterizedTypeReference ;
43+ import org .springframework .http .HttpMethod ;
3844import org .springframework .http .HttpStatus ;
3945import org .springframework .http .ResponseEntity ;
4046import org .springframework .stereotype .Controller ;
@@ -60,6 +66,11 @@ public class UserApiController extends BaseController {
6066 final ZeroTrustRequestService ztatRequestService ;
6167 final ZeroTrustAccessTokenService ztatService ;
6268 final AgentService agentService ;
69+ final ZeroTrustClientService zeroTrustClientService ;
70+
71+
72+ @ Value ("${agentproxy.externalUrl:}" )
73+ private String agentProxyExternalUrl ;
6374
6475 static Map <String , Field > fields = new HashMap <>();
6576 static {
@@ -78,7 +89,8 @@ protected UserApiController(
7889 UserCustomizationService userThemeService ,
7990 SessionService sessionService ,
8091 ZeroTrustRequestService ztatRequestService ,
81- ZeroTrustAccessTokenService ztatService , AgentService agentService
92+ ZeroTrustAccessTokenService ztatService , AgentService agentService ,
93+ ZeroTrustClientService zeroTrustClientService
8294 ) {
8395 super (userService , systemOptions , errorOutputService );
8496 this .hostGroupService = hostGroupService ;
@@ -89,6 +101,7 @@ protected UserApiController(
89101 this .ztatRequestService = ztatRequestService ;
90102 this .ztatService = ztatService ;
91103 this .agentService = agentService ;
104+ this .zeroTrustClientService = zeroTrustClientService ;
92105 }
93106
94107 @ GetMapping ("list" )
@@ -303,10 +316,117 @@ public String deleteType(@RequestParam("id") String dtoId) throws GeneralSecurit
303316 public ResponseEntity <Map <String , Integer >> getGraphData (HttpServletRequest request ,
304317 HttpServletResponse response ) {
305318 var username = userService .getOperatingUser (request ,response , null ).getUsername ();
306- var ret = sessionService . getGraphData (username );
319+ var ret = getGraphData (username );
307320
308321 return ResponseEntity .ok (ret );
309322 }
310323
324+
325+ public Map <String , Integer > getGraphData (String username ) {
326+ List <Map <String , Object >> sessionDurations = sessionService .getGraphList (username );
327+
328+ // Add agent session durations
329+ List <Map <String , Object >> agentSessionDurations = getAgentSessionDurations ();
330+ log .info ("Fetched {} agent session durations" , agentSessionDurations .size ());
331+ log .info ("Fetched {} agent session durations" , agentSessionDurations .size ());
332+ sessionDurations .addAll (agentSessionDurations );
333+
334+ Map <String , Integer > graphData = new HashMap <>();
335+ graphData .put ("0-5 min" , 0 );
336+ graphData .put ("5-15 min" , 0 );
337+ graphData .put ("15-30 min" , 0 );
338+ graphData .put ("30+ min" , 0 );
339+
340+ for (Map <String , Object > session : sessionDurations ) {
341+ long durationMinutes = Long .valueOf ( session .get ("durationMinutes" ).toString () );
342+
343+ if (durationMinutes <= 5 ) {
344+ graphData .put ("0-5 min" , graphData .get ("0-5 min" ) + 1 );
345+ } else if (durationMinutes <= 15 ) {
346+ graphData .put ("5-15 min" , graphData .get ("5-15 min" ) + 1 );
347+ } else if (durationMinutes <= 30 ) {
348+ graphData .put ("15-30 min" , graphData .get ("15-30 min" ) + 1 );
349+ } else {
350+ graphData .put ("30+ min" , graphData .get ("30+ min" ) + 1 );
351+ }
352+ }
353+
354+ return graphData ;
355+ }
356+
357+ /**
358+ * Fetch agent session duration data from agent proxy service
359+ * @return List of agent session duration data
360+ */
361+ private List <Map <String , Object >> getAgentSessionDurations () {
362+ List <Map <String , Object >> agentSessions = new ArrayList <>();
363+
364+ if (agentProxyExternalUrl == null || agentProxyExternalUrl .trim ().isEmpty ()) {
365+ log .warn ("Agent proxy URL not configured, skipping agent session data" );
366+ return agentSessions ;
367+ }
368+
369+ try {
370+
371+ var resp = zeroTrustClientService .callAuthenticatedGetOnApi (agentProxyExternalUrl ,"/api/v1/sessions/agent" +
372+ "/durations"
373+ , null );
374+ log .info ("Fetched active agent session duration data: {}" , resp );
375+ if (null != resp ){
376+ var completedNode = JsonUtil .MAPPER .readTree (resp );
377+ Map <String , Object > completedMap = new HashMap <>();
378+ for (var node : completedNode ) {
379+ node .fields ().forEachRemaining (
380+ entry -> {
381+ completedMap .put (entry .getKey (), entry .getValue ());
382+ log .info (
383+ "Processing agent session duration entry: {} = {}" , entry .getKey (), entry .getValue ());
384+ }
385+
386+ );
387+ }
388+ if (completedMap .size () > 0 ) {
389+ log .info ("Adding completed agent session duration data: {}" , completedMap );
390+ agentSessions .add (completedMap );
391+ }
392+
393+ }
394+
395+
396+ resp = zeroTrustClientService .callAuthenticatedGetOnApi (agentProxyExternalUrl ,"/api/v1/sessions/agent/active-durations"
397+ , null );
398+
399+ log .info ("Fetched active agent session duration data: {}" , resp );
400+ if (null != resp ){
401+ var completedNode = JsonUtil .MAPPER .readTree (resp );
402+ Map <String , Object > completedMap = new HashMap <>();
403+ for (var node : completedNode ) {
404+ node .fields ().forEachRemaining (
405+ entry -> {
406+ completedMap .put (entry .getKey (), entry .getValue ());
407+ log .info (
408+ "Processing agent session duration entry: {} = {}" , entry .getKey (), entry .getValue ());
409+ }
410+
411+ );
412+ }
413+ if (completedMap .size () > 0 ) {
414+ log .info ("Adding completed agent session duration data: {}" , completedMap );
415+ agentSessions .add (completedMap );
416+ }
417+
418+ }
419+
420+ log .info ("Fetched {} agent session duration records" , agentSessions .size ());
421+
422+ } catch (Exception e ) {
423+ log .warn ("Failed to fetch agent session data from {}: {}" , agentProxyExternalUrl , e .getMessage ());
424+ } catch (ZtatException e ) {
425+ log .warn ("Failed to fetch agent session data from {}: {}" , agentProxyExternalUrl , e .getMessage ());
426+ }
427+
428+ return agentSessions ;
429+ }
430+
311431}
312432
0 commit comments