Separate index and GitHub OAuth callback handlers.

Also switch to gorilla/mux for the router and fix some variable names to be
mixedCase.
This commit is contained in:
Mihai Parparita 2014-07-06 15:20:49 -07:00
parent 22ef0540aa
commit d2bb784705

View file

@ -1,61 +1,80 @@
package githop package githop
import ( import (
"encoding/base64"
"encoding/json" "encoding/json"
"html/template" "html/template"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"net/url"
"appengine" "appengine"
"appengine/urlfetch" "appengine/urlfetch"
"code.google.com/p/goauth2/oauth" "code.google.com/p/goauth2/oauth"
"github.com/google/go-github/github" "github.com/google/go-github/github"
"github.com/gorilla/mux"
) )
var router *mux.Router
var githubOauthConfig oauth.Config
func initGithubOAuthConfig() {
path := "config/github-oauth"
if appengine.IsDevAppServer() {
path += "-dev"
}
path += ".json"
configBytes, err := ioutil.ReadFile(path)
if err != nil {
log.Panicf("Could not read GitHut OAuth config from %s: %s", path, err.Error())
}
err = json.Unmarshal(configBytes, &githubOauthConfig)
if err != nil {
log.Panicf("Could not parse GitHut OAuth %s", err.Error())
}
githubOauthConfig.Scope = "repo"
githubOauthConfig.AuthURL = "https://github.com/login/oauth/authorize"
githubOauthConfig.TokenURL = "https://github.com/login/oauth/access_token"
}
func init() { func init() {
http.HandleFunc("/", index) initGithubOAuthConfig()
router = mux.NewRouter()
router.HandleFunc("/", indexHandler).Name("index")
router.HandleFunc("/github/callback", githubOAuthCallbackHandler)
http.Handle("/", router)
} }
var indexTemplate = template.Must(template.ParseFiles("templates/index.html")) var indexTemplate = template.Must(template.ParseFiles("templates/index.html"))
func index(w http.ResponseWriter, r *http.Request) { func indexHandler(w http.ResponseWriter, r *http.Request) {
// TODO: Don't do this every request tokenEncoded := r.FormValue("token")
github_oauth_config_path := "config/github-oauth" if tokenEncoded == "" {
if appengine.IsDevAppServer() { http.Redirect(w, r, githubOauthConfig.AuthCodeURL(""), http.StatusFound)
github_oauth_config_path += "-dev" return
} }
github_oauth_config_path += ".json" tokenBytes, err := base64.URLEncoding.DecodeString(tokenEncoded)
github_oauth_config_bytes, err := ioutil.ReadFile(github_oauth_config_path)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
var github_oauth_config oauth.Config var token oauth.Token
err = json.Unmarshal(github_oauth_config_bytes, &github_oauth_config) err = json.Unmarshal(tokenBytes, &token)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
github_oauth_config.Scope = "repo" appengineContext := appengine.NewContext(r)
github_oauth_config.AuthURL = "https://github.com/login/oauth/authorize" oauthTransport := &oauth.Transport{
github_oauth_config.TokenURL = "https://github.com/login/oauth/access_token" Config: &githubOauthConfig,
Transport: &urlfetch.Transport{Context: appengineContext},
code := r.FormValue("code") Token: &token,
if code == "" {
http.Redirect(w, r, github_oauth_config.AuthCodeURL(""), http.StatusFound)
return
} }
appengine_context := appengine.NewContext(r) githubClient := github.NewClient(oauthTransport.Client())
oauth_transport := &oauth.Transport{ events, _, err := githubClient.Activity.ListEventsPerformedByUser("mihaip", false, nil)
Config: &github_oauth_config,
Transport: &urlfetch.Transport{Context: appengine_context},
}
token, _ := oauth_transport.Exchange(code)
oauth_transport.Token = token
github_client := github.NewClient(oauth_transport.Client())
events, _, err := github_client.Activity.ListEventsPerformedByUser("mihaip", false, nil)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
@ -64,3 +83,28 @@ func index(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }
func githubOAuthCallbackHandler(w http.ResponseWriter, r *http.Request) {
code := r.FormValue("code")
appengineContext := appengine.NewContext(r)
oauthTransport := &oauth.Transport{
Config: &githubOauthConfig,
Transport: &urlfetch.Transport{Context: appengineContext},
}
token, err := oauthTransport.Exchange(code)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tokenBytes, err := json.Marshal(token)
tokenEncoded := base64.StdEncoding.EncodeToString(tokenBytes)
redirectUrl, err := router.GetRoute("index").URL()
redirectParams := url.Values{}
redirectParams.Add("token", tokenEncoded)
redirectUrl.RawQuery = redirectParams.Encode()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirectUrl.String(), http.StatusFound)
}