1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-07-15 23:54:29 +02:00

Improving sessions handling

This commit is contained in:
Jesús Espino
2020-12-07 17:04:35 +01:00
parent bbddba2d2b
commit e08f9a9c96
5 changed files with 52 additions and 21 deletions

View File

@ -2,6 +2,7 @@ package app
import ( import (
"log" "log"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/mattermost/mattermost-octo-tasks/server/model" "github.com/mattermost/mattermost-octo-tasks/server/model"
@ -10,14 +11,19 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// GetSession Get a user active session and refresh the session if is needed
func (a *App) GetSession(token string) (*model.Session, error) { func (a *App) GetSession(token string) (*model.Session, error) {
session, err := a.store.GetSession(token) session, err := a.store.GetSession(token, a.config.SessionExpireTime)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to get the session for the token") return nil, errors.Wrap(err, "unable to get the session for the token")
} }
if session.UpdateAt < (time.Now().Unix() - a.config.SessionRefreshTime) {
a.store.RefreshSession(session)
}
return session, nil return session, nil
} }
// Login create a new user session if the authentication data is valid
func (a *App) Login(username string, email string, password string, mfaToken string) (string, error) { func (a *App) Login(username string, email string, password string, mfaToken string) (string, error) {
var user *model.User var user *model.User
if username != "" { if username != "" {
@ -59,6 +65,7 @@ func (a *App) Login(username string, email string, password string, mfaToken str
return session.Token, nil return session.Token, nil
} }
// RegisterUser create a new user if the provided data is valid
func (a *App) RegisterUser(username string, email string, password string) error { func (a *App) RegisterUser(username string, email string, password string) error {
var user *model.User var user *model.User
if username != "" { if username != "" {

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"runtime" "runtime"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"go.uber.org/zap" "go.uber.org/zap"
@ -13,6 +14,7 @@ import (
"github.com/mattermost/mattermost-octo-tasks/server/api" "github.com/mattermost/mattermost-octo-tasks/server/api"
"github.com/mattermost/mattermost-octo-tasks/server/app" "github.com/mattermost/mattermost-octo-tasks/server/app"
"github.com/mattermost/mattermost-octo-tasks/server/services/config" "github.com/mattermost/mattermost-octo-tasks/server/services/config"
"github.com/mattermost/mattermost-octo-tasks/server/services/scheduler"
"github.com/mattermost/mattermost-octo-tasks/server/services/store" "github.com/mattermost/mattermost-octo-tasks/server/services/store"
"github.com/mattermost/mattermost-octo-tasks/server/services/store/sqlstore" "github.com/mattermost/mattermost-octo-tasks/server/services/store/sqlstore"
"github.com/mattermost/mattermost-octo-tasks/server/services/telemetry" "github.com/mattermost/mattermost-octo-tasks/server/services/telemetry"
@ -26,13 +28,14 @@ import (
const currentVersion = "0.0.1" const currentVersion = "0.0.1"
type Server struct { type Server struct {
config *config.Configuration config *config.Configuration
wsServer *ws.Server wsServer *ws.Server
webServer *web.Server webServer *web.Server
store store.Store store store.Store
filesBackend filesstore.FileBackend filesBackend filesstore.FileBackend
telemetry *telemetry.Service telemetry *telemetry.Service
logger *zap.Logger logger *zap.Logger
cleanUpSessionsTask *scheduler.ScheduledTask
} }
func New(cfg *config.Configuration, singleUser bool) (*Server, error) { func New(cfg *config.Configuration, singleUser bool) (*Server, error) {
@ -130,6 +133,11 @@ func (s *Server) Start() error {
if err := s.webServer.Start(); err != nil { if err := s.webServer.Start(); err != nil {
return err return err
} }
s.cleanUpSessionsTask = scheduler.CreateRecurringTask("cleanUpSessions", func() {
if err := s.store.CleanUpSessions(s.config.SessionExpireTime); err != nil {
s.logger.Error("Unable to clean up the sessions", zap.Error(err))
}
}, 10*time.Minute)
return nil return nil
} }
@ -139,6 +147,8 @@ func (s *Server) Shutdown() error {
return err return err
} }
s.cleanUpSessionsTask.Cancel()
return s.store.Shutdown() return s.store.Shutdown()
} }

View File

@ -13,16 +13,18 @@ const (
// Configuration is the app configuration stored in a json file. // Configuration is the app configuration stored in a json file.
type Configuration struct { type Configuration struct {
ServerRoot string `json:"serverRoot" mapstructure:"serverRoot"` ServerRoot string `json:"serverRoot" mapstructure:"serverRoot"`
Port int `json:"port" mapstructure:"port"` Port int `json:"port" mapstructure:"port"`
DBType string `json:"dbtype" mapstructure:"dbtype"` DBType string `json:"dbtype" mapstructure:"dbtype"`
DBConfigString string `json:"dbconfig" mapstructure:"dbconfig"` DBConfigString string `json:"dbconfig" mapstructure:"dbconfig"`
UseSSL bool `json:"useSSL" mapstructure:"useSSL"` UseSSL bool `json:"useSSL" mapstructure:"useSSL"`
WebPath string `json:"webpath" mapstructure:"webpath"` WebPath string `json:"webpath" mapstructure:"webpath"`
FilesPath string `json:"filespath" mapstructure:"filespath"` FilesPath string `json:"filespath" mapstructure:"filespath"`
Telemetry bool `json:"telemetry" mapstructure:"telemetry"` Telemetry bool `json:"telemetry" mapstructure:"telemetry"`
WebhookUpdate []string `json:"webhook_update" mapstructure:"webhook_update"` WebhookUpdate []string `json:"webhook_update" mapstructure:"webhook_update"`
Secret string `json:"secret" mapstructure:"secret"` Secret string `json:"secret" mapstructure:"secret"`
SessionExpireTime int64 `json:"session_expire_time" mapstructure:"session_expire_time"`
SessionRefreshTime int64 `json:"session_refresh_time" mapstructure:"session_refresh_time"`
} }
// ReadConfigFile read the configuration from the filesystem. // ReadConfigFile read the configuration from the filesystem.
@ -37,6 +39,8 @@ func ReadConfigFile() (*Configuration, error) {
viper.SetDefault("WebPath", "./pack") viper.SetDefault("WebPath", "./pack")
viper.SetDefault("FilesPath", "./files") viper.SetDefault("FilesPath", "./files")
viper.SetDefault("WebhookUpdate", nil) viper.SetDefault("WebhookUpdate", nil)
viper.SetDefault("SessionExpireTime", 60*60*24*30) // 30 days session lifetime
viper.SetDefault("SessionRefreshTime", 60*60*5) // 5 minutes session refresh
err := viper.ReadInConfig() // Find and read the config file err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file if err != nil { // Handle errors reading the config file

View File

@ -8,11 +8,12 @@ import (
"github.com/mattermost/mattermost-octo-tasks/server/model" "github.com/mattermost/mattermost-octo-tasks/server/model"
) )
func (s *SQLStore) GetSession(token string) (*model.Session, error) { func (s *SQLStore) GetSession(token string, expireTime int64) (*model.Session, error) {
query := s.getQueryBuilder(). query := s.getQueryBuilder().
Select("id", "token", "user_id", "props"). Select("id", "token", "user_id", "props").
From("sessions"). From("sessions").
Where(sq.Eq{"token": token}) Where(sq.Eq{"token": token}).
Where(sq.Gt{"update_at": time.Now().Unix() - expireTime})
row := query.QueryRow() row := query.QueryRow()
session := model.Session{} session := model.Session{}
@ -80,3 +81,11 @@ func (s *SQLStore) DeleteSession(sessionId string) error {
_, err := query.Exec() _, err := query.Exec()
return err return err
} }
func (s *SQLStore) CleanUpSessions(expireTime int64) error {
query := s.getQueryBuilder().Delete("sessions").
Where(sq.Lt{"update_at": time.Now().Unix() - expireTime})
_, err := query.Exec()
return err
}

View File

@ -22,9 +22,10 @@ type Store interface {
GetUserByUsername(username string) (*model.User, error) GetUserByUsername(username string) (*model.User, error)
CreateUser(user *model.User) error CreateUser(user *model.User) error
UpdateUser(user *model.User) error UpdateUser(user *model.User) error
GetSession(token string) (*model.Session, error) GetSession(token string, expireTime int64) (*model.Session, error)
CreateSession(session *model.Session) error CreateSession(session *model.Session) error
RefreshSession(session *model.Session) error RefreshSession(session *model.Session) error
UpdateSession(session *model.Session) error UpdateSession(session *model.Session) error
DeleteSession(sessionId string) error DeleteSession(sessionId string) error
CleanUpSessions(expireTime int64) error
} }