2014-06-04 21:25:38 +00:00
|
|
|
package session
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
|
2014-06-12 23:41:04 +00:00
|
|
|
"github.com/drone/drone/server/database"
|
2014-08-10 02:06:37 +00:00
|
|
|
"github.com/drone/drone/shared/httputil"
|
2014-06-12 23:41:04 +00:00
|
|
|
"github.com/drone/drone/shared/model"
|
2014-06-04 21:25:38 +00:00
|
|
|
"github.com/gorilla/securecookie"
|
|
|
|
"github.com/gorilla/sessions"
|
|
|
|
)
|
|
|
|
|
|
|
|
// stores sessions using secure cookies.
|
|
|
|
var cookies = sessions.NewCookieStore(
|
|
|
|
securecookie.GenerateRandomKey(64))
|
|
|
|
|
2014-08-10 02:06:37 +00:00
|
|
|
// stores sessions using secure cookies.
|
|
|
|
var xsrftoken = string(securecookie.GenerateRandomKey(32))
|
|
|
|
|
2014-06-04 21:25:38 +00:00
|
|
|
type Session interface {
|
2014-06-12 23:41:04 +00:00
|
|
|
User(r *http.Request) *model.User
|
|
|
|
UserToken(r *http.Request) *model.User
|
|
|
|
UserCookie(r *http.Request) *model.User
|
|
|
|
SetUser(w http.ResponseWriter, r *http.Request, u *model.User)
|
2014-06-04 21:25:38 +00:00
|
|
|
Clear(w http.ResponseWriter, r *http.Request)
|
|
|
|
}
|
|
|
|
|
|
|
|
type session struct {
|
2014-06-12 23:41:04 +00:00
|
|
|
users database.UserManager
|
2014-06-04 21:25:38 +00:00
|
|
|
}
|
|
|
|
|
2014-06-12 23:41:04 +00:00
|
|
|
func NewSession(users database.UserManager) Session {
|
2014-06-04 21:25:38 +00:00
|
|
|
return &session{
|
|
|
|
users: users,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-10 02:06:37 +00:00
|
|
|
// User gets the currently authenticated user.
|
2014-06-12 23:41:04 +00:00
|
|
|
func (s *session) User(r *http.Request) *model.User {
|
2014-06-04 21:25:38 +00:00
|
|
|
switch {
|
|
|
|
case r.FormValue("access_token") == "":
|
|
|
|
return s.UserCookie(r)
|
|
|
|
case r.FormValue("access_token") != "":
|
|
|
|
return s.UserToken(r)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-10 02:06:37 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2014-06-04 21:25:38 +00:00
|
|
|
// UserToken gets the currently authenticated user for the given auth token.
|
2014-06-12 23:41:04 +00:00
|
|
|
func (s *session) UserToken(r *http.Request) *model.User {
|
2014-06-04 21:25:38 +00:00
|
|
|
token := r.FormValue("access_token")
|
|
|
|
user, _ := s.users.FindToken(token)
|
|
|
|
return user
|
|
|
|
}
|
|
|
|
|
|
|
|
// UserCookie gets the currently authenticated user from the secure cookie session.
|
2014-06-12 23:41:04 +00:00
|
|
|
func (s *session) UserCookie(r *http.Request) *model.User {
|
2014-06-04 21:25:38 +00:00
|
|
|
sess, err := cookies.Get(r, "_sess")
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// get the uid from the session
|
|
|
|
value, ok := sess.Values["uid"]
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// get the user from the database
|
|
|
|
user, _ := s.users.Find(value.(int64))
|
|
|
|
return user
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetUser writes the specified username to the session.
|
2014-06-12 23:41:04 +00:00
|
|
|
func (s *session) SetUser(w http.ResponseWriter, r *http.Request, u *model.User) {
|
2014-06-04 21:25:38 +00:00
|
|
|
sess, _ := cookies.Get(r, "_sess")
|
|
|
|
sess.Values["uid"] = u.ID
|
|
|
|
sess.Save(r, w)
|
2014-08-10 02:06:37 +00:00
|
|
|
httputil.SetXsrf(w, r, xsrftoken, u.Login)
|
2014-06-04 21:25:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clear removes the user from the session.
|
|
|
|
func (s *session) Clear(w http.ResponseWriter, r *http.Request) {
|
|
|
|
sess, _ := cookies.Get(r, "_sess")
|
|
|
|
delete(sess.Values, "uid")
|
|
|
|
sess.Save(r, w)
|
|
|
|
}
|