func (o *OAuthSession) CodeAuth(code string) error {
	t, err := o.OAuthConfig.Exchange(o.ctx, code)
	if err != nil {
		return err
	}
	o.Client = o.OAuthConfig.Client(o.ctx, t)
	return nil
}
CodeAuth creates and sets a token using an authentication code returned from AuthCodeURL.
package geddit
import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"github.com/beefsack/go-rate"
	"github.com/google/go-querystring/query"
	"golang.org/x/net/context"
	"golang.org/x/oauth2"
)
type transport struct {
	http.RoundTripper
	useragent string
}
func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	req.Header.Set("User-Agent", t.useragent)
	return t.RoundTripper.RoundTrip(req)
}
type OAuthSession struct {
	Client       *http.Client
	ClientID     string
	ClientSecret string
	OAuthConfig  *oauth2.Config
	UserAgent string
	ctx       context.Context
	throttle  *rate.RateLimiter
}
func NewOAuthSession(clientID, clientSecret, useragent, redirectURL string) (*OAuthSession, error) {
	o := &OAuthSession{}
	if len(useragent) > 0 {
		o.UserAgent = useragent
	} else {
		o.UserAgent = "Geddit Reddit Bot https://github.com/jzelinskie/geddit"
	}
	o.OAuthConfig = &oauth2.Config{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Endpoint: oauth2.Endpoint{
			AuthURL:  "https://www.reddit.com/api/v1/authorize",
			TokenURL: "https://www.reddit.com/api/v1/access_token",
		},
		RedirectURL: redirectURL,
	}
	c := &http.Client{}
	c.Transport = &transport{http.DefaultTransport, o.UserAgent}
	o.ctx = context.WithValue(context.Background(), oauth2.HTTPClient, c)
	return o, nil
}
func (o *OAuthSession) Throttle(interval time.Duration) {
	if interval == 0 {
		o.throttle = nil
		return
	}
	o.throttle = rate.New(1, interval)
}
func (o *OAuthSession) LoginAuth(username, password string) error {
	t, err := o.OAuthConfig.PasswordCredentialsToken(o.ctx, username, password)
	if err != nil {
		return err
	}
	if !t.Valid() {
		msg := "Invalid OAuth token"
		if t != nil {
			if extra := t.Extra("error"); extra != nil {
				msg = fmt.Sprintf("%s: %s", msg, extra)
			}
		}
		return errors.New(msg)
	}
	o.Client = o.OAuthConfig.Client(o.ctx, t)
	return nil
}
func (o *OAuthSession) AuthCodeURL(state string, scopes []string) string {
	o.OAuthConfig.Scopes = scopes
	return o.OAuthConfig.AuthCodeURL(state, oauth2.AccessTypeOnline)
}