AuthN: Check API Key is not trying to access another organization (#78749)

* AuthN: Check API Key is not trying to access another organization

* Revert local change

* Add test

* Discussed with Kalle we should set r.OrgID

* Syntax sugar

* Suggestion org-mismatch
This commit is contained in:
Gabriel MABILLE 2023-11-29 10:25:46 +01:00 committed by GitHub
parent d177770560
commit 059ba25973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 6 deletions

View File

@ -19,9 +19,10 @@ import (
)
var (
errAPIKeyInvalid = errutil.Unauthorized("api-key.invalid", errutil.WithPublicMessage("Invalid API key"))
errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key"))
errAPIKeyRevoked = errutil.Unauthorized("api-key.revoked", errutil.WithPublicMessage("Revoked API key"))
errAPIKeyInvalid = errutil.Unauthorized("api-key.invalid", errutil.WithPublicMessage("Invalid API key"))
errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key"))
errAPIKeyRevoked = errutil.Unauthorized("api-key.revoked", errutil.WithPublicMessage("Revoked API key"))
errAPIKeyOrgMismatch = errutil.Unauthorized("api-key.organization-mismatch", errutil.WithPublicMessage("API key does not belong to the requested organization"))
)
var _ authn.HookClient = new(APIKey)
@ -62,6 +63,12 @@ func (s *APIKey) Authenticate(ctx context.Context, r *authn.Request) (*authn.Ide
return nil, errAPIKeyRevoked.Errorf("Api key is revoked")
}
if r.OrgID == 0 {
r.OrgID = apiKey.OrgID
} else if r.OrgID != apiKey.OrgID {
return nil, errAPIKeyOrgMismatch.Errorf("API does not belong in Organization %v", r.OrgID)
}
// if the api key don't belong to a service account construct the identity and return it
if apiKey.ServiceAccountId == nil || *apiKey.ServiceAccountId < 1 {
return &authn.Identity{

View File

@ -109,6 +109,17 @@ func TestAPIKey_Authenticate(t *testing.T) {
},
expectedErr: errAPIKeyRevoked,
},
{
desc: "should fail for api key in another organization",
req: &authn.Request{OrgID: 1, HTTPRequest: &http.Request{Header: map[string][]string{"Authorization": {"Bearer " + secret}}}},
expectedKey: &apikey.APIKey{
ID: 1,
OrgID: 2,
Key: hash,
ServiceAccountId: intPtr(1),
},
expectedErr: errAPIKeyOrgMismatch,
},
}
for _, tt := range tests {
@ -123,10 +134,12 @@ func TestAPIKey_Authenticate(t *testing.T) {
if tt.expectedErr != nil {
assert.Nil(t, identity)
assert.ErrorIs(t, err, tt.expectedErr)
} else {
assert.NoError(t, err)
assert.EqualValues(t, *tt.expectedIdentity, *identity)
return
}
assert.NoError(t, err)
assert.EqualValues(t, *tt.expectedIdentity, *identity)
assert.Equal(t, tt.req.OrgID, tt.expectedIdentity.OrgID, "the request organization should match the identity's one")
})
}
}