// 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 (
	"crypto/rsa"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"mime"
	"time"

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

// 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.TokenFetcherFunc = makeThreeLeggedFetcher(o)
		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
	}
}

// RoundTripper allows you to provide a custom http.RoundTripper
// to be used to construct new oauth2.Transport instances.
// If none is provided a default RoundTripper will be used.
func RoundTripper(tr http.RoundTripper) Option {
	return func(o *Options) error {
		o.Transport = tr
		return nil
	}
}

type Flow struct {
	opts Options
}

// New initiates a new flow. It 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(options ...Option) (*Flow, error) {
	f := &Flow{}
	for _, opt := range options {
		if err := opt(&f.opts); err != nil {
			return nil, err
		}
	}
	switch {
	case f.opts.TokenFetcherFunc != nil:
		return f, nil
	case f.opts.AUD != nil:
		// TODO(jbd): Assert required JWT params.
		f.opts.TokenFetcherFunc = makeTwoLeggedFetcher(&f.opts)
		return f, nil
	case f.opts.AuthURL != nil && f.opts.TokenURL != nil:
		// TODO(jbd): Assert required OAuth2 params.
		f.opts.TokenFetcherFunc = makeThreeLeggedFetcher(&f.opts)
		return f, 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 (f *Flow) AuthCodeURL(state, accessType, prompt string) string {
	u := f.opts.AuthURL
	v := url.Values{
		"response_type":   {"code"},
		"client_id":       {f.opts.ClientID},
		"redirect_uri":    condVal(f.opts.RedirectURL),
		"scope":           condVal(strings.Join(f.opts.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 (f *Flow) exchange(code string) (*Token, error) {
	return retrieveToken(&f.opts, url.Values{
		"grant_type":   {"authorization_code"},
		"code":         {code},
		"redirect_uri": condVal(f.opts.RedirectURL),
		"scope":        condVal(strings.Join(f.opts.Scopes, " ")),
	})
}

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

// NewTransportFromToken returns a new Transport that is authorized
// and authenticated with the provided token.
func (f *Flow) NewTransportFromToken(t *Token) *Transport {
	tr := f.opts.Transport
	if tr == nil {
		tr = http.DefaultTransport
	}
	return newTransport(tr, f.opts.TokenFetcherFunc, t)
}

// NewTransport returns a Transport.
func (f *Flow) NewTransport() *Transport {
	return f.NewTransportFromToken(nil)
}

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

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

	Transport http.RoundTripper
	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
}
