mirror of
https://github.com/samsonjs/retrogit.git
synced 2026-03-25 09:25:49 +00:00
Store OAuth token in a session cookie.
Not the final design (it'll instead be persisted to the App Engine data store, and the session will just have the user ID), but this has most of the scaffolding for session cookies.
This commit is contained in:
parent
df3c31c1d0
commit
2391a279f9
4 changed files with 92 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
app/config/*oauth*.json
|
||||
app/config/session.json
|
||||
|
|
|
|||
6
app/config/session.json.SAMPLE
Normal file
6
app/config/session.json.SAMPLE
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"AuthenticationKey": "REPLACE_ME_WITH_A_32_BYTE_BASE_64_ENCODED_KEY_BYES",
|
||||
"EncryptionKey": "REPLACE_ME_WITH_A_32_BYTE_BASE_64_ENCODED_KEY_BYTES",
|
||||
"CookieName": "session",
|
||||
"TokenKey": "token_temp"
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -22,10 +21,20 @@ import (
|
|||
"code.google.com/p/goauth2/oauth"
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/sessions"
|
||||
)
|
||||
|
||||
var router *mux.Router
|
||||
var githubOauthConfig oauth.Config
|
||||
var sessionStore *sessions.CookieStore
|
||||
var sessionConfig SessionConfig
|
||||
|
||||
type SessionConfig struct {
|
||||
AuthenticationKey string
|
||||
EncryptionKey string
|
||||
CookieName string
|
||||
TokenKey string
|
||||
}
|
||||
|
||||
type RepoDigest struct {
|
||||
Repo *github.Repository
|
||||
|
|
@ -82,6 +91,32 @@ func (digest *Digest) Fetch(repos []github.Repository, githubClient *github.Clie
|
|||
return nil
|
||||
}
|
||||
|
||||
func initSessionConfig() {
|
||||
configBytes, err := ioutil.ReadFile("config/session.json")
|
||||
if err != nil {
|
||||
log.Panicf("Could not read session config: %s", err.Error())
|
||||
}
|
||||
err = json.Unmarshal(configBytes, &sessionConfig)
|
||||
if err != nil {
|
||||
log.Panicf("Could not parse session config %s: %s", configBytes, err.Error())
|
||||
}
|
||||
|
||||
authenticationKey, err := base64.StdEncoding.DecodeString(sessionConfig.AuthenticationKey)
|
||||
if err != nil {
|
||||
log.Panicf("Could not decode session config authentication key %s: %s", sessionConfig.AuthenticationKey, err.Error())
|
||||
}
|
||||
encryptionKey, err := base64.StdEncoding.DecodeString(sessionConfig.EncryptionKey)
|
||||
if err != nil {
|
||||
log.Panicf("Could not decode session config encryption key %s: %s", sessionConfig.EncryptionKey, err.Error())
|
||||
}
|
||||
|
||||
sessionStore = sessions.NewCookieStore(authenticationKey, encryptionKey)
|
||||
sessionStore.Options.Path = "/"
|
||||
sessionStore.Options.MaxAge = 86400 * 30
|
||||
sessionStore.Options.HttpOnly = true
|
||||
sessionStore.Options.Secure = !appengine.IsDevAppServer()
|
||||
}
|
||||
|
||||
func initGithubOAuthConfig() {
|
||||
path := "config/github-oauth"
|
||||
if appengine.IsDevAppServer() {
|
||||
|
|
@ -94,7 +129,7 @@ func initGithubOAuthConfig() {
|
|||
}
|
||||
err = json.Unmarshal(configBytes, &githubOauthConfig)
|
||||
if err != nil {
|
||||
log.Panicf("Could not parse GitHut OAuth %s", err.Error())
|
||||
log.Panicf("Could not parse GitHub OAuth config %s: %s", configBytes, err.Error())
|
||||
}
|
||||
githubOauthConfig.Scope = "repo"
|
||||
githubOauthConfig.AuthURL = "https://github.com/login/oauth/authorize"
|
||||
|
|
@ -102,20 +137,43 @@ func initGithubOAuthConfig() {
|
|||
}
|
||||
|
||||
func init() {
|
||||
initSessionConfig()
|
||||
initGithubOAuthConfig()
|
||||
|
||||
router = mux.NewRouter()
|
||||
router.HandleFunc("/", indexHandler).Name("index")
|
||||
router.HandleFunc("/session/sign-in", signInHandler).Name("sign-in")
|
||||
router.HandleFunc("/session/sign-out", signOutHandler).Name("sign-out")
|
||||
router.HandleFunc("/github/callback", githubOAuthCallbackHandler)
|
||||
http.Handle("/", router)
|
||||
}
|
||||
|
||||
var indexTemplate = template.Must(template.ParseFiles("templates/index.html"))
|
||||
var indexSignedOutTemplate = template.Must(template.ParseFiles("templates/index-signed-out.html"))
|
||||
|
||||
func signInHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, githubOauthConfig.AuthCodeURL(""), http.StatusFound)
|
||||
}
|
||||
|
||||
func signOutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := sessionStore.Get(r, sessionConfig.CookieName)
|
||||
session.Options.MaxAge = 0
|
||||
session.Save(r, w)
|
||||
indexUrl, _ := router.Get("index").URL()
|
||||
http.Redirect(w, r, indexUrl.String(), http.StatusFound)
|
||||
}
|
||||
|
||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
tokenEncoded := r.FormValue("token")
|
||||
if tokenEncoded == "" {
|
||||
http.Redirect(w, r, githubOauthConfig.AuthCodeURL(""), http.StatusFound)
|
||||
session, _ := sessionStore.Get(r, sessionConfig.CookieName)
|
||||
tokenEncoded, ok := session.Values[sessionConfig.TokenKey].(string)
|
||||
if !ok {
|
||||
signInUrl, _ := router.Get("sign-in").URL()
|
||||
var signedOutParams = map[string]string{
|
||||
"SignInUrl": signInUrl.String(),
|
||||
}
|
||||
if err := indexSignedOutTemplate.Execute(w, signedOutParams); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
token, err := decodeOAuthToken(tokenEncoded)
|
||||
|
|
@ -200,11 +258,13 @@ func githubOAuthCallbackHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
redirectUrl, _ := router.GetRoute("index").URL()
|
||||
redirectParams := url.Values{}
|
||||
redirectParams.Add("token", tokenEncoded)
|
||||
redirectUrl.RawQuery = redirectParams.Encode()
|
||||
http.Redirect(w, r, redirectUrl.String(), http.StatusFound)
|
||||
|
||||
session, _ := sessionStore.Get(r, sessionConfig.CookieName)
|
||||
session.Values[sessionConfig.TokenKey] = tokenEncoded
|
||||
session.Save(r, w)
|
||||
log.Printf("session.Values: %s", session.Values)
|
||||
indexUrl, _ := router.Get("index").URL()
|
||||
http.Redirect(w, r, indexUrl.String(), http.StatusFound)
|
||||
}
|
||||
|
||||
func githubOAuthTransport(r *http.Request) *oauth.Transport {
|
||||
|
|
|
|||
15
app/templates/index-signed-out.html
Normal file
15
app/templates/index-signed-out.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GitHop</title>
|
||||
<link rel="stylesheet" href="/static/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>GitHop!</h1>
|
||||
|
||||
<a href="{{.SignInUrl}}">
|
||||
Sign In
|
||||
</a>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue