Add local auth debug checkpoints

This commit is contained in:
Daniel Schädler 2026-04-14 15:32:45 +02:00
parent eff641da22
commit 1161a5da16
2 changed files with 280 additions and 3 deletions

View File

@ -21,6 +21,7 @@ module TurniereE2E
def initialize(base_url:) def initialize(base_url:)
@base_url = base_url.sub(%r{/\z}, '') @base_url = base_url.sub(%r{/\z}, '')
@auth_headers = {} @auth_headers = {}
@login_credentials = nil
end end
def register!(email:, password:, username:) def register!(email:, password:, username:)
@ -39,6 +40,8 @@ module TurniereE2E
end end
def login!(email:, password:) def login!(email:, password:)
@login_credentials = { email: email, password: password }
@auth_headers = {}
response = request( response = request(
:post, :post,
'/users/sign_in', '/users/sign_in',
@ -73,7 +76,9 @@ module TurniereE2E
private private
def request(method, path, body: nil, params: nil, headers: {}) def request(method, path, body: nil, params: nil, headers: {}, retry_on_unauthorized: true, refresh_session: true)
login!(**@login_credentials) if refresh_session && should_refresh_session?(method, path)
uri = URI.parse("#{base_url}#{path}") uri = URI.parse("#{base_url}#{path}")
uri.query = URI.encode_www_form(params) if params && !params.empty? uri.query = URI.encode_www_form(params) if params && !params.empty?
@ -101,6 +106,10 @@ module TurniereE2E
headers: response.each_header.to_h headers: response.each_header.to_h
} }
store_auth_headers!(result) store_auth_headers!(result)
if retry_on_unauthorized && result[:status] == 401 && can_reauthenticate?(path)
login!(**@login_credentials)
return request(method, path, body: body, params: params, headers: headers, retry_on_unauthorized: false, refresh_session: false)
end
result result
end end
@ -121,10 +130,19 @@ module TurniereE2E
def store_auth_headers!(response) def store_auth_headers!(response)
%w[access-token client uid expiry token-type authorization].each_with_object({}) do |key, auth_headers| %w[access-token client uid expiry token-type authorization].each_with_object({}) do |key, auth_headers|
auth_headers[key] = response[:headers][key] if response[:headers].key?(key) value = response[:headers][key]
auth_headers[key] = value if response[:headers].key?(key) && !value.to_s.empty?
end.tap do |headers| end.tap do |headers|
@auth_headers = headers unless headers.empty? @auth_headers = @auth_headers.merge(headers) unless headers.empty?
end end
end
def can_reauthenticate?(path)
!@login_credentials.nil? && path != '/users/sign_in'
end
def should_refresh_session?(method, path)
!@login_credentials.nil? && method != :get && path != '/users/sign_in'
end end
end end
end end

259
tasks.py
View File

@ -1006,6 +1006,265 @@ def docker_blackbox_follow_bootstrap_users(
) )
@task(name="docker-blackbox-follow-debug-auth")
def docker_blackbox_follow_debug_auth(
c,
source_host_port=BLACKBOX_SOURCE_HOST_PORT,
follower_host_port=BLACKBOX_FOLLOWER_HOST_PORT,
app_image=PRODUCTION_TAG,
runner_image=TEST_TAG,
postgres_image=BLACKBOX_POSTGRES_IMAGE,
):
"""Debug source/follower login and first authenticated create inside local follower blackbox runner."""
env = _follow_compose_env(
source_host_port=source_host_port,
follower_host_port=follower_host_port,
app_image=app_image,
runner_image=runner_image,
postgres_image=postgres_image,
)
script = """
require_relative 'e2e/lib/api_client'
def inspect_client(base_url)
client = TurniereE2E::ApiClient.new(base_url: base_url)
login = client.login!(email: ENV.fetch('TURNIERE_E2E_EMAIL'), password: ENV.fetch('TURNIERE_E2E_PASSWORD'))
puts({ base_url: base_url, login_status: login[:status], login_headers: login[:headers].slice('access-token', 'client', 'uid', 'expiry', 'token-type', 'authorization'), authenticated: client.authenticated? }.inspect)
create = client.post('/tournaments', body: {
name: "Debug #{base_url}",
description: 'Debug tournament',
public: false,
teams: [
{ name: 'One' },
{ name: 'Two' },
{ name: 'Three' },
{ name: 'Four' }
]
})
puts({ base_url: base_url, create_status: create[:status], create_json: create[:json], create_headers: create[:headers].slice('access-token', 'client', 'uid', 'expiry', 'token-type', 'authorization') }.inspect)
end
inspect_client(ENV.fetch('TURNIERE_SOURCE_E2E_BASE_URL'))
inspect_client(ENV.fetch('TURNIERE_FOLLOWER_E2E_BASE_URL'))
"""
command = [
"run",
"--rm",
"e2e",
"ruby",
"-e",
script,
]
print(_format_command(_docker_compose_cmd(project_name=BLACKBOX_FOLLOW_PROJECT, compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE) + command))
result = _compose_run(
command,
env=env,
capture_output=True,
check=False,
project_name=BLACKBOX_FOLLOW_PROJECT,
compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE,
)
if result.stdout:
print(result.stdout.rstrip())
if result.stderr:
print(result.stderr.rstrip())
if result.returncode != 0:
raise subprocess.CalledProcessError(
result.returncode,
result.args,
output=result.stdout,
stderr=result.stderr,
)
@task(name="docker-blackbox-follow-debug-seed")
def docker_blackbox_follow_debug_seed(
c,
source_host_port=BLACKBOX_SOURCE_HOST_PORT,
follower_host_port=BLACKBOX_FOLLOWER_HOST_PORT,
app_image=PRODUCTION_TAG,
runner_image=TEST_TAG,
postgres_image=BLACKBOX_POSTGRES_IMAGE,
):
"""Debug repeated mixed tournament creation inside local follower blackbox runner."""
env = _follow_compose_env(
source_host_port=source_host_port,
follower_host_port=follower_host_port,
app_image=app_image,
runner_image=runner_image,
postgres_image=postgres_image,
)
script = """
require_relative 'e2e/lib/api_client'
def create_playoff_payload(name)
{
name: name,
description: 'Debug playoff tournament',
public: false,
teams: [
{ name: 'One' },
{ name: 'Two' },
{ name: 'Three' },
{ name: 'Four' }
]
}
end
def create_group_payload(name)
{
name: name,
description: 'Debug group tournament',
public: true,
group_stage: true,
playoff_teams_amount: 8,
teams: 4.times.flat_map do |group_index|
4.times.map do |seed_index|
{ name: "#{name}-G#{group_index + 1}-S#{seed_index + 1}", group: group_index }
end
end
}
end
def inspect_seed(base_url)
client = TurniereE2E::ApiClient.new(base_url: base_url)
login = client.login!(email: ENV.fetch('TURNIERE_E2E_EMAIL'), password: ENV.fetch('TURNIERE_E2E_PASSWORD'))
puts({ base_url: base_url, login_status: login[:status], authenticated: client.authenticated? }.inspect)
[
['playoff-1', create_playoff_payload('Debug Playoff 1')],
['group-1', create_group_payload('Debug Group 1')],
['playoff-2', create_playoff_payload('Debug Playoff 2')],
['group-2', create_group_payload('Debug Group 2')]
].each do |label, payload|
response = client.post('/tournaments', body: payload)
puts({
base_url: base_url,
step: label,
status: response[:status],
json: response[:json],
headers: response[:headers].slice('access-token', 'client', 'uid', 'expiry', 'token-type', 'authorization'),
authenticated: client.authenticated?
}.inspect)
end
end
inspect_seed(ENV.fetch('TURNIERE_SOURCE_E2E_BASE_URL'))
inspect_seed(ENV.fetch('TURNIERE_FOLLOWER_E2E_BASE_URL'))
"""
command = [
"run",
"--rm",
"e2e",
"ruby",
"-e",
script,
]
print(_format_command(_docker_compose_cmd(project_name=BLACKBOX_FOLLOW_PROJECT, compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE) + command))
result = _compose_run(
command,
env=env,
capture_output=True,
check=False,
project_name=BLACKBOX_FOLLOW_PROJECT,
compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE,
)
if result.stdout:
print(result.stdout.rstrip())
if result.stderr:
print(result.stderr.rstrip())
if result.returncode != 0:
raise subprocess.CalledProcessError(
result.returncode,
result.args,
output=result.stdout,
stderr=result.stderr,
)
@task(name="docker-blackbox-follow-debug-group-create")
def docker_blackbox_follow_debug_group_create(
c,
source_host_port=BLACKBOX_SOURCE_HOST_PORT,
follower_host_port=BLACKBOX_FOLLOWER_HOST_PORT,
app_image=PRODUCTION_TAG,
runner_image=TEST_TAG,
postgres_image=BLACKBOX_POSTGRES_IMAGE,
):
"""Debug single fresh-login group-stage tournament creation inside local follower blackbox runner."""
env = _follow_compose_env(
source_host_port=source_host_port,
follower_host_port=follower_host_port,
app_image=app_image,
runner_image=runner_image,
postgres_image=postgres_image,
)
script = """
require_relative 'e2e/lib/api_client'
def create_group_payload(name)
{
name: name,
description: 'Debug group tournament',
public: true,
group_stage: true,
playoff_teams_amount: 8,
teams: 4.times.flat_map do |group_index|
4.times.map do |seed_index|
{ name: "#{name}-G#{group_index + 1}-S#{seed_index + 1}", group: group_index }
end
end
}
end
def inspect_group_create(base_url)
client = TurniereE2E::ApiClient.new(base_url: base_url)
login = client.login!(email: ENV.fetch('TURNIERE_E2E_EMAIL'), password: ENV.fetch('TURNIERE_E2E_PASSWORD'))
puts({ base_url: base_url, login_status: login[:status], authenticated: client.authenticated? }.inspect)
response = client.post('/tournaments', body: create_group_payload('Fresh Debug Group'))
puts({ base_url: base_url, create_status: response[:status], create_json: response[:json], create_headers: response[:headers].slice('access-token', 'client', 'uid', 'expiry', 'token-type', 'authorization') }.inspect)
end
inspect_group_create(ENV.fetch('TURNIERE_SOURCE_E2E_BASE_URL'))
inspect_group_create(ENV.fetch('TURNIERE_FOLLOWER_E2E_BASE_URL'))
"""
command = [
"run",
"--rm",
"e2e",
"ruby",
"-e",
script,
]
print(_format_command(_docker_compose_cmd(project_name=BLACKBOX_FOLLOW_PROJECT, compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE) + command))
result = _compose_run(
command,
env=env,
capture_output=True,
check=False,
project_name=BLACKBOX_FOLLOW_PROJECT,
compose_file=BLACKBOX_FOLLOW_COMPOSE_FILE,
)
if result.stdout:
print(result.stdout.rstrip())
if result.stderr:
print(result.stderr.rstrip())
if result.returncode != 0:
raise subprocess.CalledProcessError(
result.returncode,
result.args,
output=result.stdout,
stderr=result.stderr,
)
@task(name="docker-blackbox-follow-run") @task(name="docker-blackbox-follow-run")
def docker_blackbox_follow_run( def docker_blackbox_follow_run(
c, c,