1919import org .eclipse .openvsx .repositories .RepositoryService ;
2020import org .eclipse .openvsx .util .ErrorResultException ;
2121import org .eclipse .openvsx .util .LogService ;
22+ import org .eclipse .openvsx .util .NotFoundException ;
2223import org .eclipse .openvsx .util .TimeUtil ;
2324import org .slf4j .Logger ;
2425import org .slf4j .LoggerFactory ;
26+ import org .springframework .http .HttpStatus ;
2527import org .springframework .http .MediaType ;
2628import org .springframework .http .ResponseEntity ;
2729import org .springframework .web .bind .annotation .*;
30+ import org .springframework .web .server .ResponseStatusException ;
2831
32+ import java .util .List ;
2933import java .util .Optional ;
3034
3135
3438public class RateLimitAPI {
3539 private final Logger logger = LoggerFactory .getLogger (RateLimitAPI .class );
3640
41+ private static final int TOKEN_DESCRIPTION_SIZE = 255 ;
42+
3743 private final RepositoryService repositories ;
3844 private final AdminService admins ;
3945 private final LogService logs ;
@@ -59,9 +65,9 @@ public RateLimitAPI(
5965 produces = MediaType .APPLICATION_JSON_VALUE
6066 )
6167 public ResponseEntity <TierListJson > getTiers () {
62- try {
63- admins .checkAdminUser ();
68+ admins .checkAdminUser ();
6469
70+ try {
6571 var tiers = repositories .findAllTiers ();
6672 var result = new TierListJson (tiers .stream ().map (Tier ::toJson ).toList ());
6773 return ResponseEntity .ok (result );
@@ -104,6 +110,8 @@ public ResponseEntity<TierJson> createTier(@RequestBody TierJson tier) {
104110 }
105111
106112 return ResponseEntity .ok (result );
113+ } catch (ErrorResultException exc ) {
114+ return exc .toResponseEntity (TierJson .class );
107115 } catch (Exception exc ) {
108116 logger .error ("failed creating tier {}" , tier .getName (), exc );
109117 return ResponseEntity .internalServerError ().build ();
@@ -144,6 +152,8 @@ public ResponseEntity<TierJson> updateTier(@PathVariable String name, @RequestBo
144152 }
145153
146154 return ResponseEntity .ok (result );
155+ } catch (ErrorResultException exc ) {
156+ return exc .toResponseEntity (TierJson .class );
147157 } catch (Exception exc ) {
148158 logger .error ("failed updating tier {}" , name , exc );
149159 return ResponseEntity .internalServerError ().build ();
@@ -178,6 +188,8 @@ public ResponseEntity<ResultJson> deleteTier(@PathVariable String name) {
178188 }
179189
180190 return ResponseEntity .ok (result );
191+ } catch (ErrorResultException exc ) {
192+ return exc .toResponseEntity ();
181193 } catch (Exception exc ) {
182194 logger .error ("failed deleting tier {}" , name , exc );
183195 return ResponseEntity .internalServerError ().build ();
@@ -189,9 +201,9 @@ public ResponseEntity<ResultJson> deleteTier(@PathVariable String name) {
189201 produces = MediaType .APPLICATION_JSON_VALUE
190202 )
191203 public ResponseEntity <CustomerListJson > getCustomersForTier (@ PathVariable String name ) {
192- try {
193- admins .checkAdminUser ();
204+ admins .checkAdminUser ();
194205
206+ try {
195207 var tier = repositories .findTier (name );
196208 if (tier == null ) {
197209 return ResponseEntity .notFound ().build ();
@@ -211,9 +223,9 @@ public ResponseEntity<CustomerListJson> getCustomersForTier(@PathVariable String
211223 produces = MediaType .APPLICATION_JSON_VALUE
212224 )
213225 public ResponseEntity <CustomerListJson > getCustomers () {
214- try {
215- admins .checkAdminUser ();
226+ admins .checkAdminUser ();
216227
228+ try {
217229 var customers = repositories .findAllCustomers ();
218230 var result = new CustomerListJson (customers .stream ().map (Customer ::toJson ).toList ());
219231 return ResponseEntity .ok (result );
@@ -237,6 +249,8 @@ public ResponseEntity<CustomerJson> getCustomer(@PathVariable String name) {
237249 }
238250
239251 return ResponseEntity .ok (customer .toJson ());
252+ } catch (ErrorResultException exc ) {
253+ return exc .toResponseEntity (CustomerJson .class );
240254 } catch (Exception exc ) {
241255 logger .error ("failed retrieving customer {}" , name , exc );
242256 return ResponseEntity .internalServerError ().build ();
@@ -280,6 +294,8 @@ public ResponseEntity<CustomerJson> createCustomer(@RequestBody CustomerJson cus
280294 }
281295
282296 return ResponseEntity .ok (result );
297+ } catch (ErrorResultException exc ) {
298+ return exc .toResponseEntity (CustomerJson .class );
283299 } catch (Exception exc ) {
284300 logger .error ("failed creating customer {}" , customerJson .getName (), exc );
285301 return ResponseEntity .internalServerError ().build ();
@@ -321,6 +337,8 @@ public ResponseEntity<CustomerJson> updateCustomer(@PathVariable String name, @R
321337 }
322338
323339 return ResponseEntity .ok (result );
340+ } catch (ErrorResultException exc ) {
341+ return exc .toResponseEntity (CustomerJson .class );
324342 } catch (Exception exc ) {
325343 logger .error ("failed updating tier {}" , name , exc );
326344 return ResponseEntity .internalServerError ().build ();
@@ -344,6 +362,8 @@ public ResponseEntity<CustomerMembershipListJson> getCustomerMembers(@PathVariab
344362 var membershipList = new CustomerMembershipListJson ();
345363 membershipList .setCustomerMemberships (memberships .stream ().map (CustomerMembership ::toJson ).toList ());
346364 return ResponseEntity .ok (membershipList );
365+ } catch (ErrorResultException exc ) {
366+ return exc .toResponseEntity (CustomerMembershipListJson .class );
347367 } catch (Exception exc ) {
348368 logger .error ("failed retrieving customer members {}" , name , exc );
349369 return ResponseEntity .internalServerError ().build ();
@@ -419,6 +439,8 @@ public ResponseEntity<ResultJson> deleteCustomer(@PathVariable String name) {
419439 }
420440
421441 return ResponseEntity .ok (result );
442+ } catch (ErrorResultException exc ) {
443+ return exc .toResponseEntity ();
422444 } catch (Exception exc ) {
423445 logger .error ("failed deleting customer {}" , name , exc );
424446 return ResponseEntity .internalServerError ().build ();
@@ -430,9 +452,9 @@ public ResponseEntity<ResultJson> deleteCustomer(@PathVariable String name) {
430452 produces = MediaType .APPLICATION_JSON_VALUE
431453 )
432454 public ResponseEntity <UsageStatsListJson > getUsageStats (@ PathVariable String name , @ RequestParam (required = false ) String date ) {
433- try {
434- admins .checkAdminUser ();
455+ admins .checkAdminUser ();
435456
457+ try {
436458 var customer = repositories .findCustomer (name );
437459 if (customer == null ) {
438460 return ResponseEntity .notFound ().build ();
@@ -447,4 +469,83 @@ public ResponseEntity<UsageStatsListJson> getUsageStats(@PathVariable String nam
447469 return ResponseEntity .internalServerError ().build ();
448470 }
449471 }
472+
473+ @ GetMapping (
474+ path = "/customers/{name}/tokens" ,
475+ produces = MediaType .APPLICATION_JSON_VALUE
476+ )
477+ public ResponseEntity <List <RateLimitTokenJson >> getRateLimitTokens (@ PathVariable String name ) {
478+ admins .checkAdminUser ();
479+
480+ try {
481+ var customer = repositories .findCustomer (name );
482+ if (customer == null ) {
483+ return ResponseEntity .notFound ().build ();
484+ }
485+
486+ repositories .findActiveRateLimitTokens (customer );
487+ var tokens = repositories .findActiveRateLimitTokens (customer )
488+ .map (RateLimitToken ::toJson )
489+ .toList ();
490+
491+ return ResponseEntity .ok (tokens );
492+ } catch (Exception exc ) {
493+ logger .error ("failed retrieving rate limit tokens" , exc );
494+ return ResponseEntity .internalServerError ().build ();
495+ }
496+ }
497+
498+ @ PostMapping (
499+ path = "/customers/{name}/tokens" ,
500+ produces = MediaType .APPLICATION_JSON_VALUE
501+ )
502+ public ResponseEntity <RateLimitTokenJson > createRateLimitToken (
503+ @ PathVariable String name ,
504+ @ RequestParam (required = false ) String description
505+ ) {
506+ try {
507+ admins .checkAdminUser ();
508+
509+ if (description != null && description .length () > TOKEN_DESCRIPTION_SIZE ) {
510+ var json = RateLimitTokenJson .error ("The description must not be longer than " + TOKEN_DESCRIPTION_SIZE + " characters." );
511+ return new ResponseEntity <>(json , HttpStatus .BAD_REQUEST );
512+ }
513+
514+ var customer = repositories .findCustomer (name );
515+ if (customer == null ) {
516+ return ResponseEntity .notFound ().build ();
517+ }
518+
519+ return new ResponseEntity <>(customerService .createRateLimitToken (customer , description ), HttpStatus .CREATED );
520+ } catch (ErrorResultException exc ) {
521+ return exc .toResponseEntity (RateLimitTokenJson .class );
522+ } catch (Exception exc ) {
523+ logger .error ("failed creating rate limit token" , exc );
524+ return ResponseEntity .internalServerError ().build ();
525+ }
526+ }
527+
528+ @ DeleteMapping (
529+ path = "/customers/{name}/tokens/{id}" ,
530+ produces = MediaType .APPLICATION_JSON_VALUE
531+ )
532+ public ResponseEntity <ResultJson > deactivateRateLimitToken (@ PathVariable String name , @ PathVariable long id ) {
533+ try {
534+ admins .checkAdminUser ();
535+
536+ var customer = repositories .findCustomer (name );
537+ if (customer == null ) {
538+ return ResponseEntity .notFound ().build ();
539+ }
540+
541+ return ResponseEntity .ok (customerService .deactivateRateLimitToken (customer , id ));
542+ } catch (ErrorResultException exc ) {
543+ return exc .toResponseEntity ();
544+ } catch (NotFoundException exc ) {
545+ return new ResponseEntity <>(ResultJson .error ("Rate limit token does not exist." ), HttpStatus .NOT_FOUND );
546+ } catch (Exception exc ) {
547+ logger .error ("failed deactivating rate limit token" , exc );
548+ return ResponseEntity .internalServerError ().build ();
549+ }
550+ }
450551}
0 commit comments