github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/api/auth.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"net/http"
     7  
     8  	"github.com/qri-io/qri/api/util"
     9  	"github.com/qri-io/qri/auth/token"
    10  	"github.com/qri-io/qri/lib"
    11  	qhttp "github.com/qri-io/qri/lib/http"
    12  )
    13  
    14  const (
    15  	// AEToken is the token provider endpoint
    16  	AEToken qhttp.APIEndpoint = "/oauth/token"
    17  )
    18  
    19  // TokenHandler is a handler to authenticate and generate access & refresh tokens
    20  func TokenHandler(inst *lib.Instance) http.HandlerFunc {
    21  	return func(w http.ResponseWriter, r *http.Request) {
    22  		tokenRequest, err := parseTokenRequest(r)
    23  		if err != nil {
    24  			log.Debugf("tokenHandler failed to parse request: %q", err.Error())
    25  			util.WriteErrResponse(w, http.StatusBadRequest, err)
    26  			return
    27  		}
    28  		tokenResponse, err := inst.TokenProvider().Token(r.Context(), tokenRequest)
    29  		if err != nil {
    30  			log.Debugf("tokenHandler failed to create token: %q", err.Error())
    31  			util.WriteErrResponse(w, http.StatusBadRequest, err)
    32  			return
    33  		}
    34  		util.WriteResponse(w, tokenResponse)
    35  	}
    36  }
    37  
    38  // parseTokenRequest extracts the token.Request from the incoming http request
    39  func parseTokenRequest(r *http.Request) (*token.Request, error) {
    40  	tr := &token.Request{}
    41  	if r.Header.Get("Content-Type") == "application/json" {
    42  		body, err := ioutil.ReadAll(r.Body)
    43  		if err != nil {
    44  			log.Errorf("parseTokenRequest failed to parse request: %s", err.Error())
    45  			return nil, token.ErrInvalidRequest
    46  		}
    47  		err = json.Unmarshal(body, tr)
    48  		if err != nil {
    49  			log.Errorf("parseTokenRequest failed to parse request: %s", err.Error())
    50  			return nil, token.ErrInvalidRequest
    51  		}
    52  	}
    53  	if tr.GrantType.String() == "" {
    54  		tr.GrantType = token.GrantType(r.FormValue("grant_type"))
    55  	}
    56  	if tr.Code == "" {
    57  		tr.Code = r.FormValue("code")
    58  	}
    59  	if tr.RedirectURI == "" {
    60  		tr.RedirectURI = r.FormValue("redirect_uri")
    61  	}
    62  	if tr.Username == "" {
    63  		tr.Username = r.FormValue("username")
    64  	}
    65  	if tr.Password == "" {
    66  		tr.Password = r.FormValue("password")
    67  	}
    68  	if tr.RefreshToken == "" {
    69  		tr.RefreshToken = r.FormValue("refresh_token")
    70  	}
    71  	return tr, nil
    72  }