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.
Completed
Pull Request — master (#32)
by
unknown
01:19
created

mollie.newError   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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