itsi 0.1.20 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -8
- data/Cargo.lock +2 -2
- data/LICENSE.txt +698 -0
- data/README.md +15 -4
- data/Rakefile +9 -5
- data/crates/itsi_acme/.gitignore +4 -0
- data/crates/itsi_acme/Cargo.toml +86 -0
- data/crates/itsi_acme/LICENSE-APACHE +201 -0
- data/crates/itsi_acme/LICENSE-MIT +23 -0
- data/crates/itsi_acme/README.md +9 -0
- data/crates/itsi_acme/examples/high_level.rs +63 -0
- data/crates/itsi_acme/examples/high_level_warp.rs +52 -0
- data/crates/itsi_acme/examples/low_level.rs +87 -0
- data/crates/itsi_acme/examples/low_level_axum.rs +66 -0
- data/crates/itsi_acme/src/acceptor.rs +81 -0
- data/crates/itsi_acme/src/acme.rs +354 -0
- data/crates/itsi_acme/src/axum.rs +86 -0
- data/crates/itsi_acme/src/cache.rs +39 -0
- data/crates/itsi_acme/src/caches/boxed.rs +80 -0
- data/crates/itsi_acme/src/caches/composite.rs +69 -0
- data/crates/itsi_acme/src/caches/dir.rs +106 -0
- data/crates/itsi_acme/src/caches/mod.rs +11 -0
- data/crates/itsi_acme/src/caches/no.rs +78 -0
- data/crates/itsi_acme/src/caches/test.rs +136 -0
- data/crates/itsi_acme/src/config.rs +172 -0
- data/crates/itsi_acme/src/https_helper.rs +69 -0
- data/crates/itsi_acme/src/incoming.rs +142 -0
- data/crates/itsi_acme/src/jose.rs +161 -0
- data/crates/itsi_acme/src/lib.rs +142 -0
- data/crates/itsi_acme/src/resolver.rs +59 -0
- data/crates/itsi_acme/src/state.rs +424 -0
- data/crates/itsi_rb_helpers/src/lib.rs +4 -3
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_scheduler/src/itsi_scheduler.rs +8 -2
- data/crates/itsi_scheduler/src/lib.rs +1 -0
- data/crates/itsi_server/Cargo.toml +1 -1
- data/crates/itsi_server/src/lib.rs +2 -1
- data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +18 -1
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +11 -3
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +122 -63
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +2 -0
- data/crates/itsi_server/src/server/binds/bind.rs +3 -0
- data/crates/itsi_server/src/server/binds/listener.rs +12 -5
- data/crates/itsi_server/src/server/binds/tls.rs +13 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +12 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +8 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +9 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +48 -43
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +11 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +39 -12
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +36 -27
- data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +25 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +12 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +74 -72
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +15 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +11 -8
- data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +19 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +5 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +2 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +11 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +17 -20
- data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +19 -8
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +16 -37
- data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +22 -12
- data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +26 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +7 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +14 -4
- data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +19 -0
- data/crates/itsi_server/src/server/middleware_stack/mod.rs +49 -13
- data/crates/itsi_server/src/server/mod.rs +1 -0
- data/crates/itsi_server/src/server/redirect_type.rs +26 -0
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +22 -16
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +49 -12
- data/crates/itsi_server/src/server/signal.rs +1 -0
- data/crates/itsi_server/src/server/size_limited_incoming.rs +6 -0
- data/crates/itsi_server/src/server/thread_worker.rs +5 -1
- data/crates/itsi_server/src/services/itsi_http_service.rs +20 -2
- data/crates/itsi_server/src/services/rate_limiter.rs +15 -4
- data/crates/itsi_server/src/services/static_file_server.rs +33 -19
- data/crates/itsi_tracing/src/lib.rs +42 -22
- data/docs/content/_index.md +1 -2
- data/docs/content/acknowledgements/_index.md +5 -2
- data/docs/content/configuration/_index.md +8 -5
- data/docs/content/contact/_index.md +8 -1
- data/docs/content/faqs/_index.md +5 -3
- data/docs/content/features/_index.md +56 -50
- data/docs/content/getting_started/_index.md +8 -5
- data/docs/content/getting_started/local_development.md +68 -8
- data/docs/content/getting_started/logging.md +16 -9
- data/docs/content/getting_started/running_itsi_in_production.md +5 -3
- data/docs/content/getting_started/signals.md +38 -0
- data/docs/content/itsi_scheduler/_index.md +8 -7
- data/docs/content/utilities/_index.md +13 -0
- data/docs/content/utilities/config_file_testing.md +17 -0
- data/docs/content/utilities/passfile_generator.md +41 -0
- data/docs/content/utilities/route_testing.md +27 -0
- data/docs/content/utilities/secrets_management.md +30 -0
- data/docs/hugo.yaml +1 -1
- data/fairytale.txt +3 -4
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/README.md +4 -5
- data/gems/scheduler/Rakefile +0 -4
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/scheduler/lib/itsi/scheduler.rb +9 -4
- data/gems/scheduler/test/test_active_record.rb +12 -7
- data/gems/server/Cargo.lock +1 -1
- data/gems/server/Rakefile +0 -4
- data/gems/server/exe/itsi +13 -2
- data/gems/server/lib/itsi/http_request/response_status_shortcodes.rb +2 -0
- data/gems/server/lib/itsi/http_request.rb +40 -9
- data/gems/server/lib/itsi/http_response.rb +2 -1
- data/gems/server/lib/itsi/passfile.rb +0 -1
- data/gems/server/lib/itsi/server/config/config_helpers.rb +20 -8
- data/gems/server/lib/itsi/server/config/dsl.rb +20 -435
- data/gems/server/lib/itsi/server/config/known_paths.rb +4 -1
- data/gems/server/lib/itsi/server/config/middleware/_index.md +6 -4
- data/gems/server/lib/itsi/server/config/middleware/allow_list.md +46 -0
- data/gems/server/lib/itsi/server/config/middleware/allow_list.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_basic.md +45 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
- data/gems/server/lib/itsi/server/config/middleware/cache_control.md +78 -0
- data/gems/server/lib/itsi/server/config/middleware/cache_control.rb +45 -0
- data/gems/server/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
- data/gems/server/lib/itsi/server/config/middleware/compression.md +50 -0
- data/gems/server/lib/itsi/server/config/middleware/compression.rb +37 -0
- data/gems/server/lib/itsi/server/config/middleware/cors.md +93 -0
- data/gems/server/lib/itsi/server/config/middleware/cors.rb +32 -0
- data/gems/server/lib/itsi/server/config/middleware/csp.md +37 -0
- data/gems/server/lib/itsi/server/config/middleware/csp.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/deny_list.md +45 -0
- data/gems/server/lib/itsi/server/config/middleware/deny_list.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
- data/gems/server/lib/itsi/server/config/middleware/error_response.md +61 -0
- data/gems/server/lib/itsi/server/config/middleware/error_response.rb +36 -0
- data/gems/server/lib/itsi/server/config/middleware/etag.md +59 -0
- data/gems/server/lib/itsi/server/config/middleware/etag.rb +27 -0
- data/gems/server/lib/itsi/server/config/middleware/grpc.md +172 -0
- data/gems/server/lib/itsi/server/config/middleware/grpc.rb +54 -0
- data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
- data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
- data/gems/server/lib/itsi/server/config/middleware/location.md +107 -0
- data/gems/server/lib/itsi/server/config/middleware/location.rb +99 -0
- data/gems/server/lib/itsi/server/config/middleware/log_requests.md +13 -11
- data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +1 -3
- data/gems/server/lib/itsi/server/config/middleware/max_body.md +18 -0
- data/gems/server/lib/itsi/server/config/middleware/max_body.rb +21 -0
- data/gems/server/lib/itsi/server/config/middleware/proxy.md +62 -0
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +41 -0
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.md +54 -0
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit.md +126 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/redirect.md +55 -0
- data/gems/server/lib/itsi/server/config/middleware/redirect.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/request_headers.md +34 -0
- data/gems/server/lib/itsi/server/config/middleware/request_headers.rb +24 -0
- data/gems/server/lib/itsi/server/config/middleware/response_headers.md +33 -0
- data/gems/server/lib/itsi/server/config/middleware/response_headers.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/run.md +60 -0
- data/gems/server/lib/itsi/server/config/middleware/run.rb +43 -0
- data/gems/server/lib/itsi/server/config/middleware/static_assets.md +73 -0
- data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +87 -0
- data/gems/server/lib/itsi/server/config/middleware/static_response.md +44 -0
- data/gems/server/lib/itsi/server/config/middleware/static_response.rb +29 -0
- data/gems/server/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
- data/gems/server/lib/itsi/server/config/middleware/token_source.rb +32 -0
- data/gems/server/lib/itsi/server/config/middleware.rb +4 -0
- data/gems/server/lib/itsi/server/config/option.rb +5 -0
- data/gems/server/lib/itsi/server/config/options/_index.md +3 -2
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.md +13 -0
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
- data/gems/server/lib/itsi/server/config/options/bind.md +71 -0
- data/gems/server/lib/itsi/server/config/options/bind.rb +26 -0
- data/gems/server/lib/itsi/server/config/options/certificates.md +65 -0
- data/gems/server/lib/itsi/server/config/options/daemonize.md +14 -0
- data/gems/server/lib/itsi/server/config/options/daemonize.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +1 -2
- data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +6 -3
- data/gems/server/lib/itsi/server/config/options/header_read_timeout.md +17 -0
- data/gems/server/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/hooks/_index.md +11 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_start.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/include.md +20 -0
- data/gems/server/lib/itsi/server/config/options/include.rb +36 -0
- data/gems/server/lib/itsi/server/config/options/listen_backlog.md +11 -0
- data/gems/server/lib/itsi/server/config/options/listen_backlog.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_format.md +18 -0
- data/gems/server/lib/itsi/server/config/options/log_format.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_level.md +34 -0
- data/gems/server/lib/itsi/server/config/options/log_level.rb +20 -0
- data/gems/server/lib/itsi/server/config/options/log_target.md +38 -0
- data/gems/server/lib/itsi/server/config/options/log_target.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_target_filters.md +17 -0
- data/gems/server/lib/itsi/server/config/options/log_target_filters.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
- data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
- data/gems/server/lib/itsi/server/config/options/nodelay.md +16 -0
- data/gems/server/lib/itsi/server/config/options/nodelay.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
- data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
- data/gems/server/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/preload.md +21 -0
- data/gems/server/lib/itsi/server/config/options/preload.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
- data/gems/server/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
- data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
- data/gems/server/lib/itsi/server/config/options/request_timeout.md +23 -0
- data/gems/server/lib/itsi/server/config/options/request_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/reuse_address.md +16 -0
- data/gems/server/lib/itsi/server/config/options/reuse_address.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/reuse_port.md +16 -0
- data/gems/server/lib/itsi/server/config/options/reuse_port.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/scheduler_threads.md +34 -0
- data/gems/server/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
- data/gems/server/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
- data/gems/server/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/stream_body.md +32 -0
- data/gems/server/lib/itsi/server/config/options/stream_body.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/threads.md +7 -2
- data/gems/server/lib/itsi/server/config/options/threads.rb +1 -1
- data/gems/server/lib/itsi/server/config/options/watch.md +16 -0
- data/gems/server/lib/itsi/server/config/options/watch.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
- data/gems/server/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/workers.md +1 -2
- data/gems/server/lib/itsi/server/config/options/workers.rb +1 -1
- data/gems/server/lib/itsi/server/config/typed_struct.rb +59 -20
- data/gems/server/lib/itsi/server/config.rb +77 -48
- data/gems/server/lib/itsi/server/default_config/Itsi.rb +3 -3
- data/gems/server/lib/itsi/server/grpc/grpc_call.rb +1 -1
- data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +11 -4
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -3
- data/gems/server/lib/itsi/server/route_tester.rb +58 -8
- data/gems/server/lib/itsi/server/signal_trap.rb +1 -1
- data/gems/server/lib/itsi/server/typed_handlers/param_parser.rb +14 -18
- data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +5 -4
- data/gems/server/lib/itsi/server/typed_handlers.rb +12 -4
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +98 -14
- data/gems/server/lib/ruby_lsp/itsi/addon.rb +20 -18
- data/gems/server/test/helpers/test_helper.rb +89 -29
- data/gems/server/test/middleware/allow_list.rb +128 -0
- data/gems/server/test/middleware/auth_api_key.rb +141 -0
- data/gems/server/test/middleware/auth_basic.rb +91 -0
- data/gems/server/test/middleware/auth_jwt.rb +214 -0
- data/gems/server/test/middleware/cache_control.rb +82 -0
- data/gems/server/test/middleware/cidr_to_regex.rb +46 -0
- data/gems/server/test/middleware/compression.rb +89 -0
- data/gems/server/test/middleware/cors.rb +113 -0
- data/gems/server/test/middleware/csp.rb +62 -0
- data/gems/server/test/middleware/deny_list.rb +131 -0
- data/gems/server/test/middleware/endpoint.rb +300 -0
- data/gems/server/test/middleware/etag.rb +75 -0
- data/gems/server/test/middleware/grpc/grpc.rb +158 -0
- data/gems/server/test/middleware/grpc/test_service.proto +32 -0
- data/gems/server/test/middleware/grpc/test_service_impl.rb +28 -0
- data/gems/server/test/middleware/grpc/test_service_pb.rb +18 -0
- data/gems/server/test/middleware/grpc/test_service_services_pb.rb +30 -0
- data/gems/server/test/middleware/header_interpolation.rb +35 -0
- data/gems/server/test/middleware/intrusion_protection.rb +259 -0
- data/gems/server/test/middleware/location.rb +220 -0
- data/gems/server/test/middleware/max_body.rb +20 -0
- data/gems/server/test/middleware/proxy.rb +415 -0
- data/gems/server/test/middleware/rate_limit.rb +211 -0
- data/gems/server/test/middleware/redirect.rb +85 -0
- data/gems/server/test/middleware/request_headers.rb +50 -0
- data/gems/server/test/middleware/response_headers.rb +50 -0
- data/gems/server/test/middleware/static_assets.rb +374 -0
- data/gems/server/test/middleware/static_response.rb +56 -0
- data/gems/server/test/middleware/string_rewrite.rb +112 -0
- data/gems/server/test/options/bind.rb +47 -0
- data/gems/server/test/options/header_read_timeout.rb +23 -0
- data/gems/server/test/options/test_request_timeout.rb +16 -0
- data/gems/server/test/options/test_workers.rb +2 -4
- data/gems/server/test/{test_itsi_server.rb → rack/test_rack_server.rb} +2 -2
- data/grpc_test/Itsi.rb +11 -0
- data/grpc_test/echo.proto +14 -0
- data/grpc_test/echo_pb.rb +16 -0
- data/grpc_test/echo_service_impl.rb +8 -0
- data/grpc_test/echo_services_pb.rb +22 -0
- data/lib/itsi/version.rb +1 -1
- data/tasks.txt +15 -72
- metadata +210 -7
- data/gems/server/lib/itsi/server/default_config/Itsi-rackup.rb +0 -119
@@ -7,7 +7,7 @@ use crate::{
|
|
7
7
|
},
|
8
8
|
};
|
9
9
|
use derive_more::Debug;
|
10
|
-
use
|
10
|
+
use itsi_error::ItsiError;
|
11
11
|
use itsi_rb_helpers::{call_with_gvl, print_rb_backtrace, HeapValue};
|
12
12
|
use itsi_tracing::{set_format, set_level, set_target, set_target_filters};
|
13
13
|
use magnus::{
|
@@ -25,7 +25,11 @@ use std::{
|
|
25
25
|
collections::HashMap,
|
26
26
|
os::fd::{AsRawFd, OwnedFd, RawFd},
|
27
27
|
path::PathBuf,
|
28
|
-
|
28
|
+
str::FromStr,
|
29
|
+
sync::{
|
30
|
+
atomic::{AtomicBool, Ordering::Relaxed},
|
31
|
+
Arc, OnceLock,
|
32
|
+
},
|
29
33
|
time::Duration,
|
30
34
|
};
|
31
35
|
use tracing::{debug, error};
|
@@ -71,8 +75,33 @@ pub struct ServerParams {
|
|
71
75
|
#[debug(skip)]
|
72
76
|
pub(crate) listeners: Mutex<Vec<Listener>>,
|
73
77
|
listener_info: Mutex<HashMap<String, i32>>,
|
78
|
+
pub itsi_server_token_preference: ItsiServerTokenPreference,
|
79
|
+
pub preloaded: AtomicBool,
|
80
|
+
socket_opts: SocketOpts,
|
81
|
+
preexisting_listeners: Option<String>,
|
82
|
+
}
|
83
|
+
|
84
|
+
#[derive(Debug, Clone)]
|
85
|
+
pub enum ItsiServerTokenPreference {
|
86
|
+
Version,
|
87
|
+
Name,
|
88
|
+
None,
|
89
|
+
}
|
90
|
+
|
91
|
+
impl FromStr for ItsiServerTokenPreference {
|
92
|
+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
93
|
+
Ok(match s {
|
94
|
+
"version" => ItsiServerTokenPreference::Version,
|
95
|
+
"name" => ItsiServerTokenPreference::Name,
|
96
|
+
"none" => ItsiServerTokenPreference::None,
|
97
|
+
_ => ItsiServerTokenPreference::Version,
|
98
|
+
})
|
99
|
+
}
|
100
|
+
|
101
|
+
type Err = ItsiError;
|
74
102
|
}
|
75
103
|
|
104
|
+
#[derive(Debug, Clone)]
|
76
105
|
pub struct SocketOpts {
|
77
106
|
pub reuse_address: bool,
|
78
107
|
pub reuse_port: bool,
|
@@ -83,8 +112,10 @@ pub struct SocketOpts {
|
|
83
112
|
|
84
113
|
impl ServerParams {
|
85
114
|
pub fn preload_ruby(self: &Arc<Self>) -> Result<()> {
|
115
|
+
if self.preloaded.load(Relaxed) {
|
116
|
+
return Ok(());
|
117
|
+
}
|
86
118
|
call_with_gvl(|ruby| -> Result<()> {
|
87
|
-
debug!("Preloading Ruby");
|
88
119
|
if self
|
89
120
|
.scheduler_class
|
90
121
|
.as_ref()
|
@@ -103,9 +134,7 @@ impl ServerParams {
|
|
103
134
|
}
|
104
135
|
})?
|
105
136
|
.map(|mw| mw.into());
|
106
|
-
debug!("Middleware routes returned");
|
107
137
|
let middleware = MiddlewareSet::new(routes_raw)?;
|
108
|
-
debug!("Middleware loaded");
|
109
138
|
self.middleware.set(middleware).map_err(|_| {
|
110
139
|
magnus::Error::new(
|
111
140
|
magnus::exception::runtime_error(),
|
@@ -114,6 +143,7 @@ impl ServerParams {
|
|
114
143
|
})?;
|
115
144
|
Ok(())
|
116
145
|
})?;
|
146
|
+
self.preloaded.store(true, Relaxed);
|
117
147
|
Ok(())
|
118
148
|
}
|
119
149
|
|
@@ -154,11 +184,11 @@ impl ServerParams {
|
|
154
184
|
.transpose()?
|
155
185
|
.unwrap_or_default();
|
156
186
|
let preload: bool = rb_param_hash.fetch("preload")?;
|
157
|
-
let request_timeout: Option<
|
158
|
-
let request_timeout = request_timeout.map(Duration::
|
187
|
+
let request_timeout: Option<f64> = rb_param_hash.fetch("request_timeout")?;
|
188
|
+
let request_timeout = request_timeout.map(Duration::from_secs_f64);
|
159
189
|
let header_read_timeout: Duration = rb_param_hash
|
160
|
-
.fetch::<_, Option<
|
161
|
-
.map(Duration::
|
190
|
+
.fetch::<_, Option<f64>>("header_read_timeout")?
|
191
|
+
.map(Duration::from_secs_f64)
|
162
192
|
.unwrap_or(Duration::from_secs(1));
|
163
193
|
|
164
194
|
let notify_watchers: Option<Vec<(String, Vec<Vec<String>>)>> =
|
@@ -226,6 +256,12 @@ impl ServerParams {
|
|
226
256
|
.map(|s| s.parse())
|
227
257
|
.collect::<itsi_error::Result<Vec<Bind>>>()?;
|
228
258
|
|
259
|
+
let itsi_server_token_preference: String = rb_param_hash
|
260
|
+
.fetch("itsi_server_token_preference")
|
261
|
+
.unwrap_or_default();
|
262
|
+
let itsi_server_token_preference: ItsiServerTokenPreference =
|
263
|
+
itsi_server_token_preference.parse()?;
|
264
|
+
|
229
265
|
let socket_opts = SocketOpts {
|
230
266
|
reuse_address,
|
231
267
|
reuse_port,
|
@@ -233,10 +269,42 @@ impl ServerParams {
|
|
233
269
|
nodelay,
|
234
270
|
recv_buffer_size,
|
235
271
|
};
|
236
|
-
let
|
237
|
-
|
238
|
-
{
|
239
|
-
|
272
|
+
let preexisting_listeners = rb_param_hash.delete::<_, Option<String>>("listeners")?;
|
273
|
+
|
274
|
+
let params = ServerParams {
|
275
|
+
workers,
|
276
|
+
worker_memory_limit,
|
277
|
+
silence,
|
278
|
+
multithreaded_reactor,
|
279
|
+
pin_worker_cores,
|
280
|
+
shutdown_timeout,
|
281
|
+
hooks,
|
282
|
+
preload,
|
283
|
+
request_timeout,
|
284
|
+
header_read_timeout,
|
285
|
+
notify_watchers,
|
286
|
+
threads,
|
287
|
+
scheduler_threads,
|
288
|
+
streamable_body,
|
289
|
+
scheduler_class,
|
290
|
+
oob_gc_responses_threshold,
|
291
|
+
binds,
|
292
|
+
itsi_server_token_preference,
|
293
|
+
socket_opts,
|
294
|
+
preexisting_listeners,
|
295
|
+
listener_info: Mutex::new(HashMap::new()),
|
296
|
+
listeners: Mutex::new(Vec::new()),
|
297
|
+
middleware_loader: middleware_loader.into(),
|
298
|
+
middleware: OnceLock::new(),
|
299
|
+
preloaded: AtomicBool::new(false),
|
300
|
+
};
|
301
|
+
|
302
|
+
Ok(params)
|
303
|
+
}
|
304
|
+
|
305
|
+
pub fn setup_listeners(&self) -> Result<()> {
|
306
|
+
let listeners = if let Some(preexisting_listeners) = self.preexisting_listeners.as_ref() {
|
307
|
+
let bind_to_fd_map: HashMap<String, i32> = serde_json::from_str(preexisting_listeners)
|
240
308
|
.map_err(|e| {
|
241
309
|
magnus::Error::new(
|
242
310
|
magnus::exception::standard_error(),
|
@@ -244,24 +312,24 @@ impl ServerParams {
|
|
244
312
|
)
|
245
313
|
})?;
|
246
314
|
|
247
|
-
binds
|
315
|
+
self.binds
|
248
316
|
.iter()
|
249
317
|
.cloned()
|
250
318
|
.map(|bind| {
|
251
319
|
if let Some(fd) = bind_to_fd_map.get(&bind.listener_address_string()) {
|
252
|
-
Listener::inherit_fd(bind, *fd, &socket_opts)
|
320
|
+
Listener::inherit_fd(bind, *fd, &self.socket_opts)
|
253
321
|
} else {
|
254
|
-
Listener::build(bind, &socket_opts)
|
322
|
+
Listener::build(bind, &self.socket_opts)
|
255
323
|
}
|
256
324
|
})
|
257
325
|
.collect::<std::result::Result<Vec<Listener>, _>>()?
|
258
326
|
.into_iter()
|
259
327
|
.collect::<Vec<_>>()
|
260
328
|
} else {
|
261
|
-
binds
|
329
|
+
self.binds
|
262
330
|
.iter()
|
263
331
|
.cloned()
|
264
|
-
.map(|b| Listener::build(b, &socket_opts))
|
332
|
+
.map(|b| Listener::build(b, &self.socket_opts))
|
265
333
|
.collect::<std::result::Result<Vec<Listener>, _>>()?
|
266
334
|
.into_iter()
|
267
335
|
.collect::<Vec<_>>()
|
@@ -276,29 +344,9 @@ impl ServerParams {
|
|
276
344
|
})
|
277
345
|
.collect::<Result<HashMap<String, i32>>>()?;
|
278
346
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
silence,
|
283
|
-
multithreaded_reactor,
|
284
|
-
pin_worker_cores,
|
285
|
-
shutdown_timeout,
|
286
|
-
hooks,
|
287
|
-
preload,
|
288
|
-
request_timeout,
|
289
|
-
header_read_timeout,
|
290
|
-
notify_watchers,
|
291
|
-
threads,
|
292
|
-
scheduler_threads,
|
293
|
-
streamable_body,
|
294
|
-
scheduler_class,
|
295
|
-
oob_gc_responses_threshold,
|
296
|
-
binds,
|
297
|
-
listener_info: Mutex::new(listener_info),
|
298
|
-
listeners: Mutex::new(listeners),
|
299
|
-
middleware_loader: middleware_loader.into(),
|
300
|
-
middleware: OnceLock::new(),
|
301
|
-
})
|
347
|
+
*self.listener_info.lock() = listener_info;
|
348
|
+
*self.listeners.lock() = listeners;
|
349
|
+
Ok(())
|
302
350
|
}
|
303
351
|
}
|
304
352
|
|
@@ -310,28 +358,34 @@ impl ItsiServerConfig {
|
|
310
358
|
itsi_config_proc: Option<Proc>,
|
311
359
|
) -> Result<Self> {
|
312
360
|
let itsi_config_proc = Arc::new(itsi_config_proc.map(HeapValue::from));
|
313
|
-
|
361
|
+
match Self::combine_params(
|
314
362
|
ruby,
|
315
363
|
cli_params,
|
316
364
|
itsifile_path.as_ref(),
|
317
365
|
itsi_config_proc.clone(),
|
318
|
-
)
|
319
|
-
|
320
|
-
|
366
|
+
) {
|
367
|
+
Ok(server_params) => {
|
368
|
+
cli_params.delete::<_, Value>(Symbol::new("listeners"))?;
|
321
369
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
370
|
+
let watcher_fd = if let Some(watchers) = server_params.notify_watchers.clone() {
|
371
|
+
file_watcher::watch_groups(watchers)?
|
372
|
+
} else {
|
373
|
+
None
|
374
|
+
};
|
375
|
+
|
376
|
+
Ok(ItsiServerConfig {
|
377
|
+
cli_params: Arc::new(cli_params.into()),
|
378
|
+
server_params: RwLock::new(server_params.clone()).into(),
|
379
|
+
itsi_config_proc,
|
380
|
+
itsifile_path,
|
381
|
+
watcher_fd: watcher_fd.into(),
|
382
|
+
})
|
383
|
+
}
|
384
|
+
Err(err) => Err(magnus::Error::new(
|
385
|
+
magnus::exception::standard_error(),
|
386
|
+
format!("Error loading initial configuration {:?}", err),
|
387
|
+
)),
|
388
|
+
}
|
335
389
|
}
|
336
390
|
|
337
391
|
/// Reload
|
@@ -397,7 +451,7 @@ impl ItsiServerConfig {
|
|
397
451
|
Ok(())
|
398
452
|
}
|
399
453
|
|
400
|
-
pub fn get_config_errors(&self) -> Option<Vec<String>> {
|
454
|
+
pub async fn get_config_errors(&self) -> Option<Vec<String>> {
|
401
455
|
let rb_param_hash = call_with_gvl(|ruby| {
|
402
456
|
let inner = self
|
403
457
|
.itsi_config_proc
|
@@ -424,8 +478,13 @@ impl ItsiServerConfig {
|
|
424
478
|
let err_val = call_with_gvl(|_| format!("{}", err));
|
425
479
|
return Some(vec![err_val]);
|
426
480
|
}
|
427
|
-
|
428
|
-
|
481
|
+
|
482
|
+
if let Err(err) = params_arc
|
483
|
+
.middleware
|
484
|
+
.get()
|
485
|
+
.unwrap()
|
486
|
+
.initialize_layers()
|
487
|
+
.await
|
429
488
|
{
|
430
489
|
let err_val = call_with_gvl(|_| format!("{}", err));
|
431
490
|
return Some(vec![err_val]);
|
@@ -477,8 +536,8 @@ impl ItsiServerConfig {
|
|
477
536
|
}
|
478
537
|
}
|
479
538
|
|
480
|
-
pub fn check_config(&self) -> bool {
|
481
|
-
if let Some(errors) = self.get_config_errors() {
|
539
|
+
pub async fn check_config(&self) -> bool {
|
540
|
+
if let Some(errors) = self.get_config_errors().await {
|
482
541
|
Self::print_config_errors(errors);
|
483
542
|
return false;
|
484
543
|
}
|
@@ -42,6 +42,7 @@ impl ItsiServer {
|
|
42
42
|
|
43
43
|
#[instrument(skip(self))]
|
44
44
|
pub fn start(&self) -> Result<()> {
|
45
|
+
self.config.lock().server_params.read().setup_listeners()?;
|
45
46
|
let result = if self.config.lock().server_params.read().silence {
|
46
47
|
run_silently(|| self.build_and_run_strategy())
|
47
48
|
} else {
|
@@ -49,6 +50,7 @@ impl ItsiServer {
|
|
49
50
|
self.build_and_run_strategy()
|
50
51
|
};
|
51
52
|
if let Err(e) = result {
|
53
|
+
error!("Error starting server: {:?}", e);
|
52
54
|
if let Some(err_value) = e.value() {
|
53
55
|
print_rb_backtrace(err_value);
|
54
56
|
}
|
@@ -10,6 +10,7 @@ use std::{
|
|
10
10
|
path::PathBuf,
|
11
11
|
str::FromStr,
|
12
12
|
};
|
13
|
+
use tracing::{instrument, Level};
|
13
14
|
|
14
15
|
#[derive(Debug, Clone)]
|
15
16
|
pub enum BindAddress {
|
@@ -86,6 +87,7 @@ impl std::fmt::Debug for Bind {
|
|
86
87
|
impl FromStr for Bind {
|
87
88
|
type Err = ItsiError;
|
88
89
|
|
90
|
+
#[instrument(ret(level = Level::DEBUG))]
|
89
91
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
90
92
|
let (protocol, remainder) = if let Some((proto, rest)) = s.split_once("://") {
|
91
93
|
(proto.parse::<BindProtocol>()?, rest)
|
@@ -180,6 +182,7 @@ fn parse_bind_options(query: &str) -> HashMap<String, String> {
|
|
180
182
|
}
|
181
183
|
|
182
184
|
/// Attempts to resolve a hostname into an IP address.
|
185
|
+
#[instrument(ret(level = Level::DEBUG))]
|
183
186
|
fn resolve_hostname(hostname: &str) -> Option<IpAddr> {
|
184
187
|
(hostname, 0)
|
185
188
|
.to_socket_addrs()
|
@@ -418,8 +418,12 @@ fn connect_tcp_socket(addr: IpAddr, port: u16, socket_opts: &SocketOpts) -> Resu
|
|
418
418
|
.set_recv_buffer_size(socket_opts.recv_buffer_size)
|
419
419
|
.ok();
|
420
420
|
socket.set_only_v6(false).ok();
|
421
|
-
socket.bind(&socket_address.into())
|
422
|
-
|
421
|
+
if let Err(e) = socket.bind(&socket_address.into()) {
|
422
|
+
error!("Failed to bind socket: {}", e);
|
423
|
+
};
|
424
|
+
if let Err(e) = socket.listen(socket_opts.listen_backlog as i32) {
|
425
|
+
error!("Failed to listen on socket: {}", e);
|
426
|
+
};
|
423
427
|
Ok(socket.into())
|
424
428
|
}
|
425
429
|
|
@@ -430,8 +434,11 @@ fn connect_unix_socket(path: &PathBuf, socket_opts: &SocketOpts) -> Result<UnixL
|
|
430
434
|
|
431
435
|
let socket_address = socket2::SockAddr::unix(path)?;
|
432
436
|
|
433
|
-
socket.bind(&socket_address)
|
434
|
-
|
435
|
-
|
437
|
+
if let Err(e) = socket.bind(&socket_address) {
|
438
|
+
error!("Failed to bind socket: {}", e);
|
439
|
+
};
|
440
|
+
if let Err(e) = socket.listen(socket_opts.listen_backlog as i32) {
|
441
|
+
error!("Failed to listen on socket: {}", e);
|
442
|
+
};
|
436
443
|
Ok(socket.into())
|
437
444
|
}
|
@@ -3,8 +3,10 @@ use itsi_acme::{AcmeAcceptor, AcmeConfig, AcmeState};
|
|
3
3
|
use itsi_error::Result;
|
4
4
|
use itsi_tracing::info;
|
5
5
|
use locked_dir_cache::LockedDirCache;
|
6
|
+
use rcgen::ExtendedKeyUsagePurpose;
|
6
7
|
use rcgen::{
|
7
|
-
BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair,
|
8
|
+
BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair, KeyUsagePurpose,
|
9
|
+
SanType,
|
8
10
|
};
|
9
11
|
use rustls::{
|
10
12
|
pki_types::{CertificateDer, PrivateKeyDer},
|
@@ -228,13 +230,14 @@ pub fn generate_ca_signed_cert(
|
|
228
230
|
.push(DnType::CommonName, domains[0].clone());
|
229
231
|
|
230
232
|
ee_params.use_authority_key_identifier_extension = true;
|
233
|
+
ee_params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth];
|
231
234
|
|
232
235
|
let ee_cert = ee_params.signed_by(&ee_key, &ca_cert, &ca_kp).unwrap();
|
233
236
|
let ee_cert_der = ee_cert.der().to_vec();
|
234
237
|
let ee_cert = CertificateDer::from(ee_cert_der);
|
235
|
-
|
238
|
+
|
236
239
|
Ok((
|
237
|
-
vec![ee_cert
|
240
|
+
vec![ee_cert],
|
238
241
|
PrivateKeyDer::try_from(ee_key.serialize_der()).unwrap(),
|
239
242
|
))
|
240
243
|
}
|
@@ -253,12 +256,17 @@ fn get_or_create_local_dev_ca() -> Result<(String, String)> {
|
|
253
256
|
|
254
257
|
Ok((key_pem, cert_pem))
|
255
258
|
} else {
|
256
|
-
let subject_alt_names = vec!["
|
259
|
+
let subject_alt_names = vec!["ca.itsi.fyi".to_string(), "localhost".to_string()];
|
257
260
|
let mut params = CertificateParams::new(subject_alt_names)?;
|
258
261
|
let mut distinguished_name = DistinguishedName::new();
|
259
|
-
distinguished_name.push(DnType::CommonName, "
|
262
|
+
distinguished_name.push(DnType::CommonName, "ca.itsi.fyi");
|
260
263
|
params.distinguished_name = distinguished_name;
|
261
264
|
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
|
265
|
+
params.key_usages = vec![
|
266
|
+
KeyUsagePurpose::KeyCertSign,
|
267
|
+
KeyUsagePurpose::CrlSign,
|
268
|
+
KeyUsagePurpose::DigitalSignature, // useful for OCSP/CRL signing
|
269
|
+
];
|
262
270
|
let key_pair = KeyPair::generate()?;
|
263
271
|
let cert = params.self_signed(&key_pair)?;
|
264
272
|
|
@@ -1,23 +1,23 @@
|
|
1
|
+
use super::{token_source::TokenSource, ErrorResponse, FromValue, MiddlewareLayer};
|
1
2
|
use crate::{
|
2
3
|
server::http_message_types::{HttpRequest, HttpResponse, RequestExt},
|
3
4
|
services::itsi_http_service::HttpRequestContext,
|
4
5
|
};
|
5
|
-
|
6
|
-
use super::{ErrorResponse, FromValue, MiddlewareLayer};
|
7
|
-
|
8
6
|
use async_trait::async_trait;
|
9
7
|
use either::Either;
|
10
8
|
use itsi_error::ItsiError;
|
11
9
|
use magnus::error::Result;
|
12
10
|
use regex::RegexSet;
|
13
11
|
use serde::Deserialize;
|
14
|
-
use std::sync::OnceLock;
|
12
|
+
use std::{collections::HashMap, sync::OnceLock};
|
13
|
+
use tracing::debug;
|
15
14
|
|
16
15
|
#[derive(Debug, Clone, Deserialize)]
|
17
16
|
pub struct AllowList {
|
18
17
|
#[serde(skip_deserializing)]
|
19
18
|
pub allowed_ips: OnceLock<RegexSet>,
|
20
19
|
pub allowed_patterns: Vec<String>,
|
20
|
+
pub trusted_proxies: HashMap<String, TokenSource>,
|
21
21
|
#[serde(default = "forbidden_error_response")]
|
22
22
|
pub error_response: ErrorResponse,
|
23
23
|
}
|
@@ -42,7 +42,14 @@ impl MiddlewareLayer for AllowList {
|
|
42
42
|
context: &mut HttpRequestContext,
|
43
43
|
) -> Result<Either<HttpRequest, HttpResponse>> {
|
44
44
|
if let Some(allowed_ips) = self.allowed_ips.get() {
|
45
|
-
if
|
45
|
+
let addr = if self.trusted_proxies.contains_key(&context.addr) {
|
46
|
+
let source = self.trusted_proxies.get(&context.addr).unwrap();
|
47
|
+
source.extract_token(&req).unwrap_or(&context.addr)
|
48
|
+
} else {
|
49
|
+
&context.addr
|
50
|
+
};
|
51
|
+
if !allowed_ips.is_match(addr) {
|
52
|
+
debug!(target: "middleware::allow_list", "IP address {} is not allowed", addr);
|
46
53
|
return Ok(Either::Right(
|
47
54
|
self.error_response
|
48
55
|
.to_http_response(req.accept().into())
|
@@ -11,6 +11,7 @@ use async_trait::async_trait;
|
|
11
11
|
use either::Either;
|
12
12
|
use magnus::error::Result;
|
13
13
|
use serde::Deserialize;
|
14
|
+
use tracing::debug;
|
14
15
|
|
15
16
|
type PasswordHash = String;
|
16
17
|
|
@@ -51,6 +52,8 @@ impl MiddlewareLayer for AuthAPIKey {
|
|
51
52
|
}
|
52
53
|
TokenSource::Query(query_name) => req.query_param(query_name),
|
53
54
|
} {
|
55
|
+
debug!(target: "middleware::auth_api_key", "API Key Retrieved. Anonymous {}", self.key_id_source.is_none());
|
56
|
+
|
54
57
|
if let Some(key_id) = self.key_id_source.as_ref() {
|
55
58
|
let key_id = match &key_id {
|
56
59
|
TokenSource::Header { name, prefix } => {
|
@@ -66,17 +69,21 @@ impl MiddlewareLayer for AuthAPIKey {
|
|
66
69
|
}
|
67
70
|
TokenSource::Query(query_name) => req.query_param(query_name),
|
68
71
|
};
|
72
|
+
debug!(target: "middleware::auth_api_key", "Key ID Retrieved");
|
69
73
|
if let Some(hash) = key_id.and_then(|kid| self.valid_keys.get(kid)) {
|
74
|
+
debug!(target: "middleware::auth_api_key", "Key for ID found");
|
70
75
|
if password_hasher::verify_password_hash(submitted_key, hash).is_ok_and(|v| v) {
|
71
76
|
return Ok(Either::Left(req));
|
72
77
|
}
|
73
78
|
}
|
74
|
-
} else if self.valid_keys.
|
79
|
+
} else if self.valid_keys.values().any(|key| {
|
75
80
|
password_hasher::verify_password_hash(submitted_key, key).is_ok_and(|v| v)
|
76
81
|
}) {
|
77
82
|
return Ok(Either::Left(req));
|
78
83
|
}
|
79
84
|
}
|
85
|
+
|
86
|
+
debug!(target: "middleware::auth_api_key", "Failed to authenticate API key");
|
80
87
|
Ok(Either::Right(
|
81
88
|
self.error_response
|
82
89
|
.to_http_response(req.accept().into())
|
@@ -8,6 +8,7 @@ use magnus::error::Result;
|
|
8
8
|
use serde::{Deserialize, Serialize};
|
9
9
|
use std::collections::HashMap;
|
10
10
|
use std::str;
|
11
|
+
use tracing::debug;
|
11
12
|
|
12
13
|
use crate::{
|
13
14
|
server::http_message_types::{HttpRequest, HttpResponse, RequestExt},
|
@@ -48,6 +49,7 @@ impl MiddlewareLayer for AuthBasic {
|
|
48
49
|
let auth_header = req.header("Authorization");
|
49
50
|
|
50
51
|
if !auth_header.is_some_and(|header| header.starts_with("Basic ")) {
|
52
|
+
debug!(target: "middleware::auth_basic", "Basic auth failed. Authorization Header doesn't start with 'Basic '");
|
51
53
|
return Ok(Either::Right(self.basic_auth_failed_response()));
|
52
54
|
}
|
53
55
|
|
@@ -57,6 +59,7 @@ impl MiddlewareLayer for AuthBasic {
|
|
57
59
|
let decoded = match general_purpose::STANDARD.decode(encoded_credentials) {
|
58
60
|
Ok(bytes) => bytes,
|
59
61
|
Err(_) => {
|
62
|
+
debug!(target: "middleware::auth_basic", "Basic auth failed. Decoding failed");
|
60
63
|
return Ok(Either::Right(self.basic_auth_failed_response()));
|
61
64
|
}
|
62
65
|
};
|
@@ -64,6 +67,7 @@ impl MiddlewareLayer for AuthBasic {
|
|
64
67
|
let decoded_str = match str::from_utf8(&decoded) {
|
65
68
|
Ok(s) => s,
|
66
69
|
Err(_) => {
|
70
|
+
debug!(target: "middleware::auth_basic", "Basic auth failed. Decoding failed");
|
67
71
|
return Ok(Either::Right(self.basic_auth_failed_response()));
|
68
72
|
}
|
69
73
|
};
|
@@ -71,6 +75,7 @@ impl MiddlewareLayer for AuthBasic {
|
|
71
75
|
let mut parts = decoded_str.splitn(2, ':');
|
72
76
|
let username = parts.next().unwrap_or("");
|
73
77
|
let password = parts.next().unwrap_or("");
|
78
|
+
|
74
79
|
match self.credential_pairs.get(username) {
|
75
80
|
Some(expected_password_hash) => {
|
76
81
|
match verify_password_hash(password, expected_password_hash) {
|
@@ -78,7 +83,10 @@ impl MiddlewareLayer for AuthBasic {
|
|
78
83
|
_ => Ok(Either::Right(self.basic_auth_failed_response())),
|
79
84
|
}
|
80
85
|
}
|
81
|
-
None =>
|
86
|
+
None => {
|
87
|
+
debug!(target: "middleware::auth_basic", "Basic auth failed. Username {} not found", username);
|
88
|
+
Ok(Either::Right(self.basic_auth_failed_response()))
|
89
|
+
}
|
82
90
|
}
|
83
91
|
}
|
84
92
|
}
|