Sync GitHub / sync (push) Successful in 8s
Add PublicAccessListener (priority 84) that allows rate-limited unauthenticated access to configured public paths. Authenticated users bypass this listener entirely via AcceptListener/AllowListener. New components: - PublicPathMatcher service with wildcard path matching (* and **) and optional host-prefix scoping - PublicAccessListener applying per-IP rate limiting to public paths - Separate public_limiter compound rate limiter (burst + sustained) - publicRateLimitCache pool (APCu in prod, array in tests) New env vars: - PUBLIC_PATHS (comma-separated path patterns, empty = disabled) - PUBLIC_BURST_COUNT/PUBLIC_BURST_TIME (default 100/60s) - PUBLIC_UPPER_COUNT/PUBLIC_UPPER_TIME (default 500/3600s) Tests: 52 new tests (29 unit for PublicPathMatcher, 12 unit for PublicAccessListener, 11 functional for PublicAccessFlowTest). Total: 293 tests, 605 assertions, all passing. PHP CS Fixer: 0 of 63 files need fixing. Documentation: README, CHANGELOG, ROADMAP, Caddyfile, example.env all updated with public access configuration and examples.
113 lines
5.2 KiB
YAML
113 lines
5.2 KiB
YAML
# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json
|
|
|
|
# This file is the entry point to configure your own services.
|
|
# Files in the packages/ subdirectory configure your dependencies.
|
|
# See also https://symfony.com/doc/current/service_container/import.html
|
|
|
|
# Put parameters here that don't need to change on each machine where the app is deployed
|
|
# https://symfony.com/doc/current/best_practices.html
|
|
# #use-parameters-for-application-configuration
|
|
parameters:
|
|
# --- main options ---
|
|
# URI containing secret and config for TOTP, which determines the token to login
|
|
# app will generate one, if not provided, but you should copy it to your .env file
|
|
# format: "otpauth://totp/<label>?secret=<secret-key>"
|
|
env(TOTP_URI): '' # blank to have the app generate one at random
|
|
# how long will someone stay logged in, measured in seconds, zero for DEFAULT
|
|
env(COOKIE_TTL): '2592000' # default 30 days
|
|
# Enable optional redirection to a dedicated authentication subdomain
|
|
env(SUBDOMAIN_REDIRECT): '0' # boolean, 1 to enable
|
|
# The subdomain (e.g., auth.example.com) to which unauthenticated users are redirected
|
|
env(AUTH_SUBDOMAIN): ''
|
|
|
|
# --- extra options ---
|
|
# how long do we allow all traffic from an ip address after successful login
|
|
# could be useful if you have a system which does not handle cookies
|
|
env(IP_TTL): '0' # default disabled, time in seconds
|
|
# once blocked, do we respond with "I'm a teapot", false to use "Too many requests"
|
|
env(TEAPOT): '1' # boolean
|
|
|
|
# --- remote-user header ---
|
|
# Controls the value sent in the Remote-User header on successful auth.
|
|
# session: the session id (default, backward-compatible)
|
|
# static: a fixed string (set via REMOTE_USER_STATIC)
|
|
# mapped: look up session id in REMOTE_USER_MAP (format: id1:user1,id2:user2)
|
|
# none: do not send the Remote-User header at all
|
|
env(REMOTE_USER): 'session'
|
|
env(REMOTE_USER_STATIC): 'authenticated'
|
|
env(REMOTE_USER_MAP): ''
|
|
|
|
# --- rate limiting ---
|
|
# Note: rate limiting can *NOT* be disabled, but you could allow hundreds of logins a second
|
|
# rate limiting, default is the lower of 2 per 30 seconds or 10 per hour
|
|
env(BURST_COUNT): 2 # 2 per 30 seconds
|
|
env(BURST_TIME): 30 # seconds
|
|
env(UPPER_COUNT): 10 # 10 per hour
|
|
env(UPPER_TIME): 3600 # seconds (1 hour)
|
|
|
|
# --- public access (rate-limited, no auth required) ---
|
|
# Comma-separated path patterns for public access. Wildcards: * (single
|
|
# segment), ** (cross segments). Optional host prefix: host.com/path/**
|
|
# When empty (default), the feature is fully disabled.
|
|
env(PUBLIC_PATHS): ''
|
|
env(PUBLIC_BURST_COUNT): 100 # max requests per burst window per IP
|
|
env(PUBLIC_BURST_TIME): 60 # burst window in seconds
|
|
env(PUBLIC_UPPER_COUNT): 500 # max requests per sustained window per IP
|
|
env(PUBLIC_UPPER_TIME): 3600 # sustained window in seconds (1 hour)
|
|
|
|
# --- styling options ---
|
|
env(TITLE): 'Pre-Authentication System'
|
|
env(BG_COLOR): '#029386' # teal
|
|
env(FG_COLOR): '#ffffff' # white
|
|
env(ERROR_COLOR): '#ffb16d' # apricot (light orange)
|
|
env(ID_NAME): 'Session ID'
|
|
env(TOKEN_NAME): 'Authentication Token'
|
|
env(SUBMIT_NAME): 'Submit'
|
|
env(ERROR_MESSAGE): 'Unsuccessful login attempt'
|
|
# title and message to use on block page, if teapot is true
|
|
env(TEAPOT_TITLE): "I'm a teapot"
|
|
env(TEAPOT_MESSAGE): 'I refuse to brew coffee'
|
|
# title and message to use on block page, if teapot is false
|
|
env(TOO_MANY_TITLE): 'Too many requests'
|
|
env(TOO_MANY_MESSAGE): 'Try again later'
|
|
|
|
# --- debug options ---
|
|
env(SHELL_VERBOSITY): '0' # set to 3 to log debug
|
|
|
|
# --- application variables ---
|
|
app.totp_uri: '%env(TOTP_URI)%'
|
|
app.cookie_ttl: '%env(int:COOKIE_TTL)%'
|
|
app.subdomain_redirect: '%env(bool:SUBDOMAIN_REDIRECT)%'
|
|
app.auth_subdomain: '%env(AUTH_SUBDOMAIN)%'
|
|
|
|
app.ip_ttl: '%env(int:IP_TTL)%'
|
|
app.teapot: '%env(bool:TEAPOT)%'
|
|
|
|
app.remote_user: '%env(REMOTE_USER)%'
|
|
app.remote_user_static: '%env(REMOTE_USER_STATIC)%'
|
|
app.remote_user_map: '%env(REMOTE_USER_MAP)%'
|
|
|
|
app.public_paths: '%env(PUBLIC_PATHS)%'
|
|
app.public_burst_count: '%env(int:PUBLIC_BURST_COUNT)%'
|
|
app.public_burst_time: '%env(int:PUBLIC_BURST_TIME)%'
|
|
app.public_upper_count: '%env(int:PUBLIC_UPPER_COUNT)%'
|
|
app.public_upper_time: '%env(int:PUBLIC_UPPER_TIME)%'
|
|
|
|
app.error_message: '%env(ERROR_MESSAGE)%'
|
|
app.teapot_title: '%env(TEAPOT_TITLE)%'
|
|
app.too_many_title: '%env(TOO_MANY_TITLE)%'
|
|
|
|
services:
|
|
# default configuration for services in *this* file
|
|
_defaults:
|
|
autowire: true # Automatically injects dependencies in your services.
|
|
autoconfigure: true # Automatically registers your services.
|
|
|
|
# makes classes in src/ available to be used as services
|
|
# this creates a service per class whose id is the fully-qualified class name
|
|
App\:
|
|
resource: '../src/'
|
|
|
|
# add more service definitions when explicit configuration is needed
|
|
# please note that last definitions always *replace* previous ones
|