Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new: Implement API changes for 4.129.0 #265

Merged
merged 2 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ type Client struct {
ObjectStorage *Resource
Payments *Resource
Profile *Resource
ProfilePhoneNumber *Resource
ProfileSecurityQuestions *Resource
Regions *Resource
SSHKeys *Resource
StackScripts *Resource
Expand Down Expand Up @@ -467,6 +469,8 @@ func addResources(client *Client) {
objectStorageName: NewResource(client, objectStorageName, objectStorageEndpoint, false, nil, nil),
paymentsName: NewResource(client, paymentsName, paymentsEndpoint, false, Payment{}, PaymentsPagedResponse{}),
profileName: NewResource(client, profileName, profileEndpoint, false, nil, nil), // really?
profilePhoneNumberName: NewResource(client, profilePhoneNumberName, profilePhoneNumberEndpoint, false, nil, nil),
profileSecurityQuestionsName: NewResource(client, profileSecurityQuestionsName, profileSecurityQuestionsEndpoint, false, nil, nil),
regionsName: NewResource(client, regionsName, regionsEndpoint, false, Region{}, RegionsPagedResponse{}),
sshkeysName: NewResource(client, sshkeysName, sshkeysEndpoint, false, SSHKey{}, SSHKeysPagedResponse{}),
stackscriptsName: NewResource(client, stackscriptsName, stackscriptsEndpoint, false, Stackscript{}, StackscriptsPagedResponse{}),
Expand Down Expand Up @@ -527,6 +531,8 @@ func addResources(client *Client) {
client.ObjectStorage = resources[objectStorageName]
client.Payments = resources[paymentsName]
client.Profile = resources[profileName]
client.ProfilePhoneNumber = resources[profilePhoneNumberName]
client.ProfileSecurityQuestions = resources[profileSecurityQuestionsName]
client.Regions = resources[regionsName]
client.SSHKeys = resources[sshkeysName]
client.StackScripts = resources[stackscriptsName]
Expand Down
2 changes: 0 additions & 2 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

func TestConfig_LoadWithDefaults(t *testing.T) {

client := NewClient(nil)

file := createTestConfig(t, configLoadWithDefault)
Expand Down Expand Up @@ -100,7 +99,6 @@ func TestConfig_OverrideDefaults(t *testing.T) {
}

func TestConfig_NoDefaults(t *testing.T) {

client := NewClient(nil)

file := createTestConfig(t, configNoDefaults)
Expand Down
84 changes: 84 additions & 0 deletions profile_phone_number.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package linodego

import (
"context"
"encoding/json"
"fmt"
)

// SendPhoneNumberVerificationCodeOptions fields are those accepted by SendPhoneNumberVerificationCode
type SendPhoneNumberVerificationCodeOptions struct {
ISOCode string `json:"iso_code"`
PhoneNumber string `json:"phone_number"`
}

// VerifyPhoneNumberOptions fields are those accepted by VerifyPhoneNumber
type VerifyPhoneNumberOptions struct {
OTPCode string `json:"otp_code"`
}

// SendPhoneNumberVerificationCode sends a one-time verification code via SMS message to the submitted phone number.
func (c *Client) SendPhoneNumberVerificationCode(ctx context.Context, opts SendPhoneNumberVerificationCodeOptions) error {
var body string
e, err := c.ProfilePhoneNumber.Endpoint()
if err != nil {
return err
}

req := c.R(ctx)

if bodyData, err := json.Marshal(opts); err == nil {
body = string(bodyData)
} else {
return NewError(err)
}

if _, err := coupleAPIErrors(req.
SetBody(body).
Post(e)); err != nil {
return err
}
return nil
}

// DeletePhoneNumber deletes the verified phone number for the User making this request.
func (c *Client) DeletePhoneNumber(ctx context.Context) error {
e, err := c.ProfilePhoneNumber.Endpoint()
if err != nil {
return err
}

req := c.R(ctx)

if _, err := coupleAPIErrors(req.
Delete(e)); err != nil {
return err
}
return nil
}

// VerifyPhoneNumber verifies a phone number by confirming the one-time code received via SMS message after accessing the Phone Verification Code Send command.
func (c *Client) VerifyPhoneNumber(ctx context.Context, opts VerifyPhoneNumberOptions) error {
var body string
e, err := c.ProfilePhoneNumber.Endpoint()
if err != nil {
return err
}

e = fmt.Sprintf("%s/verify", e)

req := c.R(ctx)

if bodyData, err := json.Marshal(opts); err == nil {
body = string(bodyData)
} else {
return NewError(err)
}

if _, err := coupleAPIErrors(req.
SetBody(body).
Post(e)); err != nil {
return err
}
return nil
}
65 changes: 65 additions & 0 deletions profile_security_questions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package linodego

import (
"context"
"encoding/json"
)

type SecurityQuestion struct {
ID int `json:"id"`
Question string `json:"question"`
Response string `json:"response"`
}

type SecurityQuestionsListResponse struct {
SecurityQuestions []SecurityQuestion `json:"security_questions"`
}

type SecurityQuestionsAnswerQuestion struct {
QuestionID int `json:"question_id"`
Response string `json:"response"`
}

type SecurityQuestionsAnswerOptions struct {
SecurityQuestions []SecurityQuestionsAnswerQuestion `json:"security_questions"`
}

// SecurityQuestionsList returns a collection of security questions and their responses, if any, for your User Profile.
func (c *Client) SecurityQuestionsList(ctx context.Context) (*SecurityQuestionsListResponse, error) {
e, err := c.ProfileSecurityQuestions.Endpoint()
if err != nil {
return nil, err
}

req := c.R(ctx).SetResult(&SecurityQuestionsListResponse{})

r, err := coupleAPIErrors(req.Get(e))
if err != nil {
return nil, err
}
return r.Result().(*SecurityQuestionsListResponse), nil
}

// SecurityQuestionsAnswer adds security question responses for your User.
func (c *Client) SecurityQuestionsAnswer(ctx context.Context, opts SecurityQuestionsAnswerOptions) error {
var body string
e, err := c.ProfileSecurityQuestions.Endpoint()
if err != nil {
return err
}

req := c.R(ctx)

if bodyData, err := json.Marshal(opts); err == nil {
body = string(bodyData)
} else {
return NewError(err)
}

if _, err := coupleAPIErrors(req.
SetBody(body).
Post(e)); err != nil {
return err
}
return nil
}
114 changes: 114 additions & 0 deletions profile_tfa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package linodego

import (
"context"
"encoding/json"
"fmt"
"time"

"github.com/linode/linodego/internal/parseabletime"
)

// TwoFactorSecret contains fields returned by CreateTwoFactorSecret
type TwoFactorSecret struct {
Expiry *time.Time `json:"expiry"`
Secret string `json:"secret"`
}

// ConfirmTwoFactorOptions contains fields used by ConfirmTwoFactor
type ConfirmTwoFactorOptions struct {
TFACode string `json:"tfa_code"`
}

// ConfirmTwoFactorResponse contains fields returned by ConfirmTwoFactor
type ConfirmTwoFactorResponse struct {
Scratch string `json:"scratch"`
}

func (s *TwoFactorSecret) UnmarshalJSON(b []byte) error {
type Mask TwoFactorSecret

p := struct {
*Mask
Expiry *parseabletime.ParseableTime `json:"expiry"`
}{
Mask: (*Mask)(s),
}

if err := json.Unmarshal(b, &p); err != nil {
return err
}

s.Expiry = (*time.Time)(p.Expiry)

return nil
}

// CreateTwoFactorSecret generates a Two Factor secret for your User.
func (c *Client) CreateTwoFactorSecret(ctx context.Context) (*TwoFactorSecret, error) {
e, err := c.Profile.Endpoint()
if err != nil {
return nil, err
}

e = fmt.Sprintf("%s/tfa-enable", e)

req := c.R(ctx).SetResult(&TwoFactorSecret{})

r, err := coupleAPIErrors(req.
Post(e))
if err != nil {
return nil, err
}

return r.Result().(*TwoFactorSecret), nil
}

// DisableTwoFactor disables Two Factor Authentication for your User.
func (c *Client) DisableTwoFactor(ctx context.Context) error {
e, err := c.Profile.Endpoint()
if err != nil {
return err
}

e = fmt.Sprintf("%s/tfa-disable", e)

req := c.R(ctx)

_, err = coupleAPIErrors(req.
Post(e))
if err != nil {
return err
}

return nil
}

// ConfirmTwoFactor confirms that you can successfully generate Two Factor codes and enables TFA on your Account.
func (c *Client) ConfirmTwoFactor(ctx context.Context, opts ConfirmTwoFactorOptions) (*ConfirmTwoFactorResponse, error) {
var body string

e, err := c.Profile.Endpoint()
if err != nil {
return nil, err
}

e = fmt.Sprintf("%s/tfa-enable-confirm", e)

if bodyData, err := json.Marshal(opts); err == nil {
body = string(bodyData)
} else {
return nil, NewError(err)
}

req := c.R(ctx).SetResult(&ConfirmTwoFactorResponse{})

r, err := coupleAPIErrors(req.
SetBody(body).
Post(e))
if err != nil {
return nil, err
}

return r.Result().(*ConfirmTwoFactorResponse), nil
}
4 changes: 4 additions & 0 deletions resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const (
objectStorageName = "objectstorage"
paymentsName = "payments"
profileName = "profile"
profilePhoneNumberName = "profilephonenumber"
profileSecurityQuestionsName = "profilesecurityquestions"
regionsName = "regions"
sshkeysName = "sshkeys"
stackscriptsName = "stackscripts"
Expand Down Expand Up @@ -122,6 +124,8 @@ const (
objectStorageEndpoint = "object-storage"
paymentsEndpoint = "account/payments"
profileEndpoint = "profile"
profilePhoneNumberEndpoint = "profile/phone-number"
profileSecurityQuestionsEndpoint = "profile/security-questions"
regionsEndpoint = "regions"
sshkeysEndpoint = "profile/sshkeys"
stackscriptsEndpoint = "linode/stackscripts"
Expand Down
1 change: 1 addition & 0 deletions test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module test
require (
github.com/dnaeon/go-vcr v1.1.0
github.com/google/go-cmp v0.5.7
github.com/jarcoal/httpmock v1.2.0
github.com/linode/linodego v0.20.1
github.com/linode/linodego/k8s v0.0.0-00010101000000-000000000000
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
Expand Down
3 changes: 3 additions & 0 deletions test/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
Expand All @@ -191,6 +193,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down
3 changes: 2 additions & 1 deletion test/integration/databases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func TestDatabase_List(t *testing.T) {
}

func waitForDatabaseUpdated(t *testing.T, client *linodego.Client, dbID int,
dbType linodego.DatabaseEngineType, minStart *time.Time) {
dbType linodego.DatabaseEngineType, minStart *time.Time,
) {
_, err := client.WaitForEventFinished(context.Background(), dbID, linodego.EntityDatabase,
linodego.ActionDatabaseUpdate, *minStart, 1200)
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions test/integration/integration_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"testing"
"time"

"github.com/jarcoal/httpmock"

"github.com/dnaeon/go-vcr/cassette"
"github.com/dnaeon/go-vcr/recorder"
"github.com/linode/linodego"
Expand Down Expand Up @@ -150,6 +152,24 @@ func createTestClient(t *testing.T, fixturesYaml string) (*linodego.Client, func
return &c, recordStopper
}

func createMockClient(t *testing.T) *linodego.Client {
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: validTestAPIKey})

client := &http.Client{
Transport: &oauth2.Transport{
Source: tokenSource,
},
}
httpmock.ActivateNonDefault(client)

t.Cleanup(func() {
httpmock.DeactivateAndReset()
})

c := linodego.NewClient(client)
return &c
}

// transportRecordWrapper returns a tranport.WrapperFunc which provides the test
// recorder as an http.RoundTripper.
func transportRecorderWrapper(t *testing.T, fixtureYaml string) (transport.WrapperFunc, func()) {
Expand Down
Loading