Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 66 additions & 32 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@
#
# Each demo is an independent Gradle project (its own settings.gradle.kts and
# wrapper), so Dependabot needs to be told about each directory explicitly.
# We use `directories:` (plural) so one ecosystem entry covers them all
# with a shared group/schedule/label policy — much less duplication than
# nine near-identical entries.
# Demos are split into two gradle entries based on which starter release line
# they showcase — they get different Spring-major policies.

version: 2

updates:
# ---------------------------------------------------------------------
# Gradle: every demo + the starter ecosystems they depend on.
# Spring Boot 3 demos — pinned to the SB3 starter line.
#
# easy-paging 0.4.x and ssrf-guard 3.x are certified against
# Spring Boot 3.3-3.5. Letting Dependabot land a Spring Boot major
# (3.x → 4.x) here would silently advertise an incompatible
# combination to anyone copying one of these demos.
#
# When a given starter publishes its own SB4-compatible line (as
# easy-paging did with 0.5.x), the SB4 demos live under the second
# gradle entry below; the SB3 demos here keep getting patches on
# the 3.5.x line.
# ---------------------------------------------------------------------
- package-ecosystem: "gradle"
directories:
Expand All @@ -32,65 +41,90 @@ updates:
open-pull-requests-limit: 10
labels:
- "dependencies"
- "sb3"
commit-message:
prefix: "build(deps)"
include: "scope"
# ----------------------------------------------------------------
# Hold majors at the starter's tested baseline.
#
# The demos exist to showcase the starters at the Spring Boot
# version each starter is *certified against* (per its README).
# Letting Dependabot land a Spring Boot major (3.x → 4.x) ahead of
# the starter's own SB4 release would silently advertise
# incompatible combinations to anyone copying a demo.
#
# When a starter publishes a SB4-compatible release line (e.g.
# easy-paging 0.5.x), this ignore block gets relaxed for that
# specific starter family, and the demos are upgraded together in
# a single PR — not piecemeal by a robot.
# ----------------------------------------------------------------
ignore:
# Spring Boot + dependency-management major bumps
- dependency-name: "org.springframework.boot:*"
update-types: ["version-update:semver-major"]
- dependency-name: "io.spring.dependency-management"
update-types: ["version-update:semver-major"]
# Spring Framework / Spring Cloud — pulled in transitively by SB,
# but their majors land outside the SB BOM cadence sometimes
- dependency-name: "org.springframework:*"
update-types: ["version-update:semver-major"]
- dependency-name: "org.springframework.cloud:*"
update-types: ["version-update:semver-major"]
# Gradle wrapper — each new major (8 → 9, etc.) needs hand
# verification (deprecations may have become errors). Dependabot
# bumps the *wrapper version*, which doesn't run any code; the
# CI catches breakage on next build, but a major bump deserves
# a dedicated PR with eyes on it, not 9 silent ones.
- dependency-name: "gradle"
update-types: ["version-update:semver-major"]
# Group related bumps into single PRs to keep the queue manageable.
groups:
# devslab-kr starters this repo exists to showcase — every new release
# should produce one tight PR per demo, not N PRs across submodules.
easy-paging:
patterns:
- "kr.devslab:easy-paging*"
ssrf-guard:
patterns:
- "kr.devslab:ssrf-guard*"
# Spring Boot moves as a unit; bump everything together or nothing.
spring-boot:
patterns:
- "org.springframework.boot:*"
- "io.spring.dependency-management"
# Test deps — none of these affect runtime behaviour, batch them.
test-tooling:
patterns:
- "org.testcontainers:*"
- "org.springframework.boot:spring-boot-testcontainers"
- "io.projectreactor:reactor-test"
- "org.junit*:*"
# Database drivers — usually bumped together when Spring Boot moves.
database-drivers:
patterns:
- "org.postgresql:*"
- "com.h2database:h2"
- "io.r2dbc:*"

# ---------------------------------------------------------------------
# Spring Boot 4 demos — easy-paging 0.5.x active line.
#
# These showcase the SB4-certified starter line, so Spring majors
# are NOT held — Dependabot is free to roll the BOM through patch /
# minor / major within the SB4 family. A future SB5 jump would
# come back through here as a major bump on a dedicated PR (the
# group keeps everything atomic).
# ---------------------------------------------------------------------
- package-ecosystem: "gradle"
directories:
- "/easy-paging-sb4-demo"
- "/easy-paging-sb4-keyset-demo"
- "/easy-paging-sb4-postgres-demo"
- "/easy-paging-sb4-reactive-demo"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "Asia/Seoul"
open-pull-requests-limit: 10
labels:
- "dependencies"
- "sb4"
commit-message:
prefix: "build(deps)"
include: "scope"
# Still hold the Gradle wrapper major — has nothing to do with SB,
# and a wrapper major needs hand verification regardless of line.
ignore:
- dependency-name: "gradle"
update-types: ["version-update:semver-major"]
groups:
easy-paging:
patterns:
- "kr.devslab:easy-paging*"
spring-boot:
patterns:
- "org.springframework.boot:*"
- "io.spring.dependency-management"
test-tooling:
patterns:
- "org.testcontainers:*"
- "org.springframework.boot:spring-boot-testcontainers"
- "io.projectreactor:reactor-test"
- "org.junit*:*"
database-drivers:
patterns:
- "org.postgresql:*"
Expand Down
28 changes: 24 additions & 4 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,32 @@

## 예제

### easy-paging — Spring Boot 4 (`0.5.x` 라인)

최신 active 라인. Spring Boot 4 이상 사용 중이면 여기.

| 데모 | 보여주는 것 | Maven Central 좌표 |
| --- | --- | --- |
| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | `@KeysetPaginate` 커서(keyset) 페이지네이션 — composite `(time, id)` 키, 쓰기 중에도 안정, `OFFSET`/`COUNT(*)` 없음 | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | 동일 스타터를 **실제 PostgreSQL**과 — `bootRun`은 Docker Compose, 테스트는 Testcontainers + `@ServiceConnection`, 로컬 DB 설치 불필요 | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive 스택 — **WebFlux + R2DBC**, `R2dbcOffsetPagingSupport` 사용. MVC 데모와 동일한 JSON 봉투를 `Mono<PageResponse<T>>`로 서빙 | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |

### easy-paging — Spring Boot 3 maintenance (`0.4.x` 라인)

Spring Boot 3.3–3.5 사용 중인 앱용. 스타터의 [`0.4.x` 브랜치](https://github.com/devslab-kr/easy-paging-spring-boot-starter/tree/0.4.x)가 SB3 보안 패치를 계속 받고, 이 데모들은 그 라인에 pin 됨.

| 데모 | 보여주는 것 | Maven Central 좌표 |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | `@KeysetPaginate` 커서 페이지네이션 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | 실제 PostgreSQL 사용 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive 스택 — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |

### ssrf-guard

| 데모 | 보여주는 것 | Maven Central 좌표 |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | `@KeysetPaginate` 커서(keyset) 페이지네이션 — composite `(time, id)` 키, 쓰기 중에도 안정, `OFFSET`/`COUNT(*)` 없음 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | 동일 스타터를 **실제 PostgreSQL**과 — `bootRun`은 Docker Compose, 테스트는 Testcontainers + `@ServiceConnection`, 로컬 DB 설치 불필요 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive 스택 — **WebFlux + R2DBC**, `R2dbcOffsetPagingSupport` 사용. MVC 데모와 동일한 JSON 봉투를 `Mono<PageResponse<T>>`로 서빙 | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
| [`ssrf-guard-demo`](ssrf-guard-demo/) | SSRF(Server-Side Request Forgery) 방어를 3종 Spring HTTP 클라이언트(RestClient, RestTemplate, WebClient)에 동시 적용 — 모두 같은 `UrlPolicy`. 15가지 공격 매트릭스 엔드포인트, Micrometer 메트릭 포함 | [`kr.devslab:ssrf-guard:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
| [`ssrf-guard-springai-demo`](ssrf-guard-springai-demo/) | ⭐ **LLM 에이전트 SSRF 방어.** 모든 Spring AI `ToolCallback`을 자동으로 wrap해서 LLM이 `fetch_url`을 호출하기 전에 URL 인자를 검증. 가짜 LLM 드라이버로 API 키 없이 오프라인 실행 가능 | [`kr.devslab:ssrf-guard-springai:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-springai) |
| [`ssrf-guard-feign-demo`](ssrf-guard-feign-demo/) | Spring Cloud OpenFeign `RequestInterceptor` — `@FeignClient` 호출에 동일 `UrlPolicy` 적용. 화이트리스트 / 비화이트리스트 `@FeignClient` 2개로 차단 경로 시연 | [`kr.devslab:ssrf-guard-feign:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-feign) |
Expand Down
28 changes: 24 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,32 @@ Each subdirectory is an **independent** Spring Boot application with its own Gra

## Examples

### easy-paging — Spring Boot 4 (`0.5.x` line)

Latest active line. Use these if your app is on Spring Boot 4+.

| Demo | Showcases | Maven Central coordinates |
| --- | --- | --- |
| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` — composite `(time, id)` key, stable under writes, no `OFFSET`/`COUNT(*)` | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | Same starter against **real PostgreSQL** — Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests, no local DB install | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive stack — **WebFlux + R2DBC** via `R2dbcOffsetPagingSupport`. Same JSON envelope as the MVC demos, served as `Mono<PageResponse<T>>` | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |

### easy-paging — Spring Boot 3 maintenance (`0.4.x` line)

For apps still on Spring Boot 3.3–3.5. The starter's [`0.4.x` branch](https://github.com/devslab-kr/easy-paging-spring-boot-starter/tree/0.4.x) continues to receive SB3 security patches; these demos pin against that line.

| Demo | Showcases | Maven Central coordinates |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | Same starter against real PostgreSQL | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive stack — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |

### ssrf-guard

| Demo | Showcases | Maven Central coordinates |
| --- | --- | --- |
| [`easy-paging-demo`](easy-paging-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` — composite `(time, id)` key, stable under writes, no `OFFSET`/`COUNT(*)` | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | Same starter against **real PostgreSQL** — Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests, no local DB install | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) |
| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive stack — **WebFlux + R2DBC** via `R2dbcOffsetPagingSupport`. Same JSON envelope as the MVC demos, served as `Mono<PageResponse<T>>` | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) |
| [`ssrf-guard-demo`](ssrf-guard-demo/) | SSRF (Server-Side Request Forgery) protection across three Spring HTTP clients (RestClient, RestTemplate, WebClient) — same `UrlPolicy` for all. 15-pattern attack matrix endpoint, Micrometer metrics. | [`kr.devslab:ssrf-guard:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) |
| [`ssrf-guard-springai-demo`](ssrf-guard-springai-demo/) | ⭐ **LLM agent SSRF defense.** Wraps every Spring AI `ToolCallback` so URL-shaped tool arguments are validated before the LLM-driven `fetch_url` runs. Fake-LLM driver makes the demo runnable offline (no API key). | [`kr.devslab:ssrf-guard-springai:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-springai) |
| [`ssrf-guard-feign-demo`](ssrf-guard-feign-demo/) | Spring Cloud OpenFeign `RequestInterceptor` — same `UrlPolicy` applied to `@FeignClient` calls. Two `@FeignClient` interfaces (one whitelisted, one not) to show the block path. | [`kr.devslab:ssrf-guard-feign:3.0.1`](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard-feign) |
Expand Down
Loading