// Copyright 2014 The oauth2 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package oauth2 provides support for making
// OAuth2 authorized and authenticated HTTP requests.
// It can additionally grant authorization with Bearer JWT.
package oauth2 // import "golang.org/x/oauth2"

import (
	"crypto/rsa"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"mime"
	"time"

	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// TokenStore implementations read and write OAuth 2.0 tokens from a persistence layer.
type TokenStore interface {
	// ReadToken reads the token from the store.
	// If the read is successful, it should return the token and a nil error.
	// The returned tokens may be expired tokens.
	// If there is no token in the store, it should return a nil token and a nil error.
	// It should return a non-nil error when an unrecoverable failure occurs.
	ReadToken() (*Token, error)
	// WriteToken writes the token to the cache.
	WriteToken(*Token)
}

// Option represents a function that applies some state to
// an Options object.
type Option func(*Options) error

// Client requires the OAuth 2.0 client credentials. You need to provide
// the client identifier and optionally the client secret that are
// assigned to your application by the OAuth 2.0 provider.
func Client(id, secret string) Option {
	return func(opts *Options) error {
		opts.ClientID = id
		opts.ClientSecret = secret
		return nil
	}
}

// RedirectURL requires the URL to which the user will be returned after
// granting (or denying) access.
func RedirectURL(url string) Option {
	return func(opts *Options) error {
		opts.RedirectURL = url
		return nil
	}
}

// Scope requires a list of requested permission scopes.
// It is optinal to specify scopes.
func Scope(scopes ...string) Option {
	return func(o *Options) error {
		o.Scopes = scopes
		return nil
	}
}

// Endpoint requires OAuth 2.0 provider's authorization and token endpoints.
func Endpoint(authURL, tokenURL string) Option {
	return func(o *Options) error {
		au, err := url.Parse(authURL)
		if err != nil {
			return err
		}
		tu, err := url.Parse(tokenURL)
		if err != nil {
			return err
		}
		o.AuthURL = au
		o.TokenURL = tu
		return nil
	}
}

// HTTPClient allows you to provide a custom http.Client to be
// used to retrieve tokens from the OAuth 2.0 provider.
func HTTPClient(c *http.Client) Option {
	return func(o *Options) error {
		o.Client = c
		return nil
	}
}

// New builds a new options object and determines the type of the OAuth 2.0
// (2-legged, 3-legged or custom) by looking at the provided options.
// If the flow type cannot determined automatically, an error is returned.
func New(option ...Option) (*Options, error) {
	opts := &Options{}
	for _, fn := range option {
		if err := fn(opts); err != nil {
			return nil, err
		}
	}
	switch {
	case opts.TokenFetcherFunc != nil:
		return opts, nil
	case opts.AUD != nil:
		// TODO(jbd): Assert the required JWT params.
		opts.TokenFetcherFunc = makeTwoLeggedFetcher(opts)
		return opts, nil
	case opts.AuthURL != nil && opts.TokenURL != nil:
		// TODO(jbd): Assert the required OAuth2 params.
		opts.TokenFetcherFunc = makeThreeLeggedFetcher(opts)
		return opts, nil
	default:
		return nil, errors.New("oauth2: missing endpoints, can't determine how to fetch tokens")
	}
}

// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
// that asks for permissions for the required scopes explicitly.
//
// State is a token to protect the user from CSRF attacks. You must
// always provide a non-zero string and validate that it matches the
// the state query parameter on your redirect callback.
// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
//
// Access type is an OAuth extension that gets sent as the
// "access_type" field in the URL from AuthCodeURL.
// It may be "online" (default) or "offline".
// If your application needs to refresh access tokens when the
// user is not present at the browser, then use offline. This
// will result in your application obtaining a refresh token
// the first time your application exchanges an authorization
// code for a user.
//
// Approval prompt indicates whether the user should be
// re-prompted for consent. If set to "auto" (default) the
// user will be prompted only if they haven't previously
// granted consent and the code can only be exchanged for an
// access token. If set to "force" the user will always be prompted,
// and the code can be exchanged for a refresh token.
func (o *Options) AuthCodeURL(state, accessType, prompt string) string {
	u := *o.AuthURL
	v := url.Values{
		"response_type":   {"code"},
		"client_id":       {o.ClientID},
		"redirect_uri":    condVal(o.RedirectURL),
		"scope":           condVal(strings.Join(o.Scopes, " ")),
		"state":           condVal(state),
		"access_type":     condVal(accessType),
		"approval_prompt": condVal(prompt),
	}
	q := v.Encode()
	if u.RawQuery == "" {
		u.RawQuery = q
	} else {
		u.RawQuery += "&" + q
	}
	return u.String()
}

// exchange exchanges the authorization code with the OAuth 2.0 provider
// to retrieve a new access token.
func (o *Options) exchange(code string) (*Token, error) {
	return retrieveToken(o, url.Values{
		"grant_type":   {"authorization_code"},
		"code":         {code},
		"redirect_uri": condVal(o.RedirectURL),
		"scope":        condVal(strings.Join(o.Scopes, " ")),
	})
}

// NewTransportFromTokenStore reads the token from the store and returns
// a Transport that is authorized and the authenticated
// by the returned token.
func (o *Options) NewTransportFromTokenStore(store TokenStore) (*Transport, error) {
	tok, err := store.ReadToken()
	if err != nil {
		return nil, err
	}
	o.TokenStore = store
	if tok == nil {
		return nil, nil
	}
	return o.newTransportFromToken(tok), nil
}

// NewTransportFromCode exchanges the code to retrieve a new access token
// and returns an authorized and authenticated Transport.
func (o *Options) NewTransportFromCode(code string) (*Transport, error) {
	token, err := o.exchange(code)
	if err != nil {
		return nil, err
	}
	return o.newTransportFromToken(token), nil
}

// NewTransport returns a Transport.
func (o *Options) NewTransport() *Transport {
	return o.newTransportFromToken(nil)
}

// newTransportFromToken returns a new Transport that is authorized
// and authenticated with the provided token.
func (o *Options) newTransportFromToken(t *Token) *Transport {
	// TODO(jbd): App Engine options initiate an http.Client that
	// depends on the urlfetcher, but it breaks the promise we made
	// that the options object should be working finely with nil-values
	// for the http.Client.
	tr := http.DefaultTransport
	if o.Client != nil && o.Client.Transport != nil {
		tr = o.Client.Transport
	}
	return newTransport(tr, o, t)
}

func makeThreeLeggedFetcher(o *Options) func(t *Token) (*Token, error) {
	return func(t *Token) (*Token, error) {
		if t == nil || t.RefreshToken == "" {
			return nil, errors.New("oauth2: cannot fetch access token without refresh token")
		}
		return retrieveToken(o, url.Values{
			"grant_type":    {"refresh_token"},
			"refresh_token": {t.RefreshToken},
		})
	}
}

// Options represents an object to keep the state of the OAuth 2.0 flow.
type Options struct {
	// ClientID is the OAuth client identifier used when communicating with
	// the configured OAuth provider.
	ClientID string

	// ClientSecret is the OAuth client secret used when communicating with
	// the configured OAuth provider.
	ClientSecret string

	// RedirectURL is the URL to which the user will be returned after
	// granting (or denying) access.
	RedirectURL string

	// Email is the OAuth client identifier used when communicating with
	// the configured OAuth provider.
	Email string

	// PrivateKey contains the contents of an RSA private key or the
	// contents of a PEM file that contains a private key. The provided
	// private key is used to sign JWT payloads.
	// PEM containers with a passphrase are not supported.
	// Use the following command to convert a PKCS 12 file into a PEM.
	//
	//    $ openssl pkcs12 -in key.p12 -out key.pem -nodes
	//
	PrivateKey *rsa.PrivateKey

	// Scopes identify the level of access being requested.
	Subject string

	// Scopes optionally specifies a list of requested permission scopes.
	Scopes []string

	// AuthURL represents the authorization endpoint of the OAuth 2.0 provider.
	AuthURL *url.URL

	// TokenURL represents the token endpoint of the OAuth 2.0 provider.
	TokenURL *url.URL

	// AUD represents the token endpoint required to complete the 2-legged JWT flow.
	AUD *url.URL

	// TokenStore reads a token from the store and writes it back to the store
	// if a token refresh occurs.
	// Optional.
	TokenStore TokenStore

	TokenFetcherFunc func(t *Token) (*Token, error)

	Client *http.Client
}

func retrieveToken(o *Options, v url.Values) (*Token, error) {
	v.Set("client_id", o.ClientID)
	bustedAuth := !providerAuthHeaderWorks(o.TokenURL.String())
	if bustedAuth && o.ClientSecret != "" {
		v.Set("client_secret", o.ClientSecret)
	}
	req, err := http.NewRequest("POST", o.TokenURL.String(), strings.NewReader(v.Encode()))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	if !bustedAuth && o.ClientSecret != "" {
		req.SetBasicAuth(o.ClientID, o.ClientSecret)
	}
	c := o.Client
	if c == nil {
		c = &http.Client{}
	}
	r, err := c.Do(req)
	if err != nil {
		return nil, err
	}
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
	}
	if code := r.StatusCode; code < 200 || code > 299 {
		return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body)
	}

	token := &Token{}
	expires := int(0)
	content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
	switch content {
	case "application/x-www-form-urlencoded", "text/plain":
		vals, err := url.ParseQuery(string(body))
		if err != nil {
			return nil, err
		}
		token.AccessToken = vals.Get("access_token")
		token.TokenType = vals.Get("token_type")
		token.RefreshToken = vals.Get("refresh_token")
		token.raw = vals
		e := vals.Get("expires_in")
		if e == "" {
			// TODO(jbd): Facebook's OAuth2 implementation is broken and
			// returns expires_in field in expires. Remove the fallback to expires,
			// when Facebook fixes their implementation.
			e = vals.Get("expires")
		}
		expires, _ = strconv.Atoi(e)
	default:
		b := make(map[string]interface{})
		if err = json.Unmarshal(body, &b); err != nil {
			return nil, err
		}
		token.AccessToken, _ = b["access_token"].(string)
		token.TokenType, _ = b["token_type"].(string)
		token.RefreshToken, _ = b["refresh_token"].(string)
		token.raw = b
		e, ok := b["expires_in"].(int)
		if !ok {
			// TODO(jbd): Facebook's OAuth2 implementation is broken and
			// returns expires_in field in expires. Remove the fallback to expires,
			// when Facebook fixes their implementation.
			e, _ = b["expires"].(int)
		}
		expires = e
	}
	// Don't overwrite `RefreshToken` with an empty value
	// if this was a token refreshing request.
	if token.RefreshToken == "" {
		token.RefreshToken = v.Get("refresh_token")
	}
	if expires == 0 {
		token.Expiry = time.Time{}
	} else {
		token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
	}
	return token, nil
}

func condVal(v string) []string {
	if v == "" {
		return nil
	}
	return []string{v}
}

// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
// implements the OAuth2 spec correctly
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
// In summary:
// - Reddit only accepts client secret in the Authorization header
// - Dropbox accepts either it in URL param or Auth header, but not both.
// - Google only accepts URL param (not spec compliant?), not Auth header
func providerAuthHeaderWorks(tokenURL string) bool {
	if strings.HasPrefix(tokenURL, "https://accounts.google.com/") ||
		strings.HasPrefix(tokenURL, "https://github.com/") ||
		strings.HasPrefix(tokenURL, "https://api.instagram.com/") ||
		strings.HasPrefix(tokenURL, "https://www.douban.com/") ||
		strings.HasPrefix(tokenURL, "https://api.dropbox.com/") ||
		strings.HasPrefix(tokenURL, "https://api.soundcloud.com/") ||
		strings.HasPrefix(tokenURL, "https://www.linkedin.com/") {
		// Some sites fail to implement the OAuth2 spec fully.
		return false
	}

	// Assume the provider implements the spec properly
	// otherwise. We can add more exceptions as they're
	// discovered. We will _not_ be adding configurable hooks
	// to this package to let users select server bugs.
	return true
}
