Skip to content

716: Cache auth keys in Redis in all environments#741

Open
tahminator wants to merge 1 commit intomainfrom
716
Open

716: Cache auth keys in Redis in all environments#741
tahminator wants to merge 1 commit intomainfrom
716

Conversation

@tahminator
Copy link
Owner

@tahminator tahminator commented Feb 6, 2026

716

Description of changes

Checklist before review

  • I have done a thorough self-review of the PR
  • Copilot has reviewed my latest changes, and all comments have been fixed and/or closed.
  • If I have made database changes, I have made sure I followed all the db repo rules listed in the wiki here. (check if no db changes)
  • All tests have passed
  • I have successfully deployed this PR to staging
  • I have done manual QA in both dev (and staging if possible) and attached screenshots below.

Screenshots

Local

image image

Staging

image image

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Available PR Commands

  • /ai - Triggers all AI review commands at once
  • /review - AI review of the PR changes
  • /describe - AI-powered description of the PR
  • /improve - AI-powered suggestions
  • /deploy - Deploy to staging

See: https://github.com/tahminator/codebloom/wiki/CI-Commands

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Title

716: Catch auth keys in Redis in all environments


PR Type

Enhancement, Tests


Description

  • Use Redis auth cache in all environments

  • Fallback to Redis when DB token missing

  • Store new tokens in Redis for 4 hours

  • Non-blocking locking around cookie reload


Diagram Walkthrough

flowchart LR
  S["Scheduled auth refresh"]:::node
  DB["DB: most recent auth"]:::node
  R["Redis: auth token (4h TTL)"]:::node
  P["Playwright: steal new cookie"]:::node
  M["Update in-memory cookie/csrf"]:::node

  S -- "check token freshness" --> DB
  DB -- "fresh" --> M
  DB -- "missing/expired" --> R
  R -- "hit" --> M
  R -- "miss" --> P
  P -- "persist to DB + Redis" --> DB
  P -- "set cookie/csrf" --> M

  classDef node fill:#eef,stroke:#889;
Loading

File Walkthrough

Relevant files
Enhancement
LeetcodeAuthStealer.java
Redis-backed auth caching and concurrency tweaks                 

src/main/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealer.java

  • Check Redis for auth in all envs
  • Always cache new tokens in Redis (4h)
  • Use tryLock for reload and scheduling
  • Update logs/comments to reflect 4-hour policy
+34/-40 
Tests
LeetcodeAuthStealerTest.java
Test wiring towards Jedis client (conflict present)           

src/test/java/org/patinanetwork/codebloom/scheduled/auth/LeetcodeAuthStealerTest.java

  • Added JedisClientManager mock import/field
  • Merge conflict markers introduced in file
  • Tests wiring partially refactored toward Jedis client
+12/-0   

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Lock misuse

The code uses tryLock() without checking its return value and still proceeds to unlock in the finally block. This can throw IllegalMonitorStateException and break the scheduled job. Use lock() or guard unlock() based on the acquisition result.

LOCK.writeLock().tryLock();
try {
    Auth mostRecentAuth = authRepository.getMostRecentAuth();

    // The auth token should be refreshed every 4 hours.
    if (mostRecentAuth != null
            && mostRecentAuth
                    .getCreatedAt()
                    .isAfter(StandardizedOffsetDateTime.now().minus(4, ChronoUnit.HOURS))) {
        log.info("Auth token already exists, using token from database.");
        cookie = mostRecentAuth.getToken();
        csrf = mostRecentAuth.getCsrf();
        return;
    }

    log.info("falling back to checking redis client...");
    Optional<String> authToken = redisClient.getAuth();

    log.info("auth token in redis = {}", authToken.isPresent());

    if (authToken.isPresent()) {
        log.info("auth token found in redis client");
        cookie = authToken.get();
        csrf = null; // don't care in ci.
        return;
    }

    log.info("auth token not found in redis client");
    log.info("Auth token is missing/expired. Attempting to receive token...");

    stealCookieImpl();
} finally {
Lock misuse

reloadCookie() also calls tryLock() and unconditionally unlocks in finally. Ensure the lock is acquired before unlocking or switch to lock().

return timer().record(() -> {
    try {
        LOCK.writeLock().tryLock();
        return CompletableFuture.completedFuture(Optional.ofNullable(stealCookieImpl()));
    } finally {
        LOCK.writeLock().unlock();
    }
});
AC mismatch

When a valid DB token is found, it returns without caching it in Redis. This may violate the AC to cache all auth keys and undermines fallback if the DB is wiped before a fresh steal. Consider setting the Redis key (with 4h TTL) when using a DB-sourced token.

if (mostRecentAuth != null
        && mostRecentAuth
                .getCreatedAt()
                .isAfter(StandardizedOffsetDateTime.now().minus(4, ChronoUnit.HOURS))) {
    log.info("Auth token already exists, using token from database.");
    cookie = mostRecentAuth.getToken();
    csrf = mostRecentAuth.getCsrf();
    return;
}

@tahminator tahminator force-pushed the 716 branch 2 times, most recently from 5eccfa5 to 1bb2298 Compare February 6, 2026 06:17
@tahminator tahminator changed the title 716: Catch auth keys in Redis in all environments 716: Cache auth keys in Redis in all environments Feb 6, 2026
@tahminator tahminator force-pushed the 716 branch 4 times, most recently from b34e488 to 581a1fd Compare February 6, 2026 14:25
@tahminator
Copy link
Owner Author

/deploy

@tahminator
Copy link
Owner Author

/deploy

1 similar comment
@tahminator
Copy link
Owner Author

/deploy

@tahminator tahminator enabled auto-merge (rebase) February 6, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant