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 ( 255a0b...e2059e )
by Victor Hugo
01:20 queued 10s
created

mollie.NewClient   A

Complexity

Conditions 3

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

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