mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 04:05:40 +01:00
feat: support customize session timeout (#17767)
Add configuration session_timeout for API, then user can customize the timeout from system config page or API. The timeout is 60 minutes by default. Signed-off-by: chlins <chenyuzh@vmware.com> Signed-off-by: chlins <chenyuzh@vmware.com>
This commit is contained in:
parent
cf036df68b
commit
9c9aa58d6a
@ -8631,6 +8631,9 @@ definitions:
|
||||
type: integer
|
||||
description: 'The offset in seconds of UTC 0 o''clock, only valid when the policy type is "daily"'
|
||||
description: 'The parameters of the policy, the values are dependent on the type of the policy.'
|
||||
session_timeout:
|
||||
$ref: '#/definitions/IntegerConfigItem'
|
||||
description: The session timeout in minutes
|
||||
Configurations:
|
||||
type: object
|
||||
properties:
|
||||
@ -8884,6 +8887,11 @@ definitions:
|
||||
description: Skip audit log database
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
session_timeout:
|
||||
type: integer
|
||||
description: The session timeout for harbor, in minutes.
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
StringConfigItem:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -218,4 +218,7 @@ const (
|
||||
SkipAuditLogDatabase = "skip_audit_log_database"
|
||||
// MaxAuditRetentionHour allowed in audit log purge
|
||||
MaxAuditRetentionHour = 240000
|
||||
|
||||
// SessionTimeout defines the web session timeout
|
||||
SessionTimeout = "session_timeout"
|
||||
)
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/cache"
|
||||
"github.com/goharbor/harbor/src/lib/cache/redis"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
)
|
||||
|
||||
@ -91,8 +92,10 @@ func (rs *Store) SessionRelease(w http.ResponseWriter) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
maxlifetime := time.Duration(systemSessionTimeout(ctx, rs.maxlifetime))
|
||||
if rdb, ok := rs.c.(*redis.Cache); ok {
|
||||
cmd := rdb.Client.Set(context.TODO(), rs.sid, string(b), time.Duration(rs.maxlifetime))
|
||||
cmd := rdb.Client.Set(ctx, rs.sid, string(b), maxlifetime)
|
||||
if cmd.Err() != nil {
|
||||
log.Debugf("release session error: %v", err)
|
||||
}
|
||||
@ -136,8 +139,9 @@ func (rp *Provider) SessionExist(sid string) bool {
|
||||
// SessionRegenerate generate new sid for redis session
|
||||
func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
ctx := context.TODO()
|
||||
maxlifetime := time.Duration(systemSessionTimeout(ctx, rp.maxlifetime))
|
||||
if !rp.SessionExist(oldsid) {
|
||||
err := rp.c.Save(ctx, sid, "", time.Duration(rp.maxlifetime))
|
||||
err := rp.c.Save(ctx, sid, "", maxlifetime)
|
||||
if err != nil {
|
||||
log.Debugf("failed to save sid=%s, where oldsid=%s, error: %s", sid, oldsid, err)
|
||||
}
|
||||
@ -145,7 +149,7 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
|
||||
if rdb, ok := rp.c.(*redis.Cache); ok {
|
||||
// redis has rename command
|
||||
rdb.Rename(ctx, oldsid, sid)
|
||||
rdb.Expire(ctx, sid, time.Duration(rp.maxlifetime))
|
||||
rdb.Expire(ctx, sid, maxlifetime)
|
||||
} else {
|
||||
kv := make(map[interface{}]interface{})
|
||||
err := rp.c.Fetch(ctx, sid, &kv)
|
||||
@ -157,7 +161,7 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
|
||||
if err != nil {
|
||||
log.Debugf("failed to delete oldsid=%s, error: %s", oldsid, err)
|
||||
}
|
||||
err = rp.c.Save(ctx, sid, kv)
|
||||
err = rp.c.Save(ctx, sid, kv, maxlifetime)
|
||||
if err != nil {
|
||||
log.Debugf("failed to save sid=%s, error: %s", sid, err)
|
||||
}
|
||||
@ -181,6 +185,18 @@ func (rp *Provider) SessionAll() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// systemSessionTimeout return the system session timeout set by user.
|
||||
func systemSessionTimeout(ctx context.Context, beegoTimeout int64) int64 {
|
||||
// read from system config if it is meaningful to support change session timeout in runtime for user.
|
||||
// otherwise, use parameters beegoTimeout which set from beego.
|
||||
timeout := beegoTimeout
|
||||
if sysTimeout := config.SessionTimeout(ctx); sysTimeout > 0 {
|
||||
timeout = sysTimeout * int64(time.Minute)
|
||||
}
|
||||
|
||||
return timeout
|
||||
}
|
||||
|
||||
func init() {
|
||||
session.Register(HarborProviderName, harborpder)
|
||||
}
|
||||
|
@ -19,6 +19,10 @@ import (
|
||||
|
||||
"github.com/beego/beego/session"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/db"
|
||||
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
|
||||
)
|
||||
|
||||
type sessionTestSuite struct {
|
||||
@ -27,7 +31,9 @@ type sessionTestSuite struct {
|
||||
provider session.Provider
|
||||
}
|
||||
|
||||
func (s *sessionTestSuite) SetupTest() {
|
||||
func (s *sessionTestSuite) SetupSuite() {
|
||||
config.Init()
|
||||
|
||||
var err error
|
||||
s.provider, err = session.GetProvider("harbor")
|
||||
s.NoError(err, "should get harbor provider")
|
||||
|
@ -183,5 +183,7 @@ var (
|
||||
|
||||
{Name: common.AuditLogForwardEndpoint, Scope: UserScope, Group: BasicGroup, EnvKey: "AUDIT_LOG_FORWARD_ENDPOINT", DefaultValue: "", ItemType: &StringType{}, Editable: false, Description: `The endpoint to forward the audit log.`},
|
||||
{Name: common.SkipAuditLogDatabase, Scope: UserScope, Group: BasicGroup, EnvKey: "SKIP_LOG_AUDIT_DATABASE", DefaultValue: "false", ItemType: &BoolType{}, Editable: false, Description: `The option to skip audit log in database`},
|
||||
|
||||
{Name: common.SessionTimeout, Scope: UserScope, Group: BasicGroup, EnvKey: "SESSION_TIMEOUT", DefaultValue: "60", ItemType: &Int64Type{}, Editable: true, Description: `The session timeout in minutes`},
|
||||
}
|
||||
)
|
||||
|
@ -84,6 +84,11 @@ func LDAPGroupConf(ctx context.Context) (*cfgModels.GroupConf, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SessionTimeout returns the session timeout for web (in minute).
|
||||
func SessionTimeout(ctx context.Context) int64 {
|
||||
return DefaultMgr().Get(ctx, common.SessionTimeout).GetInt64()
|
||||
}
|
||||
|
||||
// TokenExpiration returns the token expiration time (in minute)
|
||||
func TokenExpiration(ctx context.Context) (int, error) {
|
||||
return DefaultMgr().Get(ctx, common.TokenExpiration).GetInt(), nil
|
||||
|
Loading…
Reference in New Issue
Block a user