Commit 79e2cac1 authored by Sybren A. Stüvel's avatar Sybren A. Stüvel

Added comments to all exported symbols

parent 145af892
......@@ -33,6 +33,7 @@ import (
"gopkg.in/yaml.v2"
)
// Credentials are stored in YAML and serve as our config.
type Credentials struct {
filename string
apiURL *url.URL
......@@ -46,6 +47,7 @@ type Credentials struct {
DeviceID int `yaml:"deviceID"`
}
// LoadCredentials loads credentials from a YAML file.
func LoadCredentials() Credentials {
filename, err := filepath.Abs(fileCredentials)
if err != nil {
......@@ -87,6 +89,8 @@ func LoadCredentials() Credentials {
return creds
}
// Endpoint returns the URL for a given endpoint name.
// It takes sandbox/production switching into account.
func (creds Credentials) Endpoint(endpoint string) string {
endpointURL, err := creds.apiURL.Parse(endpoint)
if err != nil {
......@@ -100,6 +104,7 @@ func (creds Credentials) Endpoint(endpoint string) string {
return endpointURL.String()
}
// Save stores the credentials in the same file they were read from.
func (creds Credentials) Save() {
logger := log.WithField("filename", creds.filename)
......
......@@ -34,6 +34,7 @@ import (
"github.com/sirupsen/logrus"
)
// Client is the bunq API client.
type Client struct {
creds Credentials
session Session
......@@ -44,6 +45,7 @@ type Client struct {
httpClient *http.Client
}
// NewClient creates a new Client using the given credentials.
func NewClient(creds Credentials) *Client {
privateKey := ensureOwnRSAKey()
publicKey := privateKey.Public()
......@@ -63,7 +65,7 @@ func NewClient(creds Credentials) *Client {
}
}
func (c *Client) NewRequest(method, endpoint string, payload interface{}) *http.Request {
func (c *Client) newRequest(method, endpoint string, payload interface{}) *http.Request {
url := c.creds.Endpoint(endpoint)
var body []byte
......@@ -107,13 +109,14 @@ func (c *Client) NewRequest(method, endpoint string, payload interface{}) *http.
return req
}
// DoRequest performs a HTTP request.
func (c *Client) DoRequest(method, endpoint string, payload interface{}, response interface{}) *ErrorResponse {
logger := log.WithFields(logrus.Fields{
"method": method,
"endpoint": endpoint,
})
req := c.NewRequest(method, endpoint, payload)
req := c.newRequest(method, endpoint, payload)
logger = logger.WithField("url", req.URL)
c.SignRequest(req)
......
......@@ -38,6 +38,7 @@ type deviceServerResponse struct {
ID BunqID `json:"Id"`
}
// CheckDeviceServer registers this device with bunq if we don't have a device ID yet.
func (c *Client) CheckDeviceServer(description string, permittedIPs []string) {
if c.creds.DeviceID != 0 {
log.WithField("deviceID", c.creds.DeviceID).Debug("device ID is known")
......@@ -46,6 +47,7 @@ func (c *Client) CheckDeviceServer(description string, permittedIPs []string) {
c.PostDeviceServer(description, permittedIPs)
}
// PostDeviceServer registers this device with bunq
func (c *Client) PostDeviceServer(description string, permittedIPs []string) {
payload := deviceServerRequest{
Description: description,
......
......@@ -30,6 +30,7 @@ import (
"github.com/sirupsen/logrus"
)
// InstallationConfig contains our installation token and the server's public RSA key.
type InstallationConfig struct {
Token string `yaml:"token,omitempty"`
ServerPublicKey string `yaml:"serverPublicKey,omitempty"`
......@@ -75,6 +76,7 @@ func publicKeyString(privateKey *rsa.PrivateKey) string {
return string(pubKeyPem)
}
// PostInstallation performs a POST to the 'installation' endpoint
func (c *Client) PostInstallation() {
payload := installationRequest{
ClientPublicKey: publicKeyString(c.privateKey),
......@@ -100,6 +102,7 @@ func (c *Client) PostInstallation() {
c.creds.Save()
}
// CheckInstallation performs a POST to the 'installation' endpoint if we have no installation token or server RSA key.
func (c *Client) CheckInstallation() {
if c.creds.InstallationToken != "" && c.creds.ServerPublicKey != "" {
log.WithFields(logrus.Fields{
......
......@@ -35,10 +35,12 @@ func init() {
})
}
// LogLevel sets the package-global log level.
func LogLevel(level logrus.Level) {
log.SetLevel(level)
}
// LogFormatter sets the package-global log formatter.
func LogFormatter(formatter logrus.Formatter) {
log.SetFormatter(formatter)
}
......@@ -28,6 +28,7 @@ import (
"github.com/sirupsen/logrus"
)
// BunqID wraps an ID
type BunqID struct {
ID int `json:"id"`
}
......@@ -39,6 +40,7 @@ type idResponse struct {
ID BunqID `json:"Id"`
}
// Geolocation is defined by the bunq API.
type Geolocation struct {
Latitude int `json:"latitude"`
Longitude int `json:"longitude"`
......@@ -46,12 +48,14 @@ type Geolocation struct {
Radius int `json:"radius"`
}
// Pointer is defined by the bunq API.
type Pointer struct {
Type string `json:"type,omitempty"`
Value string `json:"value,omitempty"`
Name string `json:"name,omitempty"`
}
// ErrorResponse is defined by the bunq API.
type ErrorResponse struct {
Error []struct {
Description string `json:"error_description"`
......@@ -59,6 +63,7 @@ type ErrorResponse struct {
} `json:"Error"`
}
// LogFields returns logrus fields that represent this error response.
func (er *ErrorResponse) LogFields() logrus.Fields {
switch len(er.Error) {
case 0:
......
......@@ -42,6 +42,7 @@ type monetaryAccountBankCreateResponse struct {
ID BunqID `json:"Id"`
}
// MonetaryAccountBank is defined by the bunq API.
type MonetaryAccountBank struct {
ID int `json:"id,omitempty"`
Created *Time `json:"created,omitempty"`
......@@ -65,6 +66,7 @@ type MonetaryAccountBank struct {
// monetary_account_profile is not yet implemented
}
// MonetaryAccountSetting is defined by the bunq API.
type MonetaryAccountSetting struct {
Color string `json:"color"`
DefaultAvatarStatus string `json:"default_avatar_status"`
......@@ -80,6 +82,7 @@ func (mab MonetaryAccountBank) AliasFields() logrus.Fields {
return fields
}
// GetMonetaryAccountBankList fetches a list of the current user's own bank accounts.
func (c *Client) GetMonetaryAccountBankList() []MonetaryAccountBank {
wrappedResponse := wrappedMonetaryAccountBankResponse{}
url := fmt.Sprintf("user/%d/monetary-account-bank", c.session.UserPerson.ID)
......@@ -96,6 +99,7 @@ func (c *Client) GetMonetaryAccountBankList() []MonetaryAccountBank {
return accounts
}
// CreateMonetaryAccountBank creates a new bank account for the current user.
func (c *Client) CreateMonetaryAccountBank(account MonetaryAccountBank) {
wrappedResponse := wrappedMonetaryAccountBankCreateResponse{}
url := fmt.Sprintf("user/%d/monetary-account-bank", c.session.UserPerson.ID)
......
......@@ -58,6 +58,7 @@ type RequestInquiry struct {
// ReferenceSplitTheBill *RequestReferenceSplitTheBillAnchorObject `json:"reference_split_the_bill,omitempty"`
}
// LabelMonetaryAccount is defined by the bunq API.
type LabelMonetaryAccount struct {
Type string `json:"type,omitempty"`
Value string `json:"value,omitempty"`
......@@ -76,6 +77,7 @@ type LabelMonetaryAccount struct {
// BunqMe *Pointer `json:"bunq_me,omitempty"`
}
// CreateRequestInquiry creates a payment request.
func (c *Client) CreateRequestInquiry(monetaryAccountID int, rfp RequestInquiry) int {
wrappedResponse := wrappedIDResponse{}
url := fmt.Sprintf("user/%d/monetary-account/%d/request-inquiry", c.session.UserPerson.ID, monetaryAccountID)
......
......@@ -55,6 +55,7 @@ type sessionServerResponse struct {
UserPerson *UserPerson `json:"UserPerson"`
}
// SessionStart creates a bunq session. It will be used in subsequent API calls.
func (c *Client) SessionStart() {
payload := sessionServerRequest{
Secret: c.creds.APIKey,
......@@ -81,6 +82,7 @@ func (c *Client) SessionStart() {
}).Info("session created")
}
// SessionStop closes the current bunq session.
func (c *Client) SessionStop() {
logger := log.WithField("sessionID", c.session.ID)
logger.Debug("closing session")
......
......@@ -52,6 +52,7 @@ func sortedHeaderKeys(header http.Header) []string {
return headerKeys
}
// SignRequest signs a HTTP request using our private RSA key.
func (c *Client) SignRequest(r *http.Request) error {
if r.Header.Get(headerXBunqClientSignature) != "" {
log.Panic("this request has already been signed")
......@@ -107,6 +108,8 @@ func (c *Client) SignRequest(r *http.Request) error {
return nil
}
// VerifyResponse verifies a HTTP response using the server's public RSA key.
// We obtained the server's key in the PostInstall() function.
func (c *Client) VerifyResponse(r *http.Response) error {
// TODO: merge common code between this function and SignRequest().
serverSignatureB64 := r.Header.Get(headerXBunqServerSignature)
......
......@@ -22,29 +22,36 @@
package bunqapi
// Alias is defined by the bunq API.
type Alias struct {
Type string `json:"type"`
Value string `json:"value"`
Name string `json:"name"`
}
// AvatarImage is defined by the bunq API.
type AvatarImage struct {
AttachmentPublicUUID string `json:"attachment_public_uuid"`
ContentType string `json:"content_type"`
Height int `json:"height"`
Width int `json:"width"`
}
// UBO is defined by the bunq API.
type UBO struct {
Name string `json:"name"`
DateOfBirth Time `json:"date_of_birth"`
Nationality string `json:"nationality"`
}
// NotificationFilter is defined by the bunq API.
type NotificationFilter struct {
NotificationDeliveryMethod string `json:"notification_delivery_method"`
NotificationTarget string `json:"notification_target"`
Category string `json:"category"`
}
// Address is defined by the bunq API.
type Address struct {
Street string `json:"street"`
HouseNumber string `json:"house_number"`
......@@ -54,12 +61,14 @@ type Address struct {
Country string `json:"country"`
}
// Avatar is defined by the bunq API.
type Avatar struct {
UUID string `json:"uuid"`
AnchorUUID string `json:"anchor_uuid"`
Image []AvatarImage `json:"image"`
}
// DirectorAlias is defined by the bunq API.
type DirectorAlias struct {
UUID string `json:"uuid"`
Avatar Avatar `json:"avatar"`
......@@ -68,11 +77,13 @@ type DirectorAlias struct {
Country string `json:"country"`
}
// Limit is defined by the bunq API.
type Limit struct {
Value string `json:"value"`
Currency string `json:"currency"`
}
// UserCompany is defined by the bunq API.
type UserCompany struct {
ID int `json:"id"`
CreatedAt Time `json:"created"`
......@@ -101,6 +112,7 @@ type UserCompany struct {
NotificationFilters []NotificationFilter `json:"notification_filters"`
}
// UserPerson is defined by the bunq API.
type UserPerson struct {
ID int `json:"id"`
Created Time `json:"created"`
......@@ -140,6 +152,7 @@ type UserPerson struct {
VersionTermsOfService string `json:"version_terms_of_service"`
}
// LabelUser is defined by the bunq API.
type LabelUser struct {
UUID string `json:"uuid,omitempty"`
DisplayName string `json:"display_name,omitempty"`
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment