github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/core/section/github/auth.go (about)

     1  // Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
     2  //
     3  // This software (Documize Community Edition) is licensed under
     4  // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
     5  //
     6  // You can operate outside the AGPL restrictions by purchasing
     7  // Documize Enterprise Edition and obtaining a commercial license
     8  // by contacting <sales@documize.com>.
     9  //
    10  // https://documize.com
    11  
    12  package github
    13  
    14  import (
    15  	"encoding/json"
    16  	"net/http"
    17  	"net/url"
    18  	"strings"
    19  
    20  	"github.com/documize/community/core/api/request"
    21  
    22  	gogithub "github.com/google/go-github/github"
    23  	"golang.org/x/oauth2"
    24  )
    25  
    26  func clientID() string {
    27  	return request.ConfigString(meta.ConfigHandle(), "clientID")
    28  }
    29  
    30  func clientSecret() string {
    31  	return request.ConfigString(meta.ConfigHandle(), "clientSecret")
    32  }
    33  
    34  func authorizationCallbackURL() string {
    35  	// NOTE: URL value must have the path and query "/api/public/validate?section=github"
    36  	return request.ConfigString(meta.ConfigHandle(), "authorizationCallbackURL")
    37  }
    38  
    39  func validateToken(ptoken string) error {
    40  	// Github authorization check
    41  	authClient := gogithub.NewClient((&gogithub.BasicAuthTransport{
    42  		Username: clientID(),
    43  		Password: clientSecret(),
    44  	}).Client())
    45  	_, _, err := authClient.Authorizations.Check(clientID(), ptoken)
    46  	return err
    47  }
    48  
    49  func (*Provider) githubClient(config *githubConfig) *gogithub.Client {
    50  	ts := oauth2.StaticTokenSource(
    51  		&oauth2.Token{AccessToken: config.Token},
    52  	)
    53  	tc := oauth2.NewClient(oauth2.NoContext, ts)
    54  
    55  	return gogithub.NewClient(tc)
    56  }
    57  
    58  // Callback is called by a browser redirect from Github, via the validation endpoint
    59  func Callback(res http.ResponseWriter, req *http.Request) error {
    60  
    61  	code := req.URL.Query().Get("code")
    62  	state := req.URL.Query().Get("state")
    63  
    64  	ghurl := "https://github.com/login/oauth/access_token"
    65  	vals := "client_id=" + clientID()
    66  	vals += "&client_secret=" + clientSecret()
    67  	vals += "&code=" + code
    68  	vals += "&state=" + state
    69  
    70  	req2, err := http.NewRequest("POST", ghurl+"?"+vals, strings.NewReader(vals))
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    76  	req2.Header.Set("Accept", "application/json")
    77  
    78  	res2, err := http.DefaultClient.Do(req2)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	var gt githubCallbackT
    84  
    85  	err = json.NewDecoder(res2.Body).Decode(&gt)
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	err = res2.Body.Close()
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	returl, err := url.QueryUnescape(state)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	up, err := url.Parse(returl)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	target := up.Scheme + "://" + up.Host + up.Path + "?mode=edit&code=" + gt.AccessToken
   106  
   107  	http.Redirect(res, req, target, http.StatusTemporaryRedirect)
   108  
   109  	return nil
   110  }