Add convenience function to authenticate using OAuth2.
This is required for users who have 2-factor authentication enabled, and is generally safer because users don't need to give their password to third-party software.
This commit is contained in:
parent
2ebf34adae
commit
c5945152ec
21
apps.go
21
apps.go
|
@ -18,7 +18,9 @@ type AppConfig struct {
|
||||||
// Where the user should be redirected after authorization (for no redirect, use urn:ietf:wg:oauth:2.0:oob)
|
// Where the user should be redirected after authorization (for no redirect, use urn:ietf:wg:oauth:2.0:oob)
|
||||||
RedirectURIs string
|
RedirectURIs string
|
||||||
|
|
||||||
// This can be a space-separated list of the following items: "read", "write" and "follow".
|
// This can be a space-separated list of items listed on the /settings/applications/new page of any Mastodon
|
||||||
|
// instance. "read", "write", and "follow" are top-level scopes that include all the permissions of the more
|
||||||
|
// specific scopes like "read:favourites", "write:statuses", and "write:follows".
|
||||||
Scopes string
|
Scopes string
|
||||||
|
|
||||||
// Optional.
|
// Optional.
|
||||||
|
@ -31,6 +33,9 @@ type Application struct {
|
||||||
RedirectURI string `json:"redirect_uri"`
|
RedirectURI string `json:"redirect_uri"`
|
||||||
ClientID string `json:"client_id"`
|
ClientID string `json:"client_id"`
|
||||||
ClientSecret string `json:"client_secret"`
|
ClientSecret string `json:"client_secret"`
|
||||||
|
|
||||||
|
// AuthURI is not part of the Mastodon API; it is generated by go-mastodon.
|
||||||
|
AuthURI string `json:"auth_uri,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterApp returns the mastodon application.
|
// RegisterApp returns the mastodon application.
|
||||||
|
@ -73,5 +78,19 @@ func RegisterApp(ctx context.Context, appConfig *AppConfig) (*Application, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u, err = url.Parse(appConfig.Server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "/oauth/authorize")
|
||||||
|
u.RawQuery = url.Values{
|
||||||
|
"scope": {appConfig.Scopes},
|
||||||
|
"response_type": {"code"},
|
||||||
|
"redirect_uri": {app.RedirectURI},
|
||||||
|
"client_id": {app.ClientID},
|
||||||
|
}.Encode()
|
||||||
|
|
||||||
|
app.AuthURI = u.String()
|
||||||
|
|
||||||
return &app, nil
|
return &app, nil
|
||||||
}
|
}
|
||||||
|
|
38
mastodon.go
38
mastodon.go
|
@ -130,14 +130,34 @@ func NewClient(config *Config) *Client {
|
||||||
|
|
||||||
// Authenticate get access-token to the API.
|
// Authenticate get access-token to the API.
|
||||||
func (c *Client) Authenticate(ctx context.Context, username, password string) error {
|
func (c *Client) Authenticate(ctx context.Context, username, password string) error {
|
||||||
params := url.Values{}
|
params := url.Values{
|
||||||
params.Set("client_id", c.config.ClientID)
|
"client_id": {c.config.ClientID},
|
||||||
params.Set("client_secret", c.config.ClientSecret)
|
"client_secret": {c.config.ClientSecret},
|
||||||
params.Set("grant_type", "password")
|
"grant_type": {"password"},
|
||||||
params.Set("username", username)
|
"username": {username},
|
||||||
params.Set("password", password)
|
"password": {password},
|
||||||
params.Set("scope", "read write follow")
|
"scope": {"read write follow"},
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.authenticate(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthenticateToken logs in using a grant token returned by Application.AuthURI.
|
||||||
|
//
|
||||||
|
// redirectURI should be the same as Application.RedirectURI.
|
||||||
|
func (c *Client) AuthenticateToken(ctx context.Context, authCode, redirectURI string) error {
|
||||||
|
params := url.Values{
|
||||||
|
"client_id": {c.config.ClientID},
|
||||||
|
"client_secret": {c.config.ClientSecret},
|
||||||
|
"grant_type": {"authorization_code"},
|
||||||
|
"code": {authCode},
|
||||||
|
"redirect_uri": {redirectURI},
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.authenticate(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) authenticate(ctx context.Context, params url.Values) error {
|
||||||
u, err := url.Parse(c.config.Server)
|
u, err := url.Parse(c.config.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -160,9 +180,9 @@ func (c *Client) Authenticate(ctx context.Context, username, password string) er
|
||||||
return parseAPIError("bad authorization", resp)
|
return parseAPIError("bad authorization", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := struct {
|
var res struct {
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
}{}
|
}
|
||||||
err = json.NewDecoder(resp.Body).Decode(&res)
|
err = json.NewDecoder(resp.Body).Decode(&res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue
Block a user