-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for missing Profile-related endpoints (#616)
* Added missing profile endpoints * Fix lint
- Loading branch information
1 parent
86d05de
commit 91c542c
Showing
12 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package linodego | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"time" | ||
|
||
"github.com/linode/linodego/internal/parseabletime" | ||
) | ||
|
||
// ProfileApp represents a ProfileApp object | ||
type ProfileApp struct { | ||
// When this app was authorized. | ||
Created *time.Time `json:"-"` | ||
|
||
// When the app's access to your account expires. | ||
Expiry *time.Time `json:"-"` | ||
|
||
// This authorization's ID, used for revoking access. | ||
ID int `json:"id"` | ||
|
||
// The name of the application you've authorized. | ||
Label string `json:"label"` | ||
|
||
// The OAuth scopes this app was authorized with. | ||
Scopes string `json:"scopes"` | ||
|
||
// The URL at which this app's thumbnail may be accessed. | ||
ThumbnailURL string `json:"thumbnail_url"` | ||
|
||
// The website where you can get more information about this app. | ||
Website string `json:"website"` | ||
} | ||
|
||
// UnmarshalJSON implements the json.Unmarshaler interface | ||
func (pa *ProfileApp) UnmarshalJSON(b []byte) error { | ||
type Mask ProfileApp | ||
|
||
l := struct { | ||
*Mask | ||
Created *parseabletime.ParseableTime `json:"created"` | ||
Expiry *parseabletime.ParseableTime `json:"expiry"` | ||
}{ | ||
Mask: (*Mask)(pa), | ||
} | ||
|
||
if err := json.Unmarshal(b, &l); err != nil { | ||
return err | ||
} | ||
|
||
pa.Created = (*time.Time)(l.Created) | ||
pa.Expiry = (*time.Time)(l.Expiry) | ||
|
||
return nil | ||
} | ||
|
||
// GetProfileApp returns the ProfileApp with the provided id | ||
func (c *Client) GetProfileApp(ctx context.Context, appID int) (*ProfileApp, error) { | ||
e := formatAPIPath("profile/apps/%d", appID) | ||
return doGETRequest[ProfileApp](ctx, c, e) | ||
} | ||
|
||
// ListProfileApps lists ProfileApps that have access to the Account | ||
func (c *Client) ListProfileApps(ctx context.Context, opts *ListOptions) ([]ProfileApp, error) { | ||
return getPaginatedResults[ProfileApp](ctx, c, "profile/apps", opts) | ||
} | ||
|
||
// DeleteProfileApp revokes the given ProfileApp's access to the account | ||
func (c *Client) DeleteProfileApp(ctx context.Context, appID int) error { | ||
e := formatAPIPath("profile/apps/%d", appID) | ||
err := doDELETERequest(ctx, c, e) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package linodego | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"time" | ||
|
||
"github.com/linode/linodego/internal/parseabletime" | ||
) | ||
|
||
// ProfileDevice represents a ProfileDevice object | ||
type ProfileDevice struct { | ||
// When this Remember Me session was started. | ||
Created *time.Time `json:"-"` | ||
|
||
// When this TrustedDevice session expires. Sessions typically last 30 days. | ||
Expiry *time.Time `json:"-"` | ||
|
||
// The unique ID for this TrustedDevice. | ||
ID int `json:"id"` | ||
|
||
// he last time this TrustedDevice was successfully used to authenticate to login.linode.com | ||
LastAuthenticated *time.Time `json:"-"` | ||
|
||
// The last IP Address to successfully authenticate with this TrustedDevice. | ||
LastRemoteAddr string `json:"last_remote_addr"` | ||
|
||
// The User Agent of the browser that created this TrustedDevice session. | ||
UserAgent string `json:"user_agent"` | ||
} | ||
|
||
// UnmarshalJSON implements the json.Unmarshaler interface | ||
func (pd *ProfileDevice) UnmarshalJSON(b []byte) error { | ||
type Mask ProfileDevice | ||
|
||
l := struct { | ||
*Mask | ||
Created *parseabletime.ParseableTime `json:"created"` | ||
Expiry *parseabletime.ParseableTime `json:"expiry"` | ||
LastAuthenticated *parseabletime.ParseableTime `json:"last_authenticated"` | ||
}{ | ||
Mask: (*Mask)(pd), | ||
} | ||
|
||
if err := json.Unmarshal(b, &l); err != nil { | ||
return err | ||
} | ||
|
||
pd.Created = (*time.Time)(l.Created) | ||
pd.Expiry = (*time.Time)(l.Expiry) | ||
pd.LastAuthenticated = (*time.Time)(l.LastAuthenticated) | ||
|
||
return nil | ||
} | ||
|
||
// GetProfileDevice returns the ProfileDevice with the provided id | ||
func (c *Client) GetProfileDevice(ctx context.Context, deviceID int) (*ProfileDevice, error) { | ||
e := formatAPIPath("profile/devices/%d", deviceID) | ||
return doGETRequest[ProfileDevice](ctx, c, e) | ||
} | ||
|
||
// ListProfileDevices lists ProfileDevices for the User | ||
func (c *Client) ListProfileDevices(ctx context.Context, opts *ListOptions) ([]ProfileDevice, error) { | ||
return getPaginatedResults[ProfileDevice](ctx, c, "profile/devices", opts) | ||
} | ||
|
||
// DeleteProfileDevice revokes the given ProfileDevice's status as a trusted device | ||
func (c *Client) DeleteProfileDevice(ctx context.Context, deviceID int) error { | ||
e := formatAPIPath("profile/devices/%d", deviceID) | ||
err := doDELETERequest(ctx, c, e) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package linodego | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
) | ||
|
||
// ProfilePreferences represents the user's preferences. | ||
// The user preferences endpoints allow consumers of the API to store arbitrary JSON data, | ||
// such as a user's font size preference or preferred display name. | ||
type ProfilePreferences map[string]interface{} | ||
|
||
// UnmarshalJSON implements the json.Unmarshaler interface | ||
func (p *ProfilePreferences) UnmarshalJSON(b []byte) error { | ||
var data map[string]interface{} | ||
if err := json.Unmarshal(b, &data); err != nil { | ||
return err | ||
} | ||
|
||
*p = data | ||
return nil | ||
} | ||
|
||
// GetProfilePreferences retrieves the user preferences for the current User | ||
func (c *Client) GetProfilePreferences(ctx context.Context) (*ProfilePreferences, error) { | ||
return doGETRequest[ProfilePreferences](ctx, c, "profile/preferences") | ||
} | ||
|
||
// UpdateProfilePreferences updates the user's preferences with the provided data | ||
func (c *Client) UpdateProfilePreferences(ctx context.Context, opts ProfilePreferences) (*ProfilePreferences, error) { | ||
return doPUTRequest[ProfilePreferences](ctx, c, "profile/preferences", opts) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"created": "2018-01-01T00:01:01", | ||
"expiry": "2018-01-15T00:01:01", | ||
"id": 123, | ||
"label": "example-app", | ||
"scopes": "linodes:read_only", | ||
"thumbnail_url": null, | ||
"website": "example.org" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"created": "2018-01-01T00:01:01", | ||
"expiry": "2018-01-15T00:01:01", | ||
"id": 123, | ||
"label": "example-app", | ||
"scopes": "linodes:read_only", | ||
"thumbnail_url": null, | ||
"website": "example.org" | ||
} | ||
], | ||
"page": 1, | ||
"pages": 1, | ||
"results": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"created": "2018-01-01T01:01:01", | ||
"expiry": "2018-01-31T01:01:01", | ||
"id": 123, | ||
"last_authenticated": "2018-01-05T12:57:12", | ||
"last_remote_addr": "203.0.113.1", | ||
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Vivaldi/2.1.1337.36" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"created": "2018-01-01T01:01:01", | ||
"expiry": "2018-01-31T01:01:01", | ||
"id": 123, | ||
"last_authenticated": "2018-01-05T12:57:12", | ||
"last_remote_addr": "203.0.113.1", | ||
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Vivaldi/2.1.1337.36" | ||
} | ||
], | ||
"page": 1, | ||
"pages": 1, | ||
"results": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"key1": "value1", | ||
"key2": "value2" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"key1": "value1_new", | ||
"key2": "value2_new" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package unit | ||
|
||
import ( | ||
"context" | ||
"github.com/jarcoal/httpmock" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestProfileApps_Get(t *testing.T) { | ||
fixtureData, err := fixtures.GetFixture("profile_apps_get") | ||
assert.NoError(t, err) | ||
|
||
var base ClientBaseCase | ||
base.SetUp(t) | ||
defer base.TearDown(t) | ||
|
||
base.MockGet("profile/apps/123", fixtureData) | ||
|
||
app, err := base.Client.GetProfileApp(context.Background(), 123) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, 123, app.ID) | ||
assert.Equal(t, "example-app", app.Label) | ||
assert.Equal(t, "linodes:read_only", app.Scopes) | ||
assert.Equal(t, "example.org", app.Website) | ||
} | ||
|
||
func TestProfileApps_List(t *testing.T) { | ||
fixtureData, err := fixtures.GetFixture("profile_apps_list") | ||
assert.NoError(t, err) | ||
|
||
var base ClientBaseCase | ||
base.SetUp(t) | ||
defer base.TearDown(t) | ||
|
||
base.MockGet("profile/apps", fixtureData) | ||
|
||
apps, err := base.Client.ListProfileApps(context.Background(), nil) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, 1, len(apps)) | ||
app := apps[0] | ||
|
||
assert.Equal(t, 123, app.ID) | ||
assert.Equal(t, "example-app", app.Label) | ||
assert.Equal(t, "linodes:read_only", app.Scopes) | ||
assert.Equal(t, "example.org", app.Website) | ||
} | ||
|
||
func TestProfileApps_Delete(t *testing.T) { | ||
client := createMockClient(t) | ||
|
||
httpmock.RegisterRegexpResponder("DELETE", mockRequestURL(t, "profile/apps/123"), httpmock.NewStringResponder(200, "{}")) | ||
|
||
if err := client.DeleteProfileApp(context.Background(), 123); err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package unit | ||
|
||
import ( | ||
"context" | ||
"github.com/jarcoal/httpmock" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestProfileDevices_Get(t *testing.T) { | ||
fixtureData, err := fixtures.GetFixture("profile_devices_get") | ||
assert.NoError(t, err) | ||
|
||
var base ClientBaseCase | ||
base.SetUp(t) | ||
defer base.TearDown(t) | ||
|
||
base.MockGet("profile/devices/123", fixtureData) | ||
|
||
device, err := base.Client.GetProfileDevice(context.Background(), 123) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, 123, device.ID) | ||
assert.Equal(t, "203.0.113.1", device.LastRemoteAddr) | ||
assert.Equal(t, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Vivaldi/2.1.1337.36", device.UserAgent) | ||
} | ||
|
||
func TestProfileDevices_List(t *testing.T) { | ||
fixtureData, err := fixtures.GetFixture("profile_devices_list") | ||
assert.NoError(t, err) | ||
|
||
var base ClientBaseCase | ||
base.SetUp(t) | ||
defer base.TearDown(t) | ||
|
||
base.MockGet("profile/devices", fixtureData) | ||
|
||
devices, err := base.Client.ListProfileDevices(context.Background(), nil) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, 1, len(devices)) | ||
device := devices[0] | ||
|
||
assert.Equal(t, 123, device.ID) | ||
assert.Equal(t, "203.0.113.1", device.LastRemoteAddr) | ||
assert.Equal(t, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Vivaldi/2.1.1337.36", device.UserAgent) | ||
} | ||
|
||
func TestProfileDevices_Delete(t *testing.T) { | ||
client := createMockClient(t) | ||
|
||
httpmock.RegisterRegexpResponder("DELETE", mockRequestURL(t, "profile/devices/123"), httpmock.NewStringResponder(200, "{}")) | ||
|
||
if err := client.DeleteProfileDevice(context.Background(), 123); err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
Oops, something went wrong.