// Token will return a token. If SingleToken = true, it will return the same token for every page. func Token(w http.ResponseWriter, r *http.Request, sess *sessions.Session) string { // Generate the map if it doesn't exist if _, ok := sess.Values[TokenName]; !ok { sess.Values[TokenName] = make(StringMap) } path := r.URL.Path if SingleToken { path = "/" } sessMap := sess.Values[TokenName].(StringMap) if _, ok := sessMap[path]; !ok { if len(sessMap) >= MaxTokens { for i, _ := range sessMap { delete(sessMap, i) } } sessMap[path] = generate(TokenLength) sess.Save(r, w) } return sessMap[path] }
func (m *MongoStore) upsert(session *sessions.Session) error { if !bson.IsObjectIdHex(session.ID) { return ErrInvalidId } var modified time.Time if val, ok := session.Values["modified"]; ok { modified, ok = val.(time.Time) if !ok { return errors.New("mongostore: invalid modified value") } } else { modified = time.Now() } encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...) if err != nil { return err } s := Session{ Id: bson.ObjectIdHex(session.ID), Data: encoded, Modified: modified, } _, err = m.coll.UpsertId(s.Id, &s) if err != nil { return err } return nil }
func (s *Store) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.codecs...) if err != nil { return err } var expiresOn time.Time exOn := session.Values["expires_on"] if exOn == nil { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } else { expiresOn = exOn.(time.Time) if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 { expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge)) } } ss := &Session{ Key: session.ID, Data: encoded, ExpiresOn: expiresOn, } if session.IsNew { return s.q.SaveSession(ss) } return s.q.UpdateSession(ss) }
func (s *RethinkDBStore) save(session *sessions.Session) error { values := map[string]interface{}{} for k, v := range session.Values { kstr, ok := k.(string) if !ok { return errors.New("cannot serialize non-string value key") } values[kstr] = v } json := map[string]interface{}{ "name": session.Name(), "values": values, } var write gorethink.WriteResponse var err error if session.ID != "" { write, err = s.term.Get(session.ID).Update(json).RunWrite(s.rethinkdbSession) if err == nil && write.Updated == 0 { json["id"] = session.ID } } if write.Updated == 0 { write, err = s.term.Insert(json).RunWrite(s.rethinkdbSession) if err == nil && len(write.GeneratedKeys) > 0 { session.ID = write.GeneratedKeys[0] } } return err }
// Clear will remove all the tokens. Call after a permission change. func Clear(w http.ResponseWriter, r *http.Request, sess *sessions.Session) { // Delete the map if it doesn't exist if _, ok := sess.Values[TokenName]; ok { delete(sess.Values, TokenName) sess.Save(r, w) } }
func googleDisconnect(w http.ResponseWriter, r *http.Request, session *sessions.Session) *appError { token := session.Values["accessToken"] if token == nil { m := "Current user not connected" return &appError{errors.New(m), m, 401} } // Execute HTTP GET request to revoke current token url := "https://accounts.google.com/o/oauth2/revoke?token=" + token.(string) resp, err := http.Get(url) if err != nil { m := "Failed to revoke token for a given user" return &appError{errors.New(m), m, 400} } defer resp.Body.Close() // Reset the user's session session.Values["accessToken"] = nil session.Values["userId"] = nil session.Values["gplusID"] = nil session.Save(r, w) return nil }
func Test_Handler_clearSession(t *testing.T) { var ok bool config := util.NewMzConfig() h, _ := testHandler(config, t) sess := new(sessions.Session) sess.Values = make(map[interface{}]interface{}) sess.Values[SESSION_USERID] = true sess.Values[SESSION_DEVICEID] = true sess.Values[SESSION_EMAIL] = true sess.Values[SESSION_TOKEN] = true sess.Values[SESSION_CSRFTOKEN] = true h.clearSession(sess) if _, ok = sess.Values[SESSION_USERID]; ok { t.Errorf("Userid not cleared") } if _, ok = sess.Values[SESSION_DEVICEID]; ok { t.Errorf("Deviceid not cleared") } if _, ok = sess.Values[SESSION_EMAIL]; ok { t.Errorf("Email not cleared") } if _, ok = sess.Values[SESSION_TOKEN]; ok { t.Errorf("Token not cleared") } if _, ok = sess.Values[SESSION_CSRFTOKEN]; ok { t.Errorf("CSRFToken not cleared") } }
func fakeCookies(req *http.Request, email, userid, token, csrftoken string) error { var err error var session *sessions.Session resp := httptest.NewRecorder() session, err = sessionStore.Get(req, SESSION_NAME) if len(email) > 0 { session.Values[SESSION_EMAIL] = email } if len(userid) > 0 { session.Values[SESSION_USERID] = userid } if len(token) > 0 { session.Values[SESSION_TOKEN] = token } if len(csrftoken) > 0 { session.Values[SESSION_CSRFTOKEN] = csrftoken } if err = session.Save(req, resp); err != nil { return fmt.Errorf("Could not set cookie! %s", err.Error()) } fcookies, ok := resp.HeaderMap["Set-Cookie"] if !ok { return fmt.Errorf("Cookie not set in header") } req.Header.Add("Cookie", strings.Split(fcookies[0], ";")[0]) return nil }
func (s *RedisStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } c := s.storeHandler.GetRedisConnection() defer c.Close() if session.ID == "" { // Because the ID is used in the filename, encode it to // use alphanumeric characters only. session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=") } c.Send("SET", "morioka_sess_"+session.ID, encoded) if err = c.Flush(); err != nil { return err } if _, err = c.Receive(); err != nil { return err } c.Send("EXPIRE", "morioka_sess_"+session.ID, 86400) if err = c.Flush(); err != nil { return err } if _, err = c.Receive(); err != nil { return err } return nil }
func createSession(w http.ResponseWriter, r *http.Request, session *sessions.Session) *ServerSession { // Each session needs a unique ID in order to be saved. if session.ID == "" { session.ID = tokens.NewSessionID() } ss := &ServerSession{ CSRFToken: tokens.NewCSRFToken(session.ID), } // Attempt to store the session. Remove the session if it's not stored // correctly. if err := ss.StoreSession(session.ID); err != nil { RemoveSession(session.ID) glog.Fatalln(err) } // Similarly, save it in our FS storage and set the user's cookie. if err := session.Save(r, w); err != nil { RemoveSession(session.ID) glog.Fatalln(err) } return ss }
// load reads a file and decodes its content into session.Values. func (s *DumbMemoryStore) load(session *sessions.Session) error { if err := securecookie.DecodeMulti(session.Name(), string(s.Data[session.ID]), &session.Values, s.Codecs...); err != nil { return err } return nil }
//load fetches a session by ID from the database and decodes its content into session.Values func (db *PGStore) load(session *sessions.Session) error { s, err := query.GetSessionByKey(session.ID) if err != nil { return err } return securecookie.DecodeMulti(session.Name(), string(s.Data), &session.Values, db.Codecs...) }
//load fetches a session by ID from the database and decodes its content into session.Values func (s *Store) load(session *sessions.Session) error { ss, err := s.q.GetSessionByKey(session.ID) if err != nil { return err } return securecookie.DecodeMulti(session.Name(), string(ss.Data), &session.Values, s.codecs...) }
func (s *Store) destroy(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { options := *s.options options.MaxAge = -1 http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options)) for k := range session.Values { delete(session.Values, k) } return s.q.DeleteSession(session.ID) }
func saveCookie(w http.ResponseWriter, s *sessions.Session, store *sessions.CookieStore) (string, error) { encoded, err := securecookie.EncodeMulti(s.Name(), s.Values, store.Codecs...) if err != nil { return "", err } cookie := sessions.NewCookie(s.Name(), encoded, s.Options) http.SetCookie(w, cookie) return cookie.Value, nil }
// ValidateAuth validates that the user cookie is set up before calling the // handler passed as parameter. func ValidateAuth(h httputils.ContextHandler) httputils.ContextHandler { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { var ( sessionData *httputils.SessionData err error ok bool cookieStore *sessions.CookieStore session *sessions.Session cfg = ctx.Value("config").(*config.Config) ) cookieStore, ok = ctx.Value("cookieStore").(*sessions.CookieStore) if !ok { httputils.WriteError(w, http.StatusInternalServerError, "") return fmt.Errorf("validate auth: could not cast value as cookie store: %s", ctx.Value("cookieStore")) } session, err = cookieStore.Get(r, cfg.SessionCookieName) if err != nil { log.Println(err) http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return nil } sessionData, ok = session.Values["data"].(*httputils.SessionData) if !ok || sessionData.IsInvalid() { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return nil } else if time.Now().After(sessionData.ExpiresAt) { session.Options.MaxAge = -1 session.Save(r, w) http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return nil } // Extend the session's lifetime. cfg, ok = ctx.Value("config").(*config.Config) if !ok { httputils.WriteError(w, http.StatusInternalServerError, "") return fmt.Errorf("validate auth: error casting config object: %s", ctx.Value("config")) } // Save session only if the session was extended. if extendSessionLifetime(sessionData, cfg.SessionLifeTime) { sessionData.ExpiresAt = time.Now().Add(cfg.SessionLifeTime) session.Save(r, w) } authenticatedContext := context.WithValue(ctx, "sessionData", sessionData) return h(authenticatedContext, w, r) } }
// save writes encoded session.Values using the memcache client func (s *DumbMemoryStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } s.Data[session.ID] = encoded return nil }
func (s *RethinkDBStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if err := s.save(session); err != nil { return err } encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
func saveUserToSessionAndSendHome(w http.ResponseWriter, r *http.Request, session *sessions.Session, userName string, id int) { session.Values["UserName"] = userName session.Values["Id"] = id err := session.Save(r, w) if err != nil { log.Fatal(err) } http.Redirect(w, r, "/", http.StatusFound) }
// save writes encoded session.Values to a database record. // writes to http_sessions table by default. func (db *DatabaseStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, db.Codecs...) if err != nil { return err } fn := func(dbConn *sql.DB) error { // Write record to sessions table. var sessionCount int = -1 // Session exists? row := dbConn.QueryRow("SELECT COUNT(key) AS count FROM \""+SESSIONS_TABLE+"\" WHERE key = $1", session.ID) err := row.Scan(&sessionCount) if err != nil { return err } tx, err := dbConn.Begin() if err != nil { return err } if sessionCount > 0 { // update _, err = tx.Exec("UPDATE \""+SESSIONS_TABLE+"\" SET data = $1 WHERE key = $2", encoded, session.ID) if err != nil { return err } } else if sessionCount == 0 { // insert _, err = tx.Exec("INSERT INTO \""+SESSIONS_TABLE+"\" (key, data) VALUES($1,$2)", session.ID, encoded) if err != nil { return err } } else { // error err = errors.New("There was an error while trying to lookup a previous session.") return err } if err = tx.Commit(); err != nil { return err } return nil } return dbLib.ExecuteFn(fn) }
func (s *RAMStore) load(session *sessions.Session) error { sessionData, err := s.getData().GetData(session.ID) if err != nil { return err } if sessionData != nil { session.Values = sessionData session.IsNew = false } return nil }
// load fetches a session by ID from the database and decodes its content // into session.Values func (db *PGStore) load(session *sessions.Session) error { var s Session err := db.DbMap.SelectOne(&s, "SELECT * FROM http_sessions WHERE key = $1", session.ID) if err := securecookie.DecodeMulti(session.Name(), string(s.Data), &session.Values, db.Codecs...); err != nil { return err } return err }
// Save saves a session to the store. If the session has no ID, Save assigns // a random one. This implementation of Save never returns a non-nil error // if client is storing sessions data in a *RamSessions instance. func (s *RAMStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { if session.ID == "" { session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := s.save(session); err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), session.ID, session.Options)) return nil }
// Remove all current user information from the session object func (c *CAS) removeCurrentUserFromSession(w http.ResponseWriter, req *http.Request, session *sessions.Session) *CASServerError { // Delete current user from session delete(session.Values, "currentUser") // Save the modified session err := session.Save(req, w) if err != nil { return &FailedToDeleteSessionError } return nil }
// load reads from redis and decodes its content into session.Values. func (s *RedisStore) load(session *sessions.Session) error { c := s.redisPool.Get() defer c.Close() encoded, err := redis.String(c.Do("GET", "s:"+session.ID)) if err != nil { return err } return securecookie.DecodeMulti(session.Name(), encoded, &session.Values, s.Codecs...) }
// save stores the session in redis. func (s *RediStore) save(session *sessions.Session) error { encoded, err := securecookie.EncodeMulti(session.Name(), session.Values, s.Codecs...) if err != nil { return err } conn := s.Pool.Get() defer conn.Close() if err = conn.Err(); err != nil { return err } _, err = conn.Do("SETEX", "session_"+session.ID, session.Options.MaxAge, encoded) return err }
func (s *RedisStore) load(session *sessions.Session) error { c := s.storeHandler.GetRedisConnection() defer c.Close() c.Send("GET", "morioka_sess_"+session.ID) c.Flush() data, err := redis.String(c.Receive()) if err != nil { return err } if err = securecookie.DecodeMulti(session.Name(), data, &session.Values, s.Codecs...); err != nil { return err } return nil }
func (db *PGStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { // Set delete if max-age is < 0 if session.Options.MaxAge < 0 { if err := db.destroy(session); err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options)) return nil } if session.ID == "" { // Generate a random session ID key suitable for storage in the DB session.ID = string(securecookie.GenerateRandomKey(32)) session.ID = strings.TrimRight( base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32)), "=") } if err := db.save(session); err != nil { return err } // Keep the session ID key in a cookie so it can be looked up in DB later. encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, db.Codecs...) if err != nil { return err } http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options)) return nil }
// Token will return a token for the specified URL. SingleToken is ignored. func TokenWithPath(w http.ResponseWriter, r *http.Request, sess *sessions.Session, urlPath string) string { // Generate the map if it doesn't exist if _, ok := sess.Values[TokenName]; !ok { sess.Values[TokenName] = make(StringMap) } sessMap := sess.Values[TokenName].(StringMap) if _, ok := sessMap[urlPath]; !ok { sessMap[urlPath] = generate(TokenLength) sess.Save(r, w) } return sessMap[urlPath] }
func loginHandler(res http.ResponseWriter, r *http.Request, session *sessions.Session, ctx *pongo2.Context) (*string, error) { var ( username = strings.ToLower(r.FormValue("username")) password = fmt.Sprintf("%x", sha1.Sum([]byte(cfg.PasswordSalt+r.FormValue("password")))) ) if !storage.IsPresent(createUserFilename(username)) { (*ctx)["error"] = true return stringPointer("login.html"), nil } userFileRaw, err := storage.Read(createUserFilename(username)) if err != nil { fmt.Printf("ERR: Unable to read user file: %s\n", err) (*ctx)["error"] = true return stringPointer("login.html"), nil } userFile, _ := readDataObject(userFileRaw) if userFile.MetaData.Password != password { (*ctx)["error"] = true return stringPointer("login.html"), nil } auth, ok := session.Values["authorizedAccounts"].(authorizedAccounts) if !ok { auth = authorizedAccounts{} } for i, v := range auth { if v.Name == username { http.Redirect(res, r, fmt.Sprintf("u/%d/overview", i), http.StatusFound) return nil, nil } } auth = append(auth, authorizedAccount{ Name: username, UserFile: createUserFilename(username), }) session.Values["authorizedAccounts"] = auth if err := session.Save(r, res); err != nil { return nil, err } http.Redirect(res, r, fmt.Sprintf("u/%d/overview", len(auth)-1), http.StatusFound) return nil, nil }