mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-03-30 18:37:55 +00:00
Compare commits
6 Commits
feat/lockd
...
refactor/o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ae16d6bdc | ||
|
|
db73c56dfe | ||
|
|
4a85a9d010 | ||
|
|
7bead41ae9 | ||
|
|
2491d453cf | ||
|
|
1a1712eaeb |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -15,6 +15,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
- name: Generate metadata
|
- name: Generate metadata
|
||||||
id: metadata
|
id: metadata
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@tanstack/eslint-plugin-query": "^5.91.4",
|
"@tanstack/eslint-plugin-query": "^5.91.4",
|
||||||
"@types/node": "^25.5.0",
|
"@types/node": "^25.4.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
@@ -417,7 +417,7 @@
|
|||||||
|
|
||||||
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
"@types/node": ["@types/node@25.4.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@tanstack/eslint-plugin-query": "^5.91.4",
|
"@tanstack/eslint-plugin-query": "^5.91.4",
|
||||||
"@types/node": "^25.5.0",
|
"@types/node": "^25.4.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
|
|||||||
@@ -21,11 +21,8 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// hard-defaults, may make configurable in the future if needed,
|
|
||||||
// but for now these are just safety limits to prevent unbounded memory usage
|
|
||||||
const MaxOAuthPendingSessions = 256
|
const MaxOAuthPendingSessions = 256
|
||||||
const OAuthCleanupCount = 16
|
const OAuthCleanupCount = 16
|
||||||
const MaxLoginAttemptRecords = 256
|
|
||||||
|
|
||||||
type OAuthPendingSession struct {
|
type OAuthPendingSession struct {
|
||||||
State string
|
State string
|
||||||
@@ -46,11 +43,6 @@ type LoginAttempt struct {
|
|||||||
LockedUntil time.Time
|
LockedUntil time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Lockdown struct {
|
|
||||||
Active bool
|
|
||||||
ActiveUntil time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthServiceConfig struct {
|
type AuthServiceConfig struct {
|
||||||
Users []config.User
|
Users []config.User
|
||||||
OauthWhitelist []string
|
OauthWhitelist []string
|
||||||
@@ -77,7 +69,6 @@ type AuthService struct {
|
|||||||
ldap *LdapService
|
ldap *LdapService
|
||||||
queries *repository.Queries
|
queries *repository.Queries
|
||||||
oauthBroker *OAuthBrokerService
|
oauthBroker *OAuthBrokerService
|
||||||
lockdown *Lockdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, queries *repository.Queries, oauthBroker *OAuthBrokerService) *AuthService {
|
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, queries *repository.Queries, oauthBroker *OAuthBrokerService) *AuthService {
|
||||||
@@ -211,11 +202,6 @@ func (auth *AuthService) IsAccountLocked(identifier string) (bool, int) {
|
|||||||
auth.loginMutex.RLock()
|
auth.loginMutex.RLock()
|
||||||
defer auth.loginMutex.RUnlock()
|
defer auth.loginMutex.RUnlock()
|
||||||
|
|
||||||
if auth.lockdown != nil && auth.lockdown.Active {
|
|
||||||
remaining := int(time.Until(auth.lockdown.ActiveUntil).Seconds())
|
|
||||||
return true, remaining
|
|
||||||
}
|
|
||||||
|
|
||||||
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
||||||
return false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
@@ -241,14 +227,6 @@ func (auth *AuthService) RecordLoginAttempt(identifier string, success bool) {
|
|||||||
auth.loginMutex.Lock()
|
auth.loginMutex.Lock()
|
||||||
defer auth.loginMutex.Unlock()
|
defer auth.loginMutex.Unlock()
|
||||||
|
|
||||||
if len(auth.loginAttempts) >= MaxLoginAttemptRecords {
|
|
||||||
if auth.lockdown != nil && auth.lockdown.Active {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go auth.lockdownMode()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
attempt, exists := auth.loginAttempts[identifier]
|
attempt, exists := auth.loginAttempts[identifier]
|
||||||
if !exists {
|
if !exists {
|
||||||
attempt = &LoginAttempt{}
|
attempt = &LoginAttempt{}
|
||||||
@@ -768,31 +746,3 @@ func (auth *AuthService) ensureOAuthSessionLimit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (auth *AuthService) lockdownMode() {
|
|
||||||
auth.loginMutex.Lock()
|
|
||||||
|
|
||||||
tlog.App.Warn().Msg("Multiple login attempts detected, possibly DDOS attack. Activating temporary lockdown.")
|
|
||||||
|
|
||||||
auth.lockdown = &Lockdown{
|
|
||||||
Active: true,
|
|
||||||
ActiveUntil: time.Now().Add(time.Duration(auth.config.LoginTimeout) * time.Second),
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point all login attemps will also expire so,
|
|
||||||
// we might as well clear them to free up memory
|
|
||||||
auth.loginAttempts = make(map[string]*LoginAttempt)
|
|
||||||
|
|
||||||
timer := time.NewTimer(time.Until(auth.lockdown.ActiveUntil))
|
|
||||||
defer timer.Stop()
|
|
||||||
|
|
||||||
auth.loginMutex.Unlock()
|
|
||||||
|
|
||||||
<-timer.C
|
|
||||||
|
|
||||||
auth.loginMutex.Lock()
|
|
||||||
|
|
||||||
tlog.App.Info().Msg("Lockdown period ended, resuming normal operation")
|
|
||||||
auth.lockdown = nil
|
|
||||||
auth.loginMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user