From aaf46458616abe94fe1c45a12110c7998c8584f7 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 08:47:20 +0200 Subject: [PATCH 01/17] feat: inital changes for deleting an identity --- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 8 +- .../generated_test.go | 8 +- .../generated_test.go | 6 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- .../generated_test.go | 10 +- go/apps/api/openapi/gen.go | 142 ++++++++++++ go/apps/api/openapi/openapi.json | 121 +++++++++- .../v2_identities_delete_identity/handler.go | 219 ++++++++++++++++++ go/go.mod | 5 +- go/go.sum | 22 +- go/pkg/codes/constants_gen.go | 51 ++-- go/pkg/db/api_find_by_id.sql_generated.go | 2 +- go/pkg/db/api_insert.sql_generated.go | 2 +- ...ind_by_workspace_and_name.sql_generated.go | 2 +- .../audit_log_bucket_insert.sql_generated.go | 61 +++++ ...dit_log_find_target_by_id.sql_generated.go | 2 +- go/pkg/db/audit_log_insert.sql_generated.go | 2 +- .../audit_log_target_insert.sql_generated.go | 2 +- go/pkg/db/identity_delete.sql_generated.go | 22 ++ ...ntity_find_by_external_id.sql_generated.go | 37 +++ .../db/identity_find_by_id.sql_generated.go | 23 +- ...ity_find_ratelimits_by_id.sql_generated.go | 2 +- go/pkg/db/identity_insert.sql_generated.go | 2 +- ...identity_insert_ratelimit.sql_generated.go | 2 +- go/pkg/db/key_find_by_hash.sql_generated.go | 2 +- go/pkg/db/key_find_by_id.sql_generated.go | 2 +- ...key_find_for_verification.sql_generated.go | 2 +- go/pkg/db/key_insert.sql_generated.go | 2 +- go/pkg/db/keyring_find_by_id.sql_generated.go | 2 +- go/pkg/db/keyring_insert.sql_generated.go | 2 +- go/pkg/db/models_generated.go | 2 +- ...ind_by_workspace_and_name.sql_generated.go | 2 +- go/pkg/db/permission_insert.sql_generated.go | 2 +- ...ion_insert_key_permission.sql_generated.go | 2 +- .../db/permissions_by_key_id.sql_generated.go | 2 +- go/pkg/db/querier_generated.go | 38 ++- ...g_bucket_id_find_by_workspace_and_name.sql | 2 + go/pkg/db/queries/audit_log_bucket_insert.sql | 14 ++ go/pkg/db/queries/identity_delete.sql | 2 + .../queries/identity_find_by_external_id.sql | 2 + go/pkg/db/queries/identity_find_by_id.sql | 2 +- go/pkg/db/queries/ratelimit_delete_many.sql | 2 + .../db/ratelimit_delete_many.sql_generated.go | 33 +++ ...atelimit_namespace_delete.sql_generated.go | 2 +- ...imit_namespace_find_by_id.sql_generated.go | 2 +- ...it_namespace_find_by_name.sql_generated.go | 2 +- ...atelimit_namespace_insert.sql_generated.go | 2 +- ...mit_namespace_soft_delete.sql_generated.go | 2 +- ...limit_override_find_by_id.sql_generated.go | 2 +- ...erride_find_by_identifier.sql_generated.go | 2 +- ...mit_override_find_matches.sql_generated.go | 2 +- ...ratelimit_override_insert.sql_generated.go | 2 +- ...ride_list_by_namespace_id.sql_generated.go | 2 +- ...imit_override_soft_delete.sql_generated.go | 2 +- ...ratelimit_override_update.sql_generated.go | 2 +- .../db/workspace_find_by_id.sql_generated.go | 2 +- .../db/workspace_hard_delete.sql_generated.go | 2 +- go/pkg/db/workspace_insert.sql_generated.go | 2 +- .../db/workspace_soft_delete.sql_generated.go | 2 +- .../workspace_update_enabled.sql_generated.go | 2 +- .../db/workspace_update_plan.sql_generated.go | 2 +- go/pkg/db/workspaces_list.sql_generated.go | 2 +- 111 files changed, 1022 insertions(+), 346 deletions(-) create mode 100644 go/apps/api/routes/v2_identities_delete_identity/handler.go create mode 100644 go/pkg/db/audit_log_bucket_insert.sql_generated.go create mode 100644 go/pkg/db/identity_delete.sql_generated.go create mode 100644 go/pkg/db/identity_find_by_external_id.sql_generated.go create mode 100644 go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql create mode 100644 go/pkg/db/queries/audit_log_bucket_insert.sql create mode 100644 go/pkg/db/queries/identity_delete.sql create mode 100644 go/pkg/db/queries/identity_find_by_external_id.sql create mode 100644 go/pkg/db/queries/ratelimit_delete_many.sql create mode 100644 go/pkg/db/ratelimit_delete_many.sql_generated.go diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go index 552fe8071b..2632152f50 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go index 0258b8b338..c969c7937f 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go index b81c522c2e..58d0d632d4 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go index 09f979ab20..93cd2ef3fd 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 1, // node count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go index 85db1f83ee..3f5b1f82cd 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 1, // node count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go index d949f73597..ee137e9ec6 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 1, // node count + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go index 22431412cd..e356b64753 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go index f4172c7b64..180b5a0885 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go index d6024ff443..0dfe9bdf82 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go index ed3979a8f9..47c9acd39e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go index 52c7ad8bc6..255272c096 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go index 14ff667795..e8c19fd2f5 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go index 78c84de3c1..9c83fcc957 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 1, // node count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go index 5c8fb2f0e5..3abe696741 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 1, // node count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go index 06909946d6..309ed5fac7 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 1, // node count + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go index 4ddf89e004..9322bde125 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go index a47bca4d26..b089452429 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go index bfc6875e3e..1c1228ed97 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go index 032ceb384d..28a52404bf 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go index 9d503efee9..51c8909235 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go index 2eaae82714..0a39a0b801 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go index 7ada487478..9c626e5fbe 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 3, // node count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go index 06d76e9d80..188bcd84a9 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 3, // node count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go index 135b981183..0bcc2a0274 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 3, // node count + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go index 4a819f8b32..d78e21ccb1 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go index b5e499078b..d44c112057 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go index e20fd3c6c1..7bf591a233 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go index 10e660d367..ad17cb979c 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go index a0670e6808..0e16b1c380 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go index 5d404e6959..3e7d690f8a 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go index 17611f51fa..3e7c431e97 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 3, // node count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go index 12b7f4419e..8d41aeb542 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 3, // node count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go index 8075d42c15..2c3e38718c 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 3, // node count + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go index ced9a853ee..2ad80f8bbc 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go index 15375931a5..b7ba029539 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go index d73118fe1c..1b245e625b 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go index ad7ea299c2..b10bda559b 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go index 7cb427ee68..c1e93bd6eb 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go index ee76aae4cf..a0ad5614c6 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go index b8afa443c1..6f0571096d 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 9, // node count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go index f1a6d596e9..ff23abb4f8 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 9, // node count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go index b671ddd1bf..7f876c7971 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 9, // node count + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go index 5dab408a1c..b90a0bfade 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go index 4ca4f08f94..4aae4855d1 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go index 7fca869568..e61efe82e7 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go index ef6e840a54..b2ddf6a409 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go index af389b45cf..5ca2212654 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go index 3cbd8ec16e..f0e8e67afe 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go index 962df1ca88..4c0ee50d70 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 9, // node count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go index 5d1dfeca6a..6399ba99e0 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 9, // node count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go index a604ef1187..5f8eb3838e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 9, // node count + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go index 334a591b39..1e5832698a 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go index 40cfddb431..3cab014dd5 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go index 6d9af71650..f932ffbe12 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/openapi/gen.go b/go/apps/api/openapi/gen.go index a39fe3bb1b..44e7a4b087 100644 --- a/go/apps/api/openapi/gen.go +++ b/go/apps/api/openapi/gen.go @@ -3,6 +3,13 @@ // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. package openapi +import ( + "encoding/json" + "fmt" + + "github.com/oapi-codegen/runtime" +) + const ( RootKeyScopes = "rootKey.Scopes" ) @@ -211,6 +218,28 @@ type V2IdentitiesCreateIdentityResponseBody struct { Meta Meta `json:"meta"` } +// V2IdentitiesDeleteIdentityRequestBody defines model for V2IdentitiesDeleteIdentityRequestBody. +type V2IdentitiesDeleteIdentityRequestBody struct { + // ExternalId The id of this identity in your system. + // + // This usually comes from your authentication provider and could be a userId, organisationId or even an email. + // It does not matter what you use, as long as it uniquely identifies something in your application. + ExternalId *string `json:"externalId,omitempty"` + + // IdentityId The Unkey Identity ID. + IdentityId *string `json:"identityId,omitempty"` + union json.RawMessage +} + +// V2IdentitiesDeleteIdentityRequestBody0 defines model for . +type V2IdentitiesDeleteIdentityRequestBody0 = interface{} + +// V2IdentitiesDeleteIdentityRequestBody1 defines model for . +type V2IdentitiesDeleteIdentityRequestBody1 = interface{} + +// V2IdentitiesDeleteIdentityResponseBody defines model for V2IdentitiesDeleteIdentityResponseBody. +type V2IdentitiesDeleteIdentityResponseBody = map[string]interface{} + // V2LivenessResponseBody defines model for V2LivenessResponseBody. type V2LivenessResponseBody struct { Data LivenessResponseData `json:"data"` @@ -353,6 +382,9 @@ type CreateApiJSONRequestBody = V2ApisCreateApiRequestBody // IdentitiesCreateIdentityJSONRequestBody defines body for IdentitiesCreateIdentity for application/json ContentType. type IdentitiesCreateIdentityJSONRequestBody = V2IdentitiesCreateIdentityRequestBody +// V2IdentitiesDeleteIdentityJSONRequestBody defines body for V2IdentitiesDeleteIdentity for application/json ContentType. +type V2IdentitiesDeleteIdentityJSONRequestBody = V2IdentitiesDeleteIdentityRequestBody + // RatelimitDeleteOverrideJSONRequestBody defines body for RatelimitDeleteOverride for application/json ContentType. type RatelimitDeleteOverrideJSONRequestBody = V2RatelimitDeleteOverrideRequestBody @@ -367,3 +399,113 @@ type RatelimitListOverridesJSONRequestBody = V2RatelimitListOverridesRequestBody // RatelimitSetOverrideJSONRequestBody defines body for RatelimitSetOverride for application/json ContentType. type RatelimitSetOverrideJSONRequestBody = V2RatelimitSetOverrideRequestBody + +// AsV2IdentitiesDeleteIdentityRequestBody0 returns the union data inside the V2IdentitiesDeleteIdentityRequestBody as a V2IdentitiesDeleteIdentityRequestBody0 +func (t V2IdentitiesDeleteIdentityRequestBody) AsV2IdentitiesDeleteIdentityRequestBody0() (V2IdentitiesDeleteIdentityRequestBody0, error) { + var body V2IdentitiesDeleteIdentityRequestBody0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromV2IdentitiesDeleteIdentityRequestBody0 overwrites any union data inside the V2IdentitiesDeleteIdentityRequestBody as the provided V2IdentitiesDeleteIdentityRequestBody0 +func (t *V2IdentitiesDeleteIdentityRequestBody) FromV2IdentitiesDeleteIdentityRequestBody0(v V2IdentitiesDeleteIdentityRequestBody0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeV2IdentitiesDeleteIdentityRequestBody0 performs a merge with any union data inside the V2IdentitiesDeleteIdentityRequestBody, using the provided V2IdentitiesDeleteIdentityRequestBody0 +func (t *V2IdentitiesDeleteIdentityRequestBody) MergeV2IdentitiesDeleteIdentityRequestBody0(v V2IdentitiesDeleteIdentityRequestBody0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsV2IdentitiesDeleteIdentityRequestBody1 returns the union data inside the V2IdentitiesDeleteIdentityRequestBody as a V2IdentitiesDeleteIdentityRequestBody1 +func (t V2IdentitiesDeleteIdentityRequestBody) AsV2IdentitiesDeleteIdentityRequestBody1() (V2IdentitiesDeleteIdentityRequestBody1, error) { + var body V2IdentitiesDeleteIdentityRequestBody1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromV2IdentitiesDeleteIdentityRequestBody1 overwrites any union data inside the V2IdentitiesDeleteIdentityRequestBody as the provided V2IdentitiesDeleteIdentityRequestBody1 +func (t *V2IdentitiesDeleteIdentityRequestBody) FromV2IdentitiesDeleteIdentityRequestBody1(v V2IdentitiesDeleteIdentityRequestBody1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeV2IdentitiesDeleteIdentityRequestBody1 performs a merge with any union data inside the V2IdentitiesDeleteIdentityRequestBody, using the provided V2IdentitiesDeleteIdentityRequestBody1 +func (t *V2IdentitiesDeleteIdentityRequestBody) MergeV2IdentitiesDeleteIdentityRequestBody1(v V2IdentitiesDeleteIdentityRequestBody1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t V2IdentitiesDeleteIdentityRequestBody) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + if err != nil { + return nil, err + } + object := make(map[string]json.RawMessage) + if t.union != nil { + err = json.Unmarshal(b, &object) + if err != nil { + return nil, err + } + } + + if t.ExternalId != nil { + object["externalId"], err = json.Marshal(t.ExternalId) + if err != nil { + return nil, fmt.Errorf("error marshaling 'externalId': %w", err) + } + } + + if t.IdentityId != nil { + object["identityId"], err = json.Marshal(t.IdentityId) + if err != nil { + return nil, fmt.Errorf("error marshaling 'identityId': %w", err) + } + } + b, err = json.Marshal(object) + return b, err +} + +func (t *V2IdentitiesDeleteIdentityRequestBody) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + if err != nil { + return err + } + object := make(map[string]json.RawMessage) + err = json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["externalId"]; found { + err = json.Unmarshal(raw, &t.ExternalId) + if err != nil { + return fmt.Errorf("error reading 'externalId': %w", err) + } + } + + if raw, found := object["identityId"]; found { + err = json.Unmarshal(raw, &t.IdentityId) + if err != nil { + return fmt.Errorf("error reading 'identityId': %w", err) + } + } + + return err +} diff --git a/go/apps/api/openapi/openapi.json b/go/apps/api/openapi/openapi.json index 2a331a834c..de9c8bfe5e 100644 --- a/go/apps/api/openapi/openapi.json +++ b/go/apps/api/openapi/openapi.json @@ -569,6 +569,35 @@ } } }, + "V2IdentitiesDeleteIdentityRequestBody": { + "additionalProperties": false, + "type": "object", + "properties": { + "externalId": { + "type": "string", + "minLength": 3, + "description": "The id of this identity in your system.\n\nThis usually comes from your authentication provider and could be a userId, organisationId or even an email.\nIt does not matter what you use, as long as it uniquely identifies something in your application.\n", + "example": "user_123" + }, + "identityId": { + "type": "string", + "minLength": 3, + "description": "The Unkey Identity ID.", + "example": "id_123" + } + }, + "anyOf": [ + { + "required": ["externalId"] + }, + { + "required": ["identityId"] + } + ] + }, + "V2IdentitiesDeleteIdentityResponseBody": { + "type": "object" + }, "V2ApisCreateApiRequestBody": { "type": "object", "required": ["name"], @@ -643,7 +672,13 @@ "minimum": 0 } }, - "required": ["namespaceId", "overrideId", "duration", "identifier", "limit"] + "required": [ + "namespaceId", + "overrideId", + "duration", + "identifier", + "limit" + ] } } }, @@ -1152,6 +1187,90 @@ } } }, + "/v2/identities.deleteIdentity": { + "post": { + "tags": ["identities"], + "operationId": "v2.identities.deleteIdentity", + "x-speakeasy-name-override": "deleteIdentity", + "security": [ + { + "rootKey": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2IdentitiesDeleteIdentityRequestBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2IdentitiesDeleteIdentityResponseBody" + } + } + }, + "description": "OK" + }, + "400": { + "description": "Bad request", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponse" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponse" + } + } + } + }, + "500": { + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/InternalServerErrorResponse" + } + } + }, + "description": "Error" + } + } + } + }, "/v2/apis.createApi": { "post": { "tags": ["apis"], diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go new file mode 100644 index 0000000000..1996fae2fe --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -0,0 +1,219 @@ +package handler + +import ( + "context" + "database/sql" + "errors" + "fmt" + "net/http" + + "github.com/unkeyed/unkey/go/apps/api/openapi" + "github.com/unkeyed/unkey/go/internal/services/auditlogs" + "github.com/unkeyed/unkey/go/internal/services/keys" + "github.com/unkeyed/unkey/go/internal/services/permissions" + "github.com/unkeyed/unkey/go/pkg/auditlog" + "github.com/unkeyed/unkey/go/pkg/codes" + "github.com/unkeyed/unkey/go/pkg/db" + "github.com/unkeyed/unkey/go/pkg/fault" + "github.com/unkeyed/unkey/go/pkg/otel/logging" + "github.com/unkeyed/unkey/go/pkg/rbac" + "github.com/unkeyed/unkey/go/pkg/zen" +) + +type Request = openapi.V2IdentitiesDeleteIdentityRequestBody +type Response = openapi.V2IdentitiesDeleteIdentityResponseBody + +type Services struct { + Logger logging.Logger + DB db.Database + Keys keys.KeyService + Permissions permissions.PermissionService + Auditlogs auditlogs.AuditLogService +} + +func New(svc Services) zen.Route { + return zen.NewRoute("POST", "/v2/identities.deleteIdentity", func(ctx context.Context, s *zen.Session) error { + auth, err := svc.Keys.VerifyRootKey(ctx, s) + if err != nil { + return err + } + + // nolint:exhaustruct + req := Request{} + err = s.BindBody(&req) + if err != nil { + return fault.Wrap(err, + fault.WithDesc("invalid request body", "The request body is invalid."), + ) + } + + permissions, err := svc.Permissions.Check( + ctx, + auth.KeyID, + rbac.Or( + rbac.T(rbac.Tuple{ + ResourceType: rbac.Identity, + ResourceID: "*", + Action: rbac.DeleteIdentity, + }), + ), + ) + if err != nil { + return fault.Wrap(err, + fault.WithDesc("unable to check permissions", "We're unable to check the permissions of your key."), + ) + } + if !permissions.Valid { + return fault.New("insufficient permissions", + fault.WithCode(codes.Auth.Authorization.InsufficientPermissions.URN()), + fault.WithDesc(permissions.Message, permissions.Message), + ) + } + + tx, err := svc.DB.RW().Begin(ctx) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to create transaction", "Unable to start database transaction."), + ) + } + + defer func() { + rollbackErr := tx.Rollback() + if rollbackErr != nil && !errors.Is(rollbackErr, sql.ErrTxDone) { + svc.Logger.Error("rollback failed", "requestId", s.RequestID(), "error", rollbackErr) + } + }() + + identity, err := getIdentity(ctx, svc, req, auth.AuthorizedWorkspaceID) + if err != nil { + if db.IsNotFound(err) { + return fault.New("identity not found", + fault.WithCode(codes.Data.Identity.NotFound.URN()), + fault.WithDesc("identity not found", "This identity does not exist."), + ) + } + + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to find the identity", "Error finding the identity."), + ) + } + + if identity.WorkspaceID != auth.AuthorizedWorkspaceID { + return fault.New("identity not found", + fault.WithCode(codes.Data.Identity.NotFound.URN()), + fault.WithDesc("wrong workspace, masking as 404", "This identity does not exist."), + ) + } + + ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, svc.DB.RO(), sql.NullString{String: identity.ID, Valid: true}) + if err != nil && !db.IsNotFound(err) { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to load identity ratelimits", "Failed to load Identity ratelimits."), + ) + } + + if len(ratelimits) > 0 { + ids := make([]string, 0) + for _, ratelimit := range ratelimits { + ids = append(ids, ratelimit.ID) + } + + err = db.Query.DeleteManyRatelimitsByIDs(ctx, tx, ids) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to delete identity ratelimits", "Failed to delete Identity ratelimits."), + ) + } + } + + err = db.Query.DeleteIdentity(ctx, tx, identity.ID) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to delete identity", "Failed to delete Identity."), + ) + } + + auditLogs := []auditlog.AuditLog{ + { + WorkspaceID: auth.AuthorizedWorkspaceID, + Event: auditlog.IdentityDeleteEvent, + Display: fmt.Sprintf("Deleted identity %s.", identity.ID), + ActorID: auth.KeyID, + ActorType: auditlog.RootKeyActor, + RemoteIP: s.Location(), + UserAgent: s.UserAgent(), + Resources: []auditlog.AuditLogResource{ + { + ID: identity.ID, + Type: auditlog.IdentityResourceType, + DisplayName: identity.ExternalID, + }, + }, + }, + } + + for _, rl := range ratelimits { + auditLogs = append(auditLogs, auditlog.AuditLog{ + WorkspaceID: auth.AuthorizedWorkspaceID, + Event: auditlog.RatelimitDeleteEvent, + Display: fmt.Sprintf("Deleted ratelimit %s.", rl.ID), + ActorID: auth.KeyID, + ActorType: auditlog.RootKeyActor, + RemoteIP: s.Location(), + UserAgent: s.UserAgent(), + Resources: []auditlog.AuditLogResource{ + { + Type: auditlog.IdentityResourceType, + ID: identity.ID, + DisplayName: identity.ExternalID, + }, + { + Type: auditlog.RatelimitResourceType, + ID: rl.ID, + DisplayName: rl.Name, + }, + }, + }) + } + + err = svc.Auditlogs.Insert(ctx, tx, auditLogs) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to insert audit logs", "Failed to insert audit logs"), + ) + } + + err = tx.Commit() + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to commit transaction", "Failed to commit changes."), + ) + } + + return s.JSON(http.StatusOK, Response{}) + }) +} + +func getIdentity(ctx context.Context, svc Services, req Request, workspaceID string) (db.Identity, error) { + switch { + case req.IdentityId != nil: + return db.Query.FindIdentityByID(ctx, svc.DB.RO(), *req.IdentityId) + case req.ExternalId != nil: + return db.Query.FindIdentityByExternalID(ctx, svc.DB.RO(), db.FindIdentityByExternalIDParams{ + WorkspaceID: workspaceID, + ExternalID: *req.ExternalId, + }) + } + + return db.Identity{}, fault.New("missing identity id or external id", + fault.WithCode(codes.App.Validation.InvalidInput.URN()), + fault.WithDesc("missing identity id or external id", "You must provide either an identity ID or external ID."), + ) +} diff --git a/go/go.mod b/go/go.mod index 428e9545ab..289aff8d45 100644 --- a/go/go.mod +++ b/go/go.mod @@ -11,6 +11,7 @@ require ( github.com/lmittmann/tint v1.0.7 github.com/maypok86/otter v1.2.4 github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 + github.com/oapi-codegen/runtime v1.1.1 github.com/ory/dockertest/v3 v3.11.0 github.com/pb33f/libopenapi v0.21.8 github.com/pb33f/libopenapi-validator v0.4.0 @@ -31,7 +32,6 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.35.0 go.opentelemetry.io/otel/trace v1.35.0 golang.org/x/text v0.24.0 - google.golang.org/protobuf v1.36.6 ) require ( @@ -44,6 +44,7 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -131,7 +132,6 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect go.opentelemetry.io/otel/log v0.11.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect @@ -148,6 +148,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go/go.sum b/go/go.sum index c4e8d5476a..1467134a64 100644 --- a/go/go.sum +++ b/go/go.sum @@ -9,18 +9,20 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ClickHouse/ch-go v0.65.1 h1:SLuxmLl5Mjj44/XbINsK2HFvzqup0s6rwKLFH347ZhU= github.com/ClickHouse/ch-go v0.65.1/go.mod h1:bsodgURwmrkvkBe5jw1qnGDgyITsYErfONKAHn05nv4= -github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= github.com/ClickHouse/clickhouse-go/v2 v2.34.0 h1:Y4rqkdrRHgExvC4o/NTbLdY5LFQ3LHS77/RNFxFX3Co= github.com/ClickHouse/clickhouse-go/v2 v2.34.0/go.mod h1:yioSINoRLVZkLyDzdMXPLRIqhDvel8iLBlwh6Iefso8= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/axiomhq/axiom-go v0.23.0 h1:kY+JkLubQ6ANwIp1O3J//YQe9OpdXFaW7xaj1wXvfps= github.com/axiomhq/axiom-go v0.23.0/go.mod h1:JGtkryt27W4QXVrgrwVxORPI/iRCM3N22H5FVi0PtQs= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= @@ -28,6 +30,7 @@ github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xW github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -65,9 +68,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= -github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/cli v27.2.0+incompatible h1:yHD1QEB1/0vr5eBNpu8tncu8gWxg8EydFPOSKHzXSMM= github.com/docker/cli v27.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v28.0.4+incompatible h1:JNNkBctYKurkw6FrHfKqY0nKIDf5nrbxjVBtS+cdcok= @@ -171,6 +173,7 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= @@ -212,6 +215,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 h1:ykgG34472DWey7TSjd8vIfNykXgjOgYJZoQbKfEeY/Q= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -241,8 +246,6 @@ github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/En github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= github.com/pb33f/libopenapi v0.21.8 h1:Fi2dAogMwC6av/5n3YIo7aMOGBZH/fBMO4OnzFB3dQA= github.com/pb33f/libopenapi v0.21.8/go.mod h1:Gc8oQkjr2InxwumK0zOBtKN9gIlv9L2VmSVIUk2YxcU= -github.com/pb33f/libopenapi-validator v0.3.1 h1:7+p/y5qPlpVcJptFMpXUWGi+6D3Pdv8p8PXYmmXy/sk= -github.com/pb33f/libopenapi-validator v0.3.1/go.mod h1:R3xMZCF8mFnYww1Hf31ABAz+/QmTheLPKG4p041IR5U= github.com/pb33f/libopenapi-validator v0.4.0 h1:3ZdmyyP1oztytrJTPU3BTYGxUgzsTTNBA2uQNgmjzqk= github.com/pb33f/libopenapi-validator v0.4.0/go.mod h1:W+odPcfKledbm+G+Ic1YAPz+WoPHKqpHzQ9UoJMnjB0= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -302,6 +305,7 @@ github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3k github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/sqlc-dev/sqlc v1.28.0 h1:2QB4X22pKNpKMyb8dRLnqZwMXW6S+ZCyYCpa+3/ICcI= github.com/sqlc-dev/sqlc v1.28.0/go.mod h1:x6wDsOHH60dTX3ES9sUUxRVaROg5aFB3l3nkkjyuK1A= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= @@ -359,8 +363,6 @@ go.opentelemetry.io/contrib/bridges/otelslog v0.10.0 h1:lRKWBp9nWoBe1HKXzc3ovkro go.opentelemetry.io/contrib/bridges/otelslog v0.10.0/go.mod h1:D+iyUv/Wxbw5LUDO5oh7x744ypftIryiWjoj42I6EKs= go.opentelemetry.io/contrib/bridges/prometheus v0.60.0 h1:x7sPooQCwSg27SjtQee8GyIIRTQcF4s7eSkac6F2+VA= go.opentelemetry.io/contrib/bridges/prometheus v0.60.0/go.mod h1:4K5UXgiHxV484efGs42ejD7E2J/sIlepYgdGoPXe7hE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/contrib/processors/minsev v0.8.0 h1:/i0gaV0Z174Twy1/NfgQoE+oQvFVbQItNl8UMwe62Jc= @@ -375,8 +377,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= -go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk= -go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c= go.opentelemetry.io/otel/log v0.11.0 h1:c24Hrlk5WJ8JWcwbQxdBqxZdOK7PcP/LFtOtwpDTe3Y= go.opentelemetry.io/otel/log v0.11.0/go.mod h1:U/sxQ83FPmT29trrifhQg+Zj2lo1/IPN1PF6RTFqdwc= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= @@ -481,12 +481,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= -google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e h1:UdXH7Kzbj+Vzastr5nVfccbmFsmYNygVLSPk1pEfDoY= google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e/go.mod h1:085qFyf2+XaZlRdCgKNCIZ3afY2p4HHZdoIRpId8F4A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA= google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index ccd985b6ca..2b3e1d97fd 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-17T14:51:39+02:00 +// Generated at: 2025-04-18T08:45:13+02:00 package codes @@ -8,11 +8,11 @@ type URN string // Error code constants for use in switch statements for exhaustive checking const ( - // ---------------- - // UnkeyAuthErrors - // ---------------- +// ---------------- +// UnkeyAuthErrors +// ---------------- - // Authentication +// Authentication // Missing indicates authentication credentials were not provided. UnkeyAuthErrorsAuthenticationMissing URN = "err:unkey:authentication:missing" @@ -21,7 +21,7 @@ const ( // KeyNotFound indicates the authentication key was not found. UnkeyAuthErrorsAuthenticationKeyNotFound URN = "err:unkey:authentication:key_not_found" - // Authorization +// Authorization // InsufficientPermissions indicates the authenticated entity lacks // sufficient permissions for the requested operation. @@ -33,82 +33,83 @@ const ( // WorkspaceDisabled indicates the associated workspace is disabled. UnkeyAuthErrorsAuthorizationWorkspaceDisabled URN = "err:unkey:authorization:workspace_disabled" - // ---------------- - // UnkeyDataErrors - // ---------------- +// ---------------- +// UnkeyDataErrors +// ---------------- - // Key +// Key // NotFound indicates the requested key was not found. UnkeyDataErrorsKeyNotFound URN = "err:unkey:data:key_not_found" - // Workspace +// Workspace // NotFound indicates the requested workspace was not found. UnkeyDataErrorsWorkspaceNotFound URN = "err:unkey:data:workspace_not_found" - // Api +// Api // NotFound indicates the requested API was not found. UnkeyDataErrorsApiNotFound URN = "err:unkey:data:api_not_found" - // Permission +// Permission // NotFound indicates the requested permission was not found. UnkeyDataErrorsPermissionNotFound URN = "err:unkey:data:permission_not_found" - // Role +// Role // NotFound indicates the requested role was not found. UnkeyDataErrorsRoleNotFound URN = "err:unkey:data:role_not_found" - // KeyAuth +// KeyAuth // NotFound indicates the requested key authentication was not found. UnkeyDataErrorsKeyAuthNotFound URN = "err:unkey:data:key_auth_not_found" - // RatelimitNamespace +// RatelimitNamespace // NotFound indicates the requested rate limit namespace was not found. UnkeyDataErrorsRatelimitNamespaceNotFound URN = "err:unkey:data:ratelimit_namespace_not_found" - // RatelimitOverride +// RatelimitOverride // NotFound indicates the requested rate limit override was not found. UnkeyDataErrorsRatelimitOverrideNotFound URN = "err:unkey:data:ratelimit_override_not_found" - // Identity +// Identity // NotFound indicates the requested identity was not found. UnkeyDataErrorsIdentityNotFound URN = "err:unkey:data:identity_not_found" // Duplicate indicates the requested identity already exists. UnkeyDataErrorsIdentityDuplicate URN = "err:unkey:data:identity_already_exists" - // AuditLog +// AuditLog // NotFound indicates the requested audit log was not found. UnkeyDataErrorsAuditLogNotFound URN = "err:unkey:data:audit_log_not_found" - // ---------------- - // UnkeyAppErrors - // ---------------- +// ---------------- +// UnkeyAppErrors +// ---------------- - // Internal +// Internal // UnexpectedError represents an unhandled or unexpected error condition. UnkeyAppErrorsInternalUnexpectedError URN = "err:unkey:application:unexpected_error" // ServiceUnavailable indicates a service is temporarily unavailable. UnkeyAppErrorsInternalServiceUnavailable URN = "err:unkey:application:service_unavailable" - // Validation +// Validation // InvalidInput indicates a client provided input that failed validation. UnkeyAppErrorsValidationInvalidInput URN = "err:unkey:application:invalid_input" // AssertionFailed indicates a runtime assertion or invariant check failed. UnkeyAppErrorsValidationAssertionFailed URN = "err:unkey:application:assertion_failed" - // Protection +// Protection // ProtectedResource indicates an attempt to modify a protected resource. UnkeyAppErrorsProtectionProtectedResource URN = "err:unkey:application:protected_resource" + ) diff --git a/go/pkg/db/api_find_by_id.sql_generated.go b/go/pkg/db/api_find_by_id.sql_generated.go index a8c87eaf93..b4c5392d03 100644 --- a/go/pkg/db/api_find_by_id.sql_generated.go +++ b/go/pkg/db/api_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: api_find_by_id.sql package db diff --git a/go/pkg/db/api_insert.sql_generated.go b/go/pkg/db/api_insert.sql_generated.go index a71d448966..f3979a099d 100644 --- a/go/pkg/db/api_insert.sql_generated.go +++ b/go/pkg/db/api_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: api_insert.sql package db diff --git a/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go b/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go index 8fafc323d7..32202bab36 100644 --- a/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go +++ b/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: audit_log_bucket_id_find_by_workspace_and_name.sql package db diff --git a/go/pkg/db/audit_log_bucket_insert.sql_generated.go b/go/pkg/db/audit_log_bucket_insert.sql_generated.go new file mode 100644 index 0000000000..e50f6a412c --- /dev/null +++ b/go/pkg/db/audit_log_bucket_insert.sql_generated.go @@ -0,0 +1,61 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: audit_log_bucket_insert.sql + +package db + +import ( + "context" + "database/sql" +) + +const insertAuditLogBucket = `-- name: InsertAuditLogBucket :exec +INSERT INTO ` + "`" + `audit_log_bucket` + "`" + ` ( + id, + workspace_id, + name, + retention_days, + created_at +) VALUES ( + ?, + ?, + ?, + ?, + ? +) +` + +type InsertAuditLogBucketParams struct { + ID string `db:"id"` + WorkspaceID string `db:"workspace_id"` + Name string `db:"name"` + RetentionDays sql.NullInt32 `db:"retention_days"` + CreatedAt int64 `db:"created_at"` +} + +// InsertAuditLogBucket +// +// INSERT INTO `audit_log_bucket` ( +// id, +// workspace_id, +// name, +// retention_days, +// created_at +// ) VALUES ( +// ?, +// ?, +// ?, +// ?, +// ? +// ) +func (q *Queries) InsertAuditLogBucket(ctx context.Context, db DBTX, arg InsertAuditLogBucketParams) error { + _, err := db.ExecContext(ctx, insertAuditLogBucket, + arg.ID, + arg.WorkspaceID, + arg.Name, + arg.RetentionDays, + arg.CreatedAt, + ) + return err +} diff --git a/go/pkg/db/audit_log_find_target_by_id.sql_generated.go b/go/pkg/db/audit_log_find_target_by_id.sql_generated.go index 7d38ff42d8..0a637d7d02 100644 --- a/go/pkg/db/audit_log_find_target_by_id.sql_generated.go +++ b/go/pkg/db/audit_log_find_target_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: audit_log_find_target_by_id.sql package db diff --git a/go/pkg/db/audit_log_insert.sql_generated.go b/go/pkg/db/audit_log_insert.sql_generated.go index 5d40a500ed..a286899335 100644 --- a/go/pkg/db/audit_log_insert.sql_generated.go +++ b/go/pkg/db/audit_log_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: audit_log_insert.sql package db diff --git a/go/pkg/db/audit_log_target_insert.sql_generated.go b/go/pkg/db/audit_log_target_insert.sql_generated.go index 8ed952b300..e103aa9b1c 100644 --- a/go/pkg/db/audit_log_target_insert.sql_generated.go +++ b/go/pkg/db/audit_log_target_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: audit_log_target_insert.sql package db diff --git a/go/pkg/db/identity_delete.sql_generated.go b/go/pkg/db/identity_delete.sql_generated.go new file mode 100644 index 0000000000..65f50679b9 --- /dev/null +++ b/go/pkg/db/identity_delete.sql_generated.go @@ -0,0 +1,22 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: identity_delete.sql + +package db + +import ( + "context" +) + +const deleteIdentity = `-- name: DeleteIdentity :exec +DELETE FROM identities WHERE id = ? +` + +// DeleteIdentity +// +// DELETE FROM identities WHERE id = ? +func (q *Queries) DeleteIdentity(ctx context.Context, db DBTX, id string) error { + _, err := db.ExecContext(ctx, deleteIdentity, id) + return err +} diff --git a/go/pkg/db/identity_find_by_external_id.sql_generated.go b/go/pkg/db/identity_find_by_external_id.sql_generated.go new file mode 100644 index 0000000000..5b78b55a84 --- /dev/null +++ b/go/pkg/db/identity_find_by_external_id.sql_generated.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: identity_find_by_external_id.sql + +package db + +import ( + "context" +) + +const findIdentityByExternalID = `-- name: FindIdentityByExternalID :one +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? +` + +type FindIdentityByExternalIDParams struct { + WorkspaceID string `db:"workspace_id"` + ExternalID string `db:"external_id"` +} + +// FindIdentityByExternalID +// +// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? +func (q *Queries) FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) { + row := db.QueryRowContext(ctx, findIdentityByExternalID, arg.WorkspaceID, arg.ExternalID) + var i Identity + err := row.Scan( + &i.ID, + &i.ExternalID, + &i.WorkspaceID, + &i.Environment, + &i.CreatedAt, + &i.UpdatedAt, + &i.Meta, + ) + return i, err +} diff --git a/go/pkg/db/identity_find_by_id.sql_generated.go b/go/pkg/db/identity_find_by_id.sql_generated.go index caa0ab9ae6..13e1ef1090 100644 --- a/go/pkg/db/identity_find_by_id.sql_generated.go +++ b/go/pkg/db/identity_find_by_id.sql_generated.go @@ -1,41 +1,32 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: identity_find_by_id.sql package db import ( "context" - "database/sql" ) const findIdentityByID = `-- name: FindIdentityByID :one -SELECT external_id, workspace_id, environment, meta, created_at, updated_at FROM identities WHERE id = ? +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? ` -type FindIdentityByIDRow struct { - ExternalID string `db:"external_id"` - WorkspaceID string `db:"workspace_id"` - Environment string `db:"environment"` - Meta []byte `db:"meta"` - CreatedAt int64 `db:"created_at"` - UpdatedAt sql.NullInt64 `db:"updated_at"` -} - // FindIdentityByID // -// SELECT external_id, workspace_id, environment, meta, created_at, updated_at FROM identities WHERE id = ? -func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, id string) (FindIdentityByIDRow, error) { +// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? +func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, id string) (Identity, error) { row := db.QueryRowContext(ctx, findIdentityByID, id) - var i FindIdentityByIDRow + var i Identity err := row.Scan( + &i.ID, &i.ExternalID, &i.WorkspaceID, &i.Environment, - &i.Meta, &i.CreatedAt, &i.UpdatedAt, + &i.Meta, ) return i, err } diff --git a/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go b/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go index 26dfbcf657..c149811383 100644 --- a/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go +++ b/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: identity_find_ratelimits_by_id.sql package db diff --git a/go/pkg/db/identity_insert.sql_generated.go b/go/pkg/db/identity_insert.sql_generated.go index a3e8c97be2..da40be05ed 100644 --- a/go/pkg/db/identity_insert.sql_generated.go +++ b/go/pkg/db/identity_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: identity_insert.sql package db diff --git a/go/pkg/db/identity_insert_ratelimit.sql_generated.go b/go/pkg/db/identity_insert_ratelimit.sql_generated.go index dda245eb67..dedde6fc8a 100644 --- a/go/pkg/db/identity_insert_ratelimit.sql_generated.go +++ b/go/pkg/db/identity_insert_ratelimit.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: identity_insert_ratelimit.sql package db diff --git a/go/pkg/db/key_find_by_hash.sql_generated.go b/go/pkg/db/key_find_by_hash.sql_generated.go index 5c1c0695da..a29a61acd4 100644 --- a/go/pkg/db/key_find_by_hash.sql_generated.go +++ b/go/pkg/db/key_find_by_hash.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: key_find_by_hash.sql package db diff --git a/go/pkg/db/key_find_by_id.sql_generated.go b/go/pkg/db/key_find_by_id.sql_generated.go index c77ca9e74a..3d46136a63 100644 --- a/go/pkg/db/key_find_by_id.sql_generated.go +++ b/go/pkg/db/key_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: key_find_by_id.sql package db diff --git a/go/pkg/db/key_find_for_verification.sql_generated.go b/go/pkg/db/key_find_for_verification.sql_generated.go index fda822a1bc..cddce9a3fc 100644 --- a/go/pkg/db/key_find_for_verification.sql_generated.go +++ b/go/pkg/db/key_find_for_verification.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: key_find_for_verification.sql package db diff --git a/go/pkg/db/key_insert.sql_generated.go b/go/pkg/db/key_insert.sql_generated.go index fdfdf49fd9..61eb43626b 100644 --- a/go/pkg/db/key_insert.sql_generated.go +++ b/go/pkg/db/key_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: key_insert.sql package db diff --git a/go/pkg/db/keyring_find_by_id.sql_generated.go b/go/pkg/db/keyring_find_by_id.sql_generated.go index e916a8818d..dc6b354abe 100644 --- a/go/pkg/db/keyring_find_by_id.sql_generated.go +++ b/go/pkg/db/keyring_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: keyring_find_by_id.sql package db diff --git a/go/pkg/db/keyring_insert.sql_generated.go b/go/pkg/db/keyring_insert.sql_generated.go index 64c1581317..a5b08b5af7 100644 --- a/go/pkg/db/keyring_insert.sql_generated.go +++ b/go/pkg/db/keyring_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: keyring_insert.sql package db diff --git a/go/pkg/db/models_generated.go b/go/pkg/db/models_generated.go index 504cd6f355..c554f86a33 100644 --- a/go/pkg/db/models_generated.go +++ b/go/pkg/db/models_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 package db diff --git a/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go b/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go index d82cdf4d33..8cff7aed06 100644 --- a/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go +++ b/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: permission_find_by_workspace_and_name.sql package db diff --git a/go/pkg/db/permission_insert.sql_generated.go b/go/pkg/db/permission_insert.sql_generated.go index a05806435c..f58788ef32 100644 --- a/go/pkg/db/permission_insert.sql_generated.go +++ b/go/pkg/db/permission_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: permission_insert.sql package db diff --git a/go/pkg/db/permission_insert_key_permission.sql_generated.go b/go/pkg/db/permission_insert_key_permission.sql_generated.go index f6458858f8..ccb8a18b7b 100644 --- a/go/pkg/db/permission_insert_key_permission.sql_generated.go +++ b/go/pkg/db/permission_insert_key_permission.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: permission_insert_key_permission.sql package db diff --git a/go/pkg/db/permissions_by_key_id.sql_generated.go b/go/pkg/db/permissions_by_key_id.sql_generated.go index 12aeb3bf72..475e580986 100644 --- a/go/pkg/db/permissions_by_key_id.sql_generated.go +++ b/go/pkg/db/permissions_by_key_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: permissions_by_key_id.sql package db diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index e589915ad5..37e97e9243 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 package db @@ -10,6 +10,14 @@ import ( ) type Querier interface { + //DeleteIdentity + // + // DELETE FROM identities WHERE id = ? + DeleteIdentity(ctx context.Context, db DBTX, id string) error + //DeleteManyRatelimitsByIDs + // + // DELETE FROM ratelimits WHERE id IN (/*SLICE:ids*/?) + DeleteManyRatelimitsByIDs(ctx context.Context, db DBTX, ids []string) error //DeleteRatelimitNamespace // // UPDATE `ratelimit_namespaces` @@ -20,6 +28,10 @@ type Querier interface { // // SELECT id, name, workspace_id, ip_whitelist, auth_type, key_auth_id, created_at_m, updated_at_m, deleted_at_m, delete_protection FROM apis WHERE id = ? FindApiById(ctx context.Context, db DBTX, id string) (Api, error) + //FindAuditLogBucketIDByWorkspaceIDAndName + // + // SELECT id FROM audit_log_bucket WHERE workspace_id = ? AND name = ? + FindAuditLogBucketIDByWorkspaceIDAndName(ctx context.Context, db DBTX, arg FindAuditLogBucketIDByWorkspaceIDAndNameParams) (string, error) //FindAuditLogTargetById // // SELECT audit_log_target.workspace_id, audit_log_target.bucket_id, audit_log_target.bucket, audit_log_target.audit_log_id, audit_log_target.display_name, audit_log_target.type, audit_log_target.id, audit_log_target.name, audit_log_target.meta, audit_log_target.created_at, audit_log_target.updated_at, audit_log.id, audit_log.workspace_id, audit_log.bucket, audit_log.bucket_id, audit_log.event, audit_log.time, audit_log.display, audit_log.remote_ip, audit_log.user_agent, audit_log.actor_type, audit_log.actor_id, audit_log.actor_name, audit_log.actor_meta, audit_log.created_at, audit_log.updated_at @@ -27,10 +39,14 @@ type Querier interface { // JOIN audit_log ON audit_log.id = audit_log_target.audit_log_id // WHERE audit_log_target.id = ? FindAuditLogTargetById(ctx context.Context, db DBTX, id string) ([]FindAuditLogTargetByIdRow, error) + //FindIdentityByExternalID + // + // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? + FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) //FindIdentityByID // - // SELECT external_id, workspace_id, environment, meta, created_at, updated_at FROM identities WHERE id = ? - FindIdentityByID(ctx context.Context, db DBTX, id string) (FindIdentityByIDRow, error) + // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? + FindIdentityByID(ctx context.Context, db DBTX, id string) (Identity, error) //FindKeyByHash // // SELECT id, key_auth_id, hash, start, workspace_id, for_workspace_id, name, owner_id, identity_id, meta, expires, created_at_m, updated_at_m, deleted_at_m, refill_day, refill_amount, last_refill_at, enabled, remaining_requests, ratelimit_async, ratelimit_limit, ratelimit_duration, environment FROM `keys` WHERE hash = ? @@ -242,6 +258,22 @@ type Querier interface { // ? // ) InsertAuditLog(ctx context.Context, db DBTX, arg InsertAuditLogParams) error + //InsertAuditLogBucket + // + // INSERT INTO `audit_log_bucket` ( + // id, + // workspace_id, + // name, + // retention_days, + // created_at + // ) VALUES ( + // ?, + // ?, + // ?, + // ?, + // ? + // ) + InsertAuditLogBucket(ctx context.Context, db DBTX, arg InsertAuditLogBucketParams) error //InsertAuditLogTarget // // INSERT INTO `audit_log_target` ( diff --git a/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql b/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql new file mode 100644 index 0000000000..da691987eb --- /dev/null +++ b/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql @@ -0,0 +1,2 @@ +-- name: FindAuditLogBucketIDByWorkspaceIDAndName :one +SELECT id FROM audit_log_bucket WHERE workspace_id = sqlc.arg(workspace_id) AND name = sqlc.arg(name); diff --git a/go/pkg/db/queries/audit_log_bucket_insert.sql b/go/pkg/db/queries/audit_log_bucket_insert.sql new file mode 100644 index 0000000000..24066e3719 --- /dev/null +++ b/go/pkg/db/queries/audit_log_bucket_insert.sql @@ -0,0 +1,14 @@ +-- name: InsertAuditLogBucket :exec +INSERT INTO `audit_log_bucket` ( + id, + workspace_id, + name, + retention_days, + created_at +) VALUES ( + sqlc.arg(id), + sqlc.arg(workspace_id), + sqlc.arg(name), + sqlc.arg(retention_days), + sqlc.arg(created_at) +); diff --git a/go/pkg/db/queries/identity_delete.sql b/go/pkg/db/queries/identity_delete.sql new file mode 100644 index 0000000000..9d758f12cf --- /dev/null +++ b/go/pkg/db/queries/identity_delete.sql @@ -0,0 +1,2 @@ +-- name: DeleteIdentity :exec +DELETE FROM identities WHERE id = sqlc.arg('id') diff --git a/go/pkg/db/queries/identity_find_by_external_id.sql b/go/pkg/db/queries/identity_find_by_external_id.sql new file mode 100644 index 0000000000..5d54c23329 --- /dev/null +++ b/go/pkg/db/queries/identity_find_by_external_id.sql @@ -0,0 +1,2 @@ +-- name: FindIdentityByExternalID :one +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? diff --git a/go/pkg/db/queries/identity_find_by_id.sql b/go/pkg/db/queries/identity_find_by_id.sql index 622afe8ccf..18d4d9b507 100644 --- a/go/pkg/db/queries/identity_find_by_id.sql +++ b/go/pkg/db/queries/identity_find_by_id.sql @@ -1,2 +1,2 @@ -- name: FindIdentityByID :one -SELECT external_id, workspace_id, environment, meta, created_at, updated_at FROM identities WHERE id = sqlc.arg(id) +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = sqlc.arg(id) diff --git a/go/pkg/db/queries/ratelimit_delete_many.sql b/go/pkg/db/queries/ratelimit_delete_many.sql new file mode 100644 index 0000000000..77d721e89b --- /dev/null +++ b/go/pkg/db/queries/ratelimit_delete_many.sql @@ -0,0 +1,2 @@ +-- name: DeleteManyRatelimitsByIDs :exec +DELETE FROM ratelimits WHERE id IN (sqlc.slice(ids)); diff --git a/go/pkg/db/ratelimit_delete_many.sql_generated.go b/go/pkg/db/ratelimit_delete_many.sql_generated.go new file mode 100644 index 0000000000..2106cfbdf0 --- /dev/null +++ b/go/pkg/db/ratelimit_delete_many.sql_generated.go @@ -0,0 +1,33 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: ratelimit_delete_many.sql + +package db + +import ( + "context" + "strings" +) + +const deleteManyRatelimitsByIDs = `-- name: DeleteManyRatelimitsByIDs :exec +DELETE FROM ratelimits WHERE id IN (/*SLICE:ids*/?) +` + +// DeleteManyRatelimitsByIDs +// +// DELETE FROM ratelimits WHERE id IN (/*SLICE:ids*/?) +func (q *Queries) DeleteManyRatelimitsByIDs(ctx context.Context, db DBTX, ids []string) error { + query := deleteManyRatelimitsByIDs + var queryParams []interface{} + if len(ids) > 0 { + for _, v := range ids { + queryParams = append(queryParams, v) + } + query = strings.Replace(query, "/*SLICE:ids*/?", strings.Repeat(",?", len(ids))[1:], 1) + } else { + query = strings.Replace(query, "/*SLICE:ids*/?", "NULL", 1) + } + _, err := db.ExecContext(ctx, query, queryParams...) + return err +} diff --git a/go/pkg/db/ratelimit_namespace_delete.sql_generated.go b/go/pkg/db/ratelimit_namespace_delete.sql_generated.go index 46757d2d80..2d6bbfa3e6 100644 --- a/go/pkg/db/ratelimit_namespace_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_namespace_delete.sql package db diff --git a/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go b/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go index a02ca1ddcd..860275d0be 100644 --- a/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_namespace_find_by_id.sql package db diff --git a/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go b/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go index 5b041bb844..5c2fe0ec54 100644 --- a/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_namespace_find_by_name.sql package db diff --git a/go/pkg/db/ratelimit_namespace_insert.sql_generated.go b/go/pkg/db/ratelimit_namespace_insert.sql_generated.go index 150c1b8aaf..d727ae8207 100644 --- a/go/pkg/db/ratelimit_namespace_insert.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_namespace_insert.sql package db diff --git a/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go b/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go index 8dd369651a..3df1948649 100644 --- a/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_namespace_soft_delete.sql package db diff --git a/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go b/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go index e40f34a185..313e002454 100644 --- a/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_find_by_id.sql package db diff --git a/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go b/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go index 550314de0b..8608a79be9 100644 --- a/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_find_by_identifier.sql package db diff --git a/go/pkg/db/ratelimit_override_find_matches.sql_generated.go b/go/pkg/db/ratelimit_override_find_matches.sql_generated.go index 64b96181bd..1e5bbf54be 100644 --- a/go/pkg/db/ratelimit_override_find_matches.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_matches.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_find_matches.sql package db diff --git a/go/pkg/db/ratelimit_override_insert.sql_generated.go b/go/pkg/db/ratelimit_override_insert.sql_generated.go index 2184eb07a3..edb34e73d8 100644 --- a/go/pkg/db/ratelimit_override_insert.sql_generated.go +++ b/go/pkg/db/ratelimit_override_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_insert.sql package db diff --git a/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go b/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go index 626d919d39..730d2d4651 100644 --- a/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go +++ b/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_list_by_namespace_id.sql package db diff --git a/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go b/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go index fb7910f14a..9fd37ee07a 100644 --- a/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_soft_delete.sql package db diff --git a/go/pkg/db/ratelimit_override_update.sql_generated.go b/go/pkg/db/ratelimit_override_update.sql_generated.go index e1a6226614..f80b0777b1 100644 --- a/go/pkg/db/ratelimit_override_update.sql_generated.go +++ b/go/pkg/db/ratelimit_override_update.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: ratelimit_override_update.sql package db diff --git a/go/pkg/db/workspace_find_by_id.sql_generated.go b/go/pkg/db/workspace_find_by_id.sql_generated.go index e24cc463ed..0e8909aff8 100644 --- a/go/pkg/db/workspace_find_by_id.sql_generated.go +++ b/go/pkg/db/workspace_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_find_by_id.sql package db diff --git a/go/pkg/db/workspace_hard_delete.sql_generated.go b/go/pkg/db/workspace_hard_delete.sql_generated.go index 0e3f8f60aa..592ec870fe 100644 --- a/go/pkg/db/workspace_hard_delete.sql_generated.go +++ b/go/pkg/db/workspace_hard_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_hard_delete.sql package db diff --git a/go/pkg/db/workspace_insert.sql_generated.go b/go/pkg/db/workspace_insert.sql_generated.go index 8967b87fc5..0377f24988 100644 --- a/go/pkg/db/workspace_insert.sql_generated.go +++ b/go/pkg/db/workspace_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_insert.sql package db diff --git a/go/pkg/db/workspace_soft_delete.sql_generated.go b/go/pkg/db/workspace_soft_delete.sql_generated.go index 5a729df821..accafa0f19 100644 --- a/go/pkg/db/workspace_soft_delete.sql_generated.go +++ b/go/pkg/db/workspace_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_soft_delete.sql package db diff --git a/go/pkg/db/workspace_update_enabled.sql_generated.go b/go/pkg/db/workspace_update_enabled.sql_generated.go index 218d181adc..ca711eabbd 100644 --- a/go/pkg/db/workspace_update_enabled.sql_generated.go +++ b/go/pkg/db/workspace_update_enabled.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_update_enabled.sql package db diff --git a/go/pkg/db/workspace_update_plan.sql_generated.go b/go/pkg/db/workspace_update_plan.sql_generated.go index 5ee2bf4fca..cca72082ee 100644 --- a/go/pkg/db/workspace_update_plan.sql_generated.go +++ b/go/pkg/db/workspace_update_plan.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspace_update_plan.sql package db diff --git a/go/pkg/db/workspaces_list.sql_generated.go b/go/pkg/db/workspaces_list.sql_generated.go index b281597760..7ef2bd6e16 100644 --- a/go/pkg/db/workspaces_list.sql_generated.go +++ b/go/pkg/db/workspaces_list.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.27.0 +// sqlc v1.28.0 // source: workspaces_list.sql package db From 88f10f33d545a6b4fc3893d1f5781d547892876c Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 08:50:38 +0200 Subject: [PATCH 02/17] fix: remove unneded files --- go/pkg/codes/constants_gen.go | 2 +- go/pkg/db/querier_generated.go | 20 ------------------- ...g_bucket_id_find_by_workspace_and_name.sql | 2 -- go/pkg/db/queries/audit_log_bucket_insert.sql | 14 ------------- 4 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql delete mode 100644 go/pkg/db/queries/audit_log_bucket_insert.sql diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index 2b3e1d97fd..7b85b4b897 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-18T08:45:13+02:00 +// Generated at: 2025-04-18T08:50:08+02:00 package codes diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index 37e97e9243..7ef1cf0d76 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -28,10 +28,6 @@ type Querier interface { // // SELECT id, name, workspace_id, ip_whitelist, auth_type, key_auth_id, created_at_m, updated_at_m, deleted_at_m, delete_protection FROM apis WHERE id = ? FindApiById(ctx context.Context, db DBTX, id string) (Api, error) - //FindAuditLogBucketIDByWorkspaceIDAndName - // - // SELECT id FROM audit_log_bucket WHERE workspace_id = ? AND name = ? - FindAuditLogBucketIDByWorkspaceIDAndName(ctx context.Context, db DBTX, arg FindAuditLogBucketIDByWorkspaceIDAndNameParams) (string, error) //FindAuditLogTargetById // // SELECT audit_log_target.workspace_id, audit_log_target.bucket_id, audit_log_target.bucket, audit_log_target.audit_log_id, audit_log_target.display_name, audit_log_target.type, audit_log_target.id, audit_log_target.name, audit_log_target.meta, audit_log_target.created_at, audit_log_target.updated_at, audit_log.id, audit_log.workspace_id, audit_log.bucket, audit_log.bucket_id, audit_log.event, audit_log.time, audit_log.display, audit_log.remote_ip, audit_log.user_agent, audit_log.actor_type, audit_log.actor_id, audit_log.actor_name, audit_log.actor_meta, audit_log.created_at, audit_log.updated_at @@ -258,22 +254,6 @@ type Querier interface { // ? // ) InsertAuditLog(ctx context.Context, db DBTX, arg InsertAuditLogParams) error - //InsertAuditLogBucket - // - // INSERT INTO `audit_log_bucket` ( - // id, - // workspace_id, - // name, - // retention_days, - // created_at - // ) VALUES ( - // ?, - // ?, - // ?, - // ?, - // ? - // ) - InsertAuditLogBucket(ctx context.Context, db DBTX, arg InsertAuditLogBucketParams) error //InsertAuditLogTarget // // INSERT INTO `audit_log_target` ( diff --git a/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql b/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql deleted file mode 100644 index da691987eb..0000000000 --- a/go/pkg/db/queries/audit_log_bucket_id_find_by_workspace_and_name.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: FindAuditLogBucketIDByWorkspaceIDAndName :one -SELECT id FROM audit_log_bucket WHERE workspace_id = sqlc.arg(workspace_id) AND name = sqlc.arg(name); diff --git a/go/pkg/db/queries/audit_log_bucket_insert.sql b/go/pkg/db/queries/audit_log_bucket_insert.sql deleted file mode 100644 index 24066e3719..0000000000 --- a/go/pkg/db/queries/audit_log_bucket_insert.sql +++ /dev/null @@ -1,14 +0,0 @@ --- name: InsertAuditLogBucket :exec -INSERT INTO `audit_log_bucket` ( - id, - workspace_id, - name, - retention_days, - created_at -) VALUES ( - sqlc.arg(id), - sqlc.arg(workspace_id), - sqlc.arg(name), - sqlc.arg(retention_days), - sqlc.arg(created_at) -); From 6137f5f8a0a39ce3a4041964faaee36f89bed3dc Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 09:12:14 +0200 Subject: [PATCH 03/17] feat: add inital nonworking tests --- .../api/routes/v2_apis_create_api/401_test.go | 1 - .../v2_identities_delete_identity/200_test.go | 181 ++++++++++++++++++ .../v2_identities_delete_identity/400_test.go | 151 +++++++++++++++ .../v2_identities_delete_identity/401_test.go | 38 ++++ .../v2_identities_delete_identity/403_test.go | 48 +++++ .../v2_identities_delete_identity/handler.go | 10 + .../v2_ratelimit_get_override/handler.go | 15 +- go/internal/services/auditlogs/insert.go | 2 +- 8 files changed, 438 insertions(+), 8 deletions(-) create mode 100644 go/apps/api/routes/v2_identities_delete_identity/200_test.go create mode 100644 go/apps/api/routes/v2_identities_delete_identity/400_test.go create mode 100644 go/apps/api/routes/v2_identities_delete_identity/401_test.go create mode 100644 go/apps/api/routes/v2_identities_delete_identity/403_test.go diff --git a/go/apps/api/routes/v2_apis_create_api/401_test.go b/go/apps/api/routes/v2_apis_create_api/401_test.go index 9634cfb8a8..7c3c666216 100644 --- a/go/apps/api/routes/v2_apis_create_api/401_test.go +++ b/go/apps/api/routes/v2_apis_create_api/401_test.go @@ -36,5 +36,4 @@ func TestCreateApi_Unauthorized(t *testing.T) { res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) require.Equal(t, http.StatusUnauthorized, res.Status, "expected 401, sent: %+v, received: %s", req, res.RawBody) }) - } diff --git a/go/apps/api/routes/v2_identities_delete_identity/200_test.go b/go/apps/api/routes/v2_identities_delete_identity/200_test.go new file mode 100644 index 0000000000..a219c8cd3f --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/200_test.go @@ -0,0 +1,181 @@ +package handler_test + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "net/http" + "slices" + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/unkeyed/unkey/go/apps/api/openapi" + handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/db" + "github.com/unkeyed/unkey/go/pkg/testutil" + "github.com/unkeyed/unkey/go/pkg/uid" +) + +func TestCreateIdentitySuccessfully(t *testing.T) { + ctx := context.Background() + h := testutil.NewHarness(t) + + route := handler.New(handler.Services{ + DB: h.DB, + Keys: h.Keys, + Logger: h.Logger, + Permissions: h.Permissions, + Auditlogs: h.Auditlogs, + }) + + h.Register(route) + + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.create_identity") + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + // Create a identity via DB + t.Run("insert identity via DB", func(t *testing.T) { + identityID := uid.New(uid.IdentityPrefix) + externalTestID := uid.New("test_external_id") + err := db.Query.InsertIdentity(ctx, h.DB.RW(), db.InsertIdentityParams{ + ID: identityID, + ExternalID: externalTestID, + WorkspaceID: h.Resources().UserWorkspace.ID, + Meta: nil, + CreatedAt: time.Now().UnixMilli(), + Environment: "default", + }) + require.NoError(t, err) + + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + require.NoError(t, err) + require.Equal(t, identity.ExternalID, externalTestID) + }) + + // Create a identity with ratelimits via DB + t.Run("insert identity via DB and add ratelimits", func(t *testing.T) { + identityID := uid.New(uid.IdentityPrefix) + externalTestID := uid.New("test_external_id") + err := db.Query.InsertIdentity(ctx, h.DB.RW(), db.InsertIdentityParams{ + ID: identityID, + ExternalID: externalTestID, + WorkspaceID: h.Resources().UserWorkspace.ID, + Meta: nil, + CreatedAt: time.Now().UnixMilli(), + Environment: "default", + }) + require.NoError(t, err) + + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + require.NoError(t, err) + require.Equal(t, identity.ExternalID, externalTestID) + + err = db.Query.InsertIdentityRatelimit(ctx, h.DB.RW(), db.InsertIdentityRatelimitParams{ + ID: uid.New(uid.RatelimitPrefix), + WorkspaceID: h.Resources().UserWorkspace.ID, + IdentityID: sql.NullString{String: identityID, Valid: true}, + Name: "Requests", + Limit: 15, + Duration: (time.Minute * 15).Milliseconds(), + CreatedAt: time.Now().UnixMilli(), + }) + require.NoError(t, err) + + rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: identityID, Valid: true}) + require.NoError(t, err) + require.Len(t, rateLimits, 1) + require.Equal(t, rateLimits[0].Name, "Requests") + require.Equal(t, rateLimits[0].Limit, int32(15)) + require.Equal(t, rateLimits[0].Duration, (time.Minute * 15).Milliseconds()) + }) + + // Test creating a identity with no other information + t.Run("create identity", func(t *testing.T) { + externalTestID := uid.New("test_external_id") + req := handler.Request{ExternalId: externalTestID} + res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) + + require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) + require.NotNil(t, res.Body) + require.NotEmpty(t, res.Body.Data.IdentityId) + + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + require.NoError(t, err) + require.Equal(t, identity.ExternalID, req.ExternalId) + }) + + // Test creating a identity with metadata + t.Run("create identity with metadata", func(t *testing.T) { + externalTestID := uid.New("test_external_id") + + meta := &map[string]interface{}{"key": "example"} + req := handler.Request{ + ExternalId: externalTestID, + Meta: meta, + } + + res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) + require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) + require.NotNil(t, res.Body) + require.NotEmpty(t, res.Body.Data.IdentityId) + + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + require.NoError(t, err) + require.Equal(t, identity.ExternalID, req.ExternalId) + + var dbMeta map[string]interface{} + err = json.Unmarshal(identity.Meta, &dbMeta) + require.NoError(t, err) + require.Equal(t, *meta, dbMeta) + }) + + // Test creating a identity with ratelimits + t.Run("create identity with ratelimits", func(t *testing.T) { + externalTestID := uid.New("test_external_id") + + identityRateLimits := []openapi.V2Ratelimit{ + { + Duration: time.Minute.Milliseconds(), + Limit: 100, + Name: "test", + }, + { + Duration: time.Minute.Milliseconds(), + Limit: 200, + Name: "test2", + }, + } + + req := handler.Request{ + ExternalId: externalTestID, + Ratelimits: &identityRateLimits, + } + + res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) + require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) + require.NotNil(t, res.Body) + require.NotEmpty(t, res.Body.Data.IdentityId) + + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + require.NoError(t, err) + require.Equal(t, identity.ExternalID, req.ExternalId) + + rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: res.Body.Data.IdentityId, Valid: true}) + require.NoError(t, err) + require.Len(t, rateLimits, len(identityRateLimits)) + + for _, ratelimit := range identityRateLimits { + idx := slices.IndexFunc(rateLimits, func(c db.FindRatelimitsByIdentityIDRow) bool { return c.Name == ratelimit.Name }) + + require.True(t, idx >= 0 && idx < len(rateLimits), "Rate limit with name %s not found in the database", ratelimit.Name) + require.Equal(t, rateLimits[idx].Duration, ratelimit.Duration) + require.Equal(t, int64(rateLimits[idx].Limit), ratelimit.Limit) + require.Equal(t, rateLimits[idx].Name, ratelimit.Name) + } + }) +} diff --git a/go/apps/api/routes/v2_identities_delete_identity/400_test.go b/go/apps/api/routes/v2_identities_delete_identity/400_test.go new file mode 100644 index 0000000000..e39cdb6931 --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/400_test.go @@ -0,0 +1,151 @@ +//nolint:exhaustruct +package handler_test + +import ( + "encoding/json" + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + "github.com/unkeyed/unkey/go/apps/api/openapi" + handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/testutil" + "github.com/unkeyed/unkey/go/pkg/uid" +) + +func TestBadRequests(t *testing.T) { + h := testutil.NewHarness(t) + + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.create_identity") + route := handler.New(handler.Services{ + DB: h.DB, + Keys: h.Keys, + Logger: h.Logger, + Permissions: h.Permissions, + Auditlogs: h.Auditlogs, + }) + + h.Register(route) + + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + t.Run("missing external id", func(t *testing.T) { + req := openapi.V2IdentitiesCreateIdentityRequestBody{} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) + require.NotNil(t, res.Body) + + require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) + require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) + require.Equal(t, "Bad Request", res.Body.Error.Title) + require.NotEmpty(t, res.Body.Meta.RequestId) + require.Greater(t, len(res.Body.Error.Errors), 0) + require.Nil(t, res.Body.Error.Instance) + }) + + t.Run("empty external id", func(t *testing.T) { + req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: ""} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) + require.NotNil(t, res.Body) + + require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) + require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) + require.Equal(t, "Bad Request", res.Body.Error.Title) + require.NotEmpty(t, res.Body.Meta.RequestId) + require.Greater(t, len(res.Body.Error.Errors), 0) + require.Nil(t, res.Body.Error.Instance) + }) + + t.Run("external id too short", func(t *testing.T) { + req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: "12"} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) + require.NotNil(t, res.Body) + + require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) + require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) + require.Equal(t, "Bad Request", res.Body.Error.Title) + require.NotEmpty(t, res.Body.Meta.RequestId) + require.Greater(t, len(res.Body.Error.Errors), 0) + require.Nil(t, res.Body.Error.Instance) + }) + + t.Run("metadata exceeds maximum size limit", func(t *testing.T) { + metaData := make(map[string]interface{}) + entriesNeeded := (handler.MAX_META_LENGTH_MB * 1024 * 1024) / 15 + for i := 0; i < entriesNeeded+1000; i++ { + var data interface{} = fmt.Sprintf("some_%d", i) + metaData[fmt.Sprintf("key_%d", i)] = &data + } + + rawMeta, _ := json.Marshal(metaData) + + req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: uid.New("test"), Meta: &metaData} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) + require.NotNil(t, res.Body) + + require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) + require.Equal(t, fmt.Sprintf("Metadata is too large, it must be less than %dMB, got: %.2f", handler.MAX_META_LENGTH_MB, float64(len(rawMeta))/1024/1024), res.Body.Error.Detail) + require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) + require.Equal(t, "Bad Request", res.Body.Error.Title) + require.NotEmpty(t, res.Body.Meta.RequestId) + require.Nil(t, res.Body.Error.Instance) + }) + + t.Run("invalid ratelimit", func(t *testing.T) { + + req := openapi.V2IdentitiesCreateIdentityRequestBody{ + ExternalId: uid.New("test"), + Ratelimits: &[]openapi.V2Ratelimit{ + { + Duration: 1, + Limit: 1, + }, + }, + } + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) + require.NotNil(t, res.Body) + + require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) + require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) + require.Equal(t, "Bad Request", res.Body.Error.Title) + require.NotEmpty(t, res.Body.Meta.RequestId) + require.Greater(t, len(res.Body.Error.Errors), 0) + require.Nil(t, res.Body.Error.Instance) + }) + + t.Run("missing authorization header", func(t *testing.T) { + headers := http.Header{ + "Content-Type": {"application/json"}, + // No Authorization header + } + + req := handler.Request{ExternalId: uid.New("test")} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusBadRequest, res.Status) + require.NotNil(t, res.Body) + }) + + t.Run("malformed authorization header", func(t *testing.T) { + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {"malformed_header"}, + } + + req := handler.Request{ExternalId: uid.New("test")} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusBadRequest, res.Status) + require.NotNil(t, res.Body) + }) +} diff --git a/go/apps/api/routes/v2_identities_delete_identity/401_test.go b/go/apps/api/routes/v2_identities_delete_identity/401_test.go new file mode 100644 index 0000000000..56228a8d7e --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/401_test.go @@ -0,0 +1,38 @@ +package handler_test + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/require" + handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/ptr" + "github.com/unkeyed/unkey/go/pkg/testutil" + "github.com/unkeyed/unkey/go/pkg/uid" +) + +func TestCreateApi_Unauthorized(t *testing.T) { + h := testutil.NewHarness(t) + + route := handler.New(handler.Services{ + DB: h.DB, + Keys: h.Keys, + Logger: h.Logger, + Permissions: h.Permissions, + Auditlogs: h.Auditlogs, + }) + + h.Register(route) + + // Invalid authorization token + t.Run("invalid auth token", func(t *testing.T) { + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {"Bearer invalid_token"}, + } + + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} + res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) + require.Equal(t, http.StatusUnauthorized, res.Status, "expected 401, sent: %+v, received: %s", req, res.RawBody) + }) +} diff --git a/go/apps/api/routes/v2_identities_delete_identity/403_test.go b/go/apps/api/routes/v2_identities_delete_identity/403_test.go new file mode 100644 index 0000000000..f65e19d599 --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/403_test.go @@ -0,0 +1,48 @@ +package handler_test + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + "github.com/unkeyed/unkey/go/apps/api/openapi" + handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/ptr" + "github.com/unkeyed/unkey/go/pkg/testutil" + "github.com/unkeyed/unkey/go/pkg/uid" +) + +func TestWorkspacePermissions(t *testing.T) { + h := testutil.NewHarness(t) + + route := handler.New(handler.Services{ + DB: h.DB, + Keys: h.Keys, + Logger: h.Logger, + Permissions: h.Permissions, + Auditlogs: h.Auditlogs, + }) + + h.Register(route) + + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID) + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + t.Run("insufficient permissions", func(t *testing.T) { + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) + require.NotNil(t, res.Body) + }) + + t.Run("delete identity from other workspace", func(t *testing.T) { + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) + require.NotNil(t, res.Body) + }) +} diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go index 1996fae2fe..d7825f1924 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/handler.go +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -143,15 +143,19 @@ func New(svc Services) zen.Route { WorkspaceID: auth.AuthorizedWorkspaceID, Event: auditlog.IdentityDeleteEvent, Display: fmt.Sprintf("Deleted identity %s.", identity.ID), + Bucket: auditlogs.DEFAULT_BUCKET, ActorID: auth.KeyID, ActorType: auditlog.RootKeyActor, + ActorName: "root key", RemoteIP: s.Location(), UserAgent: s.UserAgent(), Resources: []auditlog.AuditLogResource{ { ID: identity.ID, + Meta: nil, Type: auditlog.IdentityResourceType, DisplayName: identity.ExternalID, + Name: identity.ExternalID, }, }, }, @@ -162,20 +166,26 @@ func New(svc Services) zen.Route { WorkspaceID: auth.AuthorizedWorkspaceID, Event: auditlog.RatelimitDeleteEvent, Display: fmt.Sprintf("Deleted ratelimit %s.", rl.ID), + Bucket: auditlogs.DEFAULT_BUCKET, ActorID: auth.KeyID, ActorType: auditlog.RootKeyActor, + ActorName: "root key", RemoteIP: s.Location(), UserAgent: s.UserAgent(), Resources: []auditlog.AuditLogResource{ { Type: auditlog.IdentityResourceType, + Meta: nil, ID: identity.ID, DisplayName: identity.ExternalID, + Name: identity.ExternalID, }, { Type: auditlog.RatelimitResourceType, + Meta: nil, ID: rl.ID, DisplayName: rl.Name, + Name: rl.Name, }, }, }) diff --git a/go/apps/api/routes/v2_ratelimit_get_override/handler.go b/go/apps/api/routes/v2_ratelimit_get_override/handler.go index 0a51e80519..6ea9fb4095 100644 --- a/go/apps/api/routes/v2_ratelimit_get_override/handler.go +++ b/go/apps/api/routes/v2_ratelimit_get_override/handler.go @@ -27,7 +27,6 @@ type Services struct { func New(svc Services) zen.Route { return zen.NewRoute("POST", "/v2/ratelimit.getOverride", func(ctx context.Context, s *zen.Session) error { - auth, err := svc.Keys.VerifyRootKey(ctx, s) if err != nil { return err @@ -51,7 +50,10 @@ func New(svc Services) zen.Route { ) } if err != nil { - return err + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to find the ratelimit namespace", "Error finding the ratelimit namespace."), + ) } if namespace.WorkspaceID != auth.AuthorizedWorkspaceID { @@ -103,8 +105,12 @@ func New(svc Services) zen.Route { ) } if err != nil { - return err + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to find the override", "Error finding the ratelimit override."), + ) } + return s.JSON(http.StatusOK, Response{ Meta: openapi.Meta{ RequestId: s.RequestID(), @@ -122,12 +128,10 @@ func New(svc Services) zen.Route { } func getNamespace(ctx context.Context, svc Services, workspaceID string, req Request) (db.RatelimitNamespace, error) { - switch { case req.NamespaceId != nil: { return db.Query.FindRatelimitNamespaceByID(ctx, svc.DB.RO(), *req.NamespaceId) - } case req.NamespaceName != nil: { @@ -142,5 +146,4 @@ func getNamespace(ctx context.Context, svc Services, workspaceID string, req Req fault.WithCode(codes.App.Validation.InvalidInput.URN()), fault.WithDesc("missing namespace id or name", "You must provide either a namespace ID or name."), ) - } diff --git a/go/internal/services/auditlogs/insert.go b/go/internal/services/auditlogs/insert.go index cc8c55b7b8..cc49e413c4 100644 --- a/go/internal/services/auditlogs/insert.go +++ b/go/internal/services/auditlogs/insert.go @@ -57,6 +57,7 @@ func (s *service) Insert(ctx context.Context, tx *sql.Tx, logs []auditlog.AuditL if err != nil { return err } + auditLogs = append(auditLogs, db.InsertAuditLogParams{ ID: auditLogID, WorkspaceID: l.WorkspaceID, @@ -75,7 +76,6 @@ func (s *service) Insert(ctx context.Context, tx *sql.Tx, logs []auditlog.AuditL }) for _, resource := range l.Resources { - meta, err := json.Marshal(resource.Meta) if err != nil { return err From 2f4eaf5ec8634b72f3ab77a7b9a81ad09fcf92eb Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 12:45:35 +0200 Subject: [PATCH 04/17] feat: tests --- .../v2_identities_delete_identity/200_test.go | 205 ++++++++---------- .../v2_identities_delete_identity/400_test.go | 67 +----- .../v2_identities_delete_identity/401_test.go | 2 +- .../v2_identities_delete_identity/403_test.go | 36 ++- .../v2_identities_delete_identity/404_test.go | 68 ++++++ 5 files changed, 203 insertions(+), 175 deletions(-) create mode 100644 go/apps/api/routes/v2_identities_delete_identity/404_test.go diff --git a/go/apps/api/routes/v2_identities_delete_identity/200_test.go b/go/apps/api/routes/v2_identities_delete_identity/200_test.go index a219c8cd3f..02fb6b4358 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/200_test.go @@ -3,22 +3,68 @@ package handler_test import ( "context" "database/sql" - "encoding/json" "fmt" + "log" "net/http" - "slices" "testing" "time" "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/go/apps/api/openapi" handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" "github.com/unkeyed/unkey/go/pkg/db" + "github.com/unkeyed/unkey/go/pkg/ptr" "github.com/unkeyed/unkey/go/pkg/testutil" "github.com/unkeyed/unkey/go/pkg/uid" ) -func TestCreateIdentitySuccessfully(t *testing.T) { +type Identity struct { + ID string + ExternalID string + RatelimitIds []string +} + +// Helper function that creates a new identity with rate-limits and returns it +func newIdentity(t *testing.T, h *testutil.Harness, numberOfRatelimits int) Identity { + identityID := uid.New(uid.IdentityPrefix) + externalID := uid.New("test_external_id") + + err := db.Query.InsertIdentity(t.Context(), h.DB.RW(), db.InsertIdentityParams{ + ID: identityID, + ExternalID: externalID, + WorkspaceID: h.Resources().UserWorkspace.ID, + Meta: nil, + CreatedAt: time.Now().UnixMilli(), + Environment: "default", + }) + require.NoError(t, err) + + ratelimitIds := make([]string, 0) + for range numberOfRatelimits { + rateLimitID := uid.New(uid.RatelimitPrefix) + err = db.Query.InsertIdentityRatelimit(t.Context(), h.DB.RW(), db.InsertIdentityRatelimitParams{ + ID: rateLimitID, + WorkspaceID: h.Resources().UserWorkspace.ID, + IdentityID: sql.NullString{String: identityID, Valid: true}, + Name: "Requests", + Limit: 15, + Duration: (time.Minute * 15).Milliseconds(), + CreatedAt: time.Now().UnixMilli(), + }) + + require.NoError(t, err) + ratelimitIds = append(ratelimitIds, rateLimitID) + } + + log.Printf("Created identity with %d rate limits", len(ratelimitIds)) + + return Identity{ + ID: identityID, + ExternalID: externalID, + RatelimitIds: ratelimitIds, + } +} + +func TestDeleteIdentitySuccessfully(t *testing.T) { ctx := context.Background() h := testutil.NewHarness(t) @@ -32,150 +78,91 @@ func TestCreateIdentitySuccessfully(t *testing.T) { h.Register(route) - rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.create_identity") + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.delete_identity") headers := http.Header{ "Content-Type": {"application/json"}, "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, } - // Create a identity via DB - t.Run("insert identity via DB", func(t *testing.T) { - identityID := uid.New(uid.IdentityPrefix) - externalTestID := uid.New("test_external_id") - err := db.Query.InsertIdentity(ctx, h.DB.RW(), db.InsertIdentityParams{ - ID: identityID, - ExternalID: externalTestID, - WorkspaceID: h.Resources().UserWorkspace.ID, - Meta: nil, - CreatedAt: time.Now().UnixMilli(), - Environment: "default", - }) + // Create a identity via DB and delete it again + t.Run("delete identity via db and identity id", func(t *testing.T) { + newIdentity := newIdentity(t, h, 0) + + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) require.NoError(t, err) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + err = db.Query.DeleteIdentity(ctx, h.DB.RW(), newIdentity.ID) require.NoError(t, err) - require.Equal(t, identity.ExternalID, externalTestID) + + _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + require.Equal(t, sql.ErrNoRows, err) }) - // Create a identity with ratelimits via DB - t.Run("insert identity via DB and add ratelimits", func(t *testing.T) { - identityID := uid.New(uid.IdentityPrefix) - externalTestID := uid.New("test_external_id") - err := db.Query.InsertIdentity(ctx, h.DB.RW(), db.InsertIdentityParams{ - ID: identityID, - ExternalID: externalTestID, - WorkspaceID: h.Resources().UserWorkspace.ID, - Meta: nil, - CreatedAt: time.Now().UnixMilli(), - Environment: "default", - }) + // Create a identity via DB and delete it again + t.Run("delete identity ratelimits via db", func(t *testing.T) { + numberOfRatelimits := 2 + newIdentity := newIdentity(t, h, numberOfRatelimits) + + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) require.NoError(t, err) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) require.NoError(t, err) - require.Equal(t, identity.ExternalID, externalTestID) + require.Len(t, rateLimits, numberOfRatelimits) - err = db.Query.InsertIdentityRatelimit(ctx, h.DB.RW(), db.InsertIdentityRatelimitParams{ - ID: uid.New(uid.RatelimitPrefix), - WorkspaceID: h.Resources().UserWorkspace.ID, - IdentityID: sql.NullString{String: identityID, Valid: true}, - Name: "Requests", - Limit: 15, - Duration: (time.Minute * 15).Milliseconds(), - CreatedAt: time.Now().UnixMilli(), - }) + err = db.Query.DeleteIdentity(ctx, h.DB.RW(), newIdentity.ID) + require.NoError(t, err) + + err = db.Query.DeleteManyRatelimitsByIDs(ctx, h.DB.RW(), newIdentity.RatelimitIds) require.NoError(t, err) - rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: identityID, Valid: true}) + _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + require.Equal(t, sql.ErrNoRows, err) + + ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) require.NoError(t, err) - require.Len(t, rateLimits, 1) - require.Equal(t, rateLimits[0].Name, "Requests") - require.Equal(t, rateLimits[0].Limit, int32(15)) - require.Equal(t, rateLimits[0].Duration, (time.Minute * 15).Milliseconds()) + require.Len(t, ratelimits, 0) }) - // Test creating a identity with no other information - t.Run("create identity", func(t *testing.T) { - externalTestID := uid.New("test_external_id") - req := handler.Request{ExternalId: externalTestID} + t.Run("delete identity via identityID", func(t *testing.T) { + newIdentity := newIdentity(t, h, 0) + + req := handler.Request{IdentityId: ptr.P(newIdentity.ID)} res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) - require.NoError(t, err) - require.Equal(t, identity.ExternalID, req.ExternalId) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + require.Equal(t, sql.ErrNoRows, err) }) - // Test creating a identity with metadata - t.Run("create identity with metadata", func(t *testing.T) { - externalTestID := uid.New("test_external_id") - - meta := &map[string]interface{}{"key": "example"} - req := handler.Request{ - ExternalId: externalTestID, - Meta: meta, - } + t.Run("delete identity via identityID", func(t *testing.T) { + newIdentity := newIdentity(t, h, 0) + req := handler.Request{ExternalId: ptr.P(newIdentity.ExternalID)} res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) + require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) - require.NoError(t, err) - require.Equal(t, identity.ExternalID, req.ExternalId) - - var dbMeta map[string]interface{} - err = json.Unmarshal(identity.Meta, &dbMeta) - require.NoError(t, err) - require.Equal(t, *meta, dbMeta) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + require.Equal(t, sql.ErrNoRows, err) }) - // Test creating a identity with ratelimits - t.Run("create identity with ratelimits", func(t *testing.T) { - externalTestID := uid.New("test_external_id") - - identityRateLimits := []openapi.V2Ratelimit{ - { - Duration: time.Minute.Milliseconds(), - Limit: 100, - Name: "test", - }, - { - Duration: time.Minute.Milliseconds(), - Limit: 200, - Name: "test2", - }, - } - - req := handler.Request{ - ExternalId: externalTestID, - Ratelimits: &identityRateLimits, - } + t.Run("delete identity with ratelimits", func(t *testing.T) { + newIdentity := newIdentity(t, h, 2) + req := handler.Request{IdentityId: ptr.P(newIdentity.ID)} res := testutil.CallRoute[handler.Request, handler.Response](h, route, headers, req) require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) - require.NoError(t, err) - require.Equal(t, identity.ExternalID, req.ExternalId) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + require.Equal(t, sql.ErrNoRows, err) - rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: res.Body.Data.IdentityId, Valid: true}) + ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) require.NoError(t, err) - require.Len(t, rateLimits, len(identityRateLimits)) - - for _, ratelimit := range identityRateLimits { - idx := slices.IndexFunc(rateLimits, func(c db.FindRatelimitsByIdentityIDRow) bool { return c.Name == ratelimit.Name }) - - require.True(t, idx >= 0 && idx < len(rateLimits), "Rate limit with name %s not found in the database", ratelimit.Name) - require.Equal(t, rateLimits[idx].Duration, ratelimit.Duration) - require.Equal(t, int64(rateLimits[idx].Limit), ratelimit.Limit) - require.Equal(t, rateLimits[idx].Name, ratelimit.Name) - } + require.Len(t, ratelimits, 0) }) } diff --git a/go/apps/api/routes/v2_identities_delete_identity/400_test.go b/go/apps/api/routes/v2_identities_delete_identity/400_test.go index e39cdb6931..dcf8aaa965 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/400_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/400_test.go @@ -2,7 +2,6 @@ package handler_test import ( - "encoding/json" "fmt" "net/http" "testing" @@ -10,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/unkeyed/unkey/go/apps/api/openapi" handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/ptr" "github.com/unkeyed/unkey/go/pkg/testutil" "github.com/unkeyed/unkey/go/pkg/uid" ) @@ -33,14 +33,14 @@ func TestBadRequests(t *testing.T) { "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, } - t.Run("missing external id", func(t *testing.T) { - req := openapi.V2IdentitiesCreateIdentityRequestBody{} + t.Run("missing external id AND missing identity id", func(t *testing.T) { + req := handler.Request{} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) require.NotNil(t, res.Body) require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) - require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, "POST request body for '/v2/identities.deleteIdentity' failed to validate schema", res.Body.Error.Detail) require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) require.Equal(t, "Bad Request", res.Body.Error.Title) require.NotEmpty(t, res.Body.Meta.RequestId) @@ -49,13 +49,13 @@ func TestBadRequests(t *testing.T) { }) t.Run("empty external id", func(t *testing.T) { - req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: ""} + req := handler.Request{ExternalId: ptr.P("")} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) require.NotNil(t, res.Body) require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) - require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, "POST request body for '/v2/identities.deleteIdentity' failed to validate schema", res.Body.Error.Detail) require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) require.Equal(t, "Bad Request", res.Body.Error.Title) require.NotEmpty(t, res.Body.Meta.RequestId) @@ -64,60 +64,13 @@ func TestBadRequests(t *testing.T) { }) t.Run("external id too short", func(t *testing.T) { - req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: "12"} + req := handler.Request{ExternalId: ptr.P("")} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) require.NotNil(t, res.Body) require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) - require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) - require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) - require.Equal(t, "Bad Request", res.Body.Error.Title) - require.NotEmpty(t, res.Body.Meta.RequestId) - require.Greater(t, len(res.Body.Error.Errors), 0) - require.Nil(t, res.Body.Error.Instance) - }) - - t.Run("metadata exceeds maximum size limit", func(t *testing.T) { - metaData := make(map[string]interface{}) - entriesNeeded := (handler.MAX_META_LENGTH_MB * 1024 * 1024) / 15 - for i := 0; i < entriesNeeded+1000; i++ { - var data interface{} = fmt.Sprintf("some_%d", i) - metaData[fmt.Sprintf("key_%d", i)] = &data - } - - rawMeta, _ := json.Marshal(metaData) - - req := openapi.V2IdentitiesCreateIdentityRequestBody{ExternalId: uid.New("test"), Meta: &metaData} - res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) - require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) - require.NotNil(t, res.Body) - - require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) - require.Equal(t, fmt.Sprintf("Metadata is too large, it must be less than %dMB, got: %.2f", handler.MAX_META_LENGTH_MB, float64(len(rawMeta))/1024/1024), res.Body.Error.Detail) - require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) - require.Equal(t, "Bad Request", res.Body.Error.Title) - require.NotEmpty(t, res.Body.Meta.RequestId) - require.Nil(t, res.Body.Error.Instance) - }) - - t.Run("invalid ratelimit", func(t *testing.T) { - - req := openapi.V2IdentitiesCreateIdentityRequestBody{ - ExternalId: uid.New("test"), - Ratelimits: &[]openapi.V2Ratelimit{ - { - Duration: 1, - Limit: 1, - }, - }, - } - res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) - require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) - require.NotNil(t, res.Body) - - require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", res.Body.Error.Type) - require.Equal(t, "POST request body for '/v2/identities.createIdentity' failed to validate schema", res.Body.Error.Detail) + require.Equal(t, "POST request body for '/v2/identities.deleteIdentity' failed to validate schema", res.Body.Error.Detail) require.Equal(t, http.StatusBadRequest, res.Body.Error.Status) require.Equal(t, "Bad Request", res.Body.Error.Title) require.NotEmpty(t, res.Body.Meta.RequestId) @@ -131,7 +84,7 @@ func TestBadRequests(t *testing.T) { // No Authorization header } - req := handler.Request{ExternalId: uid.New("test")} + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, http.StatusBadRequest, res.Status) require.NotNil(t, res.Body) @@ -143,7 +96,7 @@ func TestBadRequests(t *testing.T) { "Authorization": {"malformed_header"}, } - req := handler.Request{ExternalId: uid.New("test")} + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, http.StatusBadRequest, res.Status) require.NotNil(t, res.Body) diff --git a/go/apps/api/routes/v2_identities_delete_identity/401_test.go b/go/apps/api/routes/v2_identities_delete_identity/401_test.go index 56228a8d7e..f1b7611077 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/401_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/401_test.go @@ -11,7 +11,7 @@ import ( "github.com/unkeyed/unkey/go/pkg/uid" ) -func TestCreateApi_Unauthorized(t *testing.T) { +func TestDeleteIdentityUnauthorized(t *testing.T) { h := testutil.NewHarness(t) route := handler.New(handler.Services{ diff --git a/go/apps/api/routes/v2_identities_delete_identity/403_test.go b/go/apps/api/routes/v2_identities_delete_identity/403_test.go index f65e19d599..067e762536 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/403_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/403_test.go @@ -4,10 +4,12 @@ import ( "fmt" "net/http" "testing" + "time" "github.com/stretchr/testify/require" "github.com/unkeyed/unkey/go/apps/api/openapi" handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/db" "github.com/unkeyed/unkey/go/pkg/ptr" "github.com/unkeyed/unkey/go/pkg/testutil" "github.com/unkeyed/unkey/go/pkg/uid" @@ -26,13 +28,13 @@ func TestWorkspacePermissions(t *testing.T) { h.Register(route) - rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID) - headers := http.Header{ - "Content-Type": {"application/json"}, - "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, - } - t.Run("insufficient permissions", func(t *testing.T) { + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID) + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) @@ -40,9 +42,27 @@ func TestWorkspacePermissions(t *testing.T) { }) t.Run("delete identity from other workspace", func(t *testing.T) { - req := handler.Request{ExternalId: ptr.P(uid.New("test"))} + identityId := uid.New(uid.IdentityPrefix) + + err := db.Query.InsertIdentity(t.Context(), h.DB.RW(), db.InsertIdentityParams{ + ID: identityId, + ExternalID: "ext_" + identityId, + WorkspaceID: h.Resources().UserWorkspace.ID, + Environment: "default", + CreatedAt: time.Now().Unix(), + Meta: nil, + }) + require.NoError(t, err) + + rootKey := h.CreateRootKey(h.Resources().DifferentWorkspace.ID, "identity.*.delete_identity") + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + req := handler.Request{IdentityId: ptr.P(identityId)} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) - require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) + require.Equal(t, http.StatusNotFound, res.Status, "got: %s", res.RawBody) require.NotNil(t, res.Body) }) } diff --git a/go/apps/api/routes/v2_identities_delete_identity/404_test.go b/go/apps/api/routes/v2_identities_delete_identity/404_test.go new file mode 100644 index 0000000000..6a407b5b63 --- /dev/null +++ b/go/apps/api/routes/v2_identities_delete_identity/404_test.go @@ -0,0 +1,68 @@ +package handler_test + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/unkeyed/unkey/go/apps/api/openapi" + handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" + "github.com/unkeyed/unkey/go/pkg/db" + "github.com/unkeyed/unkey/go/pkg/ptr" + "github.com/unkeyed/unkey/go/pkg/testutil" + "github.com/unkeyed/unkey/go/pkg/uid" +) + +func TestNotFound(t *testing.T) { + h := testutil.NewHarness(t) + + route := handler.New(handler.Services{ + DB: h.DB, + Keys: h.Keys, + Logger: h.Logger, + Permissions: h.Permissions, + Auditlogs: h.Auditlogs, + }) + + h.Register(route) + + t.Run("insufficient permissions", func(t *testing.T) { + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID) + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + req := handler.Request{ExternalId: ptr.P(uid.New("test"))} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) + require.NotNil(t, res.Body) + }) + + t.Run("delete identity from other workspace", func(t *testing.T) { + identityId := uid.New(uid.IdentityPrefix) + + err := db.Query.InsertIdentity(t.Context(), h.DB.RW(), db.InsertIdentityParams{ + ID: identityId, + ExternalID: "ext_" + identityId, + WorkspaceID: h.Resources().UserWorkspace.ID, + Environment: "default", + CreatedAt: time.Now().Unix(), + Meta: nil, + }) + require.Nil(t, err) + + rootKey := h.CreateRootKey(h.Resources().DifferentWorkspace.ID, "identity.*.delete_identity") + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + req := handler.Request{IdentityId: ptr.P(identityId)} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusNotFound, res.Status, "got: %s", res.RawBody) + require.NotNil(t, res.Body) + }) +} From 7a4c56484c9a3b687a6ad08967f2ffe52fa81580 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 12:48:21 +0200 Subject: [PATCH 05/17] feat: actual 404 test --- .../v2_identities_delete_identity/404_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/go/apps/api/routes/v2_identities_delete_identity/404_test.go b/go/apps/api/routes/v2_identities_delete_identity/404_test.go index 6a407b5b63..33e7b6aa24 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/404_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/404_test.go @@ -65,4 +65,17 @@ func TestNotFound(t *testing.T) { require.Equal(t, http.StatusNotFound, res.Status, "got: %s", res.RawBody) require.NotNil(t, res.Body) }) + + t.Run("delete identity that doesn't exist", func(t *testing.T) { + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.delete_identity") + headers := http.Header{ + "Content-Type": {"application/json"}, + "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, + } + + req := handler.Request{IdentityId: ptr.P(uid.New(uid.IdentityPrefix))} + res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) + require.Equal(t, http.StatusNotFound, res.Status, "got: %s", res.RawBody) + require.NotNil(t, res.Body) + }) } From 7217714752e43c93a141e996032e055fad395993 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 21:29:03 +0200 Subject: [PATCH 06/17] feat: register route and remove debug --- go/apps/api/routes/register.go | 13 +++++++++++++ .../v2_identities_delete_identity/200_test.go | 3 --- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/go/apps/api/routes/register.go b/go/apps/api/routes/register.go index 79e530d2e9..a0b800b6f8 100644 --- a/go/apps/api/routes/register.go +++ b/go/apps/api/routes/register.go @@ -10,6 +10,7 @@ import ( v2RatelimitSetOverride "github.com/unkeyed/unkey/go/apps/api/routes/v2_ratelimit_set_override" v2IdentitiesCreateIdentity "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_create_identity" + v2IdentitiesDeleteIdentity "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_delete_identity" zen "github.com/unkeyed/unkey/go/pkg/zen" ) @@ -103,6 +104,18 @@ func Register(srv *zen.Server, svc *Services) { }), ) + // v2/identities.deleteIdentity + srv.RegisterRoute( + defaultMiddlewares, + v2IdentitiesDeleteIdentity.New(v2IdentitiesDeleteIdentity.Services{ + Logger: svc.Logger, + DB: svc.Database, + Keys: svc.Keys, + Permissions: svc.Permissions, + Auditlogs: svc.Auditlogs, + }), + ) + // --------------------------------------------------------------------------- // misc diff --git a/go/apps/api/routes/v2_identities_delete_identity/200_test.go b/go/apps/api/routes/v2_identities_delete_identity/200_test.go index 02fb6b4358..1cbe1daf8f 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/200_test.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "fmt" - "log" "net/http" "testing" "time" @@ -55,8 +54,6 @@ func newIdentity(t *testing.T, h *testutil.Harness, numberOfRatelimits int) Iden ratelimitIds = append(ratelimitIds, rateLimitID) } - log.Printf("Created identity with %d rate limits", len(ratelimitIds)) - return Identity{ ID: identityID, ExternalID: externalID, From 63a97b0cffbe10eab114669c6c2ccb9cdbee2b8a Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 21:35:18 +0200 Subject: [PATCH 07/17] fix: remove unneeded files --- go/pkg/codes/constants_gen.go | 2 +- ...ind_by_workspace_and_name.sql_generated.go | 29 --------- .../audit_log_bucket_insert.sql_generated.go | 61 ------------------- 3 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go delete mode 100644 go/pkg/db/audit_log_bucket_insert.sql_generated.go diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index 7b85b4b897..86c5efbe47 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-18T08:50:08+02:00 +// Generated at: 2025-04-18T21:33:50+02:00 package codes diff --git a/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go b/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go deleted file mode 100644 index 32202bab36..0000000000 --- a/go/pkg/db/audit_log_bucket_id_find_by_workspace_and_name.sql_generated.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 -// source: audit_log_bucket_id_find_by_workspace_and_name.sql - -package db - -import ( - "context" -) - -const findAuditLogBucketIDByWorkspaceIDAndName = `-- name: FindAuditLogBucketIDByWorkspaceIDAndName :one -SELECT id FROM audit_log_bucket WHERE workspace_id = ? AND name = ? -` - -type FindAuditLogBucketIDByWorkspaceIDAndNameParams struct { - WorkspaceID string `db:"workspace_id"` - Name string `db:"name"` -} - -// FindAuditLogBucketIDByWorkspaceIDAndName -// -// SELECT id FROM audit_log_bucket WHERE workspace_id = ? AND name = ? -func (q *Queries) FindAuditLogBucketIDByWorkspaceIDAndName(ctx context.Context, db DBTX, arg FindAuditLogBucketIDByWorkspaceIDAndNameParams) (string, error) { - row := db.QueryRowContext(ctx, findAuditLogBucketIDByWorkspaceIDAndName, arg.WorkspaceID, arg.Name) - var id string - err := row.Scan(&id) - return id, err -} diff --git a/go/pkg/db/audit_log_bucket_insert.sql_generated.go b/go/pkg/db/audit_log_bucket_insert.sql_generated.go deleted file mode 100644 index e50f6a412c..0000000000 --- a/go/pkg/db/audit_log_bucket_insert.sql_generated.go +++ /dev/null @@ -1,61 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 -// source: audit_log_bucket_insert.sql - -package db - -import ( - "context" - "database/sql" -) - -const insertAuditLogBucket = `-- name: InsertAuditLogBucket :exec -INSERT INTO ` + "`" + `audit_log_bucket` + "`" + ` ( - id, - workspace_id, - name, - retention_days, - created_at -) VALUES ( - ?, - ?, - ?, - ?, - ? -) -` - -type InsertAuditLogBucketParams struct { - ID string `db:"id"` - WorkspaceID string `db:"workspace_id"` - Name string `db:"name"` - RetentionDays sql.NullInt32 `db:"retention_days"` - CreatedAt int64 `db:"created_at"` -} - -// InsertAuditLogBucket -// -// INSERT INTO `audit_log_bucket` ( -// id, -// workspace_id, -// name, -// retention_days, -// created_at -// ) VALUES ( -// ?, -// ?, -// ?, -// ?, -// ? -// ) -func (q *Queries) InsertAuditLogBucket(ctx context.Context, db DBTX, arg InsertAuditLogBucketParams) error { - _, err := db.ExecContext(ctx, insertAuditLogBucket, - arg.ID, - arg.WorkspaceID, - arg.Name, - arg.RetentionDays, - arg.CreatedAt, - ) - return err -} From 0d2c5c0a42331fb74927593e545ae0f7fcc90782 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 21:40:46 +0200 Subject: [PATCH 08/17] fix: correct identity workspace idx --- internal/db/src/schema/identity.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/db/src/schema/identity.ts b/internal/db/src/schema/identity.ts index 12718fd56d..8d32e976a9 100644 --- a/internal/db/src/schema/identity.ts +++ b/internal/db/src/schema/identity.ts @@ -9,7 +9,7 @@ export const identities = mysqlTable( { id: varchar("id", { length: 256 }).primaryKey(), /** - * The extenral id is used to create a reference to the user's existing data. + * The external id is used to create a reference to the user's existing data. * They likely have an organization or user id at hand */ externalId: varchar("external_id", { length: 256 }).notNull(), @@ -19,10 +19,9 @@ export const identities = mysqlTable( meta: json("meta").$type>(), }, (table) => ({ - workspaceId: index("workspace_id_idx").on(table.workspaceId), - uniqueExternalIdPerWorkspace: uniqueIndex("external_id_workspace_id_idx").on( - table.externalId, + uniqueExternalIdPerWorkspace: uniqueIndex("workspace_id_external_id_idx").on( table.workspaceId, + table.externalId, ), }), ); From 0cf532ecfe58f70a12ee2a3a3f51d3d3811719bc Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Fri, 18 Apr 2025 21:52:29 +0200 Subject: [PATCH 09/17] fix: remove duped test --- .../v2_identities_delete_identity/400_test.go | 4 ++-- .../v2_identities_delete_identity/404_test.go | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/go/apps/api/routes/v2_identities_delete_identity/400_test.go b/go/apps/api/routes/v2_identities_delete_identity/400_test.go index dcf8aaa965..25d73722da 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/400_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/400_test.go @@ -17,7 +17,7 @@ import ( func TestBadRequests(t *testing.T) { h := testutil.NewHarness(t) - rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.create_identity") + rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID, "identity.*.delete_identity") route := handler.New(handler.Services{ DB: h.DB, Keys: h.Keys, @@ -64,7 +64,7 @@ func TestBadRequests(t *testing.T) { }) t.Run("external id too short", func(t *testing.T) { - req := handler.Request{ExternalId: ptr.P("")} + req := handler.Request{ExternalId: ptr.P("id")} res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) require.Equal(t, 400, res.Status, "expected 400, sent: %+v, received: %s", req, res.RawBody) require.NotNil(t, res.Body) diff --git a/go/apps/api/routes/v2_identities_delete_identity/404_test.go b/go/apps/api/routes/v2_identities_delete_identity/404_test.go index 33e7b6aa24..ff9cd21312 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/404_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/404_test.go @@ -28,19 +28,6 @@ func TestNotFound(t *testing.T) { h.Register(route) - t.Run("insufficient permissions", func(t *testing.T) { - rootKey := h.CreateRootKey(h.Resources().UserWorkspace.ID) - headers := http.Header{ - "Content-Type": {"application/json"}, - "Authorization": {fmt.Sprintf("Bearer %s", rootKey)}, - } - - req := handler.Request{ExternalId: ptr.P(uid.New("test"))} - res := testutil.CallRoute[handler.Request, openapi.BadRequestErrorResponse](h, route, headers, req) - require.Equal(t, http.StatusForbidden, res.Status, "got: %s", res.RawBody) - require.NotNil(t, res.Body) - }) - t.Run("delete identity from other workspace", func(t *testing.T) { identityId := uid.New(uid.IdentityPrefix) From 13d7693923bb06eeee334e25d0335f272d2bceda Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sat, 19 Apr 2025 10:54:07 +0200 Subject: [PATCH 10/17] fix: use oneOf --- go/apps/api/openapi/openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/apps/api/openapi/openapi.json b/go/apps/api/openapi/openapi.json index de9c8bfe5e..444eb91e02 100644 --- a/go/apps/api/openapi/openapi.json +++ b/go/apps/api/openapi/openapi.json @@ -586,7 +586,7 @@ "example": "id_123" } }, - "anyOf": [ + "oneOf": [ { "required": ["externalId"] }, From 64ab3a1a647d5d360cb1dc8d7c84d52d2e799100 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:26:23 +0200 Subject: [PATCH 11/17] fix: allow explicit identity permission --- .../v2_identities_delete_identity/handler.go | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go index d7825f1924..fd049a6d24 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/handler.go +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -47,16 +47,26 @@ func New(svc Services) zen.Route { ) } + checks := []rbac.PermissionQuery{ + rbac.T(rbac.Tuple{ + ResourceType: rbac.Identity, + ResourceID: "*", + Action: rbac.DeleteIdentity, + }), + } + + if req.IdentityId != nil { + checks = append(checks, rbac.T(rbac.Tuple{ + ResourceType: rbac.Identity, + ResourceID: *req.IdentityId, + Action: rbac.DeleteIdentity, + })) + } + permissions, err := svc.Permissions.Check( ctx, auth.KeyID, - rbac.Or( - rbac.T(rbac.Tuple{ - ResourceType: rbac.Identity, - ResourceID: "*", - Action: rbac.DeleteIdentity, - }), - ), + rbac.Or(checks...), ) if err != nil { return fault.Wrap(err, From 0672ec2ec08eadebed11ae68b2880322c1183cb8 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:28:37 +0200 Subject: [PATCH 12/17] chore: add namespace name example --- go/apps/api/openapi/openapi.json | 1 + 1 file changed, 1 insertion(+) diff --git a/go/apps/api/openapi/openapi.json b/go/apps/api/openapi/openapi.json index 444eb91e02..9afb240412 100644 --- a/go/apps/api/openapi/openapi.json +++ b/go/apps/api/openapi/openapi.json @@ -532,6 +532,7 @@ "name": { "description": "The name of this limit. You will need to use this again when verifying a key.", "type": "string", + "example": "api", "minLength": 3, "maxLength": 128 }, From e671bd5b924099971592aee8cfa32b62115e4f57 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sat, 19 Apr 2025 21:59:45 +0200 Subject: [PATCH 13/17] fix: fmt --- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 8 +-- .../generated_test.go | 8 +-- .../generated_test.go | 6 +-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../generated_test.go | 10 ++-- .../v2_identities_delete_identity/handler.go | 2 + go/pkg/codes/constants_gen.go | 49 +++++++++---------- 56 files changed, 272 insertions(+), 271 deletions(-) diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go index 2632152f50..552fe8071b 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go index c969c7937f..0258b8b338 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go index 58d0d632d4..b81c522c2e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 1, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go index 93cd2ef3fd..09f979ab20 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 1, // node count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go index 3f5b1f82cd..85db1f83ee 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 1, // node count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go index ee137e9ec6..d949f73597 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 1, // node count + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go index e356b64753..22431412cd 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go index 180b5a0885..f4172c7b64 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go index 0dfe9bdf82..d6024ff443 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 1, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go index 47c9acd39e..ed3979a8f9 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go index 255272c096..52c7ad8bc6 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go index e8c19fd2f5..14ff667795 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 1, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go index 9c83fcc957..78c84de3c1 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 1, // node count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go index 3abe696741..5c8fb2f0e5 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 1, // node count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go index 309ed5fac7..06909946d6 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 1, // node count + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go index 9322bde125..4ddf89e004 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go index b089452429..a47bca4d26 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go index 1c1228ed97..bfc6875e3e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes1_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 1, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 1, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go index 28a52404bf..032ceb384d 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go index 51c8909235..9d503efee9 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go index 0a39a0b801..2eaae82714 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 3, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go index 9c626e5fbe..7ada487478 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 3, // node count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go index 188bcd84a9..06d76e9d80 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 3, // node count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go index 0bcc2a0274..135b981183 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 3, // node count + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go index d78e21ccb1..4a819f8b32 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go index d44c112057..b5e499078b 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go index 7bf591a233..e20fd3c6c1 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 3, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go index ad17cb979c..10e660d367 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go index 0e16b1c380..a0670e6808 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go index 3e7d690f8a..5d404e6959 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 3, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go index 3e7c431e97..17611f51fa 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 3, // node count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go index 8d41aeb542..12b7f4419e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 3, // node count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go index 2c3e38718c..8075d42c15 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 3, // node count + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go index 2ad80f8bbc..ced9a853ee 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go index b7ba029539..15375931a5 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go index 1b245e625b..d73118fe1c 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes3_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 3, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 3, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go index b10bda559b..ad7ea299c2 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go index c1e93bd6eb..7cb427ee68 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load10_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 10, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go index a0ad5614c6..ee76aae4cf 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration1000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 100, // limit - 1000, // duration - 10, // window count - 2, // load factor - 9, // node count + 100, // limit + 1000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go index 6f0571096d..b8afa443c1 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load0_90_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 9, // node count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go index ff23abb4f8..f1a6d596e9 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load10_00_Windows run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count - 10, // load factor - 9, // node count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go index 7f876c7971..b671ddd1bf 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration3600000_Load2_00_Windows1 run.RunRateLimitTest( t, h, - 100, // limit - 3600000, // duration + 100, // limit + 3600000, // duration 10, // window count 2, // load factor - 9, // node count + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go index b90a0bfade..5dab408a1c 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go index 4aae4855d1..4ca4f08f94 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 10, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go index e61efe82e7..7fca869568 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit100_Duration60000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 100, // limit - 60000, // duration - 10, // window count - 2, // load factor - 9, // node count + 100, // limit + 60000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go index b2ddf6a409..ef6e840a54 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load0_90_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go index 5ca2212654..af389b45cf 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 10, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go index f0e8e67afe..3cbd8ec16e 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration1000_Load2_00_Windows10(t * run.RunRateLimitTest( t, h, - 5, // limit - 1000, // duration - 10, // window count - 2, // load factor - 9, // node count + 5, // limit + 1000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go index 4c0ee50d70..962df1ca88 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load0_90_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 0.9, // load factor - 9, // node count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go index 6399ba99e0..5d1dfeca6a 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load10_00_Windows10 run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count - 10, // load factor - 9, // node count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go index 5f8eb3838e..a604ef1187 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration3600000_Load2_00_Windows10( run.RunRateLimitTest( t, h, - 5, // limit - 3600000, // duration + 5, // limit + 3600000, // duration 10, // window count 2, // load factor - 9, // node count + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go index 1e5832698a..334a591b39 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load0_90_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 0.9, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 0.9, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go index 3cab014dd5..40cfddb431 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load10_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 10, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 10, // load factor + 9, // node count ) } diff --git a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go index f932ffbe12..6d9af71650 100644 --- a/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go +++ b/go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go @@ -19,10 +19,10 @@ func TestIntegration_RateLimit_Nodes9_Limit5_Duration60000_Load2_00_Windows10(t run.RunRateLimitTest( t, h, - 5, // limit - 60000, // duration - 10, // window count - 2, // load factor - 9, // node count + 5, // limit + 60000, // duration + 10, // window count + 2, // load factor + 9, // node count ) } diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go index fd049a6d24..520d5a89c9 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/handler.go +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -156,6 +156,7 @@ func New(svc Services) zen.Route { Bucket: auditlogs.DEFAULT_BUCKET, ActorID: auth.KeyID, ActorType: auditlog.RootKeyActor, + ActorMeta: nil, ActorName: "root key", RemoteIP: s.Location(), UserAgent: s.UserAgent(), @@ -179,6 +180,7 @@ func New(svc Services) zen.Route { Bucket: auditlogs.DEFAULT_BUCKET, ActorID: auth.KeyID, ActorType: auditlog.RootKeyActor, + ActorMeta: nil, ActorName: "root key", RemoteIP: s.Location(), UserAgent: s.UserAgent(), diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index 86c5efbe47..e50384731d 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -8,11 +8,11 @@ type URN string // Error code constants for use in switch statements for exhaustive checking const ( -// ---------------- -// UnkeyAuthErrors -// ---------------- + // ---------------- + // UnkeyAuthErrors + // ---------------- -// Authentication + // Authentication // Missing indicates authentication credentials were not provided. UnkeyAuthErrorsAuthenticationMissing URN = "err:unkey:authentication:missing" @@ -21,7 +21,7 @@ const ( // KeyNotFound indicates the authentication key was not found. UnkeyAuthErrorsAuthenticationKeyNotFound URN = "err:unkey:authentication:key_not_found" -// Authorization + // Authorization // InsufficientPermissions indicates the authenticated entity lacks // sufficient permissions for the requested operation. @@ -33,83 +33,82 @@ const ( // WorkspaceDisabled indicates the associated workspace is disabled. UnkeyAuthErrorsAuthorizationWorkspaceDisabled URN = "err:unkey:authorization:workspace_disabled" -// ---------------- -// UnkeyDataErrors -// ---------------- + // ---------------- + // UnkeyDataErrors + // ---------------- -// Key + // Key // NotFound indicates the requested key was not found. UnkeyDataErrorsKeyNotFound URN = "err:unkey:data:key_not_found" -// Workspace + // Workspace // NotFound indicates the requested workspace was not found. UnkeyDataErrorsWorkspaceNotFound URN = "err:unkey:data:workspace_not_found" -// Api + // Api // NotFound indicates the requested API was not found. UnkeyDataErrorsApiNotFound URN = "err:unkey:data:api_not_found" -// Permission + // Permission // NotFound indicates the requested permission was not found. UnkeyDataErrorsPermissionNotFound URN = "err:unkey:data:permission_not_found" -// Role + // Role // NotFound indicates the requested role was not found. UnkeyDataErrorsRoleNotFound URN = "err:unkey:data:role_not_found" -// KeyAuth + // KeyAuth // NotFound indicates the requested key authentication was not found. UnkeyDataErrorsKeyAuthNotFound URN = "err:unkey:data:key_auth_not_found" -// RatelimitNamespace + // RatelimitNamespace // NotFound indicates the requested rate limit namespace was not found. UnkeyDataErrorsRatelimitNamespaceNotFound URN = "err:unkey:data:ratelimit_namespace_not_found" -// RatelimitOverride + // RatelimitOverride // NotFound indicates the requested rate limit override was not found. UnkeyDataErrorsRatelimitOverrideNotFound URN = "err:unkey:data:ratelimit_override_not_found" -// Identity + // Identity // NotFound indicates the requested identity was not found. UnkeyDataErrorsIdentityNotFound URN = "err:unkey:data:identity_not_found" // Duplicate indicates the requested identity already exists. UnkeyDataErrorsIdentityDuplicate URN = "err:unkey:data:identity_already_exists" -// AuditLog + // AuditLog // NotFound indicates the requested audit log was not found. UnkeyDataErrorsAuditLogNotFound URN = "err:unkey:data:audit_log_not_found" -// ---------------- -// UnkeyAppErrors -// ---------------- + // ---------------- + // UnkeyAppErrors + // ---------------- -// Internal + // Internal // UnexpectedError represents an unhandled or unexpected error condition. UnkeyAppErrorsInternalUnexpectedError URN = "err:unkey:application:unexpected_error" // ServiceUnavailable indicates a service is temporarily unavailable. UnkeyAppErrorsInternalServiceUnavailable URN = "err:unkey:application:service_unavailable" -// Validation + // Validation // InvalidInput indicates a client provided input that failed validation. UnkeyAppErrorsValidationInvalidInput URN = "err:unkey:application:invalid_input" // AssertionFailed indicates a runtime assertion or invariant check failed. UnkeyAppErrorsValidationAssertionFailed URN = "err:unkey:application:assertion_failed" -// Protection + // Protection // ProtectedResource indicates an attempt to modify a protected resource. UnkeyAppErrorsProtectionProtectedResource URN = "err:unkey:application:protected_resource" - ) From 0f817cb454408e7c54ba7ef0581370c7f924588d Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sun, 20 Apr 2025 09:19:20 +0200 Subject: [PATCH 14/17] do db changes for soft-deletes --- internal/db/src/schema/identity.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/db/src/schema/identity.ts b/internal/db/src/schema/identity.ts index 8d32e976a9..e18b88a271 100644 --- a/internal/db/src/schema/identity.ts +++ b/internal/db/src/schema/identity.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm"; -import { bigint, index, int, json, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"; +import { bigint, boolean, index, int, json, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"; import { keys } from "./keys"; import { lifecycleDates } from "./util/lifecycle_dates"; import { workspaces } from "./workspaces"; @@ -15,13 +15,15 @@ export const identities = mysqlTable( externalId: varchar("external_id", { length: 256 }).notNull(), workspaceId: varchar("workspace_id", { length: 256 }).notNull(), environment: varchar("environment", { length: 256 }).notNull().default("default"), - ...lifecycleDates, meta: json("meta").$type>(), + deleted: boolean("deleted").default(false), + ...lifecycleDates, }, (table) => ({ - uniqueExternalIdPerWorkspace: uniqueIndex("workspace_id_external_id_idx").on( + uniqueDeletedExternalIdPerWorkspace: uniqueIndex("workspace_id_external_id_deleted_idx").on( table.workspaceId, table.externalId, + table.deleted, ), }), ); From 328f3db9d35957cabb05f57b1c985dfc499cb640 Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Sun, 20 Apr 2025 09:32:07 +0200 Subject: [PATCH 15/17] cleanup code and fix ratelimit component naming --- go/apps/api/openapi/gen.go | 26 +++++++++---------- go/apps/api/openapi/openapi.json | 4 +-- .../v2_identities_create_identity/200_test.go | 2 +- .../v2_identities_create_identity/400_test.go | 11 ++++---- go/pkg/codes/constants_gen.go | 2 +- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/go/apps/api/openapi/gen.go b/go/apps/api/openapi/gen.go index 44e7a4b087..ad8f403a05 100644 --- a/go/apps/api/openapi/gen.go +++ b/go/apps/api/openapi/gen.go @@ -125,6 +125,18 @@ type PreconditionFailedErrorResponse struct { Meta Meta `json:"meta"` } +// Ratelimit defines model for Ratelimit. +type Ratelimit struct { + // Duration The duration for each ratelimit window in milliseconds. + Duration int64 `json:"duration"` + + // Limit How many requests may pass within a given window before requests are rejected. + Limit int64 `json:"limit"` + + // Name The name of this limit. You will need to use this again when verifying a key. + Name string `json:"name"` +} + // RatelimitDeleteOverrideResponseData defines model for RatelimitDeleteOverrideResponseData. type RatelimitDeleteOverrideResponseData = map[string]interface{} @@ -209,7 +221,7 @@ type V2IdentitiesCreateIdentityRequestBody struct { // Ratelimits Attach ratelimits to this identity. // // When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits. - Ratelimits *[]V2Ratelimit `json:"ratelimits,omitempty"` + Ratelimits *[]Ratelimit `json:"ratelimits,omitempty"` } // V2IdentitiesCreateIdentityResponseBody defines model for V2IdentitiesCreateIdentityResponseBody. @@ -246,18 +258,6 @@ type V2LivenessResponseBody struct { Meta Meta `json:"meta"` } -// V2Ratelimit defines model for V2Ratelimit. -type V2Ratelimit struct { - // Duration The duration for each ratelimit window in milliseconds. - Duration int64 `json:"duration"` - - // Limit How many requests may pass within a given window before requests are rejected. - Limit int64 `json:"limit"` - - // Name The name of this limit. You will need to use this again when verifying a key. - Name string `json:"name"` -} - // V2RatelimitDeleteOverrideRequestBody Deletes an existing override. type V2RatelimitDeleteOverrideRequestBody struct { // Identifier Identifier of the override to delete diff --git a/go/apps/api/openapi/openapi.json b/go/apps/api/openapi/openapi.json index 9afb240412..9ed0c5c473 100644 --- a/go/apps/api/openapi/openapi.json +++ b/go/apps/api/openapi/openapi.json @@ -519,13 +519,13 @@ "ratelimits": { "type": "array", "items": { - "$ref": "#/components/schemas/V2Ratelimit" + "$ref": "#/components/schemas/Ratelimit" }, "description": "Attach ratelimits to this identity.\n\nWhen verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits." } } }, - "V2Ratelimit": { + "Ratelimit": { "type": "object", "required": ["name", "limit", "duration"], "properties": { diff --git a/go/apps/api/routes/v2_identities_create_identity/200_test.go b/go/apps/api/routes/v2_identities_create_identity/200_test.go index c07aa3e26d..00c22a16b3 100644 --- a/go/apps/api/routes/v2_identities_create_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_create_identity/200_test.go @@ -138,7 +138,7 @@ func TestCreateIdentitySuccessfully(t *testing.T) { t.Run("create identity with ratelimits", func(t *testing.T) { externalTestID := uid.New("test_external_id") - identityRateLimits := []openapi.V2Ratelimit{ + identityRateLimits := []openapi.Ratelimit{ { Duration: time.Minute.Milliseconds(), Limit: 100, diff --git a/go/apps/api/routes/v2_identities_create_identity/400_test.go b/go/apps/api/routes/v2_identities_create_identity/400_test.go index 54a2d62fc2..a1bd1ab741 100644 --- a/go/apps/api/routes/v2_identities_create_identity/400_test.go +++ b/go/apps/api/routes/v2_identities_create_identity/400_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/unkeyed/unkey/go/apps/api/openapi" handler "github.com/unkeyed/unkey/go/apps/api/routes/v2_identities_create_identity" + "github.com/unkeyed/unkey/go/pkg/ptr" "github.com/unkeyed/unkey/go/pkg/testutil" "github.com/unkeyed/unkey/go/pkg/uid" ) @@ -79,11 +80,10 @@ func TestBadRequests(t *testing.T) { }) t.Run("metadata exceeds maximum size limit", func(t *testing.T) { - metaData := make(map[string]interface{}) + metaData := make(map[string]any) entriesNeeded := (handler.MAX_META_LENGTH_MB * 1024 * 1024) / 15 - for i := 0; i < entriesNeeded+1000; i++ { - var data interface{} = fmt.Sprintf("some_%d", i) - metaData[fmt.Sprintf("key_%d", i)] = &data + for i := range entriesNeeded + 1000 { + metaData[fmt.Sprintf("key_%d", i)] = ptr.P(fmt.Sprintf("some_%d", i)) } rawMeta, _ := json.Marshal(metaData) @@ -102,10 +102,9 @@ func TestBadRequests(t *testing.T) { }) t.Run("invalid ratelimit", func(t *testing.T) { - req := openapi.V2IdentitiesCreateIdentityRequestBody{ ExternalId: uid.New("test"), - Ratelimits: &[]openapi.V2Ratelimit{ + Ratelimits: &[]openapi.Ratelimit{ { Duration: 1, Limit: 1, diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index e50384731d..2080a0eae0 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-18T21:33:50+02:00 +// Generated at: 2025-04-20T09:23:21+02:00 package codes From 1503dac5eb484bd443ae8f75b8fdaf7acf24ca1a Mon Sep 17 00:00:00 2001 From: Flo <53355483+Flo4604@users.noreply.github.com> Date: Tue, 22 Apr 2025 21:43:54 +0200 Subject: [PATCH 16/17] feat: soft delete identity without tests yet --- .../v2_identities_create_identity/200_test.go | 29 +- .../v2_identities_create_identity/handler.go | 3 +- .../v2_identities_delete_identity/200_test.go | 35 +- .../v2_identities_delete_identity/handler.go | 105 +++- go/pkg/codes/constants_gen.go | 2 +- go/pkg/db/handle_err_duplicate_key.go | 13 + ...ntity_find_by_external_id.sql_generated.go | 8 +- .../db/identity_find_by_id.sql_generated.go | 14 +- .../db/identity_soft_delete.sql_generated.go | 22 + go/pkg/db/key_find_by_id.sql_generated.go | 5 +- ...key_find_for_verification.sql_generated.go | 5 +- go/pkg/db/models_generated.go | 1 + go/pkg/db/querier_generated.go | 18 +- .../queries/identity_find_by_external_id.sql | 2 +- go/pkg/db/queries/identity_find_by_id.sql | 2 +- go/pkg/db/queries/identity_soft_delete.sql | 2 + .../ratelimit_delete_by_identity_id.sql | 2 + ...mit_delete_by_identity_id.sql_generated.go | 23 + go/pkg/db/schema.sql | 565 +++++++++--------- internal/db/src/schema/identity.ts | 4 +- 20 files changed, 507 insertions(+), 353 deletions(-) create mode 100644 go/pkg/db/handle_err_duplicate_key.go create mode 100644 go/pkg/db/identity_soft_delete.sql_generated.go create mode 100644 go/pkg/db/queries/identity_soft_delete.sql create mode 100644 go/pkg/db/queries/ratelimit_delete_by_identity_id.sql create mode 100644 go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go diff --git a/go/apps/api/routes/v2_identities_create_identity/200_test.go b/go/apps/api/routes/v2_identities_create_identity/200_test.go index 00c22a16b3..01f902a146 100644 --- a/go/apps/api/routes/v2_identities_create_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_create_identity/200_test.go @@ -52,7 +52,10 @@ func TestCreateIdentitySuccessfully(t *testing.T) { }) require.NoError(t, err) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: identityID, + Deleted: false, + }) require.NoError(t, err) require.Equal(t, identity.ExternalID, externalTestID) }) @@ -71,7 +74,10 @@ func TestCreateIdentitySuccessfully(t *testing.T) { }) require.NoError(t, err) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), identityID) + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: identityID, + Deleted: false, + }) require.NoError(t, err) require.Equal(t, identity.ExternalID, externalTestID) @@ -104,7 +110,10 @@ func TestCreateIdentitySuccessfully(t *testing.T) { require.NotNil(t, res.Body) require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: res.Body.Data.IdentityId, + Deleted: false, + }) require.NoError(t, err) require.Equal(t, identity.ExternalID, req.ExternalId) }) @@ -113,7 +122,7 @@ func TestCreateIdentitySuccessfully(t *testing.T) { t.Run("create identity with metadata", func(t *testing.T) { externalTestID := uid.New("test_external_id") - meta := &map[string]interface{}{"key": "example"} + meta := &map[string]any{"key": "example"} req := handler.Request{ ExternalId: externalTestID, Meta: meta, @@ -124,11 +133,14 @@ func TestCreateIdentitySuccessfully(t *testing.T) { require.NotNil(t, res.Body) require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: res.Body.Data.IdentityId, + Deleted: false, + }) require.NoError(t, err) require.Equal(t, identity.ExternalID, req.ExternalId) - var dbMeta map[string]interface{} + var dbMeta map[string]any err = json.Unmarshal(identity.Meta, &dbMeta) require.NoError(t, err) require.Equal(t, *meta, dbMeta) @@ -161,7 +173,10 @@ func TestCreateIdentitySuccessfully(t *testing.T) { require.NotNil(t, res.Body) require.NotEmpty(t, res.Body.Data.IdentityId) - identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), res.Body.Data.IdentityId) + identity, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: res.Body.Data.IdentityId, + Deleted: false, + }) require.NoError(t, err) require.Equal(t, identity.ExternalID, req.ExternalId) diff --git a/go/apps/api/routes/v2_identities_create_identity/handler.go b/go/apps/api/routes/v2_identities_create_identity/handler.go index 1a16ecb814..3c3203d391 100644 --- a/go/apps/api/routes/v2_identities_create_identity/handler.go +++ b/go/apps/api/routes/v2_identities_create_identity/handler.go @@ -9,7 +9,6 @@ import ( "net/http" "time" - "github.com/go-sql-driver/mysql" "github.com/unkeyed/unkey/go/apps/api/openapi" "github.com/unkeyed/unkey/go/internal/services/auditlogs" "github.com/unkeyed/unkey/go/internal/services/keys" @@ -127,7 +126,7 @@ func New(svc Services) zen.Route { Meta: meta, }) if err != nil { - if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1062 { + if db.IsDuplicateKeyError(err) { return fault.Wrap(err, fault.WithCode(codes.Data.Identity.Duplicate.URN()), fault.WithDesc("identity already exists", fmt.Sprintf("Identity with externalId \"%s\" already exists in this workspace.", req.ExternalId)), diff --git a/go/apps/api/routes/v2_identities_delete_identity/200_test.go b/go/apps/api/routes/v2_identities_delete_identity/200_test.go index 1cbe1daf8f..3b5a7dd87d 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/200_test.go @@ -85,13 +85,19 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { t.Run("delete identity via db and identity id", func(t *testing.T) { newIdentity := newIdentity(t, h, 0) - _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.NoError(t, err) err = db.Query.DeleteIdentity(ctx, h.DB.RW(), newIdentity.ID) require.NoError(t, err) - _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.Equal(t, sql.ErrNoRows, err) }) @@ -100,7 +106,10 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { numberOfRatelimits := 2 newIdentity := newIdentity(t, h, numberOfRatelimits) - _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.NoError(t, err) rateLimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) @@ -113,7 +122,10 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { err = db.Query.DeleteManyRatelimitsByIDs(ctx, h.DB.RW(), newIdentity.RatelimitIds) require.NoError(t, err) - _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err = db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.Equal(t, sql.ErrNoRows, err) ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) @@ -130,7 +142,10 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.Equal(t, sql.ErrNoRows, err) }) @@ -143,7 +158,10 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.Equal(t, sql.ErrNoRows, err) }) @@ -155,7 +173,10 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { require.Equal(t, 200, res.Status, "expected 200, received: %#v", res) require.NotNil(t, res.Body) - _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), newIdentity.ID) + _, err := db.Query.FindIdentityByID(ctx, h.DB.RO(), db.FindIdentityByIDParams{ + ID: newIdentity.ID, + Deleted: false, + }) require.Equal(t, sql.ErrNoRows, err) ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go index 520d5a89c9..7cdc007bdd 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/handler.go +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -80,21 +80,6 @@ func New(svc Services) zen.Route { ) } - tx, err := svc.DB.RW().Begin(ctx) - if err != nil { - return fault.Wrap(err, - fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to create transaction", "Unable to start database transaction."), - ) - } - - defer func() { - rollbackErr := tx.Rollback() - if rollbackErr != nil && !errors.Is(rollbackErr, sql.ErrTxDone) { - svc.Logger.Error("rollback failed", "requestId", s.RequestID(), "error", rollbackErr) - } - }() - identity, err := getIdentity(ctx, svc, req, auth.AuthorizedWorkspaceID) if err != nil { if db.IsNotFound(err) { @@ -117,37 +102,47 @@ func New(svc Services) zen.Route { ) } - ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, svc.DB.RO(), sql.NullString{String: identity.ID, Valid: true}) - if err != nil && !db.IsNotFound(err) { + tx, err := svc.DB.RW().Begin(ctx) + if err != nil { return fault.Wrap(err, fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to load identity ratelimits", "Failed to load Identity ratelimits."), + fault.WithDesc("database failed to create transaction", "Unable to start database transaction."), ) } - if len(ratelimits) > 0 { - ids := make([]string, 0) - for _, ratelimit := range ratelimits { - ids = append(ids, ratelimit.ID) + defer func() { + rollbackErr := tx.Rollback() + if rollbackErr != nil && !errors.Is(rollbackErr, sql.ErrTxDone) { + svc.Logger.Error("rollback failed", "requestId", s.RequestID(), "error", rollbackErr) } + }() + + err = db.Query.SoftDeleteIdentity(ctx, tx, identity.ID) + if err != nil && !db.IsDuplicateKeyError(err) { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to soft delete identity", "Failed to delete Identity."), + ) + } - err = db.Query.DeleteManyRatelimitsByIDs(ctx, tx, ids) + // If we hit a duplicate key error, we know that we have an identity that was already soft deleted + // so we can hard delete the "old" deleted version + if err != nil && db.IsDuplicateKeyError(err) { + err = deleteOldIdentity(ctx, tx, auth.AuthorizedWorkspaceID, identity.ExternalID) if err != nil { + return err + } + + // Re-apply the soft delete operation + err = db.Query.SoftDeleteIdentity(ctx, tx, identity.ID) + if err != nil && !db.IsDuplicateKeyError(err) { return fault.Wrap(err, fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to delete identity ratelimits", "Failed to delete Identity ratelimits."), + fault.WithDesc("database failed to soft delete identity", "Failed to delete Identity."), ) } } - err = db.Query.DeleteIdentity(ctx, tx, identity.ID) - if err != nil { - return fault.Wrap(err, - fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to delete identity", "Failed to delete Identity."), - ) - } - auditLogs := []auditlog.AuditLog{ { WorkspaceID: auth.AuthorizedWorkspaceID, @@ -172,6 +167,14 @@ func New(svc Services) zen.Route { }, } + ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, tx, sql.NullString{String: identity.ID, Valid: true}) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to load identity ratelimits", "Failed to load Identity ratelimits."), + ) + } + for _, rl := range ratelimits { auditLogs = append(auditLogs, auditlog.AuditLog{ WorkspaceID: auth.AuthorizedWorkspaceID, @@ -223,14 +226,50 @@ func New(svc Services) zen.Route { }) } +func deleteOldIdentity(ctx context.Context, tx *sql.Tx, workspaceID, externalID string) error { + oldIdentity, err := db.Query.FindIdentityByExternalID(ctx, tx, db.FindIdentityByExternalIDParams{ + WorkspaceID: workspaceID, + ExternalID: externalID, + Deleted: true, + }) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to load old identity", "Failed to load Identity."), + ) + } + + err = db.Query.DeleteRatelimitsByIdentityID(ctx, tx, sql.NullString{String: oldIdentity.ID, Valid: true}) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to delete identity ratelimits", "Failed to delete Identity ratelimits."), + ) + } + + err = db.Query.DeleteIdentity(ctx, tx, oldIdentity.ID) + if err != nil { + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to delete identity", "Failed to delete Identity."), + ) + } + + return nil +} + func getIdentity(ctx context.Context, svc Services, req Request, workspaceID string) (db.Identity, error) { switch { case req.IdentityId != nil: - return db.Query.FindIdentityByID(ctx, svc.DB.RO(), *req.IdentityId) + return db.Query.FindIdentityByID(ctx, svc.DB.RO(), db.FindIdentityByIDParams{ + ID: *req.IdentityId, + Deleted: false, + }) case req.ExternalId != nil: return db.Query.FindIdentityByExternalID(ctx, svc.DB.RO(), db.FindIdentityByExternalIDParams{ WorkspaceID: workspaceID, ExternalID: *req.ExternalId, + Deleted: false, }) } diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index 2080a0eae0..e3ec51fe7f 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-20T09:23:21+02:00 +// Generated at: 2025-04-22T21:41:07+02:00 package codes diff --git a/go/pkg/db/handle_err_duplicate_key.go b/go/pkg/db/handle_err_duplicate_key.go new file mode 100644 index 0000000000..c72bbeace5 --- /dev/null +++ b/go/pkg/db/handle_err_duplicate_key.go @@ -0,0 +1,13 @@ +package db + +import ( + "github.com/go-sql-driver/mysql" +) + +func IsDuplicateKeyError(err error) bool { + if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1062 { + return true + } + + return false +} diff --git a/go/pkg/db/identity_find_by_external_id.sql_generated.go b/go/pkg/db/identity_find_by_external_id.sql_generated.go index 5b78b55a84..0552491ae0 100644 --- a/go/pkg/db/identity_find_by_external_id.sql_generated.go +++ b/go/pkg/db/identity_find_by_external_id.sql_generated.go @@ -10,19 +10,20 @@ import ( ) const findIdentityByExternalID = `-- name: FindIdentityByExternalID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? ` type FindIdentityByExternalIDParams struct { WorkspaceID string `db:"workspace_id"` ExternalID string `db:"external_id"` + Deleted bool `db:"deleted"` } // FindIdentityByExternalID // -// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? +// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? func (q *Queries) FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) { - row := db.QueryRowContext(ctx, findIdentityByExternalID, arg.WorkspaceID, arg.ExternalID) + row := db.QueryRowContext(ctx, findIdentityByExternalID, arg.WorkspaceID, arg.ExternalID, arg.Deleted) var i Identity err := row.Scan( &i.ID, @@ -32,6 +33,7 @@ func (q *Queries) FindIdentityByExternalID(ctx context.Context, db DBTX, arg Fin &i.CreatedAt, &i.UpdatedAt, &i.Meta, + &i.Deleted, ) return i, err } diff --git a/go/pkg/db/identity_find_by_id.sql_generated.go b/go/pkg/db/identity_find_by_id.sql_generated.go index 13e1ef1090..da95728fef 100644 --- a/go/pkg/db/identity_find_by_id.sql_generated.go +++ b/go/pkg/db/identity_find_by_id.sql_generated.go @@ -10,14 +10,19 @@ import ( ) const findIdentityByID = `-- name: FindIdentityByID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? ` +type FindIdentityByIDParams struct { + ID string `db:"id"` + Deleted bool `db:"deleted"` +} + // FindIdentityByID // -// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? -func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, id string) (Identity, error) { - row := db.QueryRowContext(ctx, findIdentityByID, id) +// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? +func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, arg FindIdentityByIDParams) (Identity, error) { + row := db.QueryRowContext(ctx, findIdentityByID, arg.ID, arg.Deleted) var i Identity err := row.Scan( &i.ID, @@ -27,6 +32,7 @@ func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, id string) (Ide &i.CreatedAt, &i.UpdatedAt, &i.Meta, + &i.Deleted, ) return i, err } diff --git a/go/pkg/db/identity_soft_delete.sql_generated.go b/go/pkg/db/identity_soft_delete.sql_generated.go new file mode 100644 index 0000000000..ce48fe84a7 --- /dev/null +++ b/go/pkg/db/identity_soft_delete.sql_generated.go @@ -0,0 +1,22 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: identity_soft_delete.sql + +package db + +import ( + "context" +) + +const softDeleteIdentity = `-- name: SoftDeleteIdentity :exec +UPDATE identities set deleted = 1 WHERE id = ? +` + +// SoftDeleteIdentity +// +// UPDATE identities set deleted = 1 WHERE id = ? +func (q *Queries) SoftDeleteIdentity(ctx context.Context, db DBTX, id string) error { + _, err := db.ExecContext(ctx, softDeleteIdentity, id) + return err +} diff --git a/go/pkg/db/key_find_by_id.sql_generated.go b/go/pkg/db/key_find_by_id.sql_generated.go index 3d46136a63..02e2188a22 100644 --- a/go/pkg/db/key_find_by_id.sql_generated.go +++ b/go/pkg/db/key_find_by_id.sql_generated.go @@ -12,7 +12,7 @@ import ( const findKeyByID = `-- name: FindKeyByID :one SELECT k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta + i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted FROM ` + "`" + `keys` + "`" + ` k LEFT JOIN identities i ON k.identity_id = i.id WHERE k.id = ? @@ -27,7 +27,7 @@ type FindKeyByIDRow struct { // // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, -// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta +// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted // FROM `keys` k // LEFT JOIN identities i ON k.identity_id = i.id // WHERE k.id = ? @@ -65,6 +65,7 @@ func (q *Queries) FindKeyByID(ctx context.Context, db DBTX, id string) (FindKeyB &i.Identity.CreatedAt, &i.Identity.UpdatedAt, &i.Identity.Meta, + &i.Identity.Deleted, ) return i, err } diff --git a/go/pkg/db/key_find_for_verification.sql_generated.go b/go/pkg/db/key_find_for_verification.sql_generated.go index cddce9a3fc..c1bbc365be 100644 --- a/go/pkg/db/key_find_for_verification.sql_generated.go +++ b/go/pkg/db/key_find_for_verification.sql_generated.go @@ -49,7 +49,7 @@ all_ratelimits AS ( ) SELECT k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, + i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, JSON_ARRAYAGG( JSON_OBJECT( 'target_type', rl.target_type, @@ -116,7 +116,7 @@ type FindKeyForVerificationRow struct { // ) // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, -// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, +// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, // JSON_ARRAYAGG( // JSON_OBJECT( // 'target_type', rl.target_type, @@ -169,6 +169,7 @@ func (q *Queries) FindKeyForVerification(ctx context.Context, db DBTX, hash stri &i.Identity.CreatedAt, &i.Identity.UpdatedAt, &i.Identity.Meta, + &i.Identity.Deleted, &i.Ratelimits, &i.Permissions, ) diff --git a/go/pkg/db/models_generated.go b/go/pkg/db/models_generated.go index c554f86a33..ccecdfe585 100644 --- a/go/pkg/db/models_generated.go +++ b/go/pkg/db/models_generated.go @@ -294,6 +294,7 @@ type Identity struct { CreatedAt int64 `db:"created_at"` UpdatedAt sql.NullInt64 `db:"updated_at"` Meta []byte `db:"meta"` + Deleted bool `db:"deleted"` } type Key struct { diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index 7ef1cf0d76..e75f9524b2 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -24,6 +24,10 @@ type Querier interface { // SET deleted_at_m = ? // WHERE id = ? DeleteRatelimitNamespace(ctx context.Context, db DBTX, arg DeleteRatelimitNamespaceParams) (sql.Result, error) + //DeleteRatelimitsByIdentityID + // + // DELETE FROM ratelimits WHERE identity_id = ? + DeleteRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) error //FindApiById // // SELECT id, name, workspace_id, ip_whitelist, auth_type, key_auth_id, created_at_m, updated_at_m, deleted_at_m, delete_protection FROM apis WHERE id = ? @@ -37,12 +41,12 @@ type Querier interface { FindAuditLogTargetById(ctx context.Context, db DBTX, id string) ([]FindAuditLogTargetByIdRow, error) //FindIdentityByExternalID // - // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? + // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) //FindIdentityByID // - // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = ? - FindIdentityByID(ctx context.Context, db DBTX, id string) (Identity, error) + // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? + FindIdentityByID(ctx context.Context, db DBTX, arg FindIdentityByIDParams) (Identity, error) //FindKeyByHash // // SELECT id, key_auth_id, hash, start, workspace_id, for_workspace_id, name, owner_id, identity_id, meta, expires, created_at_m, updated_at_m, deleted_at_m, refill_day, refill_amount, last_refill_at, enabled, remaining_requests, ratelimit_async, ratelimit_limit, ratelimit_duration, environment FROM `keys` WHERE hash = ? @@ -51,7 +55,7 @@ type Querier interface { // // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta + // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted // FROM `keys` k // LEFT JOIN identities i ON k.identity_id = i.id // WHERE k.id = ? @@ -95,7 +99,7 @@ type Querier interface { // ) // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, + // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, // JSON_ARRAYAGG( // JSON_OBJECT( // 'target_type', rl.target_type, @@ -501,6 +505,10 @@ type Querier interface { // ORDER BY w.id ASC // LIMIT 100 ListWorkspaces(ctx context.Context, db DBTX, cursor string) ([]ListWorkspacesRow, error) + //SoftDeleteIdentity + // + // UPDATE identities set deleted = 1 WHERE id = ? + SoftDeleteIdentity(ctx context.Context, db DBTX, id string) error //SoftDeleteRatelimitNamespace // // UPDATE `ratelimit_namespaces` diff --git a/go/pkg/db/queries/identity_find_by_external_id.sql b/go/pkg/db/queries/identity_find_by_external_id.sql index 5d54c23329..1ebb1dc891 100644 --- a/go/pkg/db/queries/identity_find_by_external_id.sql +++ b/go/pkg/db/queries/identity_find_by_external_id.sql @@ -1,2 +1,2 @@ -- name: FindIdentityByExternalID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE workspace_id = ? AND external_id = ? +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ?; diff --git a/go/pkg/db/queries/identity_find_by_id.sql b/go/pkg/db/queries/identity_find_by_id.sql index 18d4d9b507..ac16632a4e 100644 --- a/go/pkg/db/queries/identity_find_by_id.sql +++ b/go/pkg/db/queries/identity_find_by_id.sql @@ -1,2 +1,2 @@ -- name: FindIdentityByID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta FROM identities WHERE id = sqlc.arg(id) +SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = sqlc.arg(id) AND deleted = ?; diff --git a/go/pkg/db/queries/identity_soft_delete.sql b/go/pkg/db/queries/identity_soft_delete.sql new file mode 100644 index 0000000000..4ef0e838cb --- /dev/null +++ b/go/pkg/db/queries/identity_soft_delete.sql @@ -0,0 +1,2 @@ +-- name: SoftDeleteIdentity :exec +UPDATE identities set deleted = 1 WHERE id = sqlc.arg('id') diff --git a/go/pkg/db/queries/ratelimit_delete_by_identity_id.sql b/go/pkg/db/queries/ratelimit_delete_by_identity_id.sql new file mode 100644 index 0000000000..e2d8ca4426 --- /dev/null +++ b/go/pkg/db/queries/ratelimit_delete_by_identity_id.sql @@ -0,0 +1,2 @@ +-- name: DeleteRatelimitsByIdentityID :exec +DELETE FROM ratelimits WHERE identity_id = ?; diff --git a/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go b/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go new file mode 100644 index 0000000000..a9051ccfbd --- /dev/null +++ b/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go @@ -0,0 +1,23 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: ratelimit_delete_by_identity_id.sql + +package db + +import ( + "context" + "database/sql" +) + +const deleteRatelimitsByIdentityID = `-- name: DeleteRatelimitsByIdentityID :exec +DELETE FROM ratelimits WHERE identity_id = ? +` + +// DeleteRatelimitsByIdentityID +// +// DELETE FROM ratelimits WHERE identity_id = ? +func (q *Queries) DeleteRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) error { + _, err := db.ExecContext(ctx, deleteRatelimitsByIdentityID, identityID) + return err +} diff --git a/go/pkg/db/schema.sql b/go/pkg/db/schema.sql index 1b053d1453..b3183f1d85 100644 --- a/go/pkg/db/schema.sql +++ b/go/pkg/db/schema.sql @@ -1,307 +1,306 @@ CREATE TABLE `apis` ( - `id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `ip_whitelist` varchar(512), - `auth_type` enum('key','jwt'), - `key_auth_id` varchar(256), - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - `delete_protection` boolean DEFAULT false, - CONSTRAINT `apis_id` PRIMARY KEY(`id`), - CONSTRAINT `apis_key_auth_id_unique` UNIQUE(`key_auth_id`) -); + `id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `ip_whitelist` varchar(512) DEFAULT NULL, + `auth_type` enum('key','jwt') DEFAULT NULL, + `key_auth_id` varchar(256) DEFAULT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + `delete_protection` tinyint(1) DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `apis_key_auth_id_unique` (`key_auth_id`), + KEY `workspace_id_idx` (`workspace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `keys_permissions` ( - `temp_id` bigint AUTO_INCREMENT NOT NULL, - `key_id` varchar(256) NOT NULL, - `permission_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - CONSTRAINT `keys_permissions_key_id_permission_id_workspace_id` PRIMARY KEY(`key_id`,`permission_id`,`workspace_id`), - CONSTRAINT `keys_permissions_temp_id_unique` UNIQUE(`temp_id`), - CONSTRAINT `key_id_permission_id_idx` UNIQUE(`key_id`,`permission_id`) -); +CREATE TABLE `audit_log` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', + `bucket_id` varchar(256) NOT NULL, + `event` varchar(256) NOT NULL, + `time` bigint NOT NULL, + `display` varchar(256) NOT NULL, + `remote_ip` varchar(256) DEFAULT NULL, + `user_agent` varchar(256) DEFAULT NULL, + `actor_type` varchar(256) NOT NULL, + `actor_id` varchar(256) NOT NULL, + `actor_name` varchar(256) DEFAULT NULL, + `actor_meta` json DEFAULT NULL, + `created_at` bigint NOT NULL, + `updated_at` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `workspace_id_idx` (`workspace_id`), + KEY `bucket_id_idx` (`bucket_id`), + KEY `bucket_idx` (`bucket`), + KEY `event_idx` (`event`), + KEY `actor_id_idx` (`actor_id`), + KEY `time_idx` (`time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `keys_roles` ( - `key_id` varchar(256) NOT NULL, - `role_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - CONSTRAINT `keys_roles_role_id_key_id_workspace_id` PRIMARY KEY(`role_id`,`key_id`,`workspace_id`), - CONSTRAINT `unique_key_id_role_id` UNIQUE(`key_id`,`role_id`) -); +CREATE TABLE `audit_log_bucket` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `retention_days` int DEFAULT NULL, + `created_at` bigint NOT NULL, + `updated_at` bigint DEFAULT NULL, + `delete_protection` tinyint(1) DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `unique_name_per_workspace_idx` (`workspace_id`,`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `permissions` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `description` varchar(512), - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - CONSTRAINT `permissions_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) -); +CREATE TABLE `audit_log_target` ( + `workspace_id` varchar(256) NOT NULL, + `bucket_id` varchar(256) NOT NULL, + `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', + `audit_log_id` varchar(256) NOT NULL, + `display_name` varchar(256) NOT NULL, + `type` varchar(256) NOT NULL, + `id` varchar(256) NOT NULL, + `name` varchar(256) DEFAULT NULL, + `meta` json DEFAULT NULL, + `created_at` bigint NOT NULL, + `updated_at` bigint DEFAULT NULL, + PRIMARY KEY (`audit_log_id`,`id`), + KEY `bucket` (`bucket`), + KEY `audit_log_id` (`audit_log_id`), + KEY `id_idx` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `roles` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `description` varchar(512), - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - CONSTRAINT `roles_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) -); +CREATE TABLE `encrypted_keys` ( + `workspace_id` varchar(256) NOT NULL, + `key_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL DEFAULT '0', + `updated_at` bigint DEFAULT NULL, + `encrypted` varchar(1024) NOT NULL, + `encryption_key_id` varchar(256) NOT NULL, + UNIQUE KEY `key_id_idx` (`key_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `roles_permissions` ( - `role_id` varchar(256) NOT NULL, - `permission_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - CONSTRAINT `roles_permissions_role_id_permission_id_workspace_id` PRIMARY KEY(`role_id`,`permission_id`,`workspace_id`), - CONSTRAINT `unique_tuple_permission_id_role_id` UNIQUE(`permission_id`,`role_id`) -); +CREATE TABLE `identities` ( + `id` varchar(256) NOT NULL, + `external_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `environment` varchar(256) NOT NULL DEFAULT 'default', + `created_at` bigint NOT NULL, + `updated_at` bigint DEFAULT NULL, + `meta` json DEFAULT NULL, + `deleted` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `workspace_id_external_id_deleted_idx` (`workspace_id`,`external_id`,`deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `key_auth` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - `store_encrypted_keys` boolean NOT NULL DEFAULT false, - `default_prefix` varchar(8), - `default_bytes` int DEFAULT 16, - `size_approx` int NOT NULL DEFAULT 0, - `size_last_updated_at` bigint NOT NULL DEFAULT 0, - CONSTRAINT `key_auth_id` PRIMARY KEY(`id`) -); + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + `store_encrypted_keys` tinyint(1) NOT NULL DEFAULT '0', + `default_prefix` varchar(8) DEFAULT NULL, + `default_bytes` int DEFAULT '16', + `size_approx` int NOT NULL DEFAULT '0', + `size_last_updated_at` bigint NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `encrypted_keys` ( - `workspace_id` varchar(256) NOT NULL, - `key_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL DEFAULT 0, - `updated_at` bigint, - `encrypted` varchar(1024) NOT NULL, - `encryption_key_id` varchar(256) NOT NULL, - CONSTRAINT `key_id_idx` UNIQUE(`key_id`) -); +CREATE TABLE `key_migration_errors` ( + `id` varchar(256) NOT NULL, + `migration_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `message` json NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `keys` ( - `id` varchar(256) NOT NULL, - `key_auth_id` varchar(256) NOT NULL, - `hash` varchar(256) NOT NULL, - `start` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `for_workspace_id` varchar(256), - `name` varchar(256), - `owner_id` varchar(256), - `identity_id` varchar(256), - `meta` text, - `expires` datetime(3), - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - `refill_day` tinyint, - `refill_amount` int, - `last_refill_at` datetime(3), - `enabled` boolean NOT NULL DEFAULT true, - `remaining_requests` int, - `ratelimit_async` boolean, - `ratelimit_limit` int, - `ratelimit_duration` bigint, - `environment` varchar(256), - CONSTRAINT `keys_id` PRIMARY KEY(`id`), - CONSTRAINT `hash_idx` UNIQUE(`hash`) -); - -CREATE TABLE `vercel_bindings` ( - `id` varchar(256) NOT NULL, - `integration_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `project_id` varchar(256) NOT NULL, - `environment` enum('development','preview','production') NOT NULL, - `resource_id` varchar(256) NOT NULL, - `resource_type` enum('rootKey','apiId') NOT NULL, - `vercel_env_id` varchar(256) NOT NULL, - `last_edited_by` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - CONSTRAINT `vercel_bindings_id` PRIMARY KEY(`id`), - CONSTRAINT `project_environment_resource_type_idx` UNIQUE(`project_id`,`environment`,`resource_type`) -); + `id` varchar(256) NOT NULL, + `key_auth_id` varchar(256) NOT NULL, + `hash` varchar(256) NOT NULL, + `start` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `for_workspace_id` varchar(256) DEFAULT NULL, + `name` varchar(256) DEFAULT NULL, + `owner_id` varchar(256) DEFAULT NULL, + `identity_id` varchar(256) DEFAULT NULL, + `meta` text, + `expires` datetime(3) DEFAULT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + `refill_day` tinyint DEFAULT NULL, + `refill_amount` int DEFAULT NULL, + `last_refill_at` datetime(3) DEFAULT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `remaining_requests` int DEFAULT NULL, + `ratelimit_async` tinyint(1) DEFAULT NULL, + `ratelimit_limit` int DEFAULT NULL, + `ratelimit_duration` bigint DEFAULT NULL, + `environment` varchar(256) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `hash_idx` (`hash`), + KEY `key_auth_id_deleted_at_idx` (`key_auth_id`,`deleted_at_m`), + KEY `idx_keys_on_for_workspace_id` (`for_workspace_id`), + KEY `owner_id_idx` (`owner_id`), + KEY `identity_id_idx` (`identity_id`), + KEY `deleted_at_idx` (`deleted_at_m`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `vercel_integrations` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `team_id` varchar(256), - `access_token` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - CONSTRAINT `vercel_integrations_id` PRIMARY KEY(`id`) -); +CREATE TABLE `keys_permissions` ( + `temp_id` bigint NOT NULL AUTO_INCREMENT, + `key_id` varchar(256) NOT NULL, + `permission_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`key_id`,`permission_id`,`workspace_id`), + UNIQUE KEY `keys_permissions_temp_id_unique` (`temp_id`), + UNIQUE KEY `key_id_permission_id_idx` (`key_id`,`permission_id`) +) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `ratelimit_namespaces` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - CONSTRAINT `ratelimit_namespaces_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) -); +CREATE TABLE `keys_roles` ( + `key_id` varchar(256) NOT NULL, + `role_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`role_id`,`key_id`,`workspace_id`), + UNIQUE KEY `unique_key_id_role_id` (`key_id`,`role_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `ratelimit_overrides` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `namespace_id` varchar(256) NOT NULL, - `identifier` varchar(512) NOT NULL, - `limit` int NOT NULL, - `duration` int NOT NULL, - `async` boolean, - `sharding` enum('edge'), - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - CONSTRAINT `ratelimit_overrides_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_identifier_per_namespace_idx` UNIQUE(`identifier`,`namespace_id`) -); +CREATE TABLE `permissions` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`), + KEY `workspace_id_idx` (`workspace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `workspaces` ( - `id` varchar(256) NOT NULL, - `org_id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `plan` enum('free','pro','enterprise') DEFAULT 'free', - `tier` varchar(256) DEFAULT 'Free', - `stripe_customer_id` varchar(256), - `stripe_subscription_id` varchar(256), - `beta_features` json NOT NULL, - `features` json NOT NULL, - `subscriptions` json, - `enabled` boolean NOT NULL DEFAULT true, - `delete_protection` boolean DEFAULT false, - `created_at_m` bigint NOT NULL DEFAULT 0, - `updated_at_m` bigint, - `deleted_at_m` bigint, - CONSTRAINT `workspaces_id` PRIMARY KEY(`id`), - CONSTRAINT `workspaces_org_id_unique` UNIQUE(`org_id`) -); +CREATE TABLE `quota` ( + `workspace_id` varchar(256) NOT NULL, + `requests_per_month` bigint NOT NULL DEFAULT '0', + `logs_retention_days` int NOT NULL DEFAULT '0', + `audit_logs_retention_days` int NOT NULL DEFAULT '0', + `team` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`workspace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `key_migration_errors` ( - `id` varchar(256) NOT NULL, - `migration_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `message` json NOT NULL, - CONSTRAINT `key_migration_errors_id` PRIMARY KEY(`id`) -); +CREATE TABLE `ratelimit_namespaces` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `identities` ( - `id` varchar(256) NOT NULL, - `external_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `environment` varchar(256) NOT NULL DEFAULT 'default', - `created_at` bigint NOT NULL, - `updated_at` bigint, - `meta` json, - CONSTRAINT `identities_id` PRIMARY KEY(`id`), - CONSTRAINT `external_id_workspace_id_idx` UNIQUE(`external_id`,`workspace_id`) -); +CREATE TABLE `ratelimit_overrides` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `namespace_id` varchar(256) NOT NULL, + `identifier` varchar(512) NOT NULL, + `limit` int NOT NULL, + `duration` int NOT NULL, + `async` tinyint(1) DEFAULT NULL, + `sharding` enum('edge') DEFAULT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_identifier_per_namespace_idx` (`identifier`,`namespace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `ratelimits` ( - `id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL, - `updated_at` bigint, - `key_id` varchar(256), - `identity_id` varchar(256), - `limit` int NOT NULL, - `duration` bigint NOT NULL, - CONSTRAINT `ratelimits_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_name_idx` UNIQUE(`name`,`key_id`,`identity_id`) -); + `id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL, + `updated_at` bigint DEFAULT NULL, + `key_id` varchar(256) DEFAULT NULL, + `identity_id` varchar(256) DEFAULT NULL, + `limit` int NOT NULL, + `duration` bigint NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_name_idx` (`name`,`key_id`,`identity_id`), + KEY `name_idx` (`name`), + KEY `identity_id_idx` (`identity_id`), + KEY `key_id_idx` (`key_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `quota` ( - `workspace_id` varchar(256) NOT NULL, - `requests_per_month` bigint NOT NULL DEFAULT 0, - `logs_retention_days` int NOT NULL DEFAULT 0, - `audit_logs_retention_days` int NOT NULL DEFAULT 0, - `team` boolean NOT NULL DEFAULT false, - CONSTRAINT `quota_workspace_id` PRIMARY KEY(`workspace_id`) -); +CREATE TABLE `roles` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `description` varchar(512) DEFAULT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`), + KEY `workspace_id_idx` (`workspace_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `audit_log` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', - `bucket_id` varchar(256) NOT NULL, - `event` varchar(256) NOT NULL, - `time` bigint NOT NULL, - `display` varchar(256) NOT NULL, - `remote_ip` varchar(256), - `user_agent` varchar(256), - `actor_type` varchar(256) NOT NULL, - `actor_id` varchar(256) NOT NULL, - `actor_name` varchar(256), - `actor_meta` json, - `created_at` bigint NOT NULL, - `updated_at` bigint, - CONSTRAINT `audit_log_id` PRIMARY KEY(`id`) -); +CREATE TABLE `roles_permissions` ( + `role_id` varchar(256) NOT NULL, + `permission_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`role_id`,`permission_id`,`workspace_id`), + UNIQUE KEY `unique_tuple_permission_id_role_id` (`permission_id`,`role_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `audit_log_bucket` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `retention_days` int, - `created_at` bigint NOT NULL, - `updated_at` bigint, - `delete_protection` boolean DEFAULT false, - CONSTRAINT `audit_log_bucket_id` PRIMARY KEY(`id`), - CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`workspace_id`,`name`) -); +CREATE TABLE `vercel_bindings` ( + `id` varchar(256) NOT NULL, + `integration_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `project_id` varchar(256) NOT NULL, + `environment` enum('development','preview','production') NOT NULL, + `resource_id` varchar(256) NOT NULL, + `resource_type` enum('rootKey','apiId') NOT NULL, + `vercel_env_id` varchar(256) NOT NULL, + `last_edited_by` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `project_environment_resource_type_idx` (`project_id`,`environment`,`resource_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE TABLE `audit_log_target` ( - `workspace_id` varchar(256) NOT NULL, - `bucket_id` varchar(256) NOT NULL, - `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', - `audit_log_id` varchar(256) NOT NULL, - `display_name` varchar(256) NOT NULL, - `type` varchar(256) NOT NULL, - `id` varchar(256) NOT NULL, - `name` varchar(256), - `meta` json, - `created_at` bigint NOT NULL, - `updated_at` bigint, - CONSTRAINT `audit_log_target_audit_log_id_id_pk` PRIMARY KEY(`audit_log_id`,`id`) -); +CREATE TABLE `vercel_integrations` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `team_id` varchar(256) DEFAULT NULL, + `access_token` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -CREATE INDEX `workspace_id_idx` ON `apis` (`workspace_id`); -CREATE INDEX `workspace_id_idx` ON `permissions` (`workspace_id`); -CREATE INDEX `workspace_id_idx` ON `roles` (`workspace_id`); -CREATE INDEX `key_auth_id_deleted_at_idx` ON `keys` (`key_auth_id`,`deleted_at_m`); -CREATE INDEX `idx_keys_on_for_workspace_id` ON `keys` (`for_workspace_id`); -CREATE INDEX `owner_id_idx` ON `keys` (`owner_id`); -CREATE INDEX `identity_id_idx` ON `keys` (`identity_id`); -CREATE INDEX `deleted_at_idx` ON `keys` (`deleted_at_m`); -CREATE INDEX `workspace_id_idx` ON `identities` (`workspace_id`); -CREATE INDEX `name_idx` ON `ratelimits` (`name`); -CREATE INDEX `identity_id_idx` ON `ratelimits` (`identity_id`); -CREATE INDEX `key_id_idx` ON `ratelimits` (`key_id`); -CREATE INDEX `workspace_id_idx` ON `audit_log` (`workspace_id`); -CREATE INDEX `bucket_id_idx` ON `audit_log` (`bucket_id`); -CREATE INDEX `bucket_idx` ON `audit_log` (`bucket`); -CREATE INDEX `event_idx` ON `audit_log` (`event`); -CREATE INDEX `actor_id_idx` ON `audit_log` (`actor_id`); -CREATE INDEX `time_idx` ON `audit_log` (`time`); -CREATE INDEX `bucket` ON `audit_log_target` (`bucket`); -CREATE INDEX `audit_log_id` ON `audit_log_target` (`audit_log_id`); -CREATE INDEX `id_idx` ON `audit_log_target` (`id`); +CREATE TABLE `workspaces` ( + `id` varchar(256) NOT NULL, + `org_id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `plan` enum('free','pro','enterprise') DEFAULT 'free', + `tier` varchar(256) DEFAULT 'Free', + `stripe_customer_id` varchar(256) DEFAULT NULL, + `stripe_subscription_id` varchar(256) DEFAULT NULL, + `beta_features` json NOT NULL, + `features` json NOT NULL, + `subscriptions` json DEFAULT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `delete_protection` tinyint(1) DEFAULT '0', + `created_at_m` bigint NOT NULL DEFAULT '0', + `updated_at_m` bigint DEFAULT NULL, + `deleted_at_m` bigint DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `workspaces_org_id_unique` (`org_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/internal/db/src/schema/identity.ts b/internal/db/src/schema/identity.ts index e18b88a271..fdc666ad98 100644 --- a/internal/db/src/schema/identity.ts +++ b/internal/db/src/schema/identity.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm"; -import { bigint, boolean, index, int, json, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"; +import { bigint, boolean, index, int, json, mysqlTable, uniqueIndex, varchar, tinyint } from "drizzle-orm/mysql-core"; import { keys } from "./keys"; import { lifecycleDates } from "./util/lifecycle_dates"; import { workspaces } from "./workspaces"; @@ -16,7 +16,7 @@ export const identities = mysqlTable( workspaceId: varchar("workspace_id", { length: 256 }).notNull(), environment: varchar("environment", { length: 256 }).notNull().default("default"), meta: json("meta").$type>(), - deleted: boolean("deleted").default(false), + deleted: tinyint("deleted", { unsigned: true }).notNull().default(0), ...lifecycleDates, }, (table) => ({ From 2ce6beaf71fdb6ef7089c668f4d4fd3236f977b9 Mon Sep 17 00:00:00 2001 From: chronark Date: Wed, 23 Apr 2025 11:47:17 +0200 Subject: [PATCH 17/17] chore: clean up --- go/apps/api/openapi/openapi.json | 8 +- .../v2_identities_create_identity/200_test.go | 9 +- .../v2_identities_create_identity/409_test.go | 2 +- .../v2_identities_create_identity/handler.go | 10 +- .../v2_identities_delete_identity/200_test.go | 3 +- .../v2_identities_delete_identity/handler.go | 87 ++- .../v2_ratelimit_get_override/handler.go | 45 +- go/pkg/codes/constants_gen.go | 2 +- go/pkg/db/api_find_by_id.sql_generated.go | 2 +- go/pkg/db/api_insert.sql_generated.go | 2 +- ...dit_log_find_target_by_id.sql_generated.go | 2 +- go/pkg/db/audit_log_insert.sql_generated.go | 2 +- .../audit_log_target_insert.sql_generated.go | 2 +- go/pkg/db/identity_delete.sql_generated.go | 2 +- ...ntity_find_by_external_id.sql_generated.go | 10 +- .../db/identity_find_by_id.sql_generated.go | 10 +- ...ity_find_ratelimits_by_id.sql_generated.go | 24 +- go/pkg/db/identity_insert.sql_generated.go | 2 +- ...identity_insert_ratelimit.sql_generated.go | 2 +- .../db/identity_soft_delete.sql_generated.go | 2 +- go/pkg/db/key_find_by_hash.sql_generated.go | 2 +- go/pkg/db/key_find_by_id.sql_generated.go | 10 +- ...key_find_for_verification.sql_generated.go | 10 +- go/pkg/db/key_insert.sql_generated.go | 2 +- go/pkg/db/keyring_find_by_id.sql_generated.go | 2 +- go/pkg/db/keyring_insert.sql_generated.go | 2 +- go/pkg/db/models_generated.go | 6 +- ...ind_by_workspace_and_name.sql_generated.go | 2 +- go/pkg/db/permission_insert.sql_generated.go | 2 +- ...ion_insert_key_permission.sql_generated.go | 2 +- .../db/permissions_by_key_id.sql_generated.go | 2 +- go/pkg/db/querier_generated.go | 14 +- .../queries/identity_find_by_external_id.sql | 2 +- go/pkg/db/queries/identity_find_by_id.sql | 2 +- .../identity_find_ratelimits_by_id.sql | 2 +- ...mit_delete_by_identity_id.sql_generated.go | 2 +- .../db/ratelimit_delete_many.sql_generated.go | 2 +- ...atelimit_namespace_delete.sql_generated.go | 2 +- ...imit_namespace_find_by_id.sql_generated.go | 2 +- ...it_namespace_find_by_name.sql_generated.go | 2 +- ...atelimit_namespace_insert.sql_generated.go | 2 +- ...mit_namespace_soft_delete.sql_generated.go | 2 +- ...limit_override_find_by_id.sql_generated.go | 2 +- ...erride_find_by_identifier.sql_generated.go | 2 +- ...mit_override_find_matches.sql_generated.go | 2 +- ...ratelimit_override_insert.sql_generated.go | 2 +- ...ride_list_by_namespace_id.sql_generated.go | 2 +- ...imit_override_soft_delete.sql_generated.go | 2 +- ...ratelimit_override_update.sql_generated.go | 2 +- go/pkg/db/schema.sql | 565 +++++++++--------- .../db/workspace_find_by_id.sql_generated.go | 2 +- .../db/workspace_hard_delete.sql_generated.go | 2 +- go/pkg/db/workspace_insert.sql_generated.go | 2 +- .../db/workspace_soft_delete.sql_generated.go | 2 +- .../workspace_update_enabled.sql_generated.go | 2 +- .../db/workspace_update_plan.sql_generated.go | 2 +- go/pkg/db/workspaces_list.sql_generated.go | 2 +- go/pkg/fault/dst_test.go | 2 + go/pkg/testutil/seed/seed.go | 3 - ...nless_vargas.sql => 0000_fat_the_hand.sql} | 6 +- internal/db/drizzle/meta/0000_snapshot.json | 35 +- internal/db/drizzle/meta/_journal.json | 4 +- internal/db/src/schema/identity.ts | 13 +- 63 files changed, 521 insertions(+), 439 deletions(-) rename internal/db/drizzle/{0000_motionless_vargas.sql => 0000_fat_the_hand.sql} (98%) diff --git a/go/apps/api/openapi/openapi.json b/go/apps/api/openapi/openapi.json index 9ed0c5c473..e1e3c815f9 100644 --- a/go/apps/api/openapi/openapi.json +++ b/go/apps/api/openapi/openapi.json @@ -673,13 +673,7 @@ "minimum": 0 } }, - "required": [ - "namespaceId", - "overrideId", - "duration", - "identifier", - "limit" - ] + "required": ["namespaceId", "overrideId", "duration", "identifier", "limit"] } } }, diff --git a/go/apps/api/routes/v2_identities_create_identity/200_test.go b/go/apps/api/routes/v2_identities_create_identity/200_test.go index 01f902a146..0b4439e686 100644 --- a/go/apps/api/routes/v2_identities_create_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_create_identity/200_test.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "net/http" - "slices" "testing" "time" @@ -185,7 +184,13 @@ func TestCreateIdentitySuccessfully(t *testing.T) { require.Len(t, rateLimits, len(identityRateLimits)) for _, ratelimit := range identityRateLimits { - idx := slices.IndexFunc(rateLimits, func(c db.FindRatelimitsByIdentityIDRow) bool { return c.Name == ratelimit.Name }) + idx := -1 + for i, limit := range rateLimits { + if limit.Name == ratelimit.Name { + idx = i + break + } + } require.True(t, idx >= 0 && idx < len(rateLimits), "Rate limit with name %s not found in the database", ratelimit.Name) require.Equal(t, rateLimits[idx].Duration, ratelimit.Duration) diff --git a/go/apps/api/routes/v2_identities_create_identity/409_test.go b/go/apps/api/routes/v2_identities_create_identity/409_test.go index 2ad497ce17..9065e21f05 100644 --- a/go/apps/api/routes/v2_identities_create_identity/409_test.go +++ b/go/apps/api/routes/v2_identities_create_identity/409_test.go @@ -40,7 +40,7 @@ func TestCreateIdentityDuplicate(t *testing.T) { require.NotEmpty(t, successRes.Body.Data.IdentityId, successRes.Body) errorRes := testutil.CallRoute[handler.Request, openapi.ConflictErrorResponse](h, route, headers, req) - require.Equal(t, 409, errorRes.Status, "expected 409, received: %#v", errorRes) + require.Equal(t, 409, errorRes.Status, "expected 409, received: %s", errorRes.RawBody) require.NotNil(t, errorRes.Body) require.Equal(t, "https://unkey.com/docs/api-reference/errors-v2/unkey/data/identity_already_exists", errorRes.Body.Error.Type) }) diff --git a/go/apps/api/routes/v2_identities_create_identity/handler.go b/go/apps/api/routes/v2_identities_create_identity/handler.go index 3c3203d391..659362d518 100644 --- a/go/apps/api/routes/v2_identities_create_identity/handler.go +++ b/go/apps/api/routes/v2_identities_create_identity/handler.go @@ -117,14 +117,20 @@ func New(svc Services) zen.Route { }() identityID := uid.New(uid.IdentityPrefix) - err = db.Query.InsertIdentity(ctx, tx, db.InsertIdentityParams{ + args := db.InsertIdentityParams{ ID: identityID, ExternalID: req.ExternalId, WorkspaceID: auth.AuthorizedWorkspaceID, Environment: "default", CreatedAt: time.Now().UnixMilli(), Meta: meta, - }) + } + svc.Logger.Warn("inserting identity", + "args", args, + ) + err = db.Query.InsertIdentity(ctx, tx, args) + + svc.Logger.Error("insert identity failed", "requestId", s.RequestID(), "error", err) if err != nil { if db.IsDuplicateKeyError(err) { return fault.Wrap(err, diff --git a/go/apps/api/routes/v2_identities_delete_identity/200_test.go b/go/apps/api/routes/v2_identities_delete_identity/200_test.go index 3b5a7dd87d..3d6e887bcd 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/200_test.go +++ b/go/apps/api/routes/v2_identities_delete_identity/200_test.go @@ -179,8 +179,9 @@ func TestDeleteIdentitySuccessfully(t *testing.T) { }) require.Equal(t, sql.ErrNoRows, err) + // The old ratelimits still exist, while the identity is soft deleted ratelimits, err := db.Query.FindRatelimitsByIdentityID(ctx, h.DB.RO(), sql.NullString{String: newIdentity.ID, Valid: true}) require.NoError(t, err) - require.Len(t, ratelimits, 0) + require.Len(t, ratelimits, 2) }) } diff --git a/go/apps/api/routes/v2_identities_delete_identity/handler.go b/go/apps/api/routes/v2_identities_delete_identity/handler.go index 7cdc007bdd..a754c6b4a2 100644 --- a/go/apps/api/routes/v2_identities_delete_identity/handler.go +++ b/go/apps/api/routes/v2_identities_delete_identity/handler.go @@ -1,3 +1,68 @@ +// Package handler implements the API endpoint for deleting an identity in the Unkey system. +// +// OVERVIEW: +// This handler implements the POST /v2/identities.deleteIdentity endpoint which allows +// authorized users to delete identities from the system. The deletion is performed as a +// soft delete to maintain data integrity and audit history. +// +// FLOW DIAGRAM: +// +// +----------------+ +-------------+ +----------------+ +--------------+ +// | Verify Key |---->| Check Perms |---->| Get Identity |---->| Begin Tx | +// +----------------+ +-------------+ +----------------+ +--------------+ +// | +// v +// +----------------+ +-------------+ +----------------+ +--------------+ +// | Return 200 |<----| Commit Tx |<----| Create Audits |<----| Soft Delete | +// +----------------+ +-------------+ +----------------+ +--------------+ +// +// DETAILED PROCESS: +// 1. Authentication: Verifies the root key for API access +// 2. Permission Verification: Checks if the key has permission to delete identities +// - Checks for general identity deletion permission (*) +// - Checks for specific identity deletion permission if ID provided +// +// 3. Identity Retrieval: Gets the identity by either: +// +// +---------------+ +-----------------------+ +// | Identity ID |---->| FindIdentityByID | +// +---------------+ +-----------------------+ +// +---------------+ +-----------------------+ +// | External ID |---->| FindIdentityByExtID | +// +---------------+ +-----------------------+ +// +// 4. Soft Deletion Process: +// +// +----------------+ +// | Soft Delete | +// +--------+-------+ +// | +// v +// +---------------------------+ +------------------------+ +// | Duplicate Key Error? |--Yes->| Delete Old Soft- | +// +-----------------+---------+ | Deleted Identity | +// | +----------+-------------+ +// No | +// | | +// v v +// +--------------------------+ +------------------------+ +// | Create Audit Logs |<-----| Retry Soft Delete | +// +---------------------------+ +------------------------+ +// +// 5. Audit Logging: Creates logs for: +// - The deleted identity +// - Any rate limits associated with the identity +// +// 6. Transaction Management: +// - All database operations are wrapped in a transaction +// - Rollback occurs automatically if any operation fails +// - Commit only happens after all operations succeed +// +// ERROR HANDLING: +// - Authentication failures result in auth errors +// - Permission failures result in authorization errors +// - Database errors are wrapped with appropriate error codes and descriptions +// - Not Found errors are returned when identity doesn't exist or belongs to wrong workspace package handler import ( @@ -118,16 +183,10 @@ func New(svc Services) zen.Route { }() err = db.Query.SoftDeleteIdentity(ctx, tx, identity.ID) - if err != nil && !db.IsDuplicateKeyError(err) { - return fault.Wrap(err, - fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to soft delete identity", "Failed to delete Identity."), - ) - } // If we hit a duplicate key error, we know that we have an identity that was already soft deleted // so we can hard delete the "old" deleted version - if err != nil && db.IsDuplicateKeyError(err) { + if db.IsDuplicateKeyError(err) { err = deleteOldIdentity(ctx, tx, auth.AuthorizedWorkspaceID, identity.ExternalID) if err != nil { return err @@ -135,12 +194,14 @@ func New(svc Services) zen.Route { // Re-apply the soft delete operation err = db.Query.SoftDeleteIdentity(ctx, tx, identity.ID) - if err != nil && !db.IsDuplicateKeyError(err) { - return fault.Wrap(err, - fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to soft delete identity", "Failed to delete Identity."), - ) - } + + } + if err != nil { + + return fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to soft delete identity", "Failed to delete Identity."), + ) } auditLogs := []auditlog.AuditLog{ diff --git a/go/apps/api/routes/v2_ratelimit_get_override/handler.go b/go/apps/api/routes/v2_ratelimit_get_override/handler.go index 6ea9fb4095..43d63eca95 100644 --- a/go/apps/api/routes/v2_ratelimit_get_override/handler.go +++ b/go/apps/api/routes/v2_ratelimit_get_override/handler.go @@ -43,17 +43,9 @@ func New(svc Services) zen.Route { namespace, err := getNamespace(ctx, svc, auth.AuthorizedWorkspaceID, req) - if db.IsNotFound(err) { - return fault.New("namespace not found", - fault.WithCode(codes.Data.RatelimitNamespace.NotFound.URN()), - fault.WithDesc("namespace not found", "This namespace does not exist."), - ) - } if err != nil { - return fault.Wrap(err, - fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), - fault.WithDesc("database failed to find the ratelimit namespace", "Error finding the ratelimit namespace."), - ) + // already handled correctly in getNamespace + return err } if namespace.WorkspaceID != auth.AuthorizedWorkspaceID { @@ -127,23 +119,42 @@ func New(svc Services) zen.Route { }) } -func getNamespace(ctx context.Context, svc Services, workspaceID string, req Request) (db.RatelimitNamespace, error) { +func getNamespace(ctx context.Context, svc Services, workspaceID string, req Request) (namespace db.RatelimitNamespace, err error) { + switch { case req.NamespaceId != nil: { - return db.Query.FindRatelimitNamespaceByID(ctx, svc.DB.RO(), *req.NamespaceId) + namespace, err = db.Query.FindRatelimitNamespaceByID(ctx, svc.DB.RO(), *req.NamespaceId) + break } case req.NamespaceName != nil: { - return db.Query.FindRatelimitNamespaceByName(ctx, svc.DB.RO(), db.FindRatelimitNamespaceByNameParams{ + namespace, err = db.Query.FindRatelimitNamespaceByName(ctx, svc.DB.RO(), db.FindRatelimitNamespaceByNameParams{ WorkspaceID: workspaceID, Name: *req.NamespaceName, }) + break } + default: + return db.RatelimitNamespace{}, fault.New("namespace id or name required", + fault.WithCode(codes.App.Validation.InvalidInput.URN()), + fault.WithDesc("namespace id or name required", "You must provide either a namespace ID or name."), + ) } - return db.RatelimitNamespace{}, fault.New("missing namespace id or name", - fault.WithCode(codes.App.Validation.InvalidInput.URN()), - fault.WithDesc("missing namespace id or name", "You must provide either a namespace ID or name."), - ) + if err != nil { + + if db.IsNotFound(err) { + return db.RatelimitNamespace{}, fault.New("namespace not found", + fault.WithCode(codes.Data.RatelimitNamespace.NotFound.URN()), + fault.WithDesc("namespace not found", "The namespace was not found."), + ) + } + + return db.RatelimitNamespace{}, fault.Wrap(err, + fault.WithCode(codes.App.Internal.ServiceUnavailable.URN()), + fault.WithDesc("database failed to find the namespace", "Error finding the ratelimit namespace."), + ) + } + return namespace, nil } diff --git a/go/pkg/codes/constants_gen.go b/go/pkg/codes/constants_gen.go index e3ec51fe7f..b172147f1f 100644 --- a/go/pkg/codes/constants_gen.go +++ b/go/pkg/codes/constants_gen.go @@ -1,5 +1,5 @@ // Code generated by generate.go; DO NOT EDIT. -// Generated at: 2025-04-22T21:41:07+02:00 +// Generated at: 2025-04-23T11:47:05+02:00 package codes diff --git a/go/pkg/db/api_find_by_id.sql_generated.go b/go/pkg/db/api_find_by_id.sql_generated.go index b4c5392d03..a8c87eaf93 100644 --- a/go/pkg/db/api_find_by_id.sql_generated.go +++ b/go/pkg/db/api_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: api_find_by_id.sql package db diff --git a/go/pkg/db/api_insert.sql_generated.go b/go/pkg/db/api_insert.sql_generated.go index f3979a099d..a71d448966 100644 --- a/go/pkg/db/api_insert.sql_generated.go +++ b/go/pkg/db/api_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: api_insert.sql package db diff --git a/go/pkg/db/audit_log_find_target_by_id.sql_generated.go b/go/pkg/db/audit_log_find_target_by_id.sql_generated.go index 0a637d7d02..7d38ff42d8 100644 --- a/go/pkg/db/audit_log_find_target_by_id.sql_generated.go +++ b/go/pkg/db/audit_log_find_target_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: audit_log_find_target_by_id.sql package db diff --git a/go/pkg/db/audit_log_insert.sql_generated.go b/go/pkg/db/audit_log_insert.sql_generated.go index a286899335..5d40a500ed 100644 --- a/go/pkg/db/audit_log_insert.sql_generated.go +++ b/go/pkg/db/audit_log_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: audit_log_insert.sql package db diff --git a/go/pkg/db/audit_log_target_insert.sql_generated.go b/go/pkg/db/audit_log_target_insert.sql_generated.go index e103aa9b1c..8ed952b300 100644 --- a/go/pkg/db/audit_log_target_insert.sql_generated.go +++ b/go/pkg/db/audit_log_target_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: audit_log_target_insert.sql package db diff --git a/go/pkg/db/identity_delete.sql_generated.go b/go/pkg/db/identity_delete.sql_generated.go index 65f50679b9..412703effa 100644 --- a/go/pkg/db/identity_delete.sql_generated.go +++ b/go/pkg/db/identity_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_delete.sql package db diff --git a/go/pkg/db/identity_find_by_external_id.sql_generated.go b/go/pkg/db/identity_find_by_external_id.sql_generated.go index 0552491ae0..465f6a6ff3 100644 --- a/go/pkg/db/identity_find_by_external_id.sql_generated.go +++ b/go/pkg/db/identity_find_by_external_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_find_by_external_id.sql package db @@ -10,7 +10,7 @@ import ( ) const findIdentityByExternalID = `-- name: FindIdentityByExternalID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? +SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? ` type FindIdentityByExternalIDParams struct { @@ -21,7 +21,7 @@ type FindIdentityByExternalIDParams struct { // FindIdentityByExternalID // -// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? +// SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? func (q *Queries) FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) { row := db.QueryRowContext(ctx, findIdentityByExternalID, arg.WorkspaceID, arg.ExternalID, arg.Deleted) var i Identity @@ -30,10 +30,10 @@ func (q *Queries) FindIdentityByExternalID(ctx context.Context, db DBTX, arg Fin &i.ExternalID, &i.WorkspaceID, &i.Environment, - &i.CreatedAt, - &i.UpdatedAt, &i.Meta, &i.Deleted, + &i.CreatedAt, + &i.UpdatedAt, ) return i, err } diff --git a/go/pkg/db/identity_find_by_id.sql_generated.go b/go/pkg/db/identity_find_by_id.sql_generated.go index da95728fef..f54ddbb60e 100644 --- a/go/pkg/db/identity_find_by_id.sql_generated.go +++ b/go/pkg/db/identity_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_find_by_id.sql package db @@ -10,7 +10,7 @@ import ( ) const findIdentityByID = `-- name: FindIdentityByID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? +SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE id = ? AND deleted = ? ` type FindIdentityByIDParams struct { @@ -20,7 +20,7 @@ type FindIdentityByIDParams struct { // FindIdentityByID // -// SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? +// SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE id = ? AND deleted = ? func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, arg FindIdentityByIDParams) (Identity, error) { row := db.QueryRowContext(ctx, findIdentityByID, arg.ID, arg.Deleted) var i Identity @@ -29,10 +29,10 @@ func (q *Queries) FindIdentityByID(ctx context.Context, db DBTX, arg FindIdentit &i.ExternalID, &i.WorkspaceID, &i.Environment, - &i.CreatedAt, - &i.UpdatedAt, &i.Meta, &i.Deleted, + &i.CreatedAt, + &i.UpdatedAt, ) return i, err } diff --git a/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go b/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go index c149811383..09fd0fe78e 100644 --- a/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go +++ b/go/pkg/db/identity_find_ratelimits_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_find_ratelimits_by_id.sql package db @@ -11,37 +11,29 @@ import ( ) const findRatelimitsByIdentityID = `-- name: FindRatelimitsByIdentityID :many -SELECT id, name, workspace_id, created_at, updated_at, ` + "`" + `limit` + "`" + `, duration FROM ratelimits WHERE identity_id = ? +SELECT id, name, workspace_id, created_at, updated_at, key_id, identity_id, ` + "`" + `limit` + "`" + `, duration FROM ratelimits WHERE identity_id = ? ` -type FindRatelimitsByIdentityIDRow struct { - ID string `db:"id"` - Name string `db:"name"` - WorkspaceID string `db:"workspace_id"` - CreatedAt int64 `db:"created_at"` - UpdatedAt sql.NullInt64 `db:"updated_at"` - Limit int32 `db:"limit"` - Duration int64 `db:"duration"` -} - // FindRatelimitsByIdentityID // -// SELECT id, name, workspace_id, created_at, updated_at, `limit`, duration FROM ratelimits WHERE identity_id = ? -func (q *Queries) FindRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) ([]FindRatelimitsByIdentityIDRow, error) { +// SELECT id, name, workspace_id, created_at, updated_at, key_id, identity_id, `limit`, duration FROM ratelimits WHERE identity_id = ? +func (q *Queries) FindRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) ([]Ratelimit, error) { rows, err := db.QueryContext(ctx, findRatelimitsByIdentityID, identityID) if err != nil { return nil, err } defer rows.Close() - var items []FindRatelimitsByIdentityIDRow + var items []Ratelimit for rows.Next() { - var i FindRatelimitsByIdentityIDRow + var i Ratelimit if err := rows.Scan( &i.ID, &i.Name, &i.WorkspaceID, &i.CreatedAt, &i.UpdatedAt, + &i.KeyID, + &i.IdentityID, &i.Limit, &i.Duration, ); err != nil { diff --git a/go/pkg/db/identity_insert.sql_generated.go b/go/pkg/db/identity_insert.sql_generated.go index da40be05ed..a3e8c97be2 100644 --- a/go/pkg/db/identity_insert.sql_generated.go +++ b/go/pkg/db/identity_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_insert.sql package db diff --git a/go/pkg/db/identity_insert_ratelimit.sql_generated.go b/go/pkg/db/identity_insert_ratelimit.sql_generated.go index dedde6fc8a..dda245eb67 100644 --- a/go/pkg/db/identity_insert_ratelimit.sql_generated.go +++ b/go/pkg/db/identity_insert_ratelimit.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_insert_ratelimit.sql package db diff --git a/go/pkg/db/identity_soft_delete.sql_generated.go b/go/pkg/db/identity_soft_delete.sql_generated.go index ce48fe84a7..2a4013c152 100644 --- a/go/pkg/db/identity_soft_delete.sql_generated.go +++ b/go/pkg/db/identity_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: identity_soft_delete.sql package db diff --git a/go/pkg/db/key_find_by_hash.sql_generated.go b/go/pkg/db/key_find_by_hash.sql_generated.go index a29a61acd4..5c1c0695da 100644 --- a/go/pkg/db/key_find_by_hash.sql_generated.go +++ b/go/pkg/db/key_find_by_hash.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: key_find_by_hash.sql package db diff --git a/go/pkg/db/key_find_by_id.sql_generated.go b/go/pkg/db/key_find_by_id.sql_generated.go index 02e2188a22..7964eca520 100644 --- a/go/pkg/db/key_find_by_id.sql_generated.go +++ b/go/pkg/db/key_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: key_find_by_id.sql package db @@ -12,7 +12,7 @@ import ( const findKeyByID = `-- name: FindKeyByID :one SELECT k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted + i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at FROM ` + "`" + `keys` + "`" + ` k LEFT JOIN identities i ON k.identity_id = i.id WHERE k.id = ? @@ -27,7 +27,7 @@ type FindKeyByIDRow struct { // // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, -// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted +// i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at // FROM `keys` k // LEFT JOIN identities i ON k.identity_id = i.id // WHERE k.id = ? @@ -62,10 +62,10 @@ func (q *Queries) FindKeyByID(ctx context.Context, db DBTX, id string) (FindKeyB &i.Identity.ExternalID, &i.Identity.WorkspaceID, &i.Identity.Environment, - &i.Identity.CreatedAt, - &i.Identity.UpdatedAt, &i.Identity.Meta, &i.Identity.Deleted, + &i.Identity.CreatedAt, + &i.Identity.UpdatedAt, ) return i, err } diff --git a/go/pkg/db/key_find_for_verification.sql_generated.go b/go/pkg/db/key_find_for_verification.sql_generated.go index c1bbc365be..f2a0d90fd1 100644 --- a/go/pkg/db/key_find_for_verification.sql_generated.go +++ b/go/pkg/db/key_find_for_verification.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: key_find_for_verification.sql package db @@ -49,7 +49,7 @@ all_ratelimits AS ( ) SELECT k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, + i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at, JSON_ARRAYAGG( JSON_OBJECT( 'target_type', rl.target_type, @@ -116,7 +116,7 @@ type FindKeyForVerificationRow struct { // ) // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, -// i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, +// i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at, // JSON_ARRAYAGG( // JSON_OBJECT( // 'target_type', rl.target_type, @@ -166,10 +166,10 @@ func (q *Queries) FindKeyForVerification(ctx context.Context, db DBTX, hash stri &i.Identity.ExternalID, &i.Identity.WorkspaceID, &i.Identity.Environment, - &i.Identity.CreatedAt, - &i.Identity.UpdatedAt, &i.Identity.Meta, &i.Identity.Deleted, + &i.Identity.CreatedAt, + &i.Identity.UpdatedAt, &i.Ratelimits, &i.Permissions, ) diff --git a/go/pkg/db/key_insert.sql_generated.go b/go/pkg/db/key_insert.sql_generated.go index 61eb43626b..fdfdf49fd9 100644 --- a/go/pkg/db/key_insert.sql_generated.go +++ b/go/pkg/db/key_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: key_insert.sql package db diff --git a/go/pkg/db/keyring_find_by_id.sql_generated.go b/go/pkg/db/keyring_find_by_id.sql_generated.go index dc6b354abe..e916a8818d 100644 --- a/go/pkg/db/keyring_find_by_id.sql_generated.go +++ b/go/pkg/db/keyring_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: keyring_find_by_id.sql package db diff --git a/go/pkg/db/keyring_insert.sql_generated.go b/go/pkg/db/keyring_insert.sql_generated.go index a5b08b5af7..64c1581317 100644 --- a/go/pkg/db/keyring_insert.sql_generated.go +++ b/go/pkg/db/keyring_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: keyring_insert.sql package db diff --git a/go/pkg/db/models_generated.go b/go/pkg/db/models_generated.go index ccecdfe585..5d8920ea94 100644 --- a/go/pkg/db/models_generated.go +++ b/go/pkg/db/models_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 package db @@ -291,10 +291,10 @@ type Identity struct { ExternalID string `db:"external_id"` WorkspaceID string `db:"workspace_id"` Environment string `db:"environment"` - CreatedAt int64 `db:"created_at"` - UpdatedAt sql.NullInt64 `db:"updated_at"` Meta []byte `db:"meta"` Deleted bool `db:"deleted"` + CreatedAt int64 `db:"created_at"` + UpdatedAt sql.NullInt64 `db:"updated_at"` } type Key struct { diff --git a/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go b/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go index 8cff7aed06..d82cdf4d33 100644 --- a/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go +++ b/go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: permission_find_by_workspace_and_name.sql package db diff --git a/go/pkg/db/permission_insert.sql_generated.go b/go/pkg/db/permission_insert.sql_generated.go index f58788ef32..a05806435c 100644 --- a/go/pkg/db/permission_insert.sql_generated.go +++ b/go/pkg/db/permission_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: permission_insert.sql package db diff --git a/go/pkg/db/permission_insert_key_permission.sql_generated.go b/go/pkg/db/permission_insert_key_permission.sql_generated.go index ccb8a18b7b..f6458858f8 100644 --- a/go/pkg/db/permission_insert_key_permission.sql_generated.go +++ b/go/pkg/db/permission_insert_key_permission.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: permission_insert_key_permission.sql package db diff --git a/go/pkg/db/permissions_by_key_id.sql_generated.go b/go/pkg/db/permissions_by_key_id.sql_generated.go index 475e580986..12aeb3bf72 100644 --- a/go/pkg/db/permissions_by_key_id.sql_generated.go +++ b/go/pkg/db/permissions_by_key_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: permissions_by_key_id.sql package db diff --git a/go/pkg/db/querier_generated.go b/go/pkg/db/querier_generated.go index e75f9524b2..58ee4890f9 100644 --- a/go/pkg/db/querier_generated.go +++ b/go/pkg/db/querier_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 package db @@ -41,11 +41,11 @@ type Querier interface { FindAuditLogTargetById(ctx context.Context, db DBTX, id string) ([]FindAuditLogTargetByIdRow, error) //FindIdentityByExternalID // - // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? + // SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ? FindIdentityByExternalID(ctx context.Context, db DBTX, arg FindIdentityByExternalIDParams) (Identity, error) //FindIdentityByID // - // SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = ? AND deleted = ? + // SELECT id, external_id, workspace_id, environment, meta, deleted, created_at, updated_at FROM identities WHERE id = ? AND deleted = ? FindIdentityByID(ctx context.Context, db DBTX, arg FindIdentityByIDParams) (Identity, error) //FindKeyByHash // @@ -55,7 +55,7 @@ type Querier interface { // // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted + // i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at // FROM `keys` k // LEFT JOIN identities i ON k.identity_id = i.id // WHERE k.id = ? @@ -99,7 +99,7 @@ type Querier interface { // ) // SELECT // k.id, k.key_auth_id, k.hash, k.start, k.workspace_id, k.for_workspace_id, k.name, k.owner_id, k.identity_id, k.meta, k.expires, k.created_at_m, k.updated_at_m, k.deleted_at_m, k.refill_day, k.refill_amount, k.last_refill_at, k.enabled, k.remaining_requests, k.ratelimit_async, k.ratelimit_limit, k.ratelimit_duration, k.environment, - // i.id, i.external_id, i.workspace_id, i.environment, i.created_at, i.updated_at, i.meta, i.deleted, + // i.id, i.external_id, i.workspace_id, i.environment, i.meta, i.deleted, i.created_at, i.updated_at, // JSON_ARRAYAGG( // JSON_OBJECT( // 'target_type', rl.target_type, @@ -191,8 +191,8 @@ type Querier interface { FindRatelimitOverridesByIdentifier(ctx context.Context, db DBTX, arg FindRatelimitOverridesByIdentifierParams) (RatelimitOverride, error) //FindRatelimitsByIdentityID // - // SELECT id, name, workspace_id, created_at, updated_at, `limit`, duration FROM ratelimits WHERE identity_id = ? - FindRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) ([]FindRatelimitsByIdentityIDRow, error) + // SELECT id, name, workspace_id, created_at, updated_at, key_id, identity_id, `limit`, duration FROM ratelimits WHERE identity_id = ? + FindRatelimitsByIdentityID(ctx context.Context, db DBTX, identityID sql.NullString) ([]Ratelimit, error) //FindWorkspaceByID // // SELECT id, org_id, name, plan, tier, stripe_customer_id, stripe_subscription_id, beta_features, features, subscriptions, enabled, delete_protection, created_at_m, updated_at_m, deleted_at_m FROM `workspaces` diff --git a/go/pkg/db/queries/identity_find_by_external_id.sql b/go/pkg/db/queries/identity_find_by_external_id.sql index 1ebb1dc891..61c02db6be 100644 --- a/go/pkg/db/queries/identity_find_by_external_id.sql +++ b/go/pkg/db/queries/identity_find_by_external_id.sql @@ -1,2 +1,2 @@ -- name: FindIdentityByExternalID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE workspace_id = ? AND external_id = ? AND deleted = ?; +SELECT * FROM identities WHERE workspace_id = sqlc.arg(workspace_id) AND external_id = sqlc.arg(external_id) AND deleted = sqlc.arg(deleted); diff --git a/go/pkg/db/queries/identity_find_by_id.sql b/go/pkg/db/queries/identity_find_by_id.sql index ac16632a4e..af5810122b 100644 --- a/go/pkg/db/queries/identity_find_by_id.sql +++ b/go/pkg/db/queries/identity_find_by_id.sql @@ -1,2 +1,2 @@ -- name: FindIdentityByID :one -SELECT id, external_id, workspace_id, environment, created_at, updated_at, meta, deleted FROM identities WHERE id = sqlc.arg(id) AND deleted = ?; +SELECT * FROM identities WHERE id = sqlc.arg(id) AND deleted = sqlc.arg(deleted); diff --git a/go/pkg/db/queries/identity_find_ratelimits_by_id.sql b/go/pkg/db/queries/identity_find_ratelimits_by_id.sql index 61a417dde7..deaacededf 100644 --- a/go/pkg/db/queries/identity_find_ratelimits_by_id.sql +++ b/go/pkg/db/queries/identity_find_ratelimits_by_id.sql @@ -1,2 +1,2 @@ -- name: FindRatelimitsByIdentityID :many -SELECT id, name, workspace_id, created_at, updated_at, `limit`, duration FROM ratelimits WHERE identity_id = sqlc.arg(identity_id) +SELECT * FROM ratelimits WHERE identity_id = sqlc.arg(identity_id) diff --git a/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go b/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go index a9051ccfbd..90e2d019c4 100644 --- a/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go +++ b/go/pkg/db/ratelimit_delete_by_identity_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_delete_by_identity_id.sql package db diff --git a/go/pkg/db/ratelimit_delete_many.sql_generated.go b/go/pkg/db/ratelimit_delete_many.sql_generated.go index 2106cfbdf0..42380a1d27 100644 --- a/go/pkg/db/ratelimit_delete_many.sql_generated.go +++ b/go/pkg/db/ratelimit_delete_many.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_delete_many.sql package db diff --git a/go/pkg/db/ratelimit_namespace_delete.sql_generated.go b/go/pkg/db/ratelimit_namespace_delete.sql_generated.go index 2d6bbfa3e6..46757d2d80 100644 --- a/go/pkg/db/ratelimit_namespace_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_namespace_delete.sql package db diff --git a/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go b/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go index 860275d0be..a02ca1ddcd 100644 --- a/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_namespace_find_by_id.sql package db diff --git a/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go b/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go index 5c2fe0ec54..5b041bb844 100644 --- a/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_find_by_name.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_namespace_find_by_name.sql package db diff --git a/go/pkg/db/ratelimit_namespace_insert.sql_generated.go b/go/pkg/db/ratelimit_namespace_insert.sql_generated.go index d727ae8207..150c1b8aaf 100644 --- a/go/pkg/db/ratelimit_namespace_insert.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_namespace_insert.sql package db diff --git a/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go b/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go index 3df1948649..8dd369651a 100644 --- a/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_namespace_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_namespace_soft_delete.sql package db diff --git a/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go b/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go index 313e002454..e40f34a185 100644 --- a/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_find_by_id.sql package db diff --git a/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go b/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go index 8608a79be9..550314de0b 100644 --- a/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_by_identifier.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_find_by_identifier.sql package db diff --git a/go/pkg/db/ratelimit_override_find_matches.sql_generated.go b/go/pkg/db/ratelimit_override_find_matches.sql_generated.go index 1e5bbf54be..64b96181bd 100644 --- a/go/pkg/db/ratelimit_override_find_matches.sql_generated.go +++ b/go/pkg/db/ratelimit_override_find_matches.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_find_matches.sql package db diff --git a/go/pkg/db/ratelimit_override_insert.sql_generated.go b/go/pkg/db/ratelimit_override_insert.sql_generated.go index edb34e73d8..2184eb07a3 100644 --- a/go/pkg/db/ratelimit_override_insert.sql_generated.go +++ b/go/pkg/db/ratelimit_override_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_insert.sql package db diff --git a/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go b/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go index 730d2d4651..626d919d39 100644 --- a/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go +++ b/go/pkg/db/ratelimit_override_list_by_namespace_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_list_by_namespace_id.sql package db diff --git a/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go b/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go index 9fd37ee07a..fb7910f14a 100644 --- a/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go +++ b/go/pkg/db/ratelimit_override_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_soft_delete.sql package db diff --git a/go/pkg/db/ratelimit_override_update.sql_generated.go b/go/pkg/db/ratelimit_override_update.sql_generated.go index f80b0777b1..e1a6226614 100644 --- a/go/pkg/db/ratelimit_override_update.sql_generated.go +++ b/go/pkg/db/ratelimit_override_update.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: ratelimit_override_update.sql package db diff --git a/go/pkg/db/schema.sql b/go/pkg/db/schema.sql index b3183f1d85..4fb6ea5ccd 100644 --- a/go/pkg/db/schema.sql +++ b/go/pkg/db/schema.sql @@ -1,306 +1,307 @@ CREATE TABLE `apis` ( - `id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `ip_whitelist` varchar(512) DEFAULT NULL, - `auth_type` enum('key','jwt') DEFAULT NULL, - `key_auth_id` varchar(256) DEFAULT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - `delete_protection` tinyint(1) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `apis_key_auth_id_unique` (`key_auth_id`), - KEY `workspace_id_idx` (`workspace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `ip_whitelist` varchar(512), + `auth_type` enum('key','jwt'), + `key_auth_id` varchar(256), + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + `delete_protection` boolean DEFAULT false, + CONSTRAINT `apis_id` PRIMARY KEY(`id`), + CONSTRAINT `apis_key_auth_id_unique` UNIQUE(`key_auth_id`) +); -CREATE TABLE `audit_log` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', - `bucket_id` varchar(256) NOT NULL, - `event` varchar(256) NOT NULL, - `time` bigint NOT NULL, - `display` varchar(256) NOT NULL, - `remote_ip` varchar(256) DEFAULT NULL, - `user_agent` varchar(256) DEFAULT NULL, - `actor_type` varchar(256) NOT NULL, - `actor_id` varchar(256) NOT NULL, - `actor_name` varchar(256) DEFAULT NULL, - `actor_meta` json DEFAULT NULL, - `created_at` bigint NOT NULL, - `updated_at` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `workspace_id_idx` (`workspace_id`), - KEY `bucket_id_idx` (`bucket_id`), - KEY `bucket_idx` (`bucket`), - KEY `event_idx` (`event`), - KEY `actor_id_idx` (`actor_id`), - KEY `time_idx` (`time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `keys_permissions` ( + `temp_id` bigint AUTO_INCREMENT NOT NULL, + `key_id` varchar(256) NOT NULL, + `permission_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + CONSTRAINT `keys_permissions_key_id_permission_id_workspace_id` PRIMARY KEY(`key_id`,`permission_id`,`workspace_id`), + CONSTRAINT `keys_permissions_temp_id_unique` UNIQUE(`temp_id`), + CONSTRAINT `key_id_permission_id_idx` UNIQUE(`key_id`,`permission_id`) +); -CREATE TABLE `audit_log_bucket` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `retention_days` int DEFAULT NULL, - `created_at` bigint NOT NULL, - `updated_at` bigint DEFAULT NULL, - `delete_protection` tinyint(1) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name_per_workspace_idx` (`workspace_id`,`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `keys_roles` ( + `key_id` varchar(256) NOT NULL, + `role_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + CONSTRAINT `keys_roles_role_id_key_id_workspace_id` PRIMARY KEY(`role_id`,`key_id`,`workspace_id`), + CONSTRAINT `unique_key_id_role_id` UNIQUE(`key_id`,`role_id`) +); -CREATE TABLE `audit_log_target` ( - `workspace_id` varchar(256) NOT NULL, - `bucket_id` varchar(256) NOT NULL, - `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', - `audit_log_id` varchar(256) NOT NULL, - `display_name` varchar(256) NOT NULL, - `type` varchar(256) NOT NULL, - `id` varchar(256) NOT NULL, - `name` varchar(256) DEFAULT NULL, - `meta` json DEFAULT NULL, - `created_at` bigint NOT NULL, - `updated_at` bigint DEFAULT NULL, - PRIMARY KEY (`audit_log_id`,`id`), - KEY `bucket` (`bucket`), - KEY `audit_log_id` (`audit_log_id`), - KEY `id_idx` (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `permissions` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `description` varchar(512), + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + CONSTRAINT `permissions_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) +); -CREATE TABLE `encrypted_keys` ( - `workspace_id` varchar(256) NOT NULL, - `key_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL DEFAULT '0', - `updated_at` bigint DEFAULT NULL, - `encrypted` varchar(1024) NOT NULL, - `encryption_key_id` varchar(256) NOT NULL, - UNIQUE KEY `key_id_idx` (`key_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `roles` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `description` varchar(512), + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + CONSTRAINT `roles_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) +); -CREATE TABLE `identities` ( - `id` varchar(256) NOT NULL, - `external_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `environment` varchar(256) NOT NULL DEFAULT 'default', - `created_at` bigint NOT NULL, - `updated_at` bigint DEFAULT NULL, - `meta` json DEFAULT NULL, - `deleted` tinyint(1) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `workspace_id_external_id_deleted_idx` (`workspace_id`,`external_id`,`deleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `roles_permissions` ( + `role_id` varchar(256) NOT NULL, + `permission_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + CONSTRAINT `roles_permissions_role_id_permission_id_workspace_id` PRIMARY KEY(`role_id`,`permission_id`,`workspace_id`), + CONSTRAINT `unique_tuple_permission_id_role_id` UNIQUE(`permission_id`,`role_id`) +); CREATE TABLE `key_auth` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - `store_encrypted_keys` tinyint(1) NOT NULL DEFAULT '0', - `default_prefix` varchar(8) DEFAULT NULL, - `default_bytes` int DEFAULT '16', - `size_approx` int NOT NULL DEFAULT '0', - `size_last_updated_at` bigint NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + `store_encrypted_keys` boolean NOT NULL DEFAULT false, + `default_prefix` varchar(8), + `default_bytes` int DEFAULT 16, + `size_approx` int NOT NULL DEFAULT 0, + `size_last_updated_at` bigint NOT NULL DEFAULT 0, + CONSTRAINT `key_auth_id` PRIMARY KEY(`id`) +); -CREATE TABLE `key_migration_errors` ( - `id` varchar(256) NOT NULL, - `migration_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `message` json NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `encrypted_keys` ( + `workspace_id` varchar(256) NOT NULL, + `key_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL DEFAULT 0, + `updated_at` bigint, + `encrypted` varchar(1024) NOT NULL, + `encryption_key_id` varchar(256) NOT NULL, + CONSTRAINT `key_id_idx` UNIQUE(`key_id`) +); CREATE TABLE `keys` ( - `id` varchar(256) NOT NULL, - `key_auth_id` varchar(256) NOT NULL, - `hash` varchar(256) NOT NULL, - `start` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `for_workspace_id` varchar(256) DEFAULT NULL, - `name` varchar(256) DEFAULT NULL, - `owner_id` varchar(256) DEFAULT NULL, - `identity_id` varchar(256) DEFAULT NULL, - `meta` text, - `expires` datetime(3) DEFAULT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - `refill_day` tinyint DEFAULT NULL, - `refill_amount` int DEFAULT NULL, - `last_refill_at` datetime(3) DEFAULT NULL, - `enabled` tinyint(1) NOT NULL DEFAULT '1', - `remaining_requests` int DEFAULT NULL, - `ratelimit_async` tinyint(1) DEFAULT NULL, - `ratelimit_limit` int DEFAULT NULL, - `ratelimit_duration` bigint DEFAULT NULL, - `environment` varchar(256) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `hash_idx` (`hash`), - KEY `key_auth_id_deleted_at_idx` (`key_auth_id`,`deleted_at_m`), - KEY `idx_keys_on_for_workspace_id` (`for_workspace_id`), - KEY `owner_id_idx` (`owner_id`), - KEY `identity_id_idx` (`identity_id`), - KEY `deleted_at_idx` (`deleted_at_m`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE `keys_permissions` ( - `temp_id` bigint NOT NULL AUTO_INCREMENT, - `key_id` varchar(256) NOT NULL, - `permission_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`key_id`,`permission_id`,`workspace_id`), - UNIQUE KEY `keys_permissions_temp_id_unique` (`temp_id`), - UNIQUE KEY `key_id_permission_id_idx` (`key_id`,`permission_id`) -) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `key_auth_id` varchar(256) NOT NULL, + `hash` varchar(256) NOT NULL, + `start` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `for_workspace_id` varchar(256), + `name` varchar(256), + `owner_id` varchar(256), + `identity_id` varchar(256), + `meta` text, + `expires` datetime(3), + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + `refill_day` tinyint, + `refill_amount` int, + `last_refill_at` datetime(3), + `enabled` boolean NOT NULL DEFAULT true, + `remaining_requests` int, + `ratelimit_async` boolean, + `ratelimit_limit` int, + `ratelimit_duration` bigint, + `environment` varchar(256), + CONSTRAINT `keys_id` PRIMARY KEY(`id`), + CONSTRAINT `hash_idx` UNIQUE(`hash`) +); -CREATE TABLE `keys_roles` ( - `key_id` varchar(256) NOT NULL, - `role_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`role_id`,`key_id`,`workspace_id`), - UNIQUE KEY `unique_key_id_role_id` (`key_id`,`role_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE `permissions` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `description` varchar(512) DEFAULT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`), - KEY `workspace_id_idx` (`workspace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `vercel_bindings` ( + `id` varchar(256) NOT NULL, + `integration_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `project_id` varchar(256) NOT NULL, + `environment` enum('development','preview','production') NOT NULL, + `resource_id` varchar(256) NOT NULL, + `resource_type` enum('rootKey','apiId') NOT NULL, + `vercel_env_id` varchar(256) NOT NULL, + `last_edited_by` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + CONSTRAINT `vercel_bindings_id` PRIMARY KEY(`id`), + CONSTRAINT `project_environment_resource_type_idx` UNIQUE(`project_id`,`environment`,`resource_type`) +); -CREATE TABLE `quota` ( - `workspace_id` varchar(256) NOT NULL, - `requests_per_month` bigint NOT NULL DEFAULT '0', - `logs_retention_days` int NOT NULL DEFAULT '0', - `audit_logs_retention_days` int NOT NULL DEFAULT '0', - `team` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`workspace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `vercel_integrations` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `team_id` varchar(256), + `access_token` varchar(256) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + CONSTRAINT `vercel_integrations_id` PRIMARY KEY(`id`) +); CREATE TABLE `ratelimit_namespaces` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(512) NOT NULL, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + CONSTRAINT `ratelimit_namespaces_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`name`,`workspace_id`) +); CREATE TABLE `ratelimit_overrides` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `namespace_id` varchar(256) NOT NULL, - `identifier` varchar(512) NOT NULL, - `limit` int NOT NULL, - `duration` int NOT NULL, - `async` tinyint(1) DEFAULT NULL, - `sharding` enum('edge') DEFAULT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_identifier_per_namespace_idx` (`identifier`,`namespace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `namespace_id` varchar(256) NOT NULL, + `identifier` varchar(512) NOT NULL, + `limit` int NOT NULL, + `duration` int NOT NULL, + `async` boolean, + `sharding` enum('edge'), + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + CONSTRAINT `ratelimit_overrides_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_identifier_per_namespace_idx` UNIQUE(`identifier`,`namespace_id`) +); + +CREATE TABLE `workspaces` ( + `id` varchar(256) NOT NULL, + `org_id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `plan` enum('free','pro','enterprise') DEFAULT 'free', + `tier` varchar(256) DEFAULT 'Free', + `stripe_customer_id` varchar(256), + `stripe_subscription_id` varchar(256), + `beta_features` json NOT NULL, + `features` json NOT NULL, + `subscriptions` json, + `enabled` boolean NOT NULL DEFAULT true, + `delete_protection` boolean DEFAULT false, + `created_at_m` bigint NOT NULL DEFAULT 0, + `updated_at_m` bigint, + `deleted_at_m` bigint, + CONSTRAINT `workspaces_id` PRIMARY KEY(`id`), + CONSTRAINT `workspaces_org_id_unique` UNIQUE(`org_id`) +); + +CREATE TABLE `key_migration_errors` ( + `id` varchar(256) NOT NULL, + `migration_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `message` json NOT NULL, + CONSTRAINT `key_migration_errors_id` PRIMARY KEY(`id`) +); + +CREATE TABLE `identities` ( + `id` varchar(256) NOT NULL, + `external_id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `environment` varchar(256) NOT NULL DEFAULT 'default', + `meta` json, + `deleted` boolean NOT NULL DEFAULT false, + `created_at` bigint NOT NULL, + `updated_at` bigint, + CONSTRAINT `identities_id` PRIMARY KEY(`id`), + CONSTRAINT `workspace_id_external_id_deleted_idx` UNIQUE(`workspace_id`,`external_id`,`deleted`) +); CREATE TABLE `ratelimits` ( - `id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at` bigint NOT NULL, - `updated_at` bigint DEFAULT NULL, - `key_id` varchar(256) DEFAULT NULL, - `identity_id` varchar(256) DEFAULT NULL, - `limit` int NOT NULL, - `duration` bigint NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name_idx` (`name`,`key_id`,`identity_id`), - KEY `name_idx` (`name`), - KEY `identity_id_idx` (`identity_id`), - KEY `key_id_idx` (`key_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + `id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `created_at` bigint NOT NULL, + `updated_at` bigint, + `key_id` varchar(256), + `identity_id` varchar(256), + `limit` int NOT NULL, + `duration` bigint NOT NULL, + CONSTRAINT `ratelimits_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_name_idx` UNIQUE(`name`,`key_id`,`identity_id`) +); -CREATE TABLE `roles` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `name` varchar(512) NOT NULL, - `description` varchar(512) DEFAULT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name_per_workspace_idx` (`name`,`workspace_id`), - KEY `workspace_id_idx` (`workspace_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `quota` ( + `workspace_id` varchar(256) NOT NULL, + `requests_per_month` bigint NOT NULL DEFAULT 0, + `logs_retention_days` int NOT NULL DEFAULT 0, + `audit_logs_retention_days` int NOT NULL DEFAULT 0, + `team` boolean NOT NULL DEFAULT false, + CONSTRAINT `quota_workspace_id` PRIMARY KEY(`workspace_id`) +); -CREATE TABLE `roles_permissions` ( - `role_id` varchar(256) NOT NULL, - `permission_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`role_id`,`permission_id`,`workspace_id`), - UNIQUE KEY `unique_tuple_permission_id_role_id` (`permission_id`,`role_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `audit_log` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', + `bucket_id` varchar(256) NOT NULL, + `event` varchar(256) NOT NULL, + `time` bigint NOT NULL, + `display` varchar(256) NOT NULL, + `remote_ip` varchar(256), + `user_agent` varchar(256), + `actor_type` varchar(256) NOT NULL, + `actor_id` varchar(256) NOT NULL, + `actor_name` varchar(256), + `actor_meta` json, + `created_at` bigint NOT NULL, + `updated_at` bigint, + CONSTRAINT `audit_log_id` PRIMARY KEY(`id`) +); -CREATE TABLE `vercel_bindings` ( - `id` varchar(256) NOT NULL, - `integration_id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `project_id` varchar(256) NOT NULL, - `environment` enum('development','preview','production') NOT NULL, - `resource_id` varchar(256) NOT NULL, - `resource_type` enum('rootKey','apiId') NOT NULL, - `vercel_env_id` varchar(256) NOT NULL, - `last_edited_by` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `project_environment_resource_type_idx` (`project_id`,`environment`,`resource_type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `audit_log_bucket` ( + `id` varchar(256) NOT NULL, + `workspace_id` varchar(256) NOT NULL, + `name` varchar(256) NOT NULL, + `retention_days` int, + `created_at` bigint NOT NULL, + `updated_at` bigint, + `delete_protection` boolean DEFAULT false, + CONSTRAINT `audit_log_bucket_id` PRIMARY KEY(`id`), + CONSTRAINT `unique_name_per_workspace_idx` UNIQUE(`workspace_id`,`name`) +); -CREATE TABLE `vercel_integrations` ( - `id` varchar(256) NOT NULL, - `workspace_id` varchar(256) NOT NULL, - `team_id` varchar(256) DEFAULT NULL, - `access_token` varchar(256) NOT NULL, - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE `audit_log_target` ( + `workspace_id` varchar(256) NOT NULL, + `bucket_id` varchar(256) NOT NULL, + `bucket` varchar(256) NOT NULL DEFAULT 'unkey_mutations', + `audit_log_id` varchar(256) NOT NULL, + `display_name` varchar(256) NOT NULL, + `type` varchar(256) NOT NULL, + `id` varchar(256) NOT NULL, + `name` varchar(256), + `meta` json, + `created_at` bigint NOT NULL, + `updated_at` bigint, + CONSTRAINT `audit_log_target_audit_log_id_id_pk` PRIMARY KEY(`audit_log_id`,`id`) +); -CREATE TABLE `workspaces` ( - `id` varchar(256) NOT NULL, - `org_id` varchar(256) NOT NULL, - `name` varchar(256) NOT NULL, - `plan` enum('free','pro','enterprise') DEFAULT 'free', - `tier` varchar(256) DEFAULT 'Free', - `stripe_customer_id` varchar(256) DEFAULT NULL, - `stripe_subscription_id` varchar(256) DEFAULT NULL, - `beta_features` json NOT NULL, - `features` json NOT NULL, - `subscriptions` json DEFAULT NULL, - `enabled` tinyint(1) NOT NULL DEFAULT '1', - `delete_protection` tinyint(1) DEFAULT '0', - `created_at_m` bigint NOT NULL DEFAULT '0', - `updated_at_m` bigint DEFAULT NULL, - `deleted_at_m` bigint DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `workspaces_org_id_unique` (`org_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE INDEX `workspace_id_idx` ON `apis` (`workspace_id`); +CREATE INDEX `workspace_id_idx` ON `permissions` (`workspace_id`); +CREATE INDEX `workspace_id_idx` ON `roles` (`workspace_id`); +CREATE INDEX `key_auth_id_deleted_at_idx` ON `keys` (`key_auth_id`,`deleted_at_m`); +CREATE INDEX `idx_keys_on_for_workspace_id` ON `keys` (`for_workspace_id`); +CREATE INDEX `owner_id_idx` ON `keys` (`owner_id`); +CREATE INDEX `identity_id_idx` ON `keys` (`identity_id`); +CREATE INDEX `deleted_at_idx` ON `keys` (`deleted_at_m`); +CREATE INDEX `name_idx` ON `ratelimits` (`name`); +CREATE INDEX `identity_id_idx` ON `ratelimits` (`identity_id`); +CREATE INDEX `key_id_idx` ON `ratelimits` (`key_id`); +CREATE INDEX `workspace_id_idx` ON `audit_log` (`workspace_id`); +CREATE INDEX `bucket_id_idx` ON `audit_log` (`bucket_id`); +CREATE INDEX `bucket_idx` ON `audit_log` (`bucket`); +CREATE INDEX `event_idx` ON `audit_log` (`event`); +CREATE INDEX `actor_id_idx` ON `audit_log` (`actor_id`); +CREATE INDEX `time_idx` ON `audit_log` (`time`); +CREATE INDEX `bucket` ON `audit_log_target` (`bucket`); +CREATE INDEX `audit_log_id` ON `audit_log_target` (`audit_log_id`); +CREATE INDEX `id_idx` ON `audit_log_target` (`id`); diff --git a/go/pkg/db/workspace_find_by_id.sql_generated.go b/go/pkg/db/workspace_find_by_id.sql_generated.go index 0e8909aff8..e24cc463ed 100644 --- a/go/pkg/db/workspace_find_by_id.sql_generated.go +++ b/go/pkg/db/workspace_find_by_id.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_find_by_id.sql package db diff --git a/go/pkg/db/workspace_hard_delete.sql_generated.go b/go/pkg/db/workspace_hard_delete.sql_generated.go index 592ec870fe..0e3f8f60aa 100644 --- a/go/pkg/db/workspace_hard_delete.sql_generated.go +++ b/go/pkg/db/workspace_hard_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_hard_delete.sql package db diff --git a/go/pkg/db/workspace_insert.sql_generated.go b/go/pkg/db/workspace_insert.sql_generated.go index 0377f24988..8967b87fc5 100644 --- a/go/pkg/db/workspace_insert.sql_generated.go +++ b/go/pkg/db/workspace_insert.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_insert.sql package db diff --git a/go/pkg/db/workspace_soft_delete.sql_generated.go b/go/pkg/db/workspace_soft_delete.sql_generated.go index accafa0f19..5a729df821 100644 --- a/go/pkg/db/workspace_soft_delete.sql_generated.go +++ b/go/pkg/db/workspace_soft_delete.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_soft_delete.sql package db diff --git a/go/pkg/db/workspace_update_enabled.sql_generated.go b/go/pkg/db/workspace_update_enabled.sql_generated.go index ca711eabbd..218d181adc 100644 --- a/go/pkg/db/workspace_update_enabled.sql_generated.go +++ b/go/pkg/db/workspace_update_enabled.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_update_enabled.sql package db diff --git a/go/pkg/db/workspace_update_plan.sql_generated.go b/go/pkg/db/workspace_update_plan.sql_generated.go index cca72082ee..5ee2bf4fca 100644 --- a/go/pkg/db/workspace_update_plan.sql_generated.go +++ b/go/pkg/db/workspace_update_plan.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspace_update_plan.sql package db diff --git a/go/pkg/db/workspaces_list.sql_generated.go b/go/pkg/db/workspaces_list.sql_generated.go index 7ef2bd6e16..b281597760 100644 --- a/go/pkg/db/workspaces_list.sql_generated.go +++ b/go/pkg/db/workspaces_list.sql_generated.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.28.0 +// sqlc v1.27.0 // source: workspaces_list.sql package db diff --git a/go/pkg/fault/dst_test.go b/go/pkg/fault/dst_test.go index eab7ee5f3a..ad3329359c 100644 --- a/go/pkg/fault/dst_test.go +++ b/go/pkg/fault/dst_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" "github.com/unkeyed/unkey/go/pkg/codes" "github.com/unkeyed/unkey/go/pkg/fault" + "github.com/unkeyed/unkey/go/pkg/testutil" ) var ( @@ -177,6 +178,7 @@ func (g *ErrorChainGenerator) generateErrorChain() ([]codes.URN, []string, error } func TestDST(t *testing.T) { + testutil.SkipUnlessSimulation(t) seed := time.Now().UnixNano() t.Logf("Using seed: %d", seed) diff --git a/go/pkg/testutil/seed/seed.go b/go/pkg/testutil/seed/seed.go index 0722c0c44b..a011035159 100644 --- a/go/pkg/testutil/seed/seed.go +++ b/go/pkg/testutil/seed/seed.go @@ -127,7 +127,6 @@ func (s *Seeder) CreateRootKey(ctx context.Context, workspaceID string, permissi if len(permissions) > 0 { for _, permission := range permissions { - s.t.Logf("creating permission %s for key %s", permission, insertKeyParams.ID) permissionID := uid.New(uid.TestPrefix) err := db.Query.InsertPermission(ctx, s.DB.RW(), db.InsertPermissionParams{ ID: permissionID, @@ -162,7 +161,5 @@ func (s *Seeder) CreateRootKey(ctx context.Context, workspaceID string, permissi } } - s.t.Logf("created root key: %s", insertKeyParams.ID) - return key } diff --git a/internal/db/drizzle/0000_motionless_vargas.sql b/internal/db/drizzle/0000_fat_the_hand.sql similarity index 98% rename from internal/db/drizzle/0000_motionless_vargas.sql rename to internal/db/drizzle/0000_fat_the_hand.sql index 56f4de0fa5..0ab66d12b9 100644 --- a/internal/db/drizzle/0000_motionless_vargas.sql +++ b/internal/db/drizzle/0000_fat_the_hand.sql @@ -208,11 +208,12 @@ CREATE TABLE `identities` ( `external_id` varchar(256) NOT NULL, `workspace_id` varchar(256) NOT NULL, `environment` varchar(256) NOT NULL DEFAULT 'default', + `meta` json, + `deleted` boolean NOT NULL DEFAULT false, `created_at` bigint NOT NULL, `updated_at` bigint, - `meta` json, CONSTRAINT `identities_id` PRIMARY KEY(`id`), - CONSTRAINT `external_id_workspace_id_idx` UNIQUE(`external_id`,`workspace_id`) + CONSTRAINT `workspace_id_external_id_deleted_idx` UNIQUE(`workspace_id`,`external_id`,`deleted`) ); --> statement-breakpoint CREATE TABLE `ratelimits` ( @@ -292,7 +293,6 @@ CREATE INDEX `idx_keys_on_for_workspace_id` ON `keys` (`for_workspace_id`);--> s CREATE INDEX `owner_id_idx` ON `keys` (`owner_id`);--> statement-breakpoint CREATE INDEX `identity_id_idx` ON `keys` (`identity_id`);--> statement-breakpoint CREATE INDEX `deleted_at_idx` ON `keys` (`deleted_at_m`);--> statement-breakpoint -CREATE INDEX `workspace_id_idx` ON `identities` (`workspace_id`);--> statement-breakpoint CREATE INDEX `name_idx` ON `ratelimits` (`name`);--> statement-breakpoint CREATE INDEX `identity_id_idx` ON `ratelimits` (`identity_id`);--> statement-breakpoint CREATE INDEX `key_id_idx` ON `ratelimits` (`key_id`);--> statement-breakpoint diff --git a/internal/db/drizzle/meta/0000_snapshot.json b/internal/db/drizzle/meta/0000_snapshot.json index 59d8049634..1d53e59538 100644 --- a/internal/db/drizzle/meta/0000_snapshot.json +++ b/internal/db/drizzle/meta/0000_snapshot.json @@ -1,7 +1,7 @@ { "version": "5", "dialect": "mysql", - "id": "b652299c-35af-4024-84c7-13f686c5195d", + "id": "c0a0a8fb-53ef-426f-9cbc-50d8e7f72b86", "prevId": "00000000-0000-0000-0000-000000000000", "tables": { "apis": { @@ -1307,6 +1307,21 @@ "autoincrement": false, "default": "'default'" }, + "meta": { + "name": "meta", + "type": "json", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, "created_at": { "name": "created_at", "type": "bigint", @@ -1320,24 +1335,12 @@ "primaryKey": false, "notNull": false, "autoincrement": false - }, - "meta": { - "name": "meta", - "type": "json", - "primaryKey": false, - "notNull": false, - "autoincrement": false } }, "indexes": { - "workspace_id_idx": { - "name": "workspace_id_idx", - "columns": ["workspace_id"], - "isUnique": false - }, - "external_id_workspace_id_idx": { - "name": "external_id_workspace_id_idx", - "columns": ["external_id", "workspace_id"], + "workspace_id_external_id_deleted_idx": { + "name": "workspace_id_external_id_deleted_idx", + "columns": ["workspace_id", "external_id", "deleted"], "isUnique": true } }, diff --git a/internal/db/drizzle/meta/_journal.json b/internal/db/drizzle/meta/_journal.json index 633273e231..d602259be6 100644 --- a/internal/db/drizzle/meta/_journal.json +++ b/internal/db/drizzle/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "5", - "when": 1744529464325, - "tag": "0000_motionless_vargas", + "when": 1745396754471, + "tag": "0000_fat_the_hand", "breakpoints": true } ] diff --git a/internal/db/src/schema/identity.ts b/internal/db/src/schema/identity.ts index fdc666ad98..4f5f64c069 100644 --- a/internal/db/src/schema/identity.ts +++ b/internal/db/src/schema/identity.ts @@ -1,5 +1,14 @@ import { relations } from "drizzle-orm"; -import { bigint, boolean, index, int, json, mysqlTable, uniqueIndex, varchar, tinyint } from "drizzle-orm/mysql-core"; +import { + bigint, + boolean, + index, + int, + json, + mysqlTable, + uniqueIndex, + varchar, +} from "drizzle-orm/mysql-core"; import { keys } from "./keys"; import { lifecycleDates } from "./util/lifecycle_dates"; import { workspaces } from "./workspaces"; @@ -16,7 +25,7 @@ export const identities = mysqlTable( workspaceId: varchar("workspace_id", { length: 256 }).notNull(), environment: varchar("environment", { length: 256 }).notNull().default("default"), meta: json("meta").$type>(), - deleted: tinyint("deleted", { unsigned: true }).notNull().default(0), + deleted: boolean("deleted").notNull().default(false), ...lifecycleDates, }, (table) => ({