Sessions
This commit is contained in:
		
							parent
							
								
									b070f19510
								
							
						
					
					
						commit
						317ee6e075
					
				
							
								
								
									
										14
									
								
								db/token.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								db/token.go
									
									
									
									
									
								
							@ -7,7 +7,7 @@ import (
 | 
			
		||||
type (
 | 
			
		||||
	Token struct {
 | 
			
		||||
		ID        int
 | 
			
		||||
		Owner     string
 | 
			
		||||
		User      string
 | 
			
		||||
		Token     string
 | 
			
		||||
		Limit     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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								db/user.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								db/user.go
									
									
									
									
									
										Normal file
									
								
							@ -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) {
 | 
			
		||||
	if currentUser(r) != "" {
 | 
			
		||||
		http.Redirect(w, r, "/app", 302)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	w.Header().Set("Content-Type", "text/html; charset=utf8")
 | 
			
		||||
	helloTmpl.ExecuteTemplate(w, "hello", map[string]interface{}{})
 | 
			
		||||
}
 | 
			
		||||
@ -20,7 +24,7 @@ func authSigninHandler(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	params := url.Values{}
 | 
			
		||||
	params.Set("client_id", config.C().ClientID)
 | 
			
		||||
	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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,11 +42,10 @@ func authCallbackHandler(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
			Task:   &db.Task{},
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		if token, ok := <-res; ok {
 | 
			
		||||
			fmt.Println("Got access token: ", token)
 | 
			
		||||
			w.Write([]byte(token))
 | 
			
		||||
		if login, ok := <-res; ok {
 | 
			
		||||
			authorize(r, login)
 | 
			
		||||
		} else {
 | 
			
		||||
			panic("Failed to fetch token")
 | 
			
		||||
			panic("Failed to access token or user info")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,16 +4,10 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.google.com/p/go-uuid/uuid"
 | 
			
		||||
	"github.com/GeertJohan/go.rice"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	sessionCookie = "session_id"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	helloTmpl = template.New("hello")
 | 
			
		||||
)
 | 
			
		||||
@ -34,21 +28,3 @@ func Start() {
 | 
			
		||||
	fmt.Println("Starting server at http://localhost:8080")
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								server/session.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								server/session.go
									
									
									
									
									
										Normal file
									
								
							@ -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 (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
@ -27,6 +29,7 @@ func FetchAccessToken(tk Tasker) {
 | 
			
		||||
	payload.Set("redirect_uri", config.C().RedirectURI)
 | 
			
		||||
 | 
			
		||||
	buf := bytes.NewBuffer([]byte(payload.Encode()))
 | 
			
		||||
	fmt.Println("Requesting token")
 | 
			
		||||
	resp, err := http.Post(config.C().AccessTokenURL, "application/x-www-form-urlencoded", buf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
@ -38,7 +41,36 @@ func FetchAccessToken(tk Tasker) {
 | 
			
		||||
		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 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	db.UpdateToken(&db.Token{
 | 
			
		||||
	tok := &db.Token{
 | 
			
		||||
		Token:     token,
 | 
			
		||||
		Limit:     res.Limit,
 | 
			
		||||
		Remaining: res.Remaining,
 | 
			
		||||
		ResetAt:   res.Reset.Time,
 | 
			
		||||
	})
 | 
			
		||||
	}
 | 
			
		||||
	tok.Save()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user