8 |
8 |
9 import ( |
9 import ( |
10 "encoding/json" |
10 "encoding/json" |
11 "strings" |
11 "strings" |
12 |
12 |
|
13 "golang.org/x/oauth2" |
|
14 |
13 "github.com/pkg/errors" |
15 "github.com/pkg/errors" |
14 "github.com/sendgrid/rest" |
16 "github.com/sendgrid/rest" |
15 ) |
17 ) |
|
18 |
|
19 const oAuthRelPath = "/oauth/" |
16 |
20 |
17 // UserToken represents a user token as returned by the Mastodon API |
21 // UserToken represents a user token as returned by the Mastodon API |
18 type UserToken struct { |
22 type UserToken struct { |
19 AccessToken string `json:"access_token"` |
23 AccessToken string `json:"access_token"` |
20 CreatedAt int64 `json:"created_at"` |
24 CreatedAt int64 `json:"created_at"` |
84 Scope: strings.Join(scopes, " "), |
88 Scope: strings.Join(scopes, " "), |
85 TokenType: "bearer", |
89 TokenType: "bearer", |
86 } |
90 } |
87 return nil |
91 return nil |
88 } |
92 } |
|
93 |
|
94 // LoginOAuth2 handles OAuth2 authentication |
|
95 // If code is empty, the URL to the server consent page will be returned; |
|
96 // if not, the user token is set. |
|
97 func (mc *Client) LoginOAuth2(code string, scopes []string) (string, error) { |
|
98 if mc == nil { |
|
99 return "", ErrUninitializedClient |
|
100 } |
|
101 |
|
102 conf := &oauth2.Config{ |
|
103 ClientID: mc.ID, |
|
104 ClientSecret: mc.Secret, |
|
105 Scopes: scopes, |
|
106 Endpoint: oauth2.Endpoint{ |
|
107 AuthURL: mc.InstanceURL + oAuthRelPath + "authorize", |
|
108 TokenURL: mc.InstanceURL + oAuthRelPath + "token", |
|
109 }, |
|
110 RedirectURL: NoRedirect, |
|
111 } |
|
112 |
|
113 if code == "" { |
|
114 // URL to consent page to ask for permission |
|
115 // for the scopes specified above. |
|
116 return conf.AuthCodeURL("state", oauth2.AccessTypeOffline), nil |
|
117 } |
|
118 |
|
119 // Return token |
|
120 t, err := conf.Exchange(nil, code) |
|
121 if err != nil { |
|
122 return "", errors.Wrap(err, "cannot convert code into a token") |
|
123 } |
|
124 if t == nil || t.AccessToken == "" { |
|
125 return "", errors.New("empty token") |
|
126 } |
|
127 return "", mc.SetUserToken(t.AccessToken, "", "", scopes) |
|
128 } |