mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
* feat(auth): implement OIDC authentication endpoints and error handling * feat(auth): add OIDC provider discovery endpoint and related functionality * feat(auth): add SAML2 authentication support and related functionality * feat(auth): add LDAP authentication support and related functionality * fix(auth): improve login keydown handler for better event handling
125 lines
3.2 KiB
Go
125 lines
3.2 KiB
Go
package auth
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/core/utils/ttlstore"
|
|
)
|
|
|
|
const (
|
|
MFASessionTTL = 5 * time.Minute
|
|
MFASessionStoreMaxEntries = 1024
|
|
MFASessionMaxFailures = 5
|
|
)
|
|
|
|
var mfaSessions = newMFASessionStore()
|
|
|
|
func GetMFASessionStore() *mfaSessionStore {
|
|
return mfaSessions
|
|
}
|
|
|
|
type mfaSession struct {
|
|
Name string
|
|
Entrance string
|
|
IP string
|
|
AuthSource string
|
|
AuthSourceID uint
|
|
AuthSourceConfigVersion uint64
|
|
ExternalIssuer string
|
|
ExternalNameID string
|
|
ExternalNameIDFormat string
|
|
ExternalSessionIndex string
|
|
ExternalSessionExpiresAt time.Time
|
|
ExternalSessionRequired bool
|
|
Failures int
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
type mfaSessionStore struct {
|
|
store *ttlstore.Store[mfaSession]
|
|
}
|
|
|
|
func newMFASessionStore() *mfaSessionStore {
|
|
return &mfaSessionStore{
|
|
store: ttlstore.New[mfaSession](MFASessionTTL, MFASessionStoreMaxEntries, generateMFASessionID),
|
|
}
|
|
}
|
|
|
|
func (s *mfaSessionStore) Set(name, entrance, ip string) string {
|
|
return s.store.Set(mfaSession{
|
|
Name: name,
|
|
Entrance: entrance,
|
|
IP: ip,
|
|
})
|
|
}
|
|
|
|
func (s *mfaSessionStore) SetWithAuthSource(
|
|
name, entrance, ip, authSource string,
|
|
authSourceID uint,
|
|
authSourceConfigVersion uint64,
|
|
) string {
|
|
return s.store.Set(mfaSession{
|
|
Name: name,
|
|
Entrance: entrance,
|
|
IP: ip,
|
|
AuthSource: authSource,
|
|
AuthSourceID: authSourceID,
|
|
AuthSourceConfigVersion: authSourceConfigVersion,
|
|
})
|
|
}
|
|
|
|
func (s *mfaSessionStore) SetWithAuthSourceSession(
|
|
name, entrance, ip, authSource string,
|
|
authSourceID uint,
|
|
authSourceConfigVersion uint64,
|
|
externalIssuer, externalNameID, externalNameIDFormat, externalSessionIndex string,
|
|
externalSessionExpiresAt time.Time,
|
|
externalSessionRequired bool,
|
|
) string {
|
|
return s.store.Set(mfaSession{
|
|
Name: name, Entrance: entrance, IP: ip,
|
|
AuthSource: authSource, AuthSourceID: authSourceID,
|
|
AuthSourceConfigVersion: authSourceConfigVersion,
|
|
ExternalIssuer: externalIssuer, ExternalNameID: externalNameID,
|
|
ExternalNameIDFormat: externalNameIDFormat,
|
|
ExternalSessionIndex: externalSessionIndex,
|
|
ExternalSessionExpiresAt: externalSessionExpiresAt,
|
|
ExternalSessionRequired: externalSessionRequired,
|
|
})
|
|
}
|
|
|
|
func (s *mfaSessionStore) Get(sessionID string) (mfaSession, bool) {
|
|
return s.store.Get(sessionID)
|
|
}
|
|
|
|
func (s *mfaSessionStore) Delete(sessionID string) {
|
|
s.store.Delete(sessionID)
|
|
}
|
|
|
|
func (s *mfaSessionStore) RecordFailure(sessionID string) int {
|
|
failures := 0
|
|
ok := s.store.Update(sessionID, func(item *mfaSession) bool {
|
|
item.Failures++
|
|
failures = item.Failures
|
|
return item.Failures < MFASessionMaxFailures
|
|
})
|
|
if !ok {
|
|
return 0
|
|
}
|
|
return failures
|
|
}
|
|
|
|
func generateMFASessionID() string {
|
|
raw := make([]byte, 32)
|
|
if _, err := rand.Read(raw); err != nil {
|
|
return generateFallbackMFASessionID()
|
|
}
|
|
return base64.RawURLEncoding.EncodeToString(raw)
|
|
}
|
|
|
|
func generateFallbackMFASessionID() string {
|
|
return base64.RawURLEncoding.EncodeToString([]byte(time.Now().Format(time.RFC3339Nano)))
|
|
}
|