2021-02-15 05:33:31 +00:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2022-01-02 21:12:35 +08:00
package auth
2021-02-15 05:33:31 +00:00
import (
"fmt"
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2021-02-15 05:33:31 +00:00
"code.gitea.io/gitea/modules/timeutil"
)
// Session represents a session compatible for go-chi session
type Session struct {
Key string ` xorm:"pk CHAR(16)" ` // has to be Key to match with go-chi/session
2021-11-03 00:33:54 +00:00
Data [ ] byte ` xorm:"BLOB" ` // on MySQL this has a maximum size of 64Kb - this may need to be increased
2021-02-15 05:33:31 +00:00
Expiry timeutil . TimeStamp // has to be Expiry to match with go-chi/session
}
2021-09-19 19:49:59 +08:00
func init ( ) {
db . RegisterModel ( new ( Session ) )
}
2021-02-15 05:33:31 +00:00
// UpdateSession updates the session with provided id
func UpdateSession ( key string , data [ ] byte ) error {
2021-09-23 16:45:36 +01:00
_ , err := db . GetEngine ( db . DefaultContext ) . ID ( key ) . Update ( & Session {
2021-02-15 05:33:31 +00:00
Data : data ,
Expiry : timeutil . TimeStampNow ( ) ,
} )
return err
}
// ReadSession reads the data for the provided session
func ReadSession ( key string ) ( * Session , error ) {
session := Session {
Key : key ,
}
2021-11-21 23:41:00 +08:00
2022-11-13 04:18:50 +08:00
ctx , committer , err := db . TxContext ( db . DefaultContext )
2021-11-21 23:41:00 +08:00
if err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
2021-02-15 05:33:31 +00:00
2021-11-21 23:41:00 +08:00
if has , err := db . GetByBean ( ctx , & session ) ; err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
} else if ! has {
session . Expiry = timeutil . TimeStampNow ( )
2021-11-21 23:41:00 +08:00
if err := db . Insert ( ctx , & session ) ; err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
}
2021-11-21 23:41:00 +08:00
return & session , committer . Commit ( )
2021-02-15 05:33:31 +00:00
}
// ExistSession checks if a session exists
func ExistSession ( key string ) ( bool , error ) {
session := Session {
Key : key ,
}
2021-09-23 16:45:36 +01:00
return db . GetEngine ( db . DefaultContext ) . Get ( & session )
2021-02-15 05:33:31 +00:00
}
// DestroySession destroys a session
func DestroySession ( key string ) error {
2021-09-23 16:45:36 +01:00
_ , err := db . GetEngine ( db . DefaultContext ) . Delete ( & Session {
2021-02-15 05:33:31 +00:00
Key : key ,
} )
return err
}
// RegenerateSession regenerates a session from the old id
func RegenerateSession ( oldKey , newKey string ) ( * Session , error ) {
2022-11-13 04:18:50 +08:00
ctx , committer , err := db . TxContext ( db . DefaultContext )
2021-11-21 23:41:00 +08:00
if err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
2021-02-15 05:33:31 +00:00
2021-11-21 23:41:00 +08:00
if has , err := db . GetByBean ( ctx , & Session {
2021-02-15 05:33:31 +00:00
Key : newKey ,
} ) ; err != nil {
return nil , err
} else if has {
return nil , fmt . Errorf ( "session Key: %s already exists" , newKey )
}
2021-11-21 23:41:00 +08:00
if has , err := db . GetByBean ( ctx , & Session {
2021-02-15 05:33:31 +00:00
Key : oldKey ,
} ) ; err != nil {
return nil , err
} else if ! has {
2021-11-21 23:41:00 +08:00
if err := db . Insert ( ctx , & Session {
2021-02-15 05:33:31 +00:00
Key : oldKey ,
Expiry : timeutil . TimeStampNow ( ) ,
2021-11-21 23:41:00 +08:00
} ) ; err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
}
2021-11-21 23:41:00 +08:00
if _ , err := db . Exec ( ctx , "UPDATE " + db . TableName ( & Session { } ) + " SET `key` = ? WHERE `key`=?" , newKey , oldKey ) ; err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
s := Session {
Key : newKey ,
}
2021-11-21 23:41:00 +08:00
if _ , err := db . GetByBean ( ctx , & s ) ; err != nil {
2021-02-15 05:33:31 +00:00
return nil , err
}
2021-11-21 23:41:00 +08:00
return & s , committer . Commit ( )
2021-02-15 05:33:31 +00:00
}
// CountSessions returns the number of sessions
func CountSessions ( ) ( int64 , error ) {
2021-09-23 16:45:36 +01:00
return db . GetEngine ( db . DefaultContext ) . Count ( & Session { } )
2021-02-15 05:33:31 +00:00
}
// CleanupSessions cleans up expired sessions
func CleanupSessions ( maxLifetime int64 ) error {
2021-09-23 16:45:36 +01:00
_ , err := db . GetEngine ( db . DefaultContext ) . Where ( "expiry <= ?" , timeutil . TimeStampNow ( ) . Add ( - maxLifetime ) ) . Delete ( & Session { } )
2021-02-15 05:33:31 +00:00
return err
}