Sessions
This commit is contained in:
parent
b070f19510
commit
317ee6e075
14
db/token.go
14
db/token.go
|
@ -7,7 +7,7 @@ import (
|
||||||
type (
|
type (
|
||||||
Token struct {
|
Token struct {
|
||||||
ID int
|
ID int
|
||||||
Owner string
|
User string
|
||||||
Token string
|
Token string
|
||||||
Limit int
|
Limit int
|
||||||
Remaining int
|
Remaining int
|
||||||
|
@ -16,6 +16,16 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func UpdateToken(t *Token) {
|
const (
|
||||||
|
saveTokenQuery = "" +
|
||||||
|
"insert into tokens (`user`, token, `limit`, remaining, reset_at, created_at) " +
|
||||||
|
"values (?, ?, ?, ?, ?, now()) " +
|
||||||
|
"on duplicate key update " +
|
||||||
|
"`limit` = values(`limit`), remaining = values(remaining), reset_at = values(reset_at)"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *Token) Save() {
|
||||||
|
if _, err := stmt(saveTokenQuery).Exec(t.User, t.Token, t.Limit, t.Remaining, t.ResetAt); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
type (
|
||||||
|
User struct {
|
||||||
|
Login string `json:"login"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
saveUserQuery = "" +
|
||||||
|
"insert into users (login, name, id, avatar_url) " +
|
||||||
|
"values (?, ?, ?, ?) " +
|
||||||
|
"on duplicate key update " +
|
||||||
|
"login=values(login), name=values(name), avatar_url=values(avatar_url)"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u *User) Save() {
|
||||||
|
if _, err := stmt(saveUserQuery).Exec(u.Login, u.Name, u.ID, u.AvatarURL); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func authHelloHandler(w http.ResponseWriter, r *http.Request) {
|
func authHelloHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if currentUser(r) != "" {
|
||||||
|
http.Redirect(w, r, "/app", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf8")
|
w.Header().Set("Content-Type", "text/html; charset=utf8")
|
||||||
helloTmpl.ExecuteTemplate(w, "hello", map[string]interface{}{})
|
helloTmpl.ExecuteTemplate(w, "hello", map[string]interface{}{})
|
||||||
}
|
}
|
||||||
|
@ -20,7 +24,7 @@ func authSigninHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Set("client_id", config.C().ClientID)
|
params.Set("client_id", config.C().ClientID)
|
||||||
params.Set("redirect_uri", config.C().RedirectURI)
|
params.Set("redirect_uri", config.C().RedirectURI)
|
||||||
params.Set("scope", "repo")
|
params.Set("scope", "read:org, repo, admin:org_hook")
|
||||||
http.Redirect(w, r, config.C().AuthURL+"?"+params.Encode(), 302)
|
http.Redirect(w, r, config.C().AuthURL+"?"+params.Encode(), 302)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +42,10 @@ func authCallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Task: &db.Task{},
|
Task: &db.Task{},
|
||||||
})
|
})
|
||||||
|
|
||||||
if token, ok := <-res; ok {
|
if login, ok := <-res; ok {
|
||||||
fmt.Println("Got access token: ", token)
|
authorize(r, login)
|
||||||
w.Write([]byte(token))
|
|
||||||
} else {
|
} else {
|
||||||
panic("Failed to fetch token")
|
panic("Failed to access token or user info")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
|
|
||||||
"code.google.com/p/go-uuid/uuid"
|
|
||||||
"github.com/GeertJohan/go.rice"
|
"github.com/GeertJohan/go.rice"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
sessionCookie = "session_id"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
helloTmpl = template.New("hello")
|
helloTmpl = template.New("hello")
|
||||||
)
|
)
|
||||||
|
@ -34,21 +28,3 @@ func Start() {
|
||||||
fmt.Println("Starting server at http://localhost:8080")
|
fmt.Println("Starting server at http://localhost:8080")
|
||||||
http.ListenAndServe(":8080", nil)
|
http.ListenAndServe(":8080", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sessionHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if cook, err := r.Cookie(sessionCookie); err != nil {
|
|
||||||
cook = &http.Cookie{
|
|
||||||
Name: sessionCookie,
|
|
||||||
Value: uuid.New(),
|
|
||||||
Path: "/",
|
|
||||||
Expires: time.Now().Add(365 * 24 * time.Hour),
|
|
||||||
HttpOnly: true,
|
|
||||||
}
|
|
||||||
http.SetCookie(w, cook)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sessionID(r *http.Request) string {
|
|
||||||
cook, _ := r.Cookie(sessionCookie)
|
|
||||||
return cook.Value
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.google.com/p/go-uuid/uuid"
|
||||||
|
"github.com/garyburd/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
sessionCookie = "session_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
redisC = redis.NewPool(dialRedis, 10)
|
||||||
|
)
|
||||||
|
|
||||||
|
func dialRedis() (redis.Conn, error) {
|
||||||
|
return redis.Dial("tcp", ":6379")
|
||||||
|
}
|
||||||
|
|
||||||
|
func sessionHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if cook, err := r.Cookie(sessionCookie); err != nil {
|
||||||
|
cook = &http.Cookie{
|
||||||
|
Name: sessionCookie,
|
||||||
|
Value: uuid.New(),
|
||||||
|
Path: "/",
|
||||||
|
Expires: time.Now().Add(365 * 24 * time.Hour),
|
||||||
|
HttpOnly: true,
|
||||||
|
}
|
||||||
|
http.SetCookie(w, cook)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sessionID(r *http.Request) string {
|
||||||
|
cook, _ := r.Cookie(sessionCookie)
|
||||||
|
return cook.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func currentUser(r *http.Request) string {
|
||||||
|
conn := redisC.Get()
|
||||||
|
login, _ := redis.String(conn.Do("HGET", "sessions", sessionID(r)))
|
||||||
|
|
||||||
|
return login
|
||||||
|
}
|
||||||
|
|
||||||
|
func authorize(r *http.Request, login string) {
|
||||||
|
redisC.Get().Do("HSET", "sessions", sessionID(r), login)
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ package task
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -27,6 +29,7 @@ func FetchAccessToken(tk Tasker) {
|
||||||
payload.Set("redirect_uri", config.C().RedirectURI)
|
payload.Set("redirect_uri", config.C().RedirectURI)
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte(payload.Encode()))
|
buf := bytes.NewBuffer([]byte(payload.Encode()))
|
||||||
|
fmt.Println("Requesting token")
|
||||||
resp, err := http.Post(config.C().AccessTokenURL, "application/x-www-form-urlencoded", buf)
|
resp, err := http.Post(config.C().AccessTokenURL, "application/x-www-form-urlencoded", buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -38,7 +41,36 @@ func FetchAccessToken(tk Tasker) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pairs, _ := url.ParseQuery(string(body))
|
fmt.Println(string(body))
|
||||||
|
|
||||||
t.Result <- pairs.Get("access_token")
|
pairs, _ := url.ParseQuery(string(body))
|
||||||
|
token := pairs.Get("access_token")
|
||||||
|
fmt.Println("Got token: " + token)
|
||||||
|
|
||||||
|
fmt.Println("Requesting info")
|
||||||
|
resp, err = http.Get("https://api.github.com/user?access_token=" + token)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err = ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(body))
|
||||||
|
|
||||||
|
user := &db.User{}
|
||||||
|
json.Unmarshal(body, &user)
|
||||||
|
user.Save()
|
||||||
|
fmt.Println("Saving user", user)
|
||||||
|
|
||||||
|
tok := &db.Token{
|
||||||
|
User: user.Login,
|
||||||
|
Token: token,
|
||||||
|
}
|
||||||
|
fmt.Println("Saving token", tok)
|
||||||
|
tok.Save()
|
||||||
|
|
||||||
|
t.Result <- user.Login
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@ func saveResponseMeta(token string, res *github.Response) {
|
||||||
if res == nil {
|
if res == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
db.UpdateToken(&db.Token{
|
tok := &db.Token{
|
||||||
Token: token,
|
Token: token,
|
||||||
Limit: res.Limit,
|
Limit: res.Limit,
|
||||||
Remaining: res.Remaining,
|
Remaining: res.Remaining,
|
||||||
ResetAt: res.Reset.Time,
|
ResetAt: res.Reset.Time,
|
||||||
})
|
}
|
||||||
|
tok.Save()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue