ability to set xsrf token

This commit is contained in:
Brad Rydzewski 2014-08-09 19:06:37 -07:00
parent 062e275388
commit ca2a93ed9f
2 changed files with 44 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/drone/drone/server/database" "github.com/drone/drone/server/database"
"github.com/drone/drone/shared/httputil"
"github.com/drone/drone/shared/model" "github.com/drone/drone/shared/model"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
@ -13,6 +14,9 @@ import (
var cookies = sessions.NewCookieStore( var cookies = sessions.NewCookieStore(
securecookie.GenerateRandomKey(64)) securecookie.GenerateRandomKey(64))
// stores sessions using secure cookies.
var xsrftoken = string(securecookie.GenerateRandomKey(32))
type Session interface { type Session interface {
User(r *http.Request) *model.User User(r *http.Request) *model.User
UserToken(r *http.Request) *model.User UserToken(r *http.Request) *model.User
@ -31,7 +35,7 @@ func NewSession(users database.UserManager) Session {
} }
} }
// User gets the currently authenticated user from the secure cookie session. // User gets the currently authenticated user.
func (s *session) User(r *http.Request) *model.User { func (s *session) User(r *http.Request) *model.User {
switch { switch {
case r.FormValue("access_token") == "": case r.FormValue("access_token") == "":
@ -42,6 +46,19 @@ func (s *session) User(r *http.Request) *model.User {
return nil return nil
} }
// UserXsrf gets the currently authenticated user and
// validates the xsrf session token, if necessary.
func (s *session) UserXsrf(r *http.Request) *model.User {
user := s.User(r)
if user == nil || r.FormValue("access_token") != "" {
return user
}
if !httputil.CheckXsrf(r, xsrftoken, user.Login) {
return nil
}
return user
}
// UserToken gets the currently authenticated user for the given auth token. // UserToken gets the currently authenticated user for the given auth token.
func (s *session) UserToken(r *http.Request) *model.User { func (s *session) UserToken(r *http.Request) *model.User {
token := r.FormValue("access_token") token := r.FormValue("access_token")
@ -70,6 +87,7 @@ func (s *session) SetUser(w http.ResponseWriter, r *http.Request, u *model.User)
sess, _ := cookies.Get(r, "_sess") sess, _ := cookies.Get(r, "_sess")
sess.Values["uid"] = u.ID sess.Values["uid"] = u.ID
sess.Save(r, w) sess.Save(r, w)
httputil.SetXsrf(w, r, xsrftoken, u.Login)
} }
// Clear removes the user from the session. // Clear removes the user from the session.

View file

@ -3,6 +3,8 @@ package httputil
import ( import (
"net/http" "net/http"
"strings" "strings"
"code.google.com/p/xsrftoken"
) )
// IsHttps is a helper function that evaluates the http.Request // IsHttps is a helper function that evaluates the http.Request
@ -103,3 +105,26 @@ func DelCookie(w http.ResponseWriter, r *http.Request, name string) {
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
} }
// SetXsrf writes the cookie value.
func SetXsrf(w http.ResponseWriter, r *http.Request, token, login string) {
cookie := http.Cookie{
Name: "XSRF-TOKEN",
Value: xsrftoken.Generate(token, login, "/"),
Path: "/",
Domain: r.URL.Host,
HttpOnly: false,
Secure: IsHttps(r),
}
http.SetCookie(w, &cookie)
}
// CheckXsrf verifies the xsrf value.
func CheckXsrf(r *http.Request, token, login string) bool {
if r.Method == "GET" {
return true
}
return xsrftoken.Valid(
r.Header.Get("X-XSRF-TOKEN"), token, login, "/")
}