Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit befddae

Browse files
authoredFeb 22, 2024··
Merge branch 'main' into file-delivery-order
2 parents 1f02dac + 5c244b3 commit befddae

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: enhancement
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Respond with 429 if elasticsearch API key auth gives 429
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component:
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: 3278
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
# issue: https://github.com/owner/repo/1234

‎internal/pkg/api/auth.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package api
77

88
import (
99
"errors"
10-
"fmt"
1110
"net/http"
1211
"time"
1312

@@ -60,7 +59,7 @@ func authAPIKey(r *http.Request, bulker bulk.Bulk, c cache.Cache) (*apikey.APIKe
6059
Str(LogAPIKeyID, key.ID).
6160
Int64(ECSEventDuration, time.Since(start).Nanoseconds()).
6261
Msg("ApiKey fail authentication")
63-
return nil, fmt.Errorf("%w: %w", apikey.ErrUnauthorized, err)
62+
return nil, err
6463
}
6564

6665
hlog.FromRequest(r).Debug().

‎internal/pkg/api/error.go

+9
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ func NewHTTPErrResp(err error) HTTPErrResp {
137137
zerolog.WarnLevel,
138138
},
139139
},
140+
{
141+
apikey.ErrElasticsearchAuthLimit,
142+
HTTPErrResp{
143+
http.StatusTooManyRequests,
144+
"ElasticsearchAPIKeyAuthLimit",
145+
"exceeded the elasticsearch api key auth limit",
146+
zerolog.WarnLevel,
147+
},
148+
},
140149
{
141150
os.ErrDeadlineExceeded,
142151
HTTPErrResp{

‎internal/pkg/apikey/auth.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import (
1515
)
1616

1717
var (
18-
ErrUnauthorized = errors.New("unauthorized")
18+
ErrUnauthorized = errors.New("unauthorized")
19+
ErrElasticsearchAuthLimit = errors.New("elasticsearch auth limit")
1920
)
2021

2122
// SecurityInfo contains all related information about an APIKey that Elasticsearch tracks.
@@ -51,7 +52,11 @@ func (k APIKey) Authenticate(ctx context.Context, es *elasticsearch.Client) (*Se
5152
}
5253

5354
if res.IsError() {
54-
return nil, fmt.Errorf("%w: %w", ErrUnauthorized, fmt.Errorf("apikey auth response %s: %s", k.ID, res.String()))
55+
returnError := ErrUnauthorized
56+
if res.StatusCode == 429 {
57+
returnError = ErrElasticsearchAuthLimit
58+
}
59+
return nil, fmt.Errorf("%w: %w", returnError, fmt.Errorf("apikey auth response %s: %s", k.ID, res.String()))
5560
}
5661

5762
var info SecurityInfo

‎internal/pkg/apikey/auth_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package apikey
6+
7+
import (
8+
"context"
9+
"encoding/base64"
10+
"net/http"
11+
"testing"
12+
13+
"github.com/elastic/fleet-server/v7/internal/pkg/testing/esutil"
14+
"github.com/elastic/go-elasticsearch/v8"
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
const (
19+
rawToken = " foo:bar"
20+
)
21+
22+
func setup(t *testing.T, statusCode int) (context.Context, *APIKey, *elasticsearch.Client) {
23+
token := base64.StdEncoding.EncodeToString([]byte(rawToken))
24+
apiKey, err := NewAPIKeyFromToken(token)
25+
assert.NoError(t, err)
26+
ctx := context.Background()
27+
28+
mockES, mockTransport := esutil.MockESClient(t)
29+
mockTransport.RoundTripFn = func(req *http.Request) (*http.Response, error) { return &http.Response{StatusCode: statusCode}, nil }
30+
31+
return ctx, apiKey, mockES
32+
}
33+
34+
func TestAuth429(t *testing.T) {
35+
ctx, apiKey, mockES := setup(t, 429)
36+
_, err := apiKey.Authenticate(ctx, mockES)
37+
38+
assert.Equal(t, "elasticsearch auth limit: apikey auth response foo: [429 Too Many Requests] ", err.Error())
39+
}
40+
41+
func TestAuth401(t *testing.T) {
42+
ctx, apiKey, mockES := setup(t, 401)
43+
_, err := apiKey.Authenticate(ctx, mockES)
44+
45+
assert.Equal(t, "unauthorized: apikey auth response foo: [401 Unauthorized] ", err.Error())
46+
}

0 commit comments

Comments
 (0)
Please sign in to comment.