client.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package apiclient
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "net/http"
  10. "net/url"
  11. "github.com/crowdsecurity/crowdsec/pkg/models"
  12. )
  13. var (
  14. InsecureSkipVerify = false
  15. Cert *tls.Certificate
  16. CaCertPool *x509.CertPool
  17. )
  18. type ApiClient struct {
  19. /*The http client used to make requests*/
  20. client *http.Client
  21. /*Reuse a single struct instead of allocating one for each service on the heap.*/
  22. common service
  23. /*config stuff*/
  24. BaseURL *url.URL
  25. PapiURL *url.URL
  26. URLPrefix string
  27. UserAgent string
  28. /*exposed Services*/
  29. Decisions *DecisionsService
  30. DecisionDelete *DecisionDeleteService
  31. Alerts *AlertsService
  32. Auth *AuthService
  33. Metrics *MetricsService
  34. Signal *SignalService
  35. HeartBeat *HeartBeatService
  36. }
  37. func (a *ApiClient) GetClient() *http.Client {
  38. return a.client
  39. }
  40. type service struct {
  41. client *ApiClient
  42. }
  43. func NewClient(config *Config) (*ApiClient, error) {
  44. t := &JWTTransport{
  45. MachineID: &config.MachineID,
  46. Password: &config.Password,
  47. Scenarios: config.Scenarios,
  48. URL: config.URL,
  49. UserAgent: config.UserAgent,
  50. VersionPrefix: config.VersionPrefix,
  51. UpdateScenario: config.UpdateScenario,
  52. }
  53. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  54. tlsconfig.RootCAs = CaCertPool
  55. if Cert != nil {
  56. tlsconfig.Certificates = []tls.Certificate{*Cert}
  57. }
  58. if ht, ok := http.DefaultTransport.(*http.Transport); ok {
  59. ht.TLSClientConfig = &tlsconfig
  60. }
  61. c := &ApiClient{client: t.Client(), BaseURL: config.URL, UserAgent: config.UserAgent, URLPrefix: config.VersionPrefix, PapiURL: config.PapiURL}
  62. c.common.client = c
  63. c.Decisions = (*DecisionsService)(&c.common)
  64. c.Alerts = (*AlertsService)(&c.common)
  65. c.Auth = (*AuthService)(&c.common)
  66. c.Metrics = (*MetricsService)(&c.common)
  67. c.Signal = (*SignalService)(&c.common)
  68. c.DecisionDelete = (*DecisionDeleteService)(&c.common)
  69. c.HeartBeat = (*HeartBeatService)(&c.common)
  70. return c, nil
  71. }
  72. func NewDefaultClient(URL *url.URL, prefix string, userAgent string, client *http.Client) (*ApiClient, error) {
  73. if client == nil {
  74. client = &http.Client{}
  75. if ht, ok := http.DefaultTransport.(*http.Transport); ok {
  76. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  77. tlsconfig.RootCAs = CaCertPool
  78. if Cert != nil {
  79. tlsconfig.Certificates = []tls.Certificate{*Cert}
  80. }
  81. ht.TLSClientConfig = &tlsconfig
  82. client.Transport = ht
  83. }
  84. }
  85. c := &ApiClient{client: client, BaseURL: URL, UserAgent: userAgent, URLPrefix: prefix}
  86. c.common.client = c
  87. c.Decisions = (*DecisionsService)(&c.common)
  88. c.Alerts = (*AlertsService)(&c.common)
  89. c.Auth = (*AuthService)(&c.common)
  90. c.Metrics = (*MetricsService)(&c.common)
  91. c.Signal = (*SignalService)(&c.common)
  92. c.DecisionDelete = (*DecisionDeleteService)(&c.common)
  93. c.HeartBeat = (*HeartBeatService)(&c.common)
  94. return c, nil
  95. }
  96. func RegisterClient(config *Config, client *http.Client) (*ApiClient, error) {
  97. if client == nil {
  98. client = &http.Client{}
  99. }
  100. tlsconfig := tls.Config{InsecureSkipVerify: InsecureSkipVerify}
  101. if Cert != nil {
  102. tlsconfig.RootCAs = CaCertPool
  103. tlsconfig.Certificates = []tls.Certificate{*Cert}
  104. }
  105. http.DefaultTransport.(*http.Transport).TLSClientConfig = &tlsconfig
  106. c := &ApiClient{client: client, BaseURL: config.URL, UserAgent: config.UserAgent, URLPrefix: config.VersionPrefix}
  107. c.common.client = c
  108. c.Decisions = (*DecisionsService)(&c.common)
  109. c.Alerts = (*AlertsService)(&c.common)
  110. c.Auth = (*AuthService)(&c.common)
  111. resp, err := c.Auth.RegisterWatcher(context.Background(), models.WatcherRegistrationRequest{MachineID: &config.MachineID, Password: &config.Password})
  112. /*if we have http status, return it*/
  113. if err != nil {
  114. if resp != nil && resp.Response != nil {
  115. return nil, fmt.Errorf("api register (%s) http %s: %w", c.BaseURL, resp.Response.Status, err)
  116. }
  117. return nil, fmt.Errorf("api register (%s): %w", c.BaseURL, err)
  118. }
  119. return c, nil
  120. }
  121. type Response struct {
  122. Response *http.Response
  123. //add our pagination stuff
  124. //NextPage int
  125. //...
  126. }
  127. type ErrorResponse struct {
  128. models.ErrorResponse
  129. }
  130. func (e *ErrorResponse) Error() string {
  131. err := fmt.Sprintf("API error: %s", *e.Message)
  132. if len(e.Errors) > 0 {
  133. err += fmt.Sprintf(" (%s)", e.Errors)
  134. }
  135. return err
  136. }
  137. func newResponse(r *http.Response) *Response {
  138. response := &Response{Response: r}
  139. return response
  140. }
  141. func CheckResponse(r *http.Response) error {
  142. if c := r.StatusCode; 200 <= c && c <= 299 || c == 304 {
  143. return nil
  144. }
  145. errorResponse := &ErrorResponse{}
  146. data, err := io.ReadAll(r.Body)
  147. if err == nil && data != nil {
  148. err := json.Unmarshal(data, errorResponse)
  149. if err != nil {
  150. return fmt.Errorf("http code %d, invalid body: %w", r.StatusCode, err)
  151. }
  152. } else {
  153. errorResponse.Message = new(string)
  154. *errorResponse.Message = fmt.Sprintf("http code %d, no error message", r.StatusCode)
  155. }
  156. return errorResponse
  157. }
  158. type ListOpts struct {
  159. //Page int
  160. //PerPage int
  161. }
  162. type DeleteOpts struct {
  163. //??
  164. }
  165. type AddOpts struct {
  166. //??
  167. }