package ffiii import ( "context" "fmt" "io" "log" "net/http" "os" "time" "golang.org/x/oauth2" ) type Client struct { url string client *http.Client apiToken string apiID string oauthToken *oauth2.Token oauthCode string reader io.Reader } func New(apiID, apiToken, url string) (*Client, error) { c := &Client{ apiID: apiID, apiToken: apiToken, url: url, reader: os.Stdin, } if err := c.Authorize(); err != nil { return nil, err } return c, nil } func (c *Client) Authorize() error { conf := &oauth2.Config{ ClientID: c.apiID, ClientSecret: c.apiToken, RedirectURL: c.url, Scopes: []string{}, Endpoint: oauth2.Endpoint{ AuthURL: fmt.Sprintf("%s/oauth/authorize", c.url), TokenURL: fmt.Sprintf("%s/oauth/token", c.url), }, } authURL := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) fmt.Printf("Go to the following link in your browser then type the "+ "authorization code: \n%v\n", authURL) var authCode string if _, err := fmt.Fscan(c.reader, &authCode); err != nil { log.Fatalf("Unable to read authorization code: %v", err) } c.oauthCode = authCode ctx, can := context.WithTimeout(context.Background(), time.Second*30) defer can() tok, err := conf.Exchange(ctx, c.oauthCode) if err != nil { return err } c.client = conf.Client(context.Background(), tok) return nil }