OWASP / OWASP/SecurityShepherd

Convert ResultSet-returning Getter methods to bounded collections (DAO refactor follow-up)

Open
#839 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.5k
Forks
515
Avg merge
3h 46m
Merged PRs (30d)
1

Description

Context

Three Getter methods return ResultSet-typed objects to callers:

  • Getter.getClassInfo(String) — all classes
  • Getter.getPlayersByClass(String, String) — players in a class
  • Getter.getAdmins(String) — all admins

These were fixed in #838 to release pooled DB connections immediately by materializing into a javax.sql.rowset.CachedRowSet. That closes the connection-pool leak but inherits one limitation of the previous API: the entire result set is held in memory at materialization time.

A protective setMaxRows(10000) cap was added in #838 as a stopgap — well above realistic Security Shepherd workloads (class rosters of tens to a few hundred students) but enough to prevent a runaway query from OOMing the JVM. That's a guardrail, not a fix.

Proposal

Replace the ResultSet-typed API with proper Java collections / DTOs:

Method Proposed return
getClassInfo(String) List<ClassInfo> (or ClassInfo[])
getPlayersByClass(String, String) List<PlayerSummary>
getAdmins(String) List<AdminSummary>

Benefits:

  • Type-safe — no getString(1)/getString(2) magic-index access at call sites.
  • No risk of leaking ResultSet semantics to the caller (cursor position, scrollability, etc.).
  • Easier to unit test with mock data.
  • Enables proper pagination when one of these methods grows past its current bounded use case.

Out of scope (for now)

  • Pagination. Realistic class sizes don't require it. If a deployment ever hits the setMaxRows cap, that's the trigger to design a proper paginated API.
  • Stored-procedure changes. The procs (classesGetData, playersByClass, playersWithoutClass, adminGetAll) work fine; this is purely a Java-side API change.

Relationship to #815

This is one concrete chunk of the broader DAO refactor proposed in #815. Could be done as part of that effort, or as a standalone first step if #815 stays parked.

Acceptance criteria

  • Three methods return List<DTO> instead of ResultSet.
  • DTO classes (or records, once a min-JDK bump allows) live alongside Getter or in a dbProcs.dto package.
  • Callers updated to iterate the lists directly (no while (next()) / getString(...) patterns).
  • setMaxRows(10000) from #838 can be reconsidered — likely keep as a safety net, but the value can be revisited once the API uses bounded collections.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Getter class and its getClassInfo, getPlayersByClass, and getAdmins methods, then trace their callers for ResultSet iteration and indexed access. Review the CachedRowSet and setMaxRows(10000) changes from #838 before defining the DTOs. Done means all three methods return typed lists, callers iterate those lists, and the existing stored procedures remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
database
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.