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 ( 76d75a...85f6e4 )
by Victor Hugo
01:21
created

mollie.NewClient   A

Complexity

Conditions 3

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 20
dl 0
loc 30
c 0
b 0
f 0
ccs 16
cts 16
cp 1
crap 3
rs 9.4
nop 2
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
	BaseURL            string = "https://api.mollie.com/"
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
	// Services
39
	Payments      *PaymentsService
40
	Chargebacks   *ChargebacksService
41
	Methods       *MethodsService
42
	Invoices      *InvoicesService
43
	Organizations *OrganizationsService
44
	Profiles      *ProfilesService
45
	Refunds       *RefundsService
46
	Shipments     *ShipmentsService
47
}
48
49
type service struct {
50
	client *Client
51
}
52
53
// WithAuthenticationValue offers a convenient setter for any of the valid authentication
54
// tokens provided by Mollie.
55
//
56
// Ideally your API key will be provided from and environment variable or
57
// a secret management engine.
58
// This should only be used when environment variables are "impossible" to be used.
59
func (c *Client) WithAuthenticationValue(k string) error {
60 1
	if k == "" {
61 1
		return errEmptyAPIKey
62
	}
63
64 1
	c.authentication = strings.TrimSpace(k)
65
66 1
	return nil
67
}
68
69
// NewAPIRequest is a wrapper around the http.NewRequest function.
70
//
71
// It will setup the authentication headers/parameters according to the client config.
72
func (c *Client) NewAPIRequest(method string, uri string, body interface{}) (req *http.Request, err error) {
73 1
	if !strings.HasSuffix(c.BaseURL.Path, "/") {
74 1
		return nil, errBadBaseURL
75
	}
76
77 1
	u, err := c.BaseURL.Parse(uri)
78 1
	if err != nil {
79 1
		return nil, err
80
	}
81
82 1
	if c.config.testing == true {
83 1
		u.Query().Add("testmode", "true")
84
	}
85
86 1
	var buf io.ReadWriter
87 1
	if body != nil {
88 1
		buf = new(bytes.Buffer)
89 1
		enc := json.NewEncoder(buf)
90 1
		enc.SetEscapeHTML(false)
91 1
		err := enc.Encode(body)
92 1
		if err != nil {
93 1
			return nil, err
94
		}
95
	}
96
97 1
	req, err = http.NewRequest(method, u.String(), buf)
98 1
	if err != nil {
99 1
		return nil, err
100
	}
101
102 1
	req.Header.Add(AuthHeader, strings.Join([]string{TokenType, c.authentication}, " "))
103
104 1
	if body != nil {
105 1
		req.Header.Set("Content-Type", RequestContentType)
106
	}
107 1
	req.Header.Set("Accept", RequestContentType)
108
109 1
	return
110
}
111
112
// Do sends an API request and returns the API response or returned as an
113
// error if an API error has occurred.
114
func (c *Client) Do(req *http.Request) (*Response, error) {
115 1
	resp, err := c.client.Do(req)
116 1
	if err != nil {
117 1
		return nil, err
118
	}
119 1
	defer resp.Body.Close()
120 1
	response := newResponse(resp)
121 1
	err = CheckResponse(resp)
122 1
	if err != nil {
123 1
		return nil, err
124
	}
125
126 1
	return response, nil
127
}
128
129
// NewClient returns a new Mollie HTTP API client.
130
// You can pass a previously build http client, if none is provided then
131
// http.DefaultClient will be used.
132
//
133
// NewClient will lookup the environment for values to assign to the
134
// API token (`MOLLIE_API_TOKEN`) and the Organization token (`MOLLIE_ORG_TOKEN`)
135
// according to the provided Config object.
136
//
137
// You can also set the token values programmatically by using the Client
138
// WithAPIKey and WithOrganizationKey functions.
139
func NewClient(baseClient *http.Client, c *Config) (mollie *Client, err error) {
140 1
	if baseClient == nil {
141 1
		baseClient = http.DefaultClient
142
	}
143
144 1
	u, _ := url.Parse(BaseURL)
145
146 1
	mollie = &Client{
147
		BaseURL: u,
148
		client:  baseClient,
149
		config:  c,
150
	}
151
152 1
	mollie.common.client = mollie
153
154
	// services for resources
155 1
	mollie.Payments = (*PaymentsService)(&mollie.common)
156 1
	mollie.Chargebacks = (*ChargebacksService)(&mollie.common)
157 1
	mollie.Methods = (*MethodsService)(&mollie.common)
158 1
	mollie.Invoices = (*InvoicesService)(&mollie.common)
159 1
	mollie.Organizations = (*OrganizationsService)(&mollie.common)
160 1
	mollie.Profiles = (*ProfilesService)(&mollie.common)
161 1
	mollie.Refunds = (*RefundsService)(&mollie.common)
162 1
	mollie.Shipments = (*ShipmentsService)(&mollie.common)
163
164
	// Parse authorization from environment
165 1
	if tkn, ok := os.LookupEnv(APITokenEnv); ok {
166 1
		mollie.authentication = tkn
167
	}
168 1
	return
169
}
170
171
/*
172
Error reports details on a failed API request.
173
The success or failure of each HTTP request is shown in the status field of the HTTP response header,
174
which contains standard HTTP status codes:
175
- a 2xx code for success
176
- a 4xx or 5xx code for failure
177
*/
178
type Error struct {
179
	Code     int            `json:"code"`
180
	Message  string         `json:"message"`
181
	Response *http.Response `json:"response"` // the full response that produced the error
182
}
183
184
// Error functions implement the Error interface on the zuora.Error struct.
185
func (e *Error) Error() string {
186 1
	return fmt.Sprintf("response failed with status %v", e.Message)
187
}
188
189
/*
190
Constructor for Error
191
*/
192
func newError(r *http.Response) *Error {
193 1
	var e Error
194 1
	e.Response = r
195 1
	e.Code = r.StatusCode
196 1
	e.Message = r.Status
197 1
	return &e
198
}
199
200
// Response is a Mollie API response. This wraps the standard http.Response
201
// returned from Mollie and provides convenient access to things like
202
// pagination links.
203
type Response struct {
204
	*http.Response
205
	content []byte
206
}
207
208
func newResponse(r *http.Response) *Response {
209 1
	var res Response
210 1
	if c, err := ioutil.ReadAll(r.Body); err == nil {
211 1
		res.content = c
212
	}
213 1
	json.NewDecoder(r.Body).Decode(&res)
214 1
	res.Response = r
215 1
	return &res
216
}
217
218
// CheckResponse checks the API response for errors, and returns them if
219
// present. A response is considered an error if it has a status code outside
220
// the 200 range.
221
// API error responses are expected to have either no response
222
// body, or a JSON response body.
223
func CheckResponse(r *http.Response) error {
224 1
	if r.StatusCode >= http.StatusMultipleChoices {
225 1
		return newError(r)
226
	}
227 1
	return nil
228
}
229