Skip to content

Commit 22d99f5

Browse files
Merge pull request #312 from ezilber-akamai/TPT-1812
Added profile login endpoints
2 parents fa3a5bc + e5eb521 commit 22d99f5

File tree

3 files changed

+243
-0
lines changed

3 files changed

+243
-0
lines changed

profile_logins.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package linodego
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"time"
8+
9+
"github.com/go-resty/resty/v2"
10+
"github.com/linode/linodego/internal/parseabletime"
11+
)
12+
13+
// Profile represents a Profile object
14+
type ProfileLogin struct {
15+
Datetime *time.Time `json:"datetime"`
16+
ID int `json:"id"`
17+
IP string `json:"ip"`
18+
Restricted bool `json:"restricted"`
19+
Status string `json:"status"`
20+
Username string `json:"username"`
21+
}
22+
23+
type ProfileLoginsPagedResponse struct {
24+
*PageOptions
25+
Data []ProfileLogin `json:"data"`
26+
}
27+
28+
func (ProfileLoginsPagedResponse) endpoint(_ ...any) string {
29+
return "profile/logins"
30+
}
31+
32+
func (resp *ProfileLoginsPagedResponse) castResult(r *resty.Request, e string) (int, int, error) {
33+
res, err := coupleAPIErrors(r.SetResult(ProfileLoginsPagedResponse{}).Get(e))
34+
if err != nil {
35+
return 0, 0, err
36+
}
37+
castedRes := res.Result().(*ProfileLoginsPagedResponse)
38+
resp.Data = append(resp.Data, castedRes.Data...)
39+
return castedRes.Pages, castedRes.Results, nil
40+
}
41+
42+
// UnmarshalJSON implements the json.Unmarshaler interface
43+
func (i *ProfileLogin) UnmarshalJSON(b []byte) error {
44+
type Mask ProfileLogin
45+
46+
l := struct {
47+
*Mask
48+
Datetime *parseabletime.ParseableTime `json:"datetime"`
49+
}{
50+
Mask: (*Mask)(i),
51+
}
52+
53+
if err := json.Unmarshal(b, &l); err != nil {
54+
return err
55+
}
56+
57+
i.Datetime = (*time.Time)(l.Datetime)
58+
59+
return nil
60+
}
61+
62+
// GetProfileLogin returns the Profile Login of the authenticated user
63+
func (c *Client) GetProfileLogin(ctx context.Context, id int) (*ProfileLogin, error) {
64+
e := fmt.Sprintf("profile/logins/%d", id)
65+
66+
req := c.R(ctx).SetResult(&ProfileLogin{})
67+
r, err := coupleAPIErrors(req.Get(e))
68+
if err != nil {
69+
return nil, err
70+
}
71+
return r.Result().(*ProfileLogin), nil
72+
}
73+
74+
// ListProfileLogins lists Profile Logins of the authenticated user
75+
func (c *Client) ListProfileLogins(ctx context.Context, opts *ListOptions) ([]ProfileLogin, error) {
76+
response := ProfileLoginsPagedResponse{}
77+
err := c.listHelper(ctx, &response, opts)
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
return response.Data, nil
83+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
version: 1
3+
interactions:
4+
- request:
5+
body: ""
6+
form: {}
7+
headers:
8+
Accept:
9+
- application/json
10+
Content-Type:
11+
- application/json
12+
User-Agent:
13+
- linodego/dev https://github.com/linode/linodego
14+
url: https://api.linode.com/v4beta/profile/logins
15+
method: GET
16+
response:
17+
body: '{"data": [{"id": 1563948056, "datetime": "2018-01-02T03:04:05", "ip": "1234::5678",
18+
"username": "ErikZilber", "status": "successful", "restricted": false}, {"id":
19+
1563982298, "datetime": "2018-01-02T03:04:05", "ip": "24.63.69.52", "username":
20+
"ErikZilber", "status": "successful", "restricted": false}, {"id": 1564542275,
21+
"datetime": "2018-01-02T03:04:05", "ip": "1234::5678",
22+
"username": "ErikZilber", "status": "failed", "restricted": false}, {"id": 1564542300,
23+
"datetime": "2018-01-02T03:04:05", "ip": "1234::5678",
24+
"username": "ErikZilber", "status": "successful", "restricted": false}, {"id":
25+
1564542307, "datetime": "2018-01-02T03:04:05", "ip": "1234::5678",
26+
"username": "ErikZilber", "status": "successful", "restricted": false}], "page":
27+
1, "pages": 1, "results": 5}'
28+
headers:
29+
Access-Control-Allow-Credentials:
30+
- "true"
31+
Access-Control-Allow-Headers:
32+
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
33+
Access-Control-Allow-Methods:
34+
- HEAD, GET, OPTIONS, POST, PUT, DELETE
35+
Access-Control-Allow-Origin:
36+
- '*'
37+
Access-Control-Expose-Headers:
38+
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
39+
Cache-Control:
40+
- private, max-age=0, s-maxage=0, no-cache, no-store
41+
- private, max-age=60, s-maxage=60
42+
Content-Length:
43+
- "878"
44+
Content-Security-Policy:
45+
- default-src 'none'
46+
Content-Type:
47+
- application/json
48+
Server:
49+
- nginx
50+
Strict-Transport-Security:
51+
- max-age=31536000
52+
Vary:
53+
- Authorization, X-Filter
54+
- Authorization, X-Filter
55+
X-Accepted-Oauth-Scopes:
56+
- account:read_only
57+
X-Content-Type-Options:
58+
- nosniff
59+
X-Frame-Options:
60+
- DENY
61+
- DENY
62+
X-Oauth-Scopes:
63+
- '*'
64+
X-Ratelimit-Limit:
65+
- "800"
66+
X-Xss-Protection:
67+
- 1; mode=block
68+
status: 200 OK
69+
code: 200
70+
duration: ""
71+
- request:
72+
body: ""
73+
form: {}
74+
headers:
75+
Accept:
76+
- application/json
77+
Content-Type:
78+
- application/json
79+
User-Agent:
80+
- linodego/dev https://github.com/linode/linodego
81+
url: https://api.linode.com/v4beta/profile/logins/1563948056
82+
method: GET
83+
response:
84+
body: '{"id": 1563948056, "datetime": "2018-01-02T03:04:05", "ip": "1234::5678",
85+
"username": "ErikZilber", "status": "successful", "restricted": false}'
86+
headers:
87+
Access-Control-Allow-Credentials:
88+
- "true"
89+
Access-Control-Allow-Headers:
90+
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
91+
Access-Control-Allow-Methods:
92+
- HEAD, GET, OPTIONS, POST, PUT, DELETE
93+
Access-Control-Allow-Origin:
94+
- '*'
95+
Access-Control-Expose-Headers:
96+
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
97+
Cache-Control:
98+
- private, max-age=0, s-maxage=0, no-cache, no-store
99+
- private, max-age=60, s-maxage=60
100+
Content-Length:
101+
- "170"
102+
Content-Security-Policy:
103+
- default-src 'none'
104+
Content-Type:
105+
- application/json
106+
Server:
107+
- nginx
108+
Strict-Transport-Security:
109+
- max-age=31536000
110+
Vary:
111+
- Authorization, X-Filter
112+
- Authorization, X-Filter
113+
X-Accepted-Oauth-Scopes:
114+
- account:read_only
115+
X-Content-Type-Options:
116+
- nosniff
117+
X-Frame-Options:
118+
- DENY
119+
- DENY
120+
X-Oauth-Scopes:
121+
- '*'
122+
X-Ratelimit-Limit:
123+
- "800"
124+
X-Xss-Protection:
125+
- 1; mode=block
126+
status: 200 OK
127+
code: 200
128+
duration: ""
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
func TestProfileLogins_List(t *testing.T) {
9+
client, teardown := createTestClient(t, "fixtures/TestProfileLogins_List")
10+
defer teardown()
11+
12+
logins, err := client.ListProfileLogins(context.Background(), nil)
13+
14+
if err != nil {
15+
t.Errorf("Error getting Profile Logins, expected struct, got error %v", err)
16+
}
17+
18+
if len(logins) < 1 {
19+
t.Errorf("Expected to see at least one Profile Login")
20+
}
21+
22+
login := logins[0]
23+
24+
response, err := client.GetProfileLogin(context.Background(), login.ID)
25+
if err != nil {
26+
t.Errorf("Failed to get one Profile Login: %v", err)
27+
}
28+
29+
if response.Username != login.Username {
30+
t.Fatal("Recieved Profile Login Username does not match source")
31+
}
32+
}

0 commit comments

Comments
 (0)