login.go
changeset 178 b63095e0f301
parent 162 68df3a01e1a7
child 199 9d9d27e7bad2
equal deleted inserted replaced
177:4fb7376fa19a 178:b63095e0f301
     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"`
    48 	if len(scopes) > 0 {
    52 	if len(scopes) > 0 {
    49 		opts["scope"] = strings.Join(scopes, " ")
    53 		opts["scope"] = strings.Join(scopes, " ")
    50 	}
    54 	}
    51 
    55 
    52 	req := rest.Request{
    56 	req := rest.Request{
    53 		BaseURL:     mc.InstanceURL + "/oauth/token",
    57 		BaseURL:     mc.InstanceURL + oAuthRelPath + "token",
    54 		Headers:     hdrs,
    58 		Headers:     hdrs,
    55 		QueryParams: opts,
    59 		QueryParams: opts,
    56 		Method:      rest.Post,
    60 		Method:      rest.Post,
    57 	}
    61 	}
    58 
    62 
    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 }