apiclient/apiserver: lint (#2739)
This commit is contained in:
parent
03bb194d2c
commit
75d8ad9798
|
@ -49,15 +49,15 @@ type AlertsDeleteOpts struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AlertsService) Add(ctx context.Context, alerts models.AddAlertsRequest) (*models.AddAlertsResponse, *Response, error) {
|
func (s *AlertsService) Add(ctx context.Context, alerts models.AddAlertsRequest) (*models.AddAlertsResponse, *Response, error) {
|
||||||
var addedIds models.AddAlertsResponse
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/alerts", s.client.URLPrefix)
|
u := fmt.Sprintf("%s/alerts", s.client.URLPrefix)
|
||||||
req, err := s.client.NewRequest(http.MethodPost, u, &alerts)
|
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodPost, u, &alerts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var addedIds models.AddAlertsResponse
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &addedIds)
|
resp, err := s.client.Do(ctx, req, &addedIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -68,22 +68,16 @@ func (s *AlertsService) Add(ctx context.Context, alerts models.AddAlertsRequest)
|
||||||
|
|
||||||
// to demo query arguments
|
// to demo query arguments
|
||||||
func (s *AlertsService) List(ctx context.Context, opts AlertsListOpts) (*models.GetAlertsResponse, *Response, error) {
|
func (s *AlertsService) List(ctx context.Context, opts AlertsListOpts) (*models.GetAlertsResponse, *Response, error) {
|
||||||
var (
|
|
||||||
alerts models.GetAlertsResponse
|
|
||||||
URI string
|
|
||||||
)
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/alerts", s.client.URLPrefix)
|
u := fmt.Sprintf("%s/alerts", s.client.URLPrefix)
|
||||||
params, err := qs.Values(opts)
|
|
||||||
|
|
||||||
|
params, err := qs.Values(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("building query: %w", err)
|
return nil, nil, fmt.Errorf("building query: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
URI := u
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
URI = fmt.Sprintf("%s?%s", u, params.Encode())
|
URI = fmt.Sprintf("%s?%s", URI, params.Encode())
|
||||||
} else {
|
|
||||||
URI = u
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, URI, nil)
|
req, err := s.client.NewRequest(http.MethodGet, URI, nil)
|
||||||
|
@ -91,6 +85,8 @@ func (s *AlertsService) List(ctx context.Context, opts AlertsListOpts) (*models.
|
||||||
return nil, nil, fmt.Errorf("building request: %w", err)
|
return nil, nil, fmt.Errorf("building request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alerts := models.GetAlertsResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &alerts)
|
resp, err := s.client.Do(ctx, req, &alerts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, fmt.Errorf("performing request: %w", err)
|
return nil, resp, fmt.Errorf("performing request: %w", err)
|
||||||
|
@ -101,8 +97,6 @@ func (s *AlertsService) List(ctx context.Context, opts AlertsListOpts) (*models.
|
||||||
|
|
||||||
// to demo query arguments
|
// to demo query arguments
|
||||||
func (s *AlertsService) Delete(ctx context.Context, opts AlertsDeleteOpts) (*models.DeleteAlertsResponse, *Response, error) {
|
func (s *AlertsService) Delete(ctx context.Context, opts AlertsDeleteOpts) (*models.DeleteAlertsResponse, *Response, error) {
|
||||||
var alerts models.DeleteAlertsResponse
|
|
||||||
|
|
||||||
params, err := qs.Values(opts)
|
params, err := qs.Values(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -115,6 +109,8 @@ func (s *AlertsService) Delete(ctx context.Context, opts AlertsDeleteOpts) (*mod
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alerts := models.DeleteAlertsResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &alerts)
|
resp, err := s.client.Do(ctx, req, &alerts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -124,8 +120,6 @@ func (s *AlertsService) Delete(ctx context.Context, opts AlertsDeleteOpts) (*mod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AlertsService) DeleteOne(ctx context.Context, alertID string) (*models.DeleteAlertsResponse, *Response, error) {
|
func (s *AlertsService) DeleteOne(ctx context.Context, alertID string) (*models.DeleteAlertsResponse, *Response, error) {
|
||||||
var alerts models.DeleteAlertsResponse
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/alerts/%s", s.client.URLPrefix, alertID)
|
u := fmt.Sprintf("%s/alerts/%s", s.client.URLPrefix, alertID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil)
|
req, err := s.client.NewRequest(http.MethodDelete, u, nil)
|
||||||
|
@ -133,6 +127,8 @@ func (s *AlertsService) DeleteOne(ctx context.Context, alertID string) (*models.
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alerts := models.DeleteAlertsResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &alerts)
|
resp, err := s.client.Do(ctx, req, &alerts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -142,8 +138,6 @@ func (s *AlertsService) DeleteOne(ctx context.Context, alertID string) (*models.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AlertsService) GetByID(ctx context.Context, alertID int) (*models.Alert, *Response, error) {
|
func (s *AlertsService) GetByID(ctx context.Context, alertID int) (*models.Alert, *Response, error) {
|
||||||
var alert models.Alert
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/alerts/%d", s.client.URLPrefix, alertID)
|
u := fmt.Sprintf("%s/alerts/%d", s.client.URLPrefix, alertID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, u, nil)
|
req, err := s.client.NewRequest(http.MethodGet, u, nil)
|
||||||
|
@ -151,6 +145,8 @@ func (s *AlertsService) GetByID(ctx context.Context, alertID int) (*models.Alert
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alert := models.Alert{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &alert)
|
resp, err := s.client.Do(ctx, req, &alert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|
|
@ -125,7 +125,7 @@ func (r retryRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-req.Context().Done():
|
case <-req.Context().Done():
|
||||||
return resp, req.Context().Err()
|
return nil, req.Context().Err()
|
||||||
case <-time.After(time.Duration(backoff) * time.Second):
|
case <-time.After(time.Duration(backoff) * time.Second):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,8 @@ func (r retryRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
clonedReq := cloneRequest(req)
|
clonedReq := cloneRequest(req)
|
||||||
resp, err = r.next.RoundTrip(clonedReq)
|
|
||||||
|
|
||||||
|
resp, err = r.next.RoundTrip(clonedReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if left := maxAttempts - i - 1; left > 0 {
|
if left := maxAttempts - i - 1; left > 0 {
|
||||||
log.Errorf("error while performing request: %s; %d retries left", err, left)
|
log.Errorf("error while performing request: %s; %d retries left", err, left)
|
||||||
|
@ -171,10 +171,11 @@ type JWTTransport struct {
|
||||||
|
|
||||||
func (t *JWTTransport) refreshJwtToken() error {
|
func (t *JWTTransport) refreshJwtToken() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if t.UpdateScenario != nil {
|
if t.UpdateScenario != nil {
|
||||||
t.Scenarios, err = t.UpdateScenario()
|
t.Scenarios, err = t.UpdateScenario()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't update scenario list: %s", err)
|
return fmt.Errorf("can't update scenario list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("scenarios list updated for '%s'", *t.MachineID)
|
log.Debugf("scenarios list updated for '%s'", *t.MachineID)
|
||||||
|
@ -186,8 +187,6 @@ func (t *JWTTransport) refreshJwtToken() error {
|
||||||
Scenarios: t.Scenarios,
|
Scenarios: t.Scenarios,
|
||||||
}
|
}
|
||||||
|
|
||||||
var response models.WatcherAuthResponse
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we don't use the main client, so let's build the body
|
we don't use the main client, so let's build the body
|
||||||
*/
|
*/
|
||||||
|
@ -250,6 +249,8 @@ func (t *JWTTransport) refreshJwtToken() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var response models.WatcherAuthResponse
|
||||||
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
||||||
return fmt.Errorf("unable to decode response: %w", err)
|
return fmt.Errorf("unable to decode response: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -300,7 +301,7 @@ func (t *JWTTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// we had an error (network error for example, or 401 because token is refused), reset the token ?
|
// we had an error (network error for example, or 401 because token is refused), reset the token?
|
||||||
t.Token = ""
|
t.Token = ""
|
||||||
|
|
||||||
return resp, fmt.Errorf("performing jwt auth: %w", err)
|
return resp, fmt.Errorf("performing jwt auth: %w", err)
|
||||||
|
@ -324,14 +325,13 @@ func (t *JWTTransport) ResetToken() {
|
||||||
t.refreshTokenMutex.Unlock()
|
t.refreshTokenMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transport() returns a round tripper that retries once when the status is unauthorized, and 5 times when the infrastructure is overloaded.
|
||||||
func (t *JWTTransport) transport() http.RoundTripper {
|
func (t *JWTTransport) transport() http.RoundTripper {
|
||||||
var transport http.RoundTripper
|
transport := t.Transport
|
||||||
if t.Transport != nil {
|
if transport == nil {
|
||||||
transport = t.Transport
|
|
||||||
} else {
|
|
||||||
transport = http.DefaultTransport
|
transport = http.DefaultTransport
|
||||||
}
|
}
|
||||||
// a round tripper that retries once when the status is unauthorized and 5 times when infrastructure is overloaded
|
|
||||||
return &retryRoundTripper{
|
return &retryRoundTripper{
|
||||||
next: &retryRoundTripper{
|
next: &retryRoundTripper{
|
||||||
next: transport,
|
next: transport,
|
||||||
|
|
|
@ -94,7 +94,7 @@ func (c *ApiClient) Do(ctx context.Context, req *http.Request, v interface{}) (*
|
||||||
|
|
||||||
if log.GetLevel() >= log.DebugLevel {
|
if log.GetLevel() >= log.DebugLevel {
|
||||||
for k, v := range resp.Header {
|
for k, v := range resp.Header {
|
||||||
log.Debugf("[headers] %s : %s", k, v)
|
log.Debugf("[headers] %s: %s", k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
dump, err := httputil.DumpResponse(resp, true)
|
dump, err := httputil.DumpResponse(resp, true)
|
||||||
|
|
|
@ -3,11 +3,11 @@ package apiclient
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
qs "github.com/google/go-querystring/query"
|
qs "github.com/google/go-querystring/query"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/ptr"
|
"github.com/crowdsecurity/go-cs-lib/ptr"
|
||||||
|
@ -61,8 +61,6 @@ type DecisionsDeleteOpts struct {
|
||||||
|
|
||||||
// to demo query arguments
|
// to demo query arguments
|
||||||
func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*models.GetDecisionsResponse, *Response, error) {
|
func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*models.GetDecisionsResponse, *Response, error) {
|
||||||
var decisions models.GetDecisionsResponse
|
|
||||||
|
|
||||||
params, err := qs.Values(opts)
|
params, err := qs.Values(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -75,6 +73,8 @@ func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*m
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var decisions models.GetDecisionsResponse
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &decisions)
|
resp, err := s.client.Do(ctx, req, &decisions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -84,13 +84,13 @@ func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) FetchV2Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
|
func (s *DecisionsService) FetchV2Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
|
||||||
var decisions models.DecisionsStreamResponse
|
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, url, nil)
|
req, err := s.client.NewRequest(http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var decisions models.DecisionsStreamResponse
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &decisions)
|
resp, err := s.client.Do(ctx, req, &decisions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -100,7 +100,7 @@ func (s *DecisionsService) FetchV2Decisions(ctx context.Context, url string) (*m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) GetDecisionsFromGroups(decisionsGroups []*modelscapi.GetDecisionsStreamResponseNewItem) []*models.Decision {
|
func (s *DecisionsService) GetDecisionsFromGroups(decisionsGroups []*modelscapi.GetDecisionsStreamResponseNewItem) []*models.Decision {
|
||||||
var decisions []*models.Decision
|
decisions := make([]*models.Decision, 0)
|
||||||
|
|
||||||
for _, decisionsGroup := range decisionsGroups {
|
for _, decisionsGroup := range decisionsGroups {
|
||||||
partialDecisions := make([]*models.Decision, len(decisionsGroup.Decisions))
|
partialDecisions := make([]*models.Decision, len(decisionsGroup.Decisions))
|
||||||
|
@ -122,11 +122,6 @@ func (s *DecisionsService) GetDecisionsFromGroups(decisionsGroups []*modelscapi.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) FetchV3Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
|
func (s *DecisionsService) FetchV3Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
|
||||||
var (
|
|
||||||
decisions modelscapi.GetDecisionsStreamResponse
|
|
||||||
v2Decisions models.DecisionsStreamResponse
|
|
||||||
)
|
|
||||||
|
|
||||||
scenarioDeleted := "deleted"
|
scenarioDeleted := "deleted"
|
||||||
durationDeleted := "1h"
|
durationDeleted := "1h"
|
||||||
|
|
||||||
|
@ -135,11 +130,14 @@ func (s *DecisionsService) FetchV3Decisions(ctx context.Context, url string) (*m
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decisions := modelscapi.GetDecisionsStreamResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &decisions)
|
resp, err := s.client.Do(ctx, req, &decisions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v2Decisions := models.DecisionsStreamResponse{}
|
||||||
v2Decisions.New = s.GetDecisionsFromGroups(decisions.New)
|
v2Decisions.New = s.GetDecisionsFromGroups(decisions.New)
|
||||||
|
|
||||||
for _, decisionsGroup := range decisions.Deleted {
|
for _, decisionsGroup := range decisions.Deleted {
|
||||||
|
@ -183,6 +181,7 @@ func (s *DecisionsService) GetDecisionsFromBlocklist(ctx context.Context, blockl
|
||||||
|
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
log.Debugf("[URL] %s %s", req.Method, req.URL)
|
log.Debugf("[URL] %s %s", req.Method, req.URL)
|
||||||
|
|
||||||
// we don't use client_http Do method because we need the reader and is not provided.
|
// we don't use client_http Do method because we need the reader and is not provided.
|
||||||
// We would be forced to use Pipe and goroutine, etc
|
// We would be forced to use Pipe and goroutine, etc
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
@ -247,11 +246,11 @@ func (s *DecisionsService) GetStream(ctx context.Context, opts DecisionsStreamOp
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.client.URLPrefix == "v3" {
|
if s.client.URLPrefix != "v3" {
|
||||||
return s.FetchV3Decisions(ctx, u)
|
|
||||||
} else {
|
|
||||||
return s.FetchV2Decisions(ctx, u)
|
return s.FetchV2Decisions(ctx, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return s.FetchV3Decisions(ctx, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) GetStreamV3(ctx context.Context, opts DecisionsStreamOpts) (*modelscapi.GetDecisionsStreamResponse, *Response, error) {
|
func (s *DecisionsService) GetStreamV3(ctx context.Context, opts DecisionsStreamOpts) (*modelscapi.GetDecisionsStreamResponse, *Response, error) {
|
||||||
|
@ -260,13 +259,13 @@ func (s *DecisionsService) GetStreamV3(ctx context.Context, opts DecisionsStream
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions modelscapi.GetDecisionsStreamResponse
|
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, u, nil)
|
req, err := s.client.NewRequest(http.MethodGet, u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decisions := modelscapi.GetDecisionsStreamResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &decisions)
|
resp, err := s.client.Do(ctx, req, &decisions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -292,8 +291,6 @@ func (s *DecisionsService) StopStream(ctx context.Context) (*Response, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) Delete(ctx context.Context, opts DecisionsDeleteOpts) (*models.DeleteDecisionResponse, *Response, error) {
|
func (s *DecisionsService) Delete(ctx context.Context, opts DecisionsDeleteOpts) (*models.DeleteDecisionResponse, *Response, error) {
|
||||||
var deleteDecisionResponse models.DeleteDecisionResponse
|
|
||||||
|
|
||||||
params, err := qs.Values(opts)
|
params, err := qs.Values(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -306,6 +303,8 @@ func (s *DecisionsService) Delete(ctx context.Context, opts DecisionsDeleteOpts)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteDecisionResponse := models.DeleteDecisionResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &deleteDecisionResponse)
|
resp, err := s.client.Do(ctx, req, &deleteDecisionResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
@ -315,8 +314,6 @@ func (s *DecisionsService) Delete(ctx context.Context, opts DecisionsDeleteOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DecisionsService) DeleteOne(ctx context.Context, decisionID string) (*models.DeleteDecisionResponse, *Response, error) {
|
func (s *DecisionsService) DeleteOne(ctx context.Context, decisionID string) (*models.DeleteDecisionResponse, *Response, error) {
|
||||||
var deleteDecisionResponse models.DeleteDecisionResponse
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/decisions/%s", s.client.URLPrefix, decisionID)
|
u := fmt.Sprintf("%s/decisions/%s", s.client.URLPrefix, decisionID)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil)
|
req, err := s.client.NewRequest(http.MethodDelete, u, nil)
|
||||||
|
@ -324,6 +321,8 @@ func (s *DecisionsService) DeleteOne(ctx context.Context, decisionID string) (*m
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteDecisionResponse := models.DeleteDecisionResponse{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &deleteDecisionResponse)
|
resp, err := s.client.Do(ctx, req, &deleteDecisionResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
|
|
@ -14,8 +14,6 @@ type DecisionDeleteService service
|
||||||
|
|
||||||
// DecisionDeleteService purposely reuses AddSignalsRequestItemDecisions model
|
// DecisionDeleteService purposely reuses AddSignalsRequestItemDecisions model
|
||||||
func (d *DecisionDeleteService) Add(ctx context.Context, deletedDecisions *models.DecisionsDeleteRequest) (interface{}, *Response, error) {
|
func (d *DecisionDeleteService) Add(ctx context.Context, deletedDecisions *models.DecisionsDeleteRequest) (interface{}, *Response, error) {
|
||||||
var response interface{}
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/decisions/delete", d.client.URLPrefix)
|
u := fmt.Sprintf("%s/decisions/delete", d.client.URLPrefix)
|
||||||
|
|
||||||
req, err := d.client.NewRequest(http.MethodPost, u, &deletedDecisions)
|
req, err := d.client.NewRequest(http.MethodPost, u, &deletedDecisions)
|
||||||
|
@ -23,15 +21,17 @@ func (d *DecisionDeleteService) Add(ctx context.Context, deletedDecisions *model
|
||||||
return nil, nil, fmt.Errorf("while building request: %w", err)
|
return nil, nil, fmt.Errorf("while building request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var response interface{}
|
||||||
|
|
||||||
resp, err := d.client.Do(ctx, req, &response)
|
resp, err := d.client.Do(ctx, req, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, fmt.Errorf("while performing request: %w", err)
|
return nil, resp, fmt.Errorf("while performing request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.Response.StatusCode != http.StatusOK {
|
if resp.Response.StatusCode != http.StatusOK {
|
||||||
log.Warnf("Decisions delete response : http %s", resp.Response.Status)
|
log.Warnf("Decisions delete response: http %s", resp.Response.Status)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Decisions delete response : http %s", resp.Response.Status)
|
log.Debugf("Decisions delete response: http %s", resp.Response.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &response, resp, nil
|
return &response, resp, nil
|
||||||
|
|
|
@ -41,13 +41,13 @@ func (h *HeartBeatService) StartHeartBeat(ctx context.Context, t *tomb.Tomb) {
|
||||||
|
|
||||||
ok, resp, err := h.Ping(ctx)
|
ok, resp, err := h.Ping(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("heartbeat error : %s", err)
|
log.Errorf("heartbeat error: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Response.Body.Close()
|
resp.Response.Body.Close()
|
||||||
if resp.Response.StatusCode != http.StatusOK {
|
if resp.Response.StatusCode != http.StatusOK {
|
||||||
log.Errorf("heartbeat unexpected return code : %d", resp.Response.StatusCode)
|
log.Errorf("heartbeat unexpected return code: %d", resp.Response.StatusCode)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -11,8 +11,6 @@ import (
|
||||||
type MetricsService service
|
type MetricsService service
|
||||||
|
|
||||||
func (s *MetricsService) Add(ctx context.Context, metrics *models.Metrics) (interface{}, *Response, error) {
|
func (s *MetricsService) Add(ctx context.Context, metrics *models.Metrics) (interface{}, *Response, error) {
|
||||||
var response interface{}
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/metrics/", s.client.URLPrefix)
|
u := fmt.Sprintf("%s/metrics/", s.client.URLPrefix)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodPost, u, &metrics)
|
req, err := s.client.NewRequest(http.MethodPost, u, &metrics)
|
||||||
|
@ -20,6 +18,8 @@ func (s *MetricsService) Add(ctx context.Context, metrics *models.Metrics) (inte
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var response interface{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &response)
|
resp, err := s.client.Do(ctx, req, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
|
|
|
@ -13,8 +13,6 @@ import (
|
||||||
type SignalService service
|
type SignalService service
|
||||||
|
|
||||||
func (s *SignalService) Add(ctx context.Context, signals *models.AddSignalsRequest) (interface{}, *Response, error) {
|
func (s *SignalService) Add(ctx context.Context, signals *models.AddSignalsRequest) (interface{}, *Response, error) {
|
||||||
var response interface{}
|
|
||||||
|
|
||||||
u := fmt.Sprintf("%s/signals", s.client.URLPrefix)
|
u := fmt.Sprintf("%s/signals", s.client.URLPrefix)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodPost, u, &signals)
|
req, err := s.client.NewRequest(http.MethodPost, u, &signals)
|
||||||
|
@ -22,6 +20,8 @@ func (s *SignalService) Add(ctx context.Context, signals *models.AddSignalsReque
|
||||||
return nil, nil, fmt.Errorf("while building request: %w", err)
|
return nil, nil, fmt.Errorf("while building request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var response interface{}
|
||||||
|
|
||||||
resp, err := s.client.Do(ctx, req, &response)
|
resp, err := s.client.Do(ctx, req, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, fmt.Errorf("while performing request: %w", err)
|
return nil, resp, fmt.Errorf("while performing request: %w", err)
|
||||||
|
|
|
@ -2,21 +2,21 @@ package apiserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/tomb.v2"
|
"gopkg.in/tomb.v2"
|
||||||
"slices"
|
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/ptr"
|
"github.com/crowdsecurity/go-cs-lib/ptr"
|
||||||
"github.com/crowdsecurity/go-cs-lib/trace"
|
"github.com/crowdsecurity/go-cs-lib/trace"
|
||||||
|
@ -652,12 +652,13 @@ func (a *apic) PullTop(forcePull bool) error {
|
||||||
|
|
||||||
addCounters, deleteCounters := makeAddAndDeleteCounters()
|
addCounters, deleteCounters := makeAddAndDeleteCounters()
|
||||||
// process deleted decisions
|
// process deleted decisions
|
||||||
if nbDeleted, err := a.HandleDeletedDecisionsV3(data.Deleted, deleteCounters); err != nil {
|
nbDeleted, err := a.HandleDeletedDecisionsV3(data.Deleted, deleteCounters)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
log.Printf("capi/community-blocklist : %d explicit deletions", nbDeleted)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("capi/community-blocklist : %d explicit deletions", nbDeleted)
|
||||||
|
|
||||||
if len(data.New) == 0 {
|
if len(data.New) == 0 {
|
||||||
log.Infof("capi/community-blocklist : received 0 new entries (expected if you just installed crowdsec)")
|
log.Infof("capi/community-blocklist : received 0 new entries (expected if you just installed crowdsec)")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -2,6 +2,7 @@ package apiserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -13,7 +14,6 @@ import (
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-co-op/gocron"
|
"github.com/go-co-op/gocron"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
"gopkg.in/tomb.v2"
|
"gopkg.in/tomb.v2"
|
||||||
|
@ -382,7 +382,9 @@ func (s *APIServer) listenAndServeURL(apiReady chan bool) {
|
||||||
if s.TLS.KeyFilePath == "" {
|
if s.TLS.KeyFilePath == "" {
|
||||||
serverError <- errors.New("missing TLS key file")
|
serverError <- errors.New("missing TLS key file")
|
||||||
return
|
return
|
||||||
} else if s.TLS.CertFilePath == "" {
|
}
|
||||||
|
|
||||||
|
if s.TLS.CertFilePath == "" {
|
||||||
serverError <- errors.New("missing TLS cert file")
|
serverError <- errors.New("missing TLS cert file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,10 @@ func FormatOneAlert(alert *ent.Alert) *models.Alert {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, eventItem := range alert.Edges.Events {
|
for _, eventItem := range alert.Edges.Events {
|
||||||
var Metas models.Meta
|
|
||||||
timestamp := eventItem.Time.String()
|
timestamp := eventItem.Time.String()
|
||||||
|
|
||||||
|
var Metas models.Meta
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(eventItem.Serialized), &Metas); err != nil {
|
if err := json.Unmarshal([]byte(eventItem.Serialized), &Metas); err != nil {
|
||||||
log.Errorf("unable to unmarshall events meta '%s' : %s", eventItem.Serialized, err)
|
log.Errorf("unable to unmarshall events meta '%s' : %s", eventItem.Serialized, err)
|
||||||
}
|
}
|
||||||
|
@ -162,6 +164,7 @@ func (c *Controller) CreateAlert(gctx *gin.Context) {
|
||||||
if alert.Source.Scope != nil {
|
if alert.Source.Scope != nil {
|
||||||
*alert.Source.Scope = normalizeScope(*alert.Source.Scope)
|
*alert.Source.Scope = normalizeScope(*alert.Source.Scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, decision := range alert.Decisions {
|
for _, decision := range alert.Decisions {
|
||||||
if decision.Scope != nil {
|
if decision.Scope != nil {
|
||||||
*decision.Scope = normalizeScope(*decision.Scope)
|
*decision.Scope = normalizeScope(*decision.Scope)
|
||||||
|
@ -183,30 +186,38 @@ func (c *Controller) CreateAlert(gctx *gin.Context) {
|
||||||
_, matched, err := profile.EvaluateProfile(alert)
|
_, matched, err := profile.EvaluateProfile(alert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
profile.Logger.Warningf("error while evaluating profile %s : %v", profile.Cfg.Name, err)
|
profile.Logger.Warningf("error while evaluating profile %s : %v", profile.Cfg.Name, err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matched {
|
if !matched {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.sendAlertToPluginChannel(alert, uint(pIdx))
|
c.sendAlertToPluginChannel(alert, uint(pIdx))
|
||||||
|
|
||||||
if profile.Cfg.OnSuccess == "break" {
|
if profile.Cfg.OnSuccess == "break" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decision := alert.Decisions[0]
|
decision := alert.Decisions[0]
|
||||||
if decision.Origin != nil && *decision.Origin == types.CscliImportOrigin {
|
if decision.Origin != nil && *decision.Origin == types.CscliImportOrigin {
|
||||||
stopFlush = true
|
stopFlush = true
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for pIdx, profile := range c.Profiles {
|
for pIdx, profile := range c.Profiles {
|
||||||
profileDecisions, matched, err := profile.EvaluateProfile(alert)
|
profileDecisions, matched, err := profile.EvaluateProfile(alert)
|
||||||
forceBreak := false
|
forceBreak := false
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch profile.Cfg.OnError {
|
switch profile.Cfg.OnError {
|
||||||
case "apply":
|
case "apply":
|
||||||
profile.Logger.Warningf("applying profile %s despite error: %s", profile.Cfg.Name, err)
|
profile.Logger.Warningf("applying profile %s despite error: %s", profile.Cfg.Name, err)
|
||||||
|
|
||||||
matched = true
|
matched = true
|
||||||
case "continue":
|
case "continue":
|
||||||
profile.Logger.Warningf("skipping %s profile due to error: %s", profile.Cfg.Name, err)
|
profile.Logger.Warningf("skipping %s profile due to error: %s", profile.Cfg.Name, err)
|
||||||
|
@ -219,18 +230,23 @@ func (c *Controller) CreateAlert(gctx *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matched {
|
if !matched {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, decision := range profileDecisions {
|
for _, decision := range profileDecisions {
|
||||||
decision.UUID = uuid.NewString()
|
decision.UUID = uuid.NewString()
|
||||||
}
|
}
|
||||||
//generate uuid here for alert
|
|
||||||
|
// generate uuid here for alert
|
||||||
if len(alert.Decisions) == 0 { // non manual decision
|
if len(alert.Decisions) == 0 { // non manual decision
|
||||||
alert.Decisions = append(alert.Decisions, profileDecisions...)
|
alert.Decisions = append(alert.Decisions, profileDecisions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
profileAlert := *alert
|
profileAlert := *alert
|
||||||
c.sendAlertToPluginChannel(&profileAlert, uint(pIdx))
|
c.sendAlertToPluginChannel(&profileAlert, uint(pIdx))
|
||||||
|
|
||||||
if profile.Cfg.OnSuccess == "break" || forceBreak {
|
if profile.Cfg.OnSuccess == "break" || forceBreak {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -275,6 +291,7 @@ func (c *Controller) FindAlerts(gctx *gin.Context) {
|
||||||
gctx.String(http.StatusOK, "")
|
gctx.String(http.StatusOK, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, data)
|
gctx.JSON(http.StatusOK, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,21 +299,25 @@ func (c *Controller) FindAlerts(gctx *gin.Context) {
|
||||||
func (c *Controller) FindAlertByID(gctx *gin.Context) {
|
func (c *Controller) FindAlertByID(gctx *gin.Context) {
|
||||||
alertIDStr := gctx.Param("alert_id")
|
alertIDStr := gctx.Param("alert_id")
|
||||||
alertID, err := strconv.Atoi(alertIDStr)
|
alertID, err := strconv.Atoi(alertIDStr)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gctx.JSON(http.StatusBadRequest, gin.H{"message": "alert_id must be valid integer"})
|
gctx.JSON(http.StatusBadRequest, gin.H{"message": "alert_id must be valid integer"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := c.DBClient.GetAlertByID(alertID)
|
result, err := c.DBClient.GetAlertByID(alertID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := FormatOneAlert(result)
|
data := FormatOneAlert(result)
|
||||||
|
|
||||||
if gctx.Request.Method == http.MethodHead {
|
if gctx.Request.Method == http.MethodHead {
|
||||||
gctx.String(http.StatusOK, "")
|
gctx.String(http.StatusOK, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, data)
|
gctx.JSON(http.StatusOK, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,15 +337,14 @@ func (c *Controller) DeleteAlertByID(gctx *gin.Context) {
|
||||||
gctx.JSON(http.StatusBadRequest, gin.H{"message": "alert_id must be valid integer"})
|
gctx.JSON(http.StatusBadRequest, gin.H{"message": "alert_id must be valid integer"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.DBClient.DeleteAlertByID(decisionID)
|
err = c.DBClient.DeleteAlertByID(decisionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAlertResp := models.DeleteAlertsResponse{
|
deleteAlertResp := models.DeleteAlertsResponse{NbDeleted: "1"}
|
||||||
NbDeleted: "1",
|
|
||||||
}
|
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, deleteAlertResp)
|
gctx.JSON(http.StatusOK, deleteAlertResp)
|
||||||
}
|
}
|
||||||
|
@ -336,15 +356,17 @@ func (c *Controller) DeleteAlerts(gctx *gin.Context) {
|
||||||
gctx.JSON(http.StatusForbidden, gin.H{"message": fmt.Sprintf("access forbidden from this IP (%s)", incomingIP)})
|
gctx.JSON(http.StatusForbidden, gin.H{"message": fmt.Sprintf("access forbidden from this IP (%s)", incomingIP)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var err error
|
|
||||||
nbDeleted, err := c.DBClient.DeleteAlertWithFilter(gctx.Request.URL.Query())
|
nbDeleted, err := c.DBClient.DeleteAlertWithFilter(gctx.Request.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAlertsResp := models.DeleteAlertsResponse{
|
deleteAlertsResp := models.DeleteAlertsResponse{
|
||||||
NbDeleted: strconv.Itoa(nbDeleted),
|
NbDeleted: strconv.Itoa(nbDeleted),
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, deleteAlertsResp)
|
gctx.JSON(http.StatusOK, deleteAlertsResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,5 +377,6 @@ func networksContainIP(networks []net.IPNet, ip string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,10 @@ func New(cfg *ControllerV1Config) (*Controller, error) {
|
||||||
TrustedIPs: cfg.TrustedIPs,
|
TrustedIPs: cfg.TrustedIPs,
|
||||||
}
|
}
|
||||||
v1.Middlewares, err = middlewares.NewMiddlewares(cfg.DbClient)
|
v1.Middlewares, err = middlewares.NewMiddlewares(cfg.DbClient)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v1, err
|
return v1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return v1, nil
|
return v1, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ func FormatDecisions(decisions []*ent.Decision) []*models.Decision {
|
||||||
}
|
}
|
||||||
results = append(results, &decision)
|
results = append(results, &decision)
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +45,14 @@ func (c *Controller) GetDecision(gctx *gin.Context) {
|
||||||
bouncerInfo, err := getBouncerFromContext(gctx)
|
bouncerInfo, err := getBouncerFromContext(gctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gctx.JSON(http.StatusUnauthorized, gin.H{"message": "not allowed"})
|
gctx.JSON(http.StatusUnauthorized, gin.H{"message": "not allowed"})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err = c.DBClient.QueryDecisionWithFilter(gctx.Request.URL.Query())
|
data, err = c.DBClient.QueryDecisionWithFilter(gctx.Request.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +67,7 @@ func (c *Controller) GetDecision(gctx *gin.Context) {
|
||||||
|
|
||||||
if gctx.Request.Method == http.MethodHead {
|
if gctx.Request.Method == http.MethodHead {
|
||||||
gctx.String(http.StatusOK, "")
|
gctx.String(http.StatusOK, "")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,20 +81,22 @@ func (c *Controller) GetDecision(gctx *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) DeleteDecisionById(gctx *gin.Context) {
|
func (c *Controller) DeleteDecisionById(gctx *gin.Context) {
|
||||||
var err error
|
|
||||||
|
|
||||||
decisionIDStr := gctx.Param("decision_id")
|
decisionIDStr := gctx.Param("decision_id")
|
||||||
|
|
||||||
decisionID, err := strconv.Atoi(decisionIDStr)
|
decisionID, err := strconv.Atoi(decisionIDStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gctx.JSON(http.StatusBadRequest, gin.H{"message": "decision_id must be valid integer"})
|
gctx.JSON(http.StatusBadRequest, gin.H{"message": "decision_id must be valid integer"})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nbDeleted, deletedFromDB, err := c.DBClient.SoftDeleteDecisionByID(decisionID)
|
nbDeleted, deletedFromDB, err := c.DBClient.SoftDeleteDecisionByID(decisionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//transform deleted decisions to be sendable to capi
|
|
||||||
|
// transform deleted decisions to be sendable to capi
|
||||||
deletedDecisions := FormatDecisions(deletedFromDB)
|
deletedDecisions := FormatDecisions(deletedFromDB)
|
||||||
|
|
||||||
if c.DecisionDeleteChan != nil {
|
if c.DecisionDeleteChan != nil {
|
||||||
|
@ -105,13 +111,14 @@ func (c *Controller) DeleteDecisionById(gctx *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) DeleteDecisions(gctx *gin.Context) {
|
func (c *Controller) DeleteDecisions(gctx *gin.Context) {
|
||||||
var err error
|
|
||||||
nbDeleted, deletedFromDB, err := c.DBClient.SoftDeleteDecisionsWithFilter(gctx.Request.URL.Query())
|
nbDeleted, deletedFromDB, err := c.DBClient.SoftDeleteDecisionsWithFilter(gctx.Request.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//transform deleted decisions to be sendable to capi
|
|
||||||
|
// transform deleted decisions to be sendable to capi
|
||||||
deletedDecisions := FormatDecisions(deletedFromDB)
|
deletedDecisions := FormatDecisions(deletedFromDB)
|
||||||
|
|
||||||
if c.DecisionDeleteChan != nil {
|
if c.DecisionDeleteChan != nil {
|
||||||
|
@ -121,6 +128,7 @@ func (c *Controller) DeleteDecisions(gctx *gin.Context) {
|
||||||
deleteDecisionResp := models.DeleteDecisionResponse{
|
deleteDecisionResp := models.DeleteDecisionResponse{
|
||||||
NbDeleted: nbDeleted,
|
NbDeleted: nbDeleted,
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, deleteDecisionResp)
|
gctx.JSON(http.StatusOK, deleteDecisionResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +155,7 @@ func writeStartupDecisions(gctx *gin.Context, filters map[string][]string, dbFun
|
||||||
results := FormatDecisions(data)
|
results := FormatDecisions(data)
|
||||||
for _, decision := range results {
|
for _, decision := range results {
|
||||||
decisionJSON, _ := json.Marshal(decision)
|
decisionJSON, _ := json.Marshal(decision)
|
||||||
|
|
||||||
if needComma {
|
if needComma {
|
||||||
//respBuffer.Write([]byte(","))
|
//respBuffer.Write([]byte(","))
|
||||||
gctx.Writer.Write([]byte(","))
|
gctx.Writer.Write([]byte(","))
|
||||||
|
@ -158,6 +167,7 @@ func writeStartupDecisions(gctx *gin.Context, filters map[string][]string, dbFun
|
||||||
_, err := gctx.Writer.Write(decisionJSON)
|
_, err := gctx.Writer.Write(decisionJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//respBuffer.Reset()
|
//respBuffer.Reset()
|
||||||
|
@ -166,9 +176,11 @@ func writeStartupDecisions(gctx *gin.Context, filters map[string][]string, dbFun
|
||||||
log.Debugf("startup: %d decisions returned (limit: %d, lastid: %d)", len(data), limit, lastId)
|
log.Debugf("startup: %d decisions returned (limit: %d, lastid: %d)", len(data), limit, lastId)
|
||||||
if len(data) < limit {
|
if len(data) < limit {
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +207,7 @@ func writeDeltaDecisions(gctx *gin.Context, filters map[string][]string, lastPul
|
||||||
results := FormatDecisions(data)
|
results := FormatDecisions(data)
|
||||||
for _, decision := range results {
|
for _, decision := range results {
|
||||||
decisionJSON, _ := json.Marshal(decision)
|
decisionJSON, _ := json.Marshal(decision)
|
||||||
|
|
||||||
if needComma {
|
if needComma {
|
||||||
//respBuffer.Write([]byte(","))
|
//respBuffer.Write([]byte(","))
|
||||||
gctx.Writer.Write([]byte(","))
|
gctx.Writer.Write([]byte(","))
|
||||||
|
@ -206,6 +219,7 @@ func writeDeltaDecisions(gctx *gin.Context, filters map[string][]string, lastPul
|
||||||
_, err := gctx.Writer.Write(decisionJSON)
|
_, err := gctx.Writer.Write(decisionJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//respBuffer.Reset()
|
//respBuffer.Reset()
|
||||||
|
@ -214,9 +228,11 @@ func writeDeltaDecisions(gctx *gin.Context, filters map[string][]string, lastPul
|
||||||
log.Debugf("startup: %d decisions returned (limit: %d, lastid: %d)", len(data), limit, lastId)
|
log.Debugf("startup: %d decisions returned (limit: %d, lastid: %d)", len(data), limit, lastId)
|
||||||
if len(data) < limit {
|
if len(data) < limit {
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,14 +246,13 @@ func (c *Controller) StreamDecisionChunked(gctx *gin.Context, bouncerInfo *ent.B
|
||||||
|
|
||||||
// if the blocker just started, return all decisions
|
// if the blocker just started, return all decisions
|
||||||
if val, ok := gctx.Request.URL.Query()["startup"]; ok && val[0] == "true" {
|
if val, ok := gctx.Request.URL.Query()["startup"]; ok && val[0] == "true" {
|
||||||
//Active decisions
|
// Active decisions
|
||||||
|
|
||||||
err := writeStartupDecisions(gctx, filters, c.DBClient.QueryAllDecisionsWithFilters)
|
err := writeStartupDecisions(gctx, filters, c.DBClient.QueryAllDecisionsWithFilters)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed sending new decisions for startup: %v", err)
|
log.Errorf("failed sending new decisions for startup: %v", err)
|
||||||
gctx.Writer.Write([]byte(`], "deleted": []}`))
|
gctx.Writer.Write([]byte(`], "deleted": []}`))
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +263,7 @@ func (c *Controller) StreamDecisionChunked(gctx *gin.Context, bouncerInfo *ent.B
|
||||||
log.Errorf("failed sending expired decisions for startup: %v", err)
|
log.Errorf("failed sending expired decisions for startup: %v", err)
|
||||||
gctx.Writer.Write([]byte(`]}`))
|
gctx.Writer.Write([]byte(`]}`))
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +275,7 @@ func (c *Controller) StreamDecisionChunked(gctx *gin.Context, bouncerInfo *ent.B
|
||||||
log.Errorf("failed sending new decisions for delta: %v", err)
|
log.Errorf("failed sending new decisions for delta: %v", err)
|
||||||
gctx.Writer.Write([]byte(`], "deleted": []}`))
|
gctx.Writer.Write([]byte(`], "deleted": []}`))
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,18 +287,21 @@ func (c *Controller) StreamDecisionChunked(gctx *gin.Context, bouncerInfo *ent.B
|
||||||
log.Errorf("failed sending expired decisions for delta: %v", err)
|
log.Errorf("failed sending expired decisions for delta: %v", err)
|
||||||
gctx.Writer.Write([]byte(`]}`))
|
gctx.Writer.Write([]byte(`]}`))
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.Writer.Write([]byte(`]}`))
|
gctx.Writer.Write([]byte(`]}`))
|
||||||
gctx.Writer.Flush()
|
gctx.Writer.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *ent.Bouncer, streamStartTime time.Time, filters map[string][]string) error {
|
func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *ent.Bouncer, streamStartTime time.Time, filters map[string][]string) error {
|
||||||
var data []*ent.Decision
|
var data []*ent.Decision
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
ret := make(map[string][]*models.Decision, 0)
|
ret := make(map[string][]*models.Decision, 0)
|
||||||
ret["new"] = []*models.Decision{}
|
ret["new"] = []*models.Decision{}
|
||||||
ret["deleted"] = []*models.Decision{}
|
ret["deleted"] = []*models.Decision{}
|
||||||
|
@ -292,6 +312,7 @@ func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *en
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed querying decisions: %v", err)
|
log.Errorf("failed querying decisions: %v", err)
|
||||||
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//data = KeepLongestDecision(data)
|
//data = KeepLongestDecision(data)
|
||||||
|
@ -302,11 +323,14 @@ func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *en
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to query expired decision for '%s' : %v", bouncerInfo.Name, err)
|
log.Errorf("unable to query expired decision for '%s' : %v", bouncerInfo.Name, err)
|
||||||
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret["deleted"] = FormatDecisions(data)
|
ret["deleted"] = FormatDecisions(data)
|
||||||
|
|
||||||
gctx.JSON(http.StatusOK, ret)
|
gctx.JSON(http.StatusOK, ret)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,6 +340,7 @@ func (c *Controller) StreamDecisionNonChunked(gctx *gin.Context, bouncerInfo *en
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to query new decision for '%s' : %v", bouncerInfo.Name, err)
|
log.Errorf("unable to query new decision for '%s' : %v", bouncerInfo.Name, err)
|
||||||
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
gctx.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//data = KeepLongestDecision(data)
|
//data = KeepLongestDecision(data)
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Controller) HeartBeat(gctx *gin.Context) {
|
func (c *Controller) HeartBeat(gctx *gin.Context) {
|
||||||
|
|
||||||
claims := jwt.ExtractClaims(gctx)
|
claims := jwt.ExtractClaims(gctx)
|
||||||
// TBD: use defined rather than hardcoded key to find back owner
|
// TBD: use defined rather than hardcoded key to find back owner
|
||||||
machineID := claims["id"].(string)
|
machineID := claims["id"].(string)
|
||||||
|
@ -17,5 +16,6 @@ func (c *Controller) HeartBeat(gctx *gin.Context) {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx.Status(http.StatusOK)
|
gctx.Status(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Controller) CreateMachine(gctx *gin.Context) {
|
func (c *Controller) CreateMachine(gctx *gin.Context) {
|
||||||
var err error
|
|
||||||
var input models.WatcherRegistrationRequest
|
var input models.WatcherRegistrationRequest
|
||||||
if err = gctx.ShouldBindJSON(&input); err != nil {
|
|
||||||
|
if err := gctx.ShouldBindJSON(&input); err != nil {
|
||||||
gctx.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
|
gctx.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = input.Validate(strfmt.Default); err != nil {
|
|
||||||
|
if err := input.Validate(strfmt.Default); err != nil {
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.DBClient.CreateMachine(input.MachineID, input.Password, gctx.ClientIP(), false, false, types.PasswordAuthType)
|
if _, err := c.DBClient.CreateMachine(input.MachineID, input.Password, gctx.ClientIP(), false, false, types.PasswordAuthType); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.HandleDBErrors(gctx, err)
|
c.HandleDBErrors(gctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ func PrometheusMachinesMiddleware() gin.HandlerFunc {
|
||||||
"method": c.Request.Method}).Inc()
|
"method": c.Request.Method}).Inc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +107,7 @@ func PrometheusBouncersMiddleware() gin.HandlerFunc {
|
||||||
"route": c.Request.URL.Path,
|
"route": c.Request.URL.Path,
|
||||||
"method": c.Request.Method}).Inc()
|
"method": c.Request.Method}).Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +119,7 @@ func PrometheusMiddleware() gin.HandlerFunc {
|
||||||
"route": c.Request.URL.Path,
|
"route": c.Request.URL.Path,
|
||||||
"method": c.Request.Method}).Inc()
|
"method": c.Request.Method}).Inc()
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
LapiResponseTime.With(prometheus.Labels{"method": c.Request.Method, "endpoint": c.Request.URL.Path}).Observe(elapsed.Seconds())
|
LapiResponseTime.With(prometheus.Labels{"method": c.Request.Method, "endpoint": c.Request.URL.Path}).Observe(elapsed.Seconds())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
const bouncerContextKey = "bouncer_info"
|
||||||
bouncerContextKey = "bouncer_info"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getBouncerFromContext(ctx *gin.Context) (*ent.Bouncer, error) {
|
func getBouncerFromContext(ctx *gin.Context) (*ent.Bouncer, error) {
|
||||||
bouncerInterface, exist := ctx.Get(bouncerContextKey)
|
bouncerInterface, exist := ctx.Get(bouncerContextKey)
|
||||||
|
|
|
@ -34,7 +34,9 @@ func GenerateAPIKey(n int) (string, error) {
|
||||||
if _, err := rand.Read(bytes); err != nil {
|
if _, err := rand.Read(bytes); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded := base64.StdEncoding.EncodeToString(bytes)
|
encoded := base64.StdEncoding.EncodeToString(bytes)
|
||||||
|
|
||||||
// the '=' can cause issues on some bouncers
|
// the '=' can cause issues on some bouncers
|
||||||
return strings.TrimRight(encoded, "="), nil
|
return strings.TrimRight(encoded, "="), nil
|
||||||
}
|
}
|
||||||
|
@ -67,6 +69,7 @@ func (a *APIKey) authTLS(c *gin.Context, logger *log.Entry) *ent.Bouncer {
|
||||||
logger.Errorf("invalid client certificate: %s", err)
|
logger.Errorf("invalid client certificate: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -88,7 +91,9 @@ func (a *APIKey) authTLS(c *gin.Context, logger *log.Entry) *ent.Bouncer {
|
||||||
logger.Errorf("error generating mock api key: %s", err)
|
logger.Errorf("error generating mock api key: %s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Infof("Creating bouncer %s", bouncerName)
|
logger.Infof("Creating bouncer %s", bouncerName)
|
||||||
|
|
||||||
bouncer, err = a.DbClient.CreateBouncer(bouncerName, c.ClientIP(), HashSHA512(apiKey), types.TlsAuthType)
|
bouncer, err = a.DbClient.CreateBouncer(bouncerName, c.ClientIP(), HashSHA512(apiKey), types.TlsAuthType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("while creating bouncer db entry: %s", err)
|
logger.Errorf("while creating bouncer db entry: %s", err)
|
||||||
|
@ -103,6 +108,7 @@ func (a *APIKey) authTLS(c *gin.Context, logger *log.Entry) *ent.Bouncer {
|
||||||
logger.Errorf("bouncer isn't allowed to auth by TLS")
|
logger.Errorf("bouncer isn't allowed to auth by TLS")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bouncer
|
return bouncer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +118,7 @@ func (a *APIKey) authPlain(c *gin.Context, logger *log.Entry) *ent.Bouncer {
|
||||||
logger.Errorf("API key not found")
|
logger.Errorf("API key not found")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
hashStr := HashSHA512(val[0])
|
hashStr := HashSHA512(val[0])
|
||||||
|
|
||||||
bouncer, err := a.DbClient.SelectBouncer(hashStr)
|
bouncer, err := a.DbClient.SelectBouncer(hashStr)
|
||||||
|
@ -162,16 +169,19 @@ func (a *APIKey) MiddlewareFunc() gin.HandlerFunc {
|
||||||
logger.Errorf("Failed to update ip address for '%s': %s\n", bouncer.Name, err)
|
logger.Errorf("Failed to update ip address for '%s': %s\n", bouncer.Name, err)
|
||||||
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if bouncer.IPAddress != c.ClientIP() && bouncer.IPAddress != "" {
|
if bouncer.IPAddress != c.ClientIP() && bouncer.IPAddress != "" {
|
||||||
log.Warningf("new IP address detected for bouncer '%s': %s (old: %s)", bouncer.Name, c.ClientIP(), bouncer.IPAddress)
|
log.Warningf("new IP address detected for bouncer '%s': %s (old: %s)", bouncer.Name, c.ClientIP(), bouncer.IPAddress)
|
||||||
|
|
||||||
if err := a.DbClient.UpdateBouncerIP(c.ClientIP(), bouncer.ID); err != nil {
|
if err := a.DbClient.UpdateBouncerIP(c.ClientIP(), bouncer.ID); err != nil {
|
||||||
logger.Errorf("Failed to update ip address for '%s': %s\n", bouncer.Name, err)
|
logger.Errorf("Failed to update ip address for '%s': %s\n", bouncer.Name, err)
|
||||||
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,6 +197,7 @@ func (a *APIKey) MiddlewareFunc() gin.HandlerFunc {
|
||||||
logger.Errorf("failed to update bouncer version and type: %s", err)
|
logger.Errorf("failed to update bouncer version and type: %s", err)
|
||||||
c.JSON(http.StatusForbidden, gin.H{"message": "bad user agent"})
|
c.JSON(http.StatusForbidden, gin.H{"message": "bad user agent"})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,15 @@ func PayloadFunc(data interface{}) jwt.MapClaims {
|
||||||
identityKey: &value.MachineID,
|
identityKey: &value.MachineID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return jwt.MapClaims{}
|
return jwt.MapClaims{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func IdentityHandler(c *gin.Context) interface{} {
|
func IdentityHandler(c *gin.Context) interface{} {
|
||||||
claims := jwt.ExtractClaims(c)
|
claims := jwt.ExtractClaims(c)
|
||||||
machineId := claims[identityKey].(string)
|
machineID := claims[identityKey].(string)
|
||||||
return &models.WatcherAuthRequest{
|
return &models.WatcherAuthRequest{
|
||||||
MachineID: &machineId,
|
MachineID: &machineID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ func (j *JWT) authTLS(c *gin.Context) (*authInput, error) {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
c.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
|
||||||
return nil, fmt.Errorf("while trying to validate client cert: %w", err)
|
return nil, fmt.Errorf("while trying to validate client cert: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ func (j *JWT) authTLS(c *gin.Context) (*authInput, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.machineID = fmt.Sprintf("%s@%s", extractedCN, c.ClientIP())
|
ret.machineID = fmt.Sprintf("%s@%s", extractedCN, c.ClientIP())
|
||||||
|
|
||||||
ret.clientMachine, err = j.DbClient.Ent.Machine.Query().
|
ret.clientMachine, err = j.DbClient.Ent.Machine.Query().
|
||||||
Where(machine.MachineId(ret.machineID)).
|
Where(machine.MachineId(ret.machineID)).
|
||||||
First(j.DbClient.CTX)
|
First(j.DbClient.CTX)
|
||||||
|
|
Loading…
Reference in a new issue