1+ package io .sentrius .sso .controllers .api ;
2+
3+ import io .sentrius .sso .core .annotations .LimitAccess ;
4+ import io .sentrius .sso .core .config .SystemOptions ;
5+ import io .sentrius .sso .core .controllers .BaseController ;
6+ import io .sentrius .sso .core .dto .capabilities .EndpointDescriptor ;
7+ import io .sentrius .sso .core .model .security .enums .ApplicationAccessEnum ;
8+ import io .sentrius .sso .core .services .ErrorOutputService ;
9+ import io .sentrius .sso .core .services .UserService ;
10+ import io .sentrius .sso .core .services .capabilities .EndpointScanningService ;
11+ import jakarta .servlet .http .HttpServletRequest ;
12+ import jakarta .servlet .http .HttpServletResponse ;
13+ import lombok .extern .slf4j .Slf4j ;
14+ import org .springframework .http .ResponseEntity ;
15+ import org .springframework .web .bind .annotation .GetMapping ;
16+ import org .springframework .web .bind .annotation .RequestMapping ;
17+ import org .springframework .web .bind .annotation .RequestParam ;
18+ import org .springframework .web .bind .annotation .RestController ;
19+
20+ import java .util .List ;
21+ import java .util .stream .Collectors ;
22+
23+ /**
24+ * API controller for exposing endpoint capabilities across the system.
25+ * This provides a unified view of all REST endpoints and Verb methods available.
26+ */
27+ @ Slf4j
28+ @ RestController
29+ @ RequestMapping ("/api/v1/capabilities" )
30+ public class CapabilitiesApiController extends BaseController {
31+
32+ private final EndpointScanningService endpointScanningService ;
33+
34+ public CapabilitiesApiController (
35+ UserService userService ,
36+ SystemOptions systemOptions ,
37+ ErrorOutputService errorOutputService ,
38+ EndpointScanningService endpointScanningService ) {
39+ super (userService , systemOptions , errorOutputService );
40+ this .endpointScanningService = endpointScanningService ;
41+ }
42+
43+ /**
44+ * Returns all available endpoints (REST and Verb) in the system.
45+ * This can be used by AI agents and other systems to understand what capabilities are available.
46+ */
47+ @ GetMapping ("/endpoints" )
48+ @ LimitAccess (applicationAccess = {ApplicationAccessEnum .CAN_LOG_IN })
49+ public ResponseEntity <List <EndpointDescriptor >> getAllEndpoints (
50+ @ RequestParam (required = false ) String type ,
51+ @ RequestParam (required = false ) Boolean requiresAuth ,
52+ HttpServletRequest request ,
53+ HttpServletResponse response ) {
54+
55+ log .info ("Retrieving all endpoints with filters - type: {}, requiresAuth: {}" , type , requiresAuth );
56+
57+ List <EndpointDescriptor > endpoints = endpointScanningService .getAllEndpoints ();
58+
59+ // Apply filters if provided
60+ if (type != null ) {
61+ endpoints = endpoints .stream ()
62+ .filter (endpoint -> type .equalsIgnoreCase (endpoint .getType ()))
63+ .collect (Collectors .toList ());
64+ }
65+
66+ if (requiresAuth != null ) {
67+ endpoints = endpoints .stream ()
68+ .filter (endpoint -> endpoint .isRequiresAuthentication () == requiresAuth )
69+ .collect (Collectors .toList ());
70+ }
71+
72+ log .info ("Returning {} endpoints" , endpoints .size ());
73+ return ResponseEntity .ok (endpoints );
74+ }
75+
76+ /**
77+ * Returns only REST API endpoints.
78+ */
79+ @ GetMapping ("/rest" )
80+ @ LimitAccess (applicationAccess = {ApplicationAccessEnum .CAN_LOG_IN })
81+ public ResponseEntity <List <EndpointDescriptor >> getRestEndpoints (
82+ HttpServletRequest request ,
83+ HttpServletResponse response ) {
84+
85+ log .info ("Retrieving REST endpoints" );
86+
87+ List <EndpointDescriptor > endpoints = endpointScanningService .getAllEndpoints ()
88+ .stream ()
89+ .filter (endpoint -> "REST" .equals (endpoint .getType ()))
90+ .collect (Collectors .toList ());
91+
92+ log .info ("Returning {} REST endpoints" , endpoints .size ());
93+ return ResponseEntity .ok (endpoints );
94+ }
95+
96+ /**
97+ * Returns only Verb methods (for AI agents).
98+ */
99+ @ GetMapping ("/verbs" )
100+ @ LimitAccess (applicationAccess = {ApplicationAccessEnum .CAN_LOG_IN })
101+ public ResponseEntity <List <EndpointDescriptor >> getVerbEndpoints (
102+ HttpServletRequest request ,
103+ HttpServletResponse response ) {
104+
105+ log .info ("Retrieving Verb endpoints" );
106+
107+ List <EndpointDescriptor > endpoints = endpointScanningService .getAllEndpoints ()
108+ .stream ()
109+ .filter (endpoint -> "VERB" .equals (endpoint .getType ()))
110+ .collect (Collectors .toList ());
111+
112+ log .info ("Returning {} Verb endpoints" , endpoints .size ());
113+ return ResponseEntity .ok (endpoints );
114+ }
115+
116+ /**
117+ * Forces a refresh of the endpoint cache.
118+ * This can be useful during development or after deploying new capabilities.
119+ */
120+ @ GetMapping ("/refresh" )
121+ @ LimitAccess (applicationAccess = {ApplicationAccessEnum .CAN_MANAGE_APPLICATION })
122+ public ResponseEntity <String > refreshEndpoints (
123+ HttpServletRequest request ,
124+ HttpServletResponse response ) {
125+
126+ log .info ("Refreshing endpoint cache" );
127+ endpointScanningService .refreshEndpoints ();
128+
129+ int count = endpointScanningService .getAllEndpoints ().size ();
130+ String message = String .format ("Endpoint cache refreshed. Found %d endpoints." , count );
131+
132+ log .info (message );
133+ return ResponseEntity .ok (message );
134+ }
135+ }
0 commit comments