GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( b021d2...7c1d1b )
by Victor Hugo
01:04 queued 10s
created

mollie.*Client.Do   A

Complexity

Conditions 3

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0987

Importance

Changes 0
Metric Value
cc 3
eloc 10
dl 0
loc 13
ccs 7
cts 9
cp 0.7778
crap 3.0987
rs 9.9
c 0
b 0
f 0
nop 1
1
package mollie
2
3
import (
4
	"bytes"
5
	"encoding/json"
6
	"errors"
7
	"fmt"
8
	"io"
9
	"io/ioutil"
10
	"net/http"
11
	"net/url"
12
	"os"
13
	"strings"
14
)
15
16
// Mollie  constants holding values to initialize the client and create requests.
17
const (
18
	BaseURLV2          string = "https://api.mollie.com/v2/"
19
	AuthHeader         string = "authorization"
20
	TokenType          string = "Bearer"
21
	APITokenEnv        string = "MOLLIE_API_TOKEN"
22
	OrgTokenEnv        string = "MOLLIE_ORG_TOKEN"
23
	RequestContentType string = "application/json"
24
)
25
26
var (
27
	errEmptyAPIKey = errors.New("you must provide a non-empty API key")
28
	errBadBaseURL  = errors.New("malformed base url, it must contain a trailing slash")
29
)
30
31
// Client manages communication with Mollie's API.
32
type Client struct {
33
	BaseURL        *url.URL
34
	authentication string
35
	client         *http.Client
36
	common         service // Reuse a single struct instead of allocating one for each service on the heap.
37
	config         *Config
38
}
39
40
type service struct {
41
	client *Client
42
}
43
44
// WithAuthenticationValue offers a convenient setter for any of the valid authentication
45
// tokens provided by Mollie.
46
//
47
// Ideally your API key will be provided from and environment variable or
48
// a secret management engine.
49
// This should only be used when environment variables are "impossible" to be used.
50
func (c *Client) WithAuthenticationValue(k string) error {
51 1
	if k == "" {
52 1
		return errEmptyAPIKey
53
	}
54
55 1
	c.authentication = strings.TrimSpace(k)
56
57 1
	return nil
58
}
59
60
// NewAPIRequest is a wrapper around the http.NewRequest function.
61
//
62
// It will setup the authentication headers/parameters according to the client config.
63
func (c *Client) NewAPIRequest(method string, uri string, body interface{}) (req *http.Request, err error) {
64 1
	if !strings.HasSuffix(c.BaseURL.Path, "/") {
65 1
		return nil, errBadBaseURL
66
	}
67
68 1
	u, err := c.BaseURL.Parse(uri)
69 1
	if err != nil {
70 1
		return nil, err
71
	}
72
73 1
	if c.config.testing == true {
74 1
		u.Query().Add("testmode", "true")
75
	}
76
77 1
	var buf io.ReadWriter
78 1
	if body != nil {
79 1
		buf = new(bytes.Buffer)
80 1
		enc := json.NewEncoder(buf)
81 1
		enc.SetEscapeHTML(false)
82 1
		err := enc.Encode(body)
83 1
		if err != nil {
84 1
			return nil, err
85
		}
86
	}
87
88 1
	req, err = http.NewRequest(method, u.String(), buf)
89 1
	if err != nil {
90 1
		return nil, err
91
	}
92
93 1
	req.Header.Add(AuthHeader, strings.Join([]string{TokenType, c.authentication}, " "))
94
95 1
	if body != nil {
96 1
		req.Header.Set("Content-Type", RequestContentType)
97
	}
98 1
	req.Header.Set("Accept", RequestContentType)
99
100 1
	return
101
}
102
103
// Do sends an API request and returns the API response or returned as an
104
// error if an API error has occurred.
105
func (c *Client) Do(req *http.Request) (*Response, error) {
106 1
	resp, err := c.client.Do(req)
107 1
	if err != nil {
108
		return nil, err
109
	}
110 1
	defer resp.Body.Close()
111 1
	response := newResponse(resp)
112 1
	err = CheckResponse(resp)
113 1
	if err != nil {
114
		return nil, err
115
	}
116
117 1
	return response, nil
118
}
119
120
// NewClient returns a new Mollie HTTP API client.
121
// You can pass a previously build http client, if none is provided then
122
// http.DefaultClient will be used.
123
//
124
// NewClient will lookup the environment for values to assign to the
125
// API token (`MOLLIE_API_TOKEN`) and the Organization token (`MOLLIE_ORG_TOKEN`)
126
// according to the provided Config object.
127
//
128
// You can also set the token values programmatically by using the Client
129
// WithAPIKey and WithOrganizationKey functions.
130
func NewClient(baseClient *http.Client, c *Config) (mollie *Client, err error) {
131 1
	if baseClient == nil {
132 1
		baseClient = http.DefaultClient
133
	}
134
135 1
	u, _ := url.Parse(BaseURLV2)
136
137 1
	mollie = &Client{
138
		BaseURL: u,
139
		client:  baseClient,
140
		config:  c,
141
	}
142
143 1
	mollie.common.client = mollie
144
145
	// Parse authorization from environment
146 1
	if tkn, ok := os.LookupEnv(APITokenEnv); ok {
147 1
		mollie.authentication = tkn
148
	}
149 1
	return
150
}
151
152
/*
153
Error reports details on a failed API request.
154
The success or failure of each HTTP request is shown in the status field of the HTTP response header,
155
which contains standard HTTP status codes:
156
- a 2xx code for success
157
- a 4xx or 5xx code for failure
158
*/
159
type Error struct {
160
	Code     int            `json:"code"`
161
	Message  string         `json:"message"`
162
	Response *http.Response `json:"response"` // the full response that produced the error
163
}
164
165
// Error functions implement the Error interface on the zuora.Error struct.
166
func (e *Error) Error() string {
167 1
	return fmt.Sprintf("response failed with status %v", e.Message)
168
}
169
170
/*
171
Constructor for Error
172
*/
173
func newError(r *http.Response) *Error {
174 1
	var e Error
175 1
	e.Response = r
176 1
	e.Code = r.StatusCode
177 1
	e.Message = r.Status
178 1
	return &e
179
}
180
181
// Response is a Mollie API response. This wraps the standard http.Response
182
// returned from Mollie and provides convenient access to things like
183
// pagination links.
184
type Response struct {
185
	*http.Response
186
	content []byte
187
}
188
189
func newResponse(r *http.Response) *Response {
190 1
	var res Response
191 1
	if c, err := ioutil.ReadAll(r.Body); err == nil {
192 1
		res.content = c
193
	}
194 1
	json.NewDecoder(r.Body).Decode(&res)
195 1
	res.Response = r
196 1
	return &res
197
}
198
199
// CheckResponse checks the API response for errors, and returns them if
200
// present. A response is considered an error if it has a status code outside
201
// the 200 range.
202
// API error responses are expected to have either no response
203
// body, or a JSON response body.
204
func CheckResponse(r *http.Response) error {
205 1
	if r.StatusCode >= http.StatusMultipleChoices {
206 1
		return newError(r)
207
	}
208 1
	return nil
209
}
210