mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
d177770560
commit
059ba25973
@ -19,9 +19,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errAPIKeyInvalid = errutil.Unauthorized("api-key.invalid", errutil.WithPublicMessage("Invalid API key"))
|
errAPIKeyInvalid = errutil.Unauthorized("api-key.invalid", errutil.WithPublicMessage("Invalid API key"))
|
||||||
errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key"))
|
errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key"))
|
||||||
errAPIKeyRevoked = errutil.Unauthorized("api-key.revoked", errutil.WithPublicMessage("Revoked 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)
|
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")
|
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 the api key don't belong to a service account construct the identity and return it
|
||||||
if apiKey.ServiceAccountId == nil || *apiKey.ServiceAccountId < 1 {
|
if apiKey.ServiceAccountId == nil || *apiKey.ServiceAccountId < 1 {
|
||||||
return &authn.Identity{
|
return &authn.Identity{
|
||||||
|
@ -109,6 +109,17 @@ func TestAPIKey_Authenticate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedErr: errAPIKeyRevoked,
|
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 {
|
for _, tt := range tests {
|
||||||
@ -123,10 +134,12 @@ func TestAPIKey_Authenticate(t *testing.T) {
|
|||||||
if tt.expectedErr != nil {
|
if tt.expectedErr != nil {
|
||||||
assert.Nil(t, identity)
|
assert.Nil(t, identity)
|
||||||
assert.ErrorIs(t, err, tt.expectedErr)
|
assert.ErrorIs(t, err, tt.expectedErr)
|
||||||
} else {
|
return
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.EqualValues(t, *tt.expectedIdentity, *identity)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user