2015-10-08 12:27:09 -04:00
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
2015-06-14 23:53:32 -08:00
// See License.txt for license information.
package store
import (
2016-01-11 09:12:51 -06:00
l4g "github.com/alecthomas/log4go"
2015-06-14 23:53:32 -08:00
"github.com/mattermost/platform/model"
2016-01-25 16:08:06 -03:00
"github.com/mattermost/platform/utils"
2015-06-14 23:53:32 -08:00
)
type SqlSessionStore struct {
* SqlStore
}
func NewSqlSessionStore ( sqlStore * SqlStore ) SessionStore {
us := & SqlSessionStore { sqlStore }
for _ , db := range sqlStore . GetAllConns ( ) {
table := db . AddTableWithName ( model . Session { } , "Sessions" ) . SetKeys ( false , "Id" )
table . ColMap ( "Id" ) . SetMaxSize ( 26 )
2015-09-16 15:49:12 -04:00
table . ColMap ( "Token" ) . SetMaxSize ( 26 )
2015-06-14 23:53:32 -08:00
table . ColMap ( "UserId" ) . SetMaxSize ( 26 )
table . ColMap ( "TeamId" ) . SetMaxSize ( 26 )
2016-02-22 16:08:40 -08:00
table . ColMap ( "DeviceId" ) . SetMaxSize ( 512 )
2015-06-14 23:53:32 -08:00
table . ColMap ( "Roles" ) . SetMaxSize ( 64 )
table . ColMap ( "Props" ) . SetMaxSize ( 1000 )
}
return us
}
func ( me SqlSessionStore ) UpgradeSchemaIfNeeded ( ) {
2016-02-22 16:08:40 -08:00
// ADDED for 2.1 REMOVE for 2.5
deviceIdLength := me . GetMaxLengthOfColumnIfExists ( "Sessions" , "DeviceId" )
if len ( deviceIdLength ) > 0 && deviceIdLength != "512" {
me . AlterColumnTypeIfExists ( "Sessions" , "DeviceId" , "VARCHAR(512)" , "VARCHAR(512)" )
}
2015-06-14 23:53:32 -08:00
}
func ( me SqlSessionStore ) CreateIndexesIfNotExists ( ) {
2015-07-12 18:19:03 -08:00
me . CreateIndexIfNotExists ( "idx_sessions_user_id" , "Sessions" , "UserId" )
2015-09-16 15:49:12 -04:00
me . CreateIndexIfNotExists ( "idx_sessions_token" , "Sessions" , "Token" )
2015-06-14 23:53:32 -08:00
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) Save ( session * model . Session ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if len ( session . Id ) > 0 {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.Save" , "store.sql_session.save.existing.app_error" , nil , "id=" + session . Id )
2015-06-14 23:53:32 -08:00
storeChannel <- result
close ( storeChannel )
return
}
session . PreSave ( )
2016-01-20 13:36:16 -06:00
if cur := <- me . CleanUpExpiredSessions ( session . UserId ) ; cur . Err != nil {
2016-01-25 16:08:06 -03:00
l4g . Error ( utils . T ( "store.sql_session.save.cleanup.error" ) , cur . Err )
2015-06-14 23:53:32 -08:00
}
if err := me . GetMaster ( ) . Insert ( session ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.Save" , "store.sql_session.save.app_error" , nil , "id=" + session . Id + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
result . Data = session
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) Get ( sessionIdOrToken string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2015-09-16 15:49:12 -04:00
var sessions [ ] * model . Session
if _ , err := me . GetReplica ( ) . Select ( & sessions , "SELECT * FROM Sessions WHERE Token = :Token OR Id = :Id LIMIT 1" , map [ string ] interface { } { "Token" : sessionIdOrToken , "Id" : sessionIdOrToken } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.Get" , "store.sql_session.get.app_error" , nil , "sessionIdOrToken=" + sessionIdOrToken + ", " + err . Error ( ) )
2015-09-16 15:49:12 -04:00
} else if sessions == nil || len ( sessions ) == 0 {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.Get" , "store.sql_session.get.app_error" , nil , "sessionIdOrToken=" + sessionIdOrToken )
2015-06-14 23:53:32 -08:00
} else {
2015-09-16 15:49:12 -04:00
result . Data = sessions [ 0 ]
2015-06-14 23:53:32 -08:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) GetSessions ( userId string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
2016-01-20 13:36:16 -06:00
if cur := <- me . CleanUpExpiredSessions ( userId ) ; cur . Err != nil {
2016-01-25 16:08:06 -03:00
l4g . Error ( utils . T ( "store.sql_session.get_sessions.error" ) , cur . Err )
2015-06-14 23:53:32 -08:00
}
result := StoreResult { }
var sessions [ ] * model . Session
2015-07-12 18:19:03 -08:00
if _ , err := me . GetReplica ( ) . Select ( & sessions , "SELECT * FROM Sessions WHERE UserId = :UserId ORDER BY LastActivityAt DESC" , map [ string ] interface { } { "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.GetSessions" , "store.sql_session.get_sessions.app_error" , nil , err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
result . Data = sessions
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) Remove ( sessionIdOrToken string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2015-09-16 15:49:12 -04:00
_ , err := me . GetMaster ( ) . Exec ( "DELETE FROM Sessions WHERE Id = :Id Or Token = :Token" , map [ string ] interface { } { "Id" : sessionIdOrToken , "Token" : sessionIdOrToken } )
2015-06-14 23:53:32 -08:00
if err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.RemoveSession" , "store.sql_session.remove.app_error" , nil , "id=" + sessionIdOrToken + ", err=" + err . Error ( ) )
2015-06-14 23:53:32 -08:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) RemoveAllSessionsForTeam ( teamId string ) StoreChannel {
2015-09-23 12:49:28 -07:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
_ , err := me . GetMaster ( ) . Exec ( "DELETE FROM Sessions WHERE TeamId = :TeamId" , map [ string ] interface { } { "TeamId" : teamId } )
if err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.RemoveAllSessionsForTeam" , "store.sql_session.remove_all_sessions_for_team.app_error" , nil , "id=" + teamId + ", err=" + err . Error ( ) )
2015-09-23 12:49:28 -07:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) PermanentDeleteSessionsByUser ( userId string ) StoreChannel {
2015-11-15 18:18:02 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
_ , err := me . GetMaster ( ) . Exec ( "DELETE FROM Sessions WHERE UserId = :UserId" , map [ string ] interface { } { "UserId" : userId } )
if err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.RemoveAllSessionsForUser" , "store.sql_session.permanent_delete_sessions_by_user.app_error" , nil , "id=" + userId + ", err=" + err . Error ( ) )
2015-11-15 18:18:02 -08:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) CleanUpExpiredSessions ( userId string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2015-07-12 18:19:03 -08:00
if _ , err := me . GetMaster ( ) . Exec ( "DELETE FROM Sessions WHERE UserId = :UserId AND ExpiresAt != 0 AND :ExpiresAt > ExpiresAt" , map [ string ] interface { } { "UserId" : userId , "ExpiresAt" : model . GetMillis ( ) } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.CleanUpExpiredSessions" , "store.sql_session.cleanup_expired_sessions.app_error" , nil , err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) UpdateLastActivityAt ( sessionId string , time int64 ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2015-07-12 18:19:03 -08:00
if _ , err := me . GetMaster ( ) . Exec ( "UPDATE Sessions SET LastActivityAt = :LastActivityAt WHERE Id = :Id" , map [ string ] interface { } { "LastActivityAt" : time , "Id" : sessionId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.UpdateLastActivityAt" , "store.sql_session.update_last_activity.app_error" , nil , "sessionId=" + sessionId )
2015-06-14 23:53:32 -08:00
} else {
result . Data = sessionId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2015-08-17 09:28:20 -04:00
2016-01-20 13:36:16 -06:00
func ( me SqlSessionStore ) UpdateRoles ( userId , roles string ) StoreChannel {
2015-08-17 09:28:20 -04:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if _ , err := me . GetMaster ( ) . Exec ( "UPDATE Sessions SET Roles = :Roles WHERE UserId = :UserId" , map [ string ] interface { } { "Roles" : roles , "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlSessionStore.UpdateRoles" , "store.sql_session.update_roles.app_error" , nil , "userId=" + userId )
2015-08-17 09:28:20 -04:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-26 20:32:24 -05:00
func ( me SqlSessionStore ) UpdateDeviceId ( id , deviceId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if _ , err := me . GetMaster ( ) . Exec ( "UPDATE Sessions SET DeviceId = :DeviceId WHERE Id = :Id" , map [ string ] interface { } { "DeviceId" : deviceId , "Id" : id } ) ; err != nil {
2016-02-22 16:08:40 -08:00
result . Err = model . NewLocAppError ( "SqlSessionStore.UpdateDeviceId" , "store.sql_session.update_device_id.app_error" , nil , err . Error ( ) )
2016-01-26 20:32:24 -05:00
} else {
result . Data = deviceId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-02-25 12:32:46 -05:00
func ( me SqlSessionStore ) AnalyticsSessionCount ( teamId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
query :=
` SELECT
COUNT ( * )
FROM
Sessions `
if len ( teamId ) > 0 {
query += " WHERE TeamId = :TeamId"
}
if c , err := me . GetReplica ( ) . SelectInt ( query , map [ string ] interface { } { "TeamId" : teamId } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlSessionStore.AnalyticsSessionCount" , "store.sql_session.analytics_session_count.app_error" , nil , err . Error ( ) )
} else {
result . Data = c
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}