From cbf5c2c772b8a45b14b6382d44d3935050651c6e Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Mon, 4 Aug 2025 17:30:35 +0000 Subject: [PATCH] fix(lib): make tests pass Signed-off-by: Xe Iaso --- lib/anubis.go | 4 ++- lib/anubis_test.go | 27 ++++++++++++++- lib/policy/config/config.go | 4 +-- lib/testdata/test_config.yaml | 9 ++++- lib/testdata/test_config_no_thresholds.yaml | 38 +++++++++++++++++++++ 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 lib/testdata/test_config_no_thresholds.yaml diff --git a/lib/anubis.go b/lib/anubis.go index 9321f2b7..d23df3f2 100644 --- a/lib/anubis.go +++ b/lib/anubis.go @@ -369,9 +369,11 @@ func (s *Server) MakeChallenge(w http.ResponseWriter, r *http.Request) { err = encoder.Encode(struct { Rules *config.ChallengeRules `json:"rules"` Challenge string `json:"challenge"` + ID string `json:"id"` }{ - Challenge: chall.RandomData, Rules: rule.Challenge, + Challenge: chall.RandomData, + ID: chall.ID, }) if err != nil { lg.Error("failed to encode challenge", "err", err) diff --git a/lib/anubis_test.go b/lib/anubis_test.go index e9c9effc..6978c650 100644 --- a/lib/anubis_test.go +++ b/lib/anubis_test.go @@ -35,6 +35,8 @@ func loadPolicies(t *testing.T, fname string, difficulty int) *policy.ParsedConf fname = "./testdata/test_config.yaml" } + t.Logf("loading policy file: %s", fname) + anubisPolicy, err := LoadPoliciesOrDefault(ctx, fname, difficulty) if err != nil { t.Fatal(err) @@ -59,6 +61,7 @@ func spawnAnubis(t *testing.T, opts Options) *Server { } type challengeResp struct { + ID string `json:"id"` Challenge string `json:"challenge"` } @@ -91,6 +94,8 @@ func makeChallenge(t *testing.T, ts *httptest.Server, cli *http.Client) challeng func handleChallengeZeroDifficulty(t *testing.T, ts *httptest.Server, cli *http.Client, chall challengeResp) *http.Response { t.Helper() + t.Logf("%#v", chall) + nonce := 0 elapsedTime := 420 redir := "/" @@ -108,8 +113,11 @@ func handleChallengeZeroDifficulty(t *testing.T, ts *httptest.Server, cli *http. q.Set("nonce", fmt.Sprint(nonce)) q.Set("redir", redir) q.Set("elapsedTime", fmt.Sprint(elapsedTime)) + q.Set("id", chall.ID) req.URL.RawQuery = q.Encode() + t.Log(q.Encode()) + resp, err := cli.Do(req) if err != nil { t.Fatalf("can't do request: %v", err) @@ -155,6 +163,17 @@ func (lcj *loggingCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) { lcj.cookies[u.Host] = append(lcj.cookies[u.Host], cookies...) } +type userAgentRoundTripper struct { + rt http.RoundTripper +} + +func (u *userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + // Only set if not already present + req = req.Clone(req.Context()) // avoid mutating original request + req.Header.Set("User-Agent", "Mozilla/5.0") + return u.rt.RoundTrip(req) +} + func httpClient(t *testing.T) *http.Client { t.Helper() @@ -163,6 +182,9 @@ func httpClient(t *testing.T) *http.Client { CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, + Transport: &userAgentRoundTripper{ + rt: http.DefaultTransport, + }, } return cli @@ -325,7 +347,7 @@ func TestCheckDefaultDifficultyMatchesPolicy(t *testing.T) { for i := 1; i < 10; i++ { t.Run(fmt.Sprint(i), func(t *testing.T) { - anubisPolicy := loadPolicies(t, "", i) + anubisPolicy := loadPolicies(t, "testdata/test_config_no_thresholds.yaml", i) s, err := New(Options{ Next: h, @@ -476,8 +498,11 @@ func TestBasePrefix(t *testing.T) { q.Set("nonce", fmt.Sprint(nonce)) q.Set("redir", redir) q.Set("elapsedTime", fmt.Sprint(elapsedTime)) + q.Set("id", chall.ID) req.URL.RawQuery = q.Encode() + t.Log(req.URL.String()) + resp, err = cli.Do(req) if err != nil { t.Fatalf("can't do challenge passing: %v", err) diff --git a/lib/policy/config/config.go b/lib/policy/config/config.go index 20979e4a..6b5946ae 100644 --- a/lib/policy/config/config.go +++ b/lib/policy/config/config.go @@ -194,7 +194,7 @@ type ChallengeRules struct { } var ( - ErrChallengeDifficultyTooLow = errors.New("config.ChallengeRules: difficulty is too low (must be >= 1)") + ErrChallengeDifficultyTooLow = errors.New("config.ChallengeRules: difficulty is too low (must be >= 0)") ErrChallengeDifficultyTooHigh = errors.New("config.ChallengeRules: difficulty is too high (must be <= 64)") ErrChallengeMustHaveAlgorithm = errors.New("config.ChallengeRules: must have algorithm name set") ) @@ -206,7 +206,7 @@ func (cr ChallengeRules) Valid() error { errs = append(errs, ErrChallengeMustHaveAlgorithm) } - if cr.Difficulty < 1 { + if cr.Difficulty < 0 { errs = append(errs, fmt.Errorf("%w, got: %d", ErrChallengeDifficultyTooLow, cr.Difficulty)) } diff --git a/lib/testdata/test_config.yaml b/lib/testdata/test_config.yaml index 11f7cb4a..9047dcbf 100644 --- a/lib/testdata/test_config.yaml +++ b/lib/testdata/test_config.yaml @@ -35,4 +35,11 @@ status_codes: CHALLENGE: 200 DENY: 200 -thresholds: [] +thresholds: + - name: minimal-suspicion + expression: "true" + action: CHALLENGE + challenge: + algorithm: fast + difficulty: 1 + report_as: 1 diff --git a/lib/testdata/test_config_no_thresholds.yaml b/lib/testdata/test_config_no_thresholds.yaml new file mode 100644 index 00000000..11f7cb4a --- /dev/null +++ b/lib/testdata/test_config_no_thresholds.yaml @@ -0,0 +1,38 @@ +bots: + - import: (data)/bots/_deny-pathological.yaml + - import: (data)/bots/aggressive-brazilian-scrapers.yaml + - import: (data)/meta/ai-block-aggressive.yaml + - import: (data)/crawlers/_allow-good.yaml + - import: (data)/clients/x-firefox-ai.yaml + - import: (data)/common/keep-internet-working.yaml + - name: countries-with-aggressive-scrapers + action: WEIGH + geoip: + countries: + - BR + - CN + weight: + adjust: 10 + - name: aggressive-asns-without-functional-abuse-contact + action: WEIGH + asns: + match: + - 13335 # Cloudflare + - 136907 # Huawei Cloud + - 45102 # Alibaba Cloud + weight: + adjust: 10 + - name: generic-browser + user_agent_regex: >- + Mozilla|Opera + action: WEIGH + weight: + adjust: 10 + +dnsbl: false + +status_codes: + CHALLENGE: 200 + DENY: 200 + +thresholds: []