Exemple #1
0
// NewSession create a new session form a store
func NewSession(store sessions.Store, request *http.Request, name string) (SessionWrapper, error) {
	session, err := store.Get(request, name)
	if err != nil {
		return nil, err
	}
	return &DefaultSessionWrapper{session}, nil
}
Exemple #2
0
func session(store sessions.Store, name string) martini.Handler {
	return func(c martini.Context, r *http.Request, w http.ResponseWriter) {
		sess, err := store.Get(r, name)
		assert(err)
		assert(sess.Save(r, w))
		c.Map(sess)
	}
}
Exemple #3
0
// New returns session middleware
func New(name string, store gorillaSessions.Store) middleware.Handler {
	return middleware.HandlerFunc(func(c context.Context, w http.ResponseWriter, r *http.Request) context.Context {
		session, _ := store.Get(r, sessionName)
		c = context.WithValue(c, storeKey, store)
		// gogo.Session(c).Values["foo"]
		return c
	})
}
Exemple #4
0
// Middleware creates a new session middleware.
func Middleware(name string, store sessions.Store) func(c *web.C, h http.Handler) http.Handler {
	return func(c *web.C, h http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			if c.Env == nil {
				c.Env = make(map[interface{}]interface{})
			}
			session, _ := store.Get(r, name)
			c.Env[envKey] = session
			h.ServeHTTP(newAutoSaver(w, r, c), r)
		}
		return http.HandlerFunc(fn)
	}
}
Exemple #5
0
func Connect(w http.ResponseWriter, r *http.Request, u auth.User, sessionStore sessions.Store, secureCookie *securecookie.SecureCookie, dbStore *Store) {
	StatCount("connect call", 1)
	session, err := sessionStore.Get(r, SESSIONNAME)
	if err != nil {
		xlog.Errorf("Error fetching session: %v", err)
		session, _ = sessionStore.New(r, SESSIONNAME)
	}

	if userID, ok := session.Values["userID"].(int); ok {
		xlog.Debugf("Connect: already logged in (userID = %d), connecting account", userID)
		// we have a valid session -> connect account to user
		username := u.Provider() + ":" + u.Id()

		err := dbStore.AddUser(username, userID)
		if err != nil {
			xlog.Errorf("Error adding user: %v", err)
			http.Error(w, err.Error(), http.StatusForbidden)
			return
		}

		w.Header().Set("Location", "/settings")
	} else {
		xlog.Debugf("Connect: not logged in, actually log in user.")
		// no valid session -> actually login user
		username := u.Provider() + ":" + u.Id()
		xlog.Debugf("Connect: username = %s", username)
		userID, err := dbStore.CreateUser(username)
		if err != nil {
			xlog.Errorf("Error creating user: %v", err)
			http.Error(w, err.Error(), http.StatusForbidden)
			return
		}

		xlog.Debugf("Connect: userID = %d", userID)

		// set session values
		session.Values["userID"] = userID
		session.Values["username"] = username
		session.Values["email"] = u.Email()
		session.Values["name"] = u.Name()
		session.Save(r, w)

		// set XSRF-TOKEN for AngularJS
		xsrftoken, _ := secureCookie.Encode(XSRFTOKEN, username)
		http.SetCookie(w, &http.Cookie{Name: XSRFTOKEN, Value: xsrftoken, Path: "/"})

		w.Header().Set("Location", "/")
	}
	w.WriteHeader(http.StatusFound)
}
Exemple #6
0
// CheckSession middleware function to validate the session cookie is set
func CheckSession(handler http.Handler, store sessions.Store) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		session, _ := store.Get(r, "auth")

		fmt.Printf("CheckSession email=%v url=%s\n", session.Values["email"], r.URL.String())

		if !strings.HasPrefix(r.URL.String(), "/auth/") && session.Values["email"] == nil {

			http.Redirect(w, r, LoginURL, http.StatusFound)
			return
		}

		handler.ServeHTTP(w, r)
	})
}
Exemple #7
0
func SessionHandler(s sessions.Store, ttl int) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		session, err := s.Get(r, "session")
		if err != nil {
			session.Values = make(map[interface{}]interface{})
		}
		if uid, ok := session.Values["uid"]; ok {
			context.Set(r, "uid", uid)
		}
		session.Options.MaxAge = ttl
		context.Set(r, "session", session)
		if err := session.Save(r, w); err != nil {
			http.Error(w, fmt.Sprintf("Could not save session: %s", err), http.StatusInternalServerError)
		}
	})
}
Exemple #8
0
func sessionMiddleware(h *handler.Handler, store sessions.Store, routeHandler func(http.ResponseWriter, *http.Request, *db.User)) func(http.ResponseWriter, *http.Request) {
	return func(res http.ResponseWriter, req *http.Request) {
		session, err := store.Get(req, "session")
		if err != nil {
			http.SetCookie(res, &http.Cookie{Name: "session", MaxAge: -1, Path: "/"})
			routeHandler(res, req, nil)
			return
		}
		id, ok := session.Values["id"].(string)
		name, ok := session.Values["name"].(string)
		if id != "" && name != "" && ok {
			user := db.User{id, name}
			routeHandler(res, req, &user)
		} else {
			routeHandler(res, req, nil)
		}
	}
}
Exemple #9
0
// SessionUser will try to read a unique user ID out of the session. Then it tries
// to populate an anonymous user object from the database based on that ID. If this
// is successful, the valid user is mapped into the context. Otherwise the anonymous
// user is mapped into the contact.
// The newUser() function should provide a valid 0value structure for the caller's
// user type.
func SessionUser(store sessions.Store, sessionName string, newUser func() User) negroni.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		session, _ := store.Get(r, sessionName)
		userId := session.Values[SessionKey]
		user := newUser()

		if userId != nil {
			err := user.GetById(userId)
			if err != nil {
				// l.Printf("Login Error: %v\n", err)
			} else {
				user.Login()
			}
		}

		context.Set(r, UserKey, user)
	}
}
Exemple #10
0
func VerifyXSRFToken(w http.ResponseWriter, r *http.Request, sessionStore sessions.Store, secureCookie *securecookie.SecureCookie) bool {
	xsrftoken := r.Header.Get(XSRFTOKENHEADER)
	userID := ""

	err := secureCookie.Decode(XSRFTOKEN, xsrftoken, &userID)
	if err == nil {
		session, _ := sessionStore.Get(r, SESSIONNAME)

		if userID != "" && userID == session.Values["username"].(string) {
			xlog.Infof("XSRF verification success for user %s", session.Values["username"].(string))
			return true
		}
		xlog.Errorf("XSRF issue: userID = %s session = %s", userID, session.Values["username"].(string))
	}

	xlog.Errorf("XSRF verification failed: %v (Request: %#v", err, *r)
	http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
	StatCount("XSRF verification failed", 1)
	return false
}
Exemple #11
0
func NewContext(r *http.Request, store sessions.Store, dbmap *gorp.DbMap, cache Cache) (*Context, error) {
	sess, err := store.Get(r, "gostbook")
	ctx := &Context{
		DbMap:   dbmap,
		Session: sess,
		Cache:   cache,
	}

	if err != nil { // no user active in this session
		return ctx, err
	}

	if userID, ok := sess.Values["user"].(int64); ok { // User ID has been set for this session value
		err = ctx.DbMap.SelectOne(&ctx.User, "select * from users where ID=?", helpers.GetIDEncoded(userID))

		if err != nil {
			log.Println(err)
		}
	}
	return ctx, err
}
Exemple #12
0
// NewUserSession creates a new UserSession and pairs it with the current
// http request.
// If a user is logged in, the returned UserSession will contain
// that user instance; otherwise returned UserSession will contain
// nil for the user instance. Upon successful completion, caller must call
// context.Clear(r) from github.com/gorilla/context.
// sessionStore is the session store; r is the current http request;
// cookieName is the name of the session cookie;
// factory creates the UserSession given a gorilla session;
// userGetter retrieves user instance from persistent storage given user ID;
// noSuchId is the error that userGetter returns if no such user exist for
// a given ID.
func NewUserSession(
	sessionStore sessions.Store,
	r *http.Request,
	cookieName string,
	factory func(s *sessions.Session) UserSession,
	userGetter UserGetter,
	noSuchId error) (UserSession, error) {
	gs, err := sessionStore.Get(r, cookieName)
	if err != nil {
		return nil, err
	}
	result := factory(gs)
	if userId, ok := result.UserId(); ok {
		userPtr, err := userGetter.GetUser(userId)
		if err == nil {
			result.SetUser(userPtr)
		} else if err != noSuchId {
			return nil, err
		}
	}
	context.Set(r, kSessionContextKey, result)
	return result, nil
}
Exemple #13
0
// WebsocketHandler handles an incoming WebSocket and dispatches to the correct
// handler based on whether the user is authenticated and whether the session
// he's viewing belongs to him.
func WebsocketHandler(s *websocket.Conn, dbStore *Store, sessionStore sessions.Store, redisAddr string) {
	StatCount("websocket", 1)
	xlog.Infof("WebsocketHandler: opened connection")
	r := s.Request()
	session, err := sessionStore.Get(r, SESSIONNAME)
	if err != nil {
		xlog.Debugf("Getting session failed: %v", err)
		StatCount("getting session failed", 1)
		return
	}

	sessionData := struct {
		SessionID string `json:"session_id"`
	}{}

	if err := websocket.JSON.Receive(s, &sessionData); err != nil {
		xlog.Errorf("WebsocketHandler: JSON.Receive failed: %v", err)
		return
	}

	owner, sessionID, err := dbStore.GetOwnerForSession(sessionData.SessionID)
	if err != nil {
		xlog.Errorf("GetOwnerForSession failed: %v", err)
		return
	}

	if session.Values["userID"] == nil {
		xlog.Errorf("WebsocketHandler is not authenticated -> slave handler")
		slaveHandler(s, sessionID, dbStore, redisAddr)
	} else if owner == session.Values["userID"].(int) {
		xlog.Infof("WebSocketHandler owner matches -> master handler")
		masterHandler(s, sessionID, dbStore, redisAddr)
	} else {
		xlog.Infof("WebSocketHandler owner doesn't match -> slave handler")
		slaveHandler(s, sessionID, dbStore, redisAddr)
	}
}
Exemple #14
0
func Route(router *mux.Router, sessionStore sessions.Store, sessionName string, entity Entity, entityStoreFactory EntityStoreFactory, getJoinResp GetJoinResp, getEntityChangeResp GetEntityChangeResp, performAct PerformAct) {
	gob.Register(entity)

	getSession := func(w http.ResponseWriter, r *http.Request) (*session, error) {
		s, err := sessionStore.Get(r, sessionName)

		session := &session{
			writer:          w,
			request:         r,
			internalSession: s,
		}

		var val interface{}
		var exists bool

		if val, exists = s.Values[_USER_ID]; exists {
			session.userId = val.(string)
		} else {
			session.userId = ``
		}

		if val, exists = s.Values[_ENTITY_ID]; exists {
			session.entityId = val.(string)
		} else {
			session.entityId = ``
		}

		if val, exists = s.Values[_ENTITY]; exists && val != nil {
			session.entity = val.(Entity)
		} else {
			session.entity = nil
		}

		return session, err
	}

	fetchEntity := func(entityId string, entityStore EntityStore) (entity Entity, err error) {
		retryCount := 0
		for {
			entity, err = entityStore.Read(entityId)
			if err == nil {
				if entity.Kick() {
					err = entityStore.Update(entityId, entity)
					if err != nil && retryCount == 0 && strings.Contains(err.Error(), `nonsequential update for entity with id "`+entityId+`"`) {
						err = nil
						retryCount++
						continue
					}
				}
			}
			break
		}
		return
	}

	create := func(w http.ResponseWriter, r *http.Request) {
		s, _ := getSession(w, r)
		if s.isNotEngaged() {
			entityStore := entityStoreFactory(r)
			entityId, entity, err := entityStore.Create()
			if err != nil {
				writeError(w, err)
				return
			}
			s.set(entity.CreatedBy(), entityId, entity)
		}
		writeJson(w, &Json{_ID: s.getEntityId()})
	}

	join := func(w http.ResponseWriter, r *http.Request) {
		entityId, _, err := getRequestData(r, false)
		if err != nil {
			writeError(w, err)
			return
		}

		entityStore := entityStoreFactory(r)
		entity, err := fetchEntity(entityId, entityStore)
		if err != nil {
			writeError(w, err)
			return
		}

		s, _ := getSession(w, r)
		if s.isNotEngaged() && entity.IsActive() {
			if userId, err := entity.RegisterNewUser(); err == nil {
				if err := entityStore.Update(entityId, entity); err == nil {
					//entity was updated successfully this user is now active in this entity
					s.set(userId, entityId, entity)
				}
			}
		}

		respJson := getJoinResp(s.getUserId(), entity)
		respJson[_VERSION] = entity.GetVersion()
		writeJson(w, &respJson)
	}

	poll := func(w http.ResponseWriter, r *http.Request) {
		entityId, version, err := getRequestData(r, true)
		if err != nil {
			writeError(w, err)
			return
		}

		entityStore := entityStoreFactory(r)
		entity, err := fetchEntity(entityId, entityStore)
		if err != nil {
			writeError(w, err)
			return
		}

		if version == entity.GetVersion() {
			return
		}

		s, _ := getSession(w, r)
		userId := s.getUserId()
		if s.getEntityId() == entityId {
			if entity.IsActive() {
				s.set(userId, entityId, entity)
			} else {
				s.clear()
			}
		}
		respJson := getEntityChangeResp(userId, entity)
		respJson[_VERSION] = entity.GetVersion()
		writeJson(w, &respJson)
	}

	act := func(w http.ResponseWriter, r *http.Request) {
		s, _ := getSession(w, r)
		userId := s.getUserId()
		sessionEntity := s.getEntity()
		if sessionEntity == nil {
			writeError(w, errors.New(`no entity in session`))
			return
		}

		json := readJson(r)
		err := performAct(json, userId, sessionEntity)
		if err != nil {
			writeError(w, err)
			return
		}

		entityStore := entityStoreFactory(r)
		entityId := s.getEntityId()
		entity, err := fetchEntity(entityId, entityStore)
		if err != nil {
			writeError(w, err)
			return
		}

		if err = performAct(json, userId, entity); err != nil {
			writeError(w, err)
			return
		}

		if err = entityStore.Update(entityId, entity); err != nil {
			writeError(w, err)
			return
		}

		if entity.IsActive() {
			s.set(s.getUserId(), entityId, entity)
		} else {
			s.clear()
		}
		respJson := getEntityChangeResp(userId, entity)
		respJson[_VERSION] = entity.GetVersion()
		writeJson(w, &respJson)
	}

	leave := func(w http.ResponseWriter, r *http.Request) {
		s, _ := getSession(w, r)
		entityId := s.getEntityId()
		sessionEntity := s.getEntity()
		if sessionEntity == nil {
			s.clear()
			return
		}

		err := sessionEntity.UnregisterUser(s.getUserId())
		if err != nil {
			writeError(w, err)
			return
		}

		entityStore := entityStoreFactory(r)
		entity, err := entityStore.Read(entityId)
		if err != nil {
			writeError(w, err)
			return
		}

		err = entity.UnregisterUser(s.getUserId())
		if err != nil {
			writeError(w, err)
			return
		}

		err = entityStore.Update(entityId, entity)
		if err != nil {
			writeError(w, err)
			return
		}

		s.clear()
	}

	router.Path(_CREATE).HandlerFunc(create)
	router.Path(_JOIN).HandlerFunc(join)
	router.Path(_POLL).HandlerFunc(poll)
	router.Path(_ACT).HandlerFunc(act)
	router.Path(_LEAVE).HandlerFunc(leave)
}
Exemple #15
0
func initSession(store sessions.Store, w http.ResponseWriter, r *http.Request) (*Session, error) {
	session, err := store.Get(r, SessionName)
	s := Session{session, w, r}
	return &s, err
}
Exemple #16
0
import (
	"errors"
	"fmt"
	"net/http"
	"os"

	"github.com/gorilla/sessions"
	"github.com/markbates/goth"
)

// SessionName is the key used to access the session store.
const SessionName = "_gothic_session"

// Store can/should be set by applications using gothic. The default is a cookie store.
var Store sessions.Store

func init() {
	key := []byte(os.Getenv("SESSION_SECRET"))
	if string(key) == "" {
		fmt.Println("goth/gothic: no SESSION_SECRET environment variable is set. The default cookie store is not available and any calls will fail. Ignore this warning if you are using a different store.")
	}
	Store = sessions.NewCookieStore([]byte(key))
}

/*
BeginAuthHandler is a convienence handler for starting the authentication process.
It expects to be able to get the name of the provider from the query parameters
as either "provider" or ":provider".

BeginAuthHandler will redirect the user to the appropriate authentication end-point
Exemple #17
0
// NewGorillaSession creates a gorilla session for the vsafe app.
func NewGorillaSession(
	sessionStore sessions.Store,
	r *http.Request) (*sessions.Session, error) {
	return sessionStore.Get(r, kCookieName)
}