From b83a4d27ca2a9c78eaf0a44a4e947e03e0cdb77c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 03:13:47 +0100 Subject: [PATCH 01/11] fix(deps): update module github.com/stretchr/testify to v1.9.0 (#91) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 46ec5f7..e154192 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/google/go-querystring v1.1.0 github.com/peterhellberg/link v1.2.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 ) require ( diff --git a/go.sum b/go.sum index 148666f..78cc725 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From faafbec697e53715ceca3f90b3d2761249f6112d Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Fri, 3 May 2024 22:42:02 +0100 Subject: [PATCH 02/11] feat: additional fields for project keys --- sentry/project_keys.go | 31 ++++-- sentry/project_keys_test.go | 189 +++++++++++++++++++++++++++--------- 2 files changed, 164 insertions(+), 56 deletions(-) diff --git a/sentry/project_keys.go b/sentry/project_keys.go index 09839c0..0c3a24b 100644 --- a/sentry/project_keys.go +++ b/sentry/project_keys.go @@ -20,22 +20,33 @@ type ProjectKeyDSN struct { CSP string `json:"csp"` Security string `json:"security"` Minidump string `json:"minidump"` + NEL string `json:"nel"` + Unreal string `json:"unreal"` CDN string `json:"cdn"` + Crons string `json:"crons"` +} + +type ProjectKeyDynamicSDKLoaderOptions struct { + HasReplay bool `json:"hasReplay"` + HasPerformance bool `json:"hasPerformance"` + HasDebugFiles bool `json:"hasDebug"` } // ProjectKey represents a client key bound to a project. // https://github.com/getsentry/sentry/blob/9.0.0/src/sentry/api/serializers/models/project_key.py type ProjectKey struct { - ID string `json:"id"` - Name string `json:"name"` - Label string `json:"label"` - Public string `json:"public"` - Secret string `json:"secret"` - ProjectID json.Number `json:"projectId"` - IsActive bool `json:"isActive"` - RateLimit *ProjectKeyRateLimit `json:"rateLimit"` - DSN ProjectKeyDSN `json:"dsn"` - DateCreated time.Time `json:"dateCreated"` + ID string `json:"id"` + Name string `json:"name"` + Label string `json:"label"` + Public string `json:"public"` + Secret string `json:"secret"` + ProjectID json.Number `json:"projectId"` + IsActive bool `json:"isActive"` + RateLimit *ProjectKeyRateLimit `json:"rateLimit"` + DSN ProjectKeyDSN `json:"dsn"` + BrowserSDKVersion string `json:"browserSdkVersion"` + DateCreated time.Time `json:"dateCreated"` + DynamicSDKLoaderOptions ProjectKeyDynamicSDKLoaderOptions `json:"dynamicSdkLoaderOptions"` } // ProjectKeysService provides methods for accessing Sentry project diff --git a/sentry/project_keys_test.go b/sentry/project_keys_test.go index e87a881..f6687a9 100644 --- a/sentry/project_keys_test.go +++ b/sentry/project_keys_test.go @@ -18,38 +18,91 @@ func TestProjectKeysService_List(t *testing.T) { assertMethod(t, "GET", r) w.Header().Set("Content-Type", "application/json") w.Header().Set("Link", "; rel=\"previous\"; results=\"true\"; cursor=\"0:0:1\", ; rel=\"next\"; results=\"false\"; cursor=\"1584513610301:0:1\"") - fmt.Fprint(w, `[{ - "browserSdk": { - "choices": [ - [ - "latest", - "latest" - ], - [ - "4.x", - "4.x" + fmt.Fprint(w, `[ + { + "id": "60120449b6b1d5e45f75561e6dabd80b", + "name": "Liked Pegasus", + "label": "Liked Pegasus", + "public": "60120449b6b1d5e45f75561e6dabd80b", + "secret": "189485c3b8ccf582bf5e12c530ef8858", + "projectId": 4505281256090153, + "isActive": true, + "rateLimit": { + "window": 7200, + "count": 1000 + }, + "dsn": { + "secret": "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + "public": "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + "csp": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + "security": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + "minidump": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + "nel": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + "unreal": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + "cdn": "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + "crons": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/" + }, + "browserSdkVersion": "7.x", + "browserSdk": { + "choices": [ + [ + "latest", + "latest" + ], + [ + "7.x", + "7.x" + ] ] - ] + }, + "dateCreated": "2023-06-21T19:50:26.036254Z", + "dynamicSdkLoaderOptions": { + "hasReplay": true, + "hasPerformance": true, + "hasDebug": true + } }, - "browserSdkVersion": "4.x", - "dateCreated": "2018-09-20T15:48:07.397Z", - "dsn": { - "cdn": "https://sentry.io/js-sdk-loader/cfc7b0341c6e4f6ea1a9d256a30dba00.min.js", - "csp": "https://sentry.io/api/2/csp-report/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", - "minidump": "https://sentry.io/api/2/minidump/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", - "public": "https://cfc7b0341c6e4f6ea1a9d256a30dba00@sentry.io/2", - "secret": "https://cfc7b0341c6e4f6ea1a9d256a30dba00:a07dcd97aa56481f82aeabaed43ca448@sentry.io/2", - "security": "https://sentry.io/api/2/security/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00" - }, - "id": "cfc7b0341c6e4f6ea1a9d256a30dba00", - "isActive": true, - "label": "Fabulous Key", - "name": "Fabulous Key", - "projectId": 2, - "public": "cfc7b0341c6e4f6ea1a9d256a30dba00", - "rateLimit": null, - "secret": "a07dcd97aa56481f82aeabaed43ca448" - }]`) + { + "id": "da8d69cb17e80677b76e08fde4656b93", + "name": "Bold Oarfish", + "label": "Bold Oarfish", + "public": "da8d69cb17e80677b76e08fde4656b93", + "secret": "5c241ebc42ccfbec281cbefbedc7ab96", + "projectId": 4505281256090153, + "isActive": true, + "rateLimit": null, + "dsn": { + "secret": "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + "public": "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + "csp": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + "security": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + "minidump": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + "nel": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + "unreal": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + "cdn": "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + "crons": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/" + }, + "browserSdkVersion": "7.x", + "browserSdk": { + "choices": [ + [ + "latest", + "latest" + ], + [ + "7.x", + "7.x" + ] + ] + }, + "dateCreated": "2023-06-21T19:50:26.036254Z", + "dynamicSdkLoaderOptions": { + "hasReplay": true, + "hasPerformance": true, + "hasDebug": true + } + } + ]`) }) ctx := context.Background() @@ -58,22 +111,63 @@ func TestProjectKeysService_List(t *testing.T) { expected := []*ProjectKey{ { - ID: "cfc7b0341c6e4f6ea1a9d256a30dba00", - Name: "Fabulous Key", - Label: "Fabulous Key", - Public: "cfc7b0341c6e4f6ea1a9d256a30dba00", - Secret: "a07dcd97aa56481f82aeabaed43ca448", - ProjectID: json.Number("2"), + ID: "60120449b6b1d5e45f75561e6dabd80b", + Name: "Liked Pegasus", + Label: "Liked Pegasus", + Public: "60120449b6b1d5e45f75561e6dabd80b", + Secret: "189485c3b8ccf582bf5e12c530ef8858", + ProjectID: json.Number("4505281256090153"), IsActive: true, + RateLimit: &ProjectKeyRateLimit{ + Window: 7200, + Count: 1000, + }, DSN: ProjectKeyDSN{ - Secret: "https://cfc7b0341c6e4f6ea1a9d256a30dba00:a07dcd97aa56481f82aeabaed43ca448@sentry.io/2", - Public: "https://cfc7b0341c6e4f6ea1a9d256a30dba00@sentry.io/2", - CSP: "https://sentry.io/api/2/csp-report/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", - Security: "https://sentry.io/api/2/security/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", - Minidump: "https://sentry.io/api/2/minidump/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", - CDN: "https://sentry.io/js-sdk-loader/cfc7b0341c6e4f6ea1a9d256a30dba00.min.js", + Secret: "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + Public: "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + CSP: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + Security: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + Minidump: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + NEL: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + Unreal: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + CDN: "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + Crons: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/", + }, + BrowserSDKVersion: "7.x", + DateCreated: mustParseTime("2023-06-21T19:50:26.036254Z"), + DynamicSDKLoaderOptions: ProjectKeyDynamicSDKLoaderOptions{ + HasReplay: true, + HasPerformance: true, + HasDebugFiles: true, + }, + }, + { + ID: "da8d69cb17e80677b76e08fde4656b93", + Name: "Bold Oarfish", + Label: "Bold Oarfish", + Public: "da8d69cb17e80677b76e08fde4656b93", + Secret: "5c241ebc42ccfbec281cbefbedc7ab96", + ProjectID: json.Number("4505281256090153"), + IsActive: true, + RateLimit: nil, + DSN: ProjectKeyDSN{ + Secret: "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + Public: "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + CSP: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + Security: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + Minidump: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + NEL: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + Unreal: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + CDN: "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + Crons: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/", + }, + BrowserSDKVersion: "7.x", + DateCreated: mustParseTime("2023-06-21T19:50:26.036254Z"), + DynamicSDKLoaderOptions: ProjectKeyDynamicSDKLoaderOptions{ + HasReplay: true, + HasPerformance: true, + HasDebugFiles: true, }, - DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), }, } assert.Equal(t, expected, projectKeys) @@ -145,7 +239,8 @@ func TestProjectKeysService_Create(t *testing.T) { Minidump: "https://sentry.io/api/2/minidump/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", CDN: "https://sentry.io/js-sdk-loader/cfc7b0341c6e4f6ea1a9d256a30dba00.min.js", }, - DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), + BrowserSDKVersion: "4.x", + DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), } assert.Equal(t, expected, projectKey) } @@ -216,7 +311,8 @@ func TestProjectKeysService_Update(t *testing.T) { Minidump: "https://sentry.io/api/2/minidump/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", CDN: "https://sentry.io/js-sdk-loader/cfc7b0341c6e4f6ea1a9d256a30dba00.min.js", }, - DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), + BrowserSDKVersion: "4.x", + DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), } assert.Equal(t, expected, projectKey) } @@ -300,7 +396,8 @@ func TestProjectKeysService_Update_RateLimit(t *testing.T) { Minidump: "https://sentry.io/api/2/minidump/?sentry_key=cfc7b0341c6e4f6ea1a9d256a30dba00", CDN: "https://sentry.io/js-sdk-loader/cfc7b0341c6e4f6ea1a9d256a30dba00.min.js", }, - DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), + BrowserSDKVersion: "4.x", + DateCreated: mustParseTime("2018-09-20T15:48:07.397Z"), } assert.Equal(t, expected, projectKey) } From 164dd3150cfc4967a7d7e949993395a48de2fb1a Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Fri, 3 May 2024 22:49:07 +0100 Subject: [PATCH 03/11] feat: retrieve a client key --- sentry/project_keys.go | 25 +++++++++- sentry/project_keys_test.go | 91 +++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/sentry/project_keys.go b/sentry/project_keys.go index 0c3a24b..ca7ff6b 100644 --- a/sentry/project_keys.go +++ b/sentry/project_keys.go @@ -54,9 +54,15 @@ type ProjectKey struct { // https://docs.sentry.io/api/projects/ type ProjectKeysService service +type ListProjectKeysParams struct { + ListCursorParams + + Status *string `url:"status,omitempty"` +} + // List client keys bound to a project. // https://docs.sentry.io/api/projects/get-project-keys/ -func (s *ProjectKeysService) List(ctx context.Context, organizationSlug string, projectSlug string, params *ListCursorParams) ([]*ProjectKey, *Response, error) { +func (s *ProjectKeysService) List(ctx context.Context, organizationSlug string, projectSlug string, params *ListProjectKeysParams) ([]*ProjectKey, *Response, error) { u := fmt.Sprintf("0/projects/%v/%v/keys/", organizationSlug, projectSlug) u, err := addQuery(u, params) if err != nil { @@ -76,6 +82,23 @@ func (s *ProjectKeysService) List(ctx context.Context, organizationSlug string, return projectKeys, resp, nil } +// Get details of a client key. +// https://docs.sentry.io/api/projects/retrieve-a-client-key/ +func (s *ProjectKeysService) Get(ctx context.Context, organizationSlug string, projectSlug string, id string) (*ProjectKey, *Response, error) { + u := fmt.Sprintf("0/projects/%v/%v/keys/%v/", organizationSlug, projectSlug, id) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + projectKey := new(ProjectKey) + resp, err := s.client.Do(ctx, req, projectKey) + if err != nil { + return nil, resp, err + } + return projectKey, resp, nil +} + // CreateProjectKeyParams are the parameters for ProjectKeyService.Create. type CreateProjectKeyParams struct { Name string `json:"name,omitempty"` diff --git a/sentry/project_keys_test.go b/sentry/project_keys_test.go index f6687a9..02f8005 100644 --- a/sentry/project_keys_test.go +++ b/sentry/project_keys_test.go @@ -173,6 +173,97 @@ func TestProjectKeysService_List(t *testing.T) { assert.Equal(t, expected, projectKeys) } +func TestProjectKeysService_Get(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/api/0/projects/the-interstellar-jurisdiction/pump-station/keys/60120449b6b1d5e45f75561e6dabd80b/", func(w http.ResponseWriter, r *http.Request) { + assertMethod(t, "GET", r) + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, `{ + "id": "60120449b6b1d5e45f75561e6dabd80b", + "name": "Liked Pegasus", + "label": "Liked Pegasus", + "public": "60120449b6b1d5e45f75561e6dabd80b", + "secret": "189485c3b8ccf582bf5e12c530ef8858", + "projectId": 4505281256090153, + "isActive": true, + "rateLimit": { + "window": 7200, + "count": 1000 + }, + "dsn": { + "secret": "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + "public": "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + "csp": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + "security": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + "minidump": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + "nel": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + "unreal": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + "cdn": "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + "crons": "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/" + }, + "browserSdkVersion": "7.x", + "browserSdk": { + "choices": [ + [ + "latest", + "latest" + ], + [ + "7.x", + "7.x" + ] + ] + }, + "dateCreated": "2023-06-21T19:50:26.036254Z", + "dynamicSdkLoaderOptions": { + "hasReplay": true, + "hasPerformance": true, + "hasDebug": true + } + }`) + }) + + ctx := context.Background() + projectKey, _, err := client.ProjectKeys.Get(ctx, "the-interstellar-jurisdiction", "pump-station", "60120449b6b1d5e45f75561e6dabd80b") + assert.NoError(t, err) + + expected := &ProjectKey{ + ID: "60120449b6b1d5e45f75561e6dabd80b", + Name: "Liked Pegasus", + Label: "Liked Pegasus", + Public: "60120449b6b1d5e45f75561e6dabd80b", + Secret: "189485c3b8ccf582bf5e12c530ef8858", + ProjectID: json.Number("4505281256090153"), + IsActive: true, + RateLimit: &ProjectKeyRateLimit{ + Window: 7200, + Count: 1000, + }, + DSN: ProjectKeyDSN{ + Secret: "https://a785682ddda742d7a8a4088810e67701:bcd99b3790b3441c85ce4b1eaa854f66@o4504765715316736.ingest.sentry.io/4505281256090153", + Public: "https://a785682ddda742d7a8a4088810e67791@o4504765715316736.ingest.sentry.io/4505281256090153", + CSP: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/csp-report/?sentry_key=a785682ddda719b7a8a4011110d75598", + Security: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/security/?sentry_key=a785682ddda719b7a8a4011110d75598", + Minidump: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/minidump/?sentry_key=a785682ddda719b7a8a4011110d75598", + NEL: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/nel/?sentry_key=a785682ddda719b7a8a4011110d75598", + Unreal: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/unreal/a785682ddda719b7a8a4011110d75598/", + CDN: "https://js.sentry-cdn.com/a785682ddda719b7a8a4011110d75598.min.js", + Crons: "https://o4504765715316736.ingest.sentry.io/api/4505281256090153/crons/___MONITOR_SLUG___/a785682ddda719b7a8a4011110d75598/", + }, + BrowserSDKVersion: "7.x", + DateCreated: mustParseTime("2023-06-21T19:50:26.036254Z"), + DynamicSDKLoaderOptions: ProjectKeyDynamicSDKLoaderOptions{ + HasReplay: true, + HasPerformance: true, + HasDebugFiles: true, + }, + } + + assert.Equal(t, expected, projectKey) +} + func TestProjectKeysService_Create(t *testing.T) { client, mux, _, teardown := setup() defer teardown() From 90f2525c798f606702319a92b5c84ad26dbe4128 Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Sun, 5 May 2024 02:45:01 +0100 Subject: [PATCH 04/11] feat: ability to supply options and query to the list projects endpoint --- sentry/projects.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sentry/projects.go b/sentry/projects.go index 6c6afd9..1fa7c58 100644 --- a/sentry/projects.go +++ b/sentry/projects.go @@ -92,9 +92,16 @@ type ProjectSummaryTeam struct { // https://docs.sentry.io/api/projects/ type ProjectsService service +type ListProjectsParams struct { + ListCursorParams + + Options string `url:"options,omitempty"` + Query string `url:"query,omitempty"` +} + // List projects available. // https://docs.sentry.io/api/projects/list-your-projects/ -func (s *ProjectsService) List(ctx context.Context, params *ListCursorParams) ([]*Project, *Response, error) { +func (s *ProjectsService) List(ctx context.Context, params *ListProjectsParams) ([]*Project, *Response, error) { u := "0/projects/" u, err := addQuery(u, params) if err != nil { From bbb059f9d8b5be2a84f3dcc8ac955301f44be094 Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Sun, 5 May 2024 02:50:01 +0100 Subject: [PATCH 05/11] feat: add projectSlug query to enable/disable spike protection endpoint --- sentry/sentry.go | 5 ++--- sentry/sentry_test.go | 6 +++--- sentry/spike_protections.go | 13 ++++++++++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/sentry/sentry.go b/sentry/sentry.go index 32b1244..6ac56ab 100644 --- a/sentry/sentry.go +++ b/sentry/sentry.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "reflect" @@ -357,7 +356,7 @@ func CheckResponse(r *http.Response) error { } errorResponse := &ErrorResponse{Response: r} - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err == nil && data != nil { apiError := new(APIError) json.Unmarshal(data, apiError) @@ -368,7 +367,7 @@ func CheckResponse(r *http.Response) error { } } // Re-populate error response body. - r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + r.Body = io.NopCloser(bytes.NewBuffer(data)) switch { case r.StatusCode == http.StatusTooManyRequests && diff --git a/sentry/sentry_test.go b/sentry/sentry_test.go index a0b0312..813b3ac 100644 --- a/sentry/sentry_test.go +++ b/sentry/sentry_test.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -272,7 +272,7 @@ func TestCheckResponse(t *testing.T) { res := &http.Response{ Request: &http.Request{}, StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader(tc.body)), + Body: io.NopCloser(strings.NewReader(tc.body)), } err := CheckResponse(res) @@ -313,7 +313,7 @@ func TestCheckResponse_rateLimit(t *testing.T) { Request: &http.Request{}, StatusCode: http.StatusTooManyRequests, Header: http.Header{}, - Body: ioutil.NopCloser(strings.NewReader(`{"detail": "Rate limit exceeded"}`)), + Body: io.NopCloser(strings.NewReader(`{"detail": "Rate limit exceeded"}`)), } tc.addHeaders(res) diff --git a/sentry/spike_protections.go b/sentry/spike_protections.go index 20c0d6b..5ef53c5 100644 --- a/sentry/spike_protections.go +++ b/sentry/spike_protections.go @@ -9,11 +9,17 @@ import ( type SpikeProtectionsService service type SpikeProtectionParams struct { - Projects []string `json:"projects"` + ProjectSlug string `json:"-" url:"projectSlug,omitempty"` + Projects []string `json:"projects" url:"-"` } func (s *SpikeProtectionsService) Enable(ctx context.Context, organizationSlug string, params *SpikeProtectionParams) (*Response, error) { u := fmt.Sprintf("0/organizations/%v/spike-protections/", organizationSlug) + u, err := addQuery(u, params) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest(http.MethodPost, u, params) if err != nil { return nil, err @@ -24,6 +30,11 @@ func (s *SpikeProtectionsService) Enable(ctx context.Context, organizationSlug s func (s *SpikeProtectionsService) Disable(ctx context.Context, organizationSlug string, params *SpikeProtectionParams) (*Response, error) { u := fmt.Sprintf("0/organizations/%v/spike-protections/", organizationSlug) + u, err := addQuery(u, params) + if err != nil { + return nil, err + } + req, err := s.client.NewRequest(http.MethodDelete, u, params) if err != nil { return nil, err From b33f9fa02d136a3b696008c2d384883f6270ee20 Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Sun, 5 May 2024 03:31:58 +0100 Subject: [PATCH 06/11] feat: new OrganizationProjectsService --- sentry/organization_projects.go | 37 +++++++++++++++++++++++++++++++++ sentry/projects.go | 3 --- sentry/sentry.go | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 sentry/organization_projects.go diff --git a/sentry/organization_projects.go b/sentry/organization_projects.go new file mode 100644 index 0000000..abaa48c --- /dev/null +++ b/sentry/organization_projects.go @@ -0,0 +1,37 @@ +package sentry + +import ( + "context" + "fmt" +) + +type OrganizationProjectsService service + +type ListOrganizationProjectsParams struct { + ListCursorParams + + Options string `url:"options,omitempty"` + Query string `url:"query,omitempty"` +} + +// List an Organization's Projects +// https://docs.sentry.io/api/organizations/list-an-organizations-projects/ +func (s *OrganizationProjectsService) List(ctx context.Context, organizationSlug string, params *ListOrganizationProjectsParams) ([]*Project, *Response, error) { + u := fmt.Sprintf("0/organizations/%v/projects/", organizationSlug) + u, err := addQuery(u, params) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + projects := []*Project{} + resp, err := s.client.Do(ctx, req, &projects) + if err != nil { + return nil, resp, err + } + return projects, resp, nil +} diff --git a/sentry/projects.go b/sentry/projects.go index 1fa7c58..4b3c7dd 100644 --- a/sentry/projects.go +++ b/sentry/projects.go @@ -94,9 +94,6 @@ type ProjectsService service type ListProjectsParams struct { ListCursorParams - - Options string `url:"options,omitempty"` - Query string `url:"query,omitempty"` } // List projects available. diff --git a/sentry/sentry.go b/sentry/sentry.go index 6ac56ab..a023bb0 100644 --- a/sentry/sentry.go +++ b/sentry/sentry.go @@ -54,6 +54,7 @@ type Client struct { OrganizationCodeMappings *OrganizationCodeMappingsService OrganizationIntegrations *OrganizationIntegrationsService OrganizationMembers *OrganizationMembersService + OrganizationProjects *OrganizationProjectsService OrganizationRepositories *OrganizationRepositoriesService Organizations *OrganizationsService ProjectFilters *ProjectFiltersService @@ -95,6 +96,7 @@ func NewClient(httpClient *http.Client) *Client { c.OrganizationCodeMappings = (*OrganizationCodeMappingsService)(&c.common) c.OrganizationIntegrations = (*OrganizationIntegrationsService)(&c.common) c.OrganizationMembers = (*OrganizationMembersService)(&c.common) + c.OrganizationProjects = (*OrganizationProjectsService)(&c.common) c.OrganizationRepositories = (*OrganizationRepositoriesService)(&c.common) c.Organizations = (*OrganizationsService)(&c.common) c.ProjectFilters = (*ProjectFiltersService)(&c.common) From 2092363c6dad7ea6eaf7b7f5ef8b63c56becff64 Mon Sep 17 00:00:00 2001 From: Jian Yuan Lee Date: Sun, 5 May 2024 23:55:49 +0100 Subject: [PATCH 07/11] feat: OrganizationIntegration endpoints use json.RawMessage --- sentry/organization_integrations.go | 15 +++++---- sentry/organization_integrations_test.go | 42 ++++++++++++------------ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/sentry/organization_integrations.go b/sentry/organization_integrations.go index 687296e..69af055 100644 --- a/sentry/organization_integrations.go +++ b/sentry/organization_integrations.go @@ -2,6 +2,7 @@ package sentry import ( "context" + "encoding/json" "fmt" "time" ) @@ -17,7 +18,7 @@ type OrganizationIntegrationProvider struct { } // IntegrationConfigData for defining integration-specific configuration data. -type IntegrationConfigData map[string]interface{} +type IntegrationConfigData map[string]json.RawMessage // OrganizationIntegration represents an integration added for the organization. // https://github.com/getsentry/sentry/blob/22.7.0/src/sentry/api/serializers/models/integration.py#L93 @@ -33,11 +34,11 @@ type OrganizationIntegration struct { Provider OrganizationIntegrationProvider `json:"provider"` // https://github.com/getsentry/sentry/blob/22.7.0/src/sentry/api/serializers/models/integration.py#L138 - ConfigData *IntegrationConfigData `json:"configData"` - ExternalId string `json:"externalId"` - OrganizationId int `json:"organizationId"` - OrganizationIntegrationStatus string `json:"organizationIntegrationStatus"` - GracePeriodEnd *time.Time `json:"gracePeriodEnd"` + ConfigData json.RawMessage `json:"configData"` + ExternalId string `json:"externalId"` + OrganizationId int `json:"organizationId"` + OrganizationIntegrationStatus string `json:"organizationIntegrationStatus"` + GracePeriodEnd *time.Time `json:"gracePeriodEnd"` } // OrganizationIntegrationsService provides methods for accessing Sentry organization integrations API endpoints. @@ -88,7 +89,7 @@ func (s *OrganizationIntegrationsService) Get(ctx context.Context, organizationS return integration, resp, nil } -type UpdateConfigOrganizationIntegrationsParams = IntegrationConfigData +type UpdateConfigOrganizationIntegrationsParams = json.RawMessage // UpdateConfig - update configData for organization integration. // https://github.com/getsentry/sentry/blob/22.7.0/src/sentry/api/endpoints/integrations/organization_integrations/details.py#L94-L102 diff --git a/sentry/organization_integrations_test.go b/sentry/organization_integrations_test.go index 63ab695..8846a3f 100644 --- a/sentry/organization_integrations_test.go +++ b/sentry/organization_integrations_test.go @@ -81,7 +81,7 @@ func TestOrganizationIntegrationsService_List(t *testing.T) { "stacktrace-link", }, }, - ConfigData: &IntegrationConfigData{}, + ConfigData: json.RawMessage("{}"), ExternalId: "87654321", OrganizationId: 2, OrganizationIntegrationStatus: "active", @@ -181,15 +181,15 @@ func TestOrganizationIntegrationsService_Get(t *testing.T) { "incident-management", }, }, - ConfigData: &IntegrationConfigData{ - "service_table": []interface{}{ - map[string]interface{}{ - "service": "testing123", - "integration_key": "abc123xyz", - "id": json.Number("22222"), - }, - }, - }, + ConfigData: json.RawMessage(`{ + "service_table": [ + { + "service": "testing123", + "integration_key": "abc123xyz", + "id": 22222 + } + ] + }`), ExternalId: "999999", OrganizationId: 2, OrganizationIntegrationStatus: "active", @@ -207,20 +207,20 @@ func TestOrganizationIntegrationsService_UpdateConfig(t *testing.T) { w.Header().Set("Content-Type", "application/json") }) - updateConfigOrganizationIntegrationsParams := UpdateConfigOrganizationIntegrationsParams{ - "service_table": []interface{}{ - map[string]interface{}{ - "service": "testing123", + updateConfigOrganizationIntegrationsParams := UpdateConfigOrganizationIntegrationsParams(`{ + "service_table": [ + { + "service": "testing123", "integration_key": "abc123xyz", - "id": json.Number("22222"), + "id": 22222 }, - map[string]interface{}{ - "service": "testing456", + { + "service": "testing456", "integration_key": "efg456lmn", - "id": "", - }, - }, - } + "id": "" + } + ] + }`) ctx := context.Background() resp, err := client.OrganizationIntegrations.UpdateConfig(ctx, "the-interstellar-jurisdiction", "456789", &updateConfigOrganizationIntegrationsParams) assert.NoError(t, err) From 954549eb82287b6e8f1bf795f4e23d622e1ca19c Mon Sep 17 00:00:00 2001 From: Andrew Gadzik Date: Tue, 14 May 2024 21:12:22 -0400 Subject: [PATCH 08/11] Adds ComparisonDelta prop to MetricAlert (#93) --- sentry/metric_alerts.go | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry/metric_alerts.go b/sentry/metric_alerts.go index ef9acb2..dbf710d 100644 --- a/sentry/metric_alerts.go +++ b/sentry/metric_alerts.go @@ -20,6 +20,7 @@ type MetricAlert struct { TimeWindow *float64 `json:"timeWindow,omitempty"` ThresholdType *int `json:"thresholdType,omitempty"` ResolveThreshold *float64 `json:"resolveThreshold,omitempty"` + ComparisonDelta *float64 `json:"comparisonDelta,omitempty"` Triggers []*MetricAlertTrigger `json:"triggers,omitempty"` Projects []string `json:"projects,omitempty"` Owner *string `json:"owner,omitempty"` From 1d83a5b013bdf6ff36fb04cbce02d8e8d7f7a357 Mon Sep 17 00:00:00 2001 From: Marten Deng Date: Wed, 19 Jun 2024 14:54:08 +1000 Subject: [PATCH 09/11] duplicate definition of ComparisonDelta prop --- sentry/metric_alerts.go | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry/metric_alerts.go b/sentry/metric_alerts.go index 492564a..938cc9d 100644 --- a/sentry/metric_alerts.go +++ b/sentry/metric_alerts.go @@ -20,7 +20,6 @@ type MetricAlert struct { TimeWindow *float64 `json:"timeWindow,omitempty"` ThresholdType *int `json:"thresholdType,omitempty"` ResolveThreshold *float64 `json:"resolveThreshold,omitempty"` - ComparisonDelta *float64 `json:"comparisonDelta,omitempty"` Triggers []*MetricAlertTrigger `json:"triggers,omitempty"` Projects []string `json:"projects,omitempty"` Owner *string `json:"owner,omitempty"` From af41ef467f2d1a05a8f5a2797ff2ba33537426c0 Mon Sep 17 00:00:00 2001 From: Marten Deng Date: Wed, 19 Jun 2024 15:08:00 +1000 Subject: [PATCH 10/11] update go.sum file --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 353c0a0..91ca244 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4 github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 62455a8dff79263728a8d1dff49c72a7e7c35f40 Mon Sep 17 00:00:00 2001 From: Marten Deng Date: Fri, 21 Jun 2024 10:06:34 +1000 Subject: [PATCH 11/11] Tag commit with version