mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-23 00:00:52 +00:00
106 lines
2.1 KiB
Go
106 lines
2.1 KiB
Go
package terminal
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var sessions sync.Map
|
|
|
|
var errSessionNotFound = errors.New("terminal session not found")
|
|
|
|
const (
|
|
HeaderUserID = "X-Panel-User-ID"
|
|
HeaderAuthSessionID = "X-Panel-Auth-Session-ID"
|
|
HeaderAuthLeaseUntil = "X-Panel-Auth-Lease-Until"
|
|
)
|
|
|
|
type Identity struct {
|
|
UserID string
|
|
AuthSessionID string
|
|
AuthLeaseUntil time.Time
|
|
}
|
|
|
|
func (i Identity) Valid() bool {
|
|
if i.UserID == "" || i.AuthSessionID == "" {
|
|
return false
|
|
}
|
|
if strings.HasPrefix(i.AuthSessionID, "api-key:") && i.AuthLeaseUntil.IsZero() {
|
|
return false
|
|
}
|
|
return i.AuthLeaseUntil.IsZero() || time.Now().Before(i.AuthLeaseUntil)
|
|
}
|
|
|
|
func registerSession(s *Session) {
|
|
sessions.Store(s.ID, s)
|
|
}
|
|
|
|
func unregisterSession(s *Session) {
|
|
sessions.CompareAndDelete(s.ID, s)
|
|
}
|
|
|
|
func Lookup(id string, identity Identity) (*Session, bool) {
|
|
if !identity.Valid() {
|
|
return nil, false
|
|
}
|
|
v, ok := sessions.Load(id)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
s := v.(*Session)
|
|
if s.UserID != identity.UserID || s.AuthSessionID != identity.AuthSessionID {
|
|
return nil, false
|
|
}
|
|
return s, true
|
|
}
|
|
|
|
func List(identity Identity) []Info {
|
|
if !identity.Valid() {
|
|
return nil
|
|
}
|
|
var out []Info
|
|
sessions.Range(func(_, v any) bool {
|
|
s := v.(*Session)
|
|
if s.UserID == identity.UserID && s.AuthSessionID == identity.AuthSessionID {
|
|
out = append(out, s.Info())
|
|
}
|
|
return true
|
|
})
|
|
sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) })
|
|
return out
|
|
}
|
|
|
|
func CloseSession(id string, identity Identity) error {
|
|
s, ok := Lookup(id, identity)
|
|
if !ok {
|
|
return errSessionNotFound
|
|
}
|
|
s.Close()
|
|
return nil
|
|
}
|
|
|
|
func Revoke(scope, userID, authSessionID string) int {
|
|
closed := 0
|
|
sessions.Range(func(_, v any) bool {
|
|
s := v.(*Session)
|
|
match := false
|
|
switch scope {
|
|
case "auth_session":
|
|
match = userID != "" && authSessionID != "" && s.UserID == userID && s.AuthSessionID == authSessionID
|
|
case "user":
|
|
match = userID != "" && s.UserID == userID
|
|
case "all":
|
|
match = true
|
|
}
|
|
if match {
|
|
closed++
|
|
s.Close()
|
|
}
|
|
return true
|
|
})
|
|
return closed
|
|
}
|