feat: API key and HTTP basic authentication support#24
feat: API key and HTTP basic authentication support#24halotukozak wants to merge 14 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class OpenAPI security scheme support (API key + HTTP Basic, alongside Bearer/backward-compat) to the parsing and codegen pipeline, and wires Gradle plugin shared-type generation to reflect spec-defined authentication.
Changes:
- Introduces
SecurityScheme/ApiKeyLocationin the core model and parses globalsecuritySchemes+securityusage from OpenAPI. - Generates auth-aware
ApiClientBase.applyAuth()and security-aware client constructors (with backward-compat behavior for legacy Bearer-only usage). - Updates Gradle plugin to feed spec files into shared type generation; adds extensive unit + functional tests.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin/src/main/kotlin/com/avsystem/justworks/gradle/JustworksSharedTypesTask.kt | Adds specFiles input and parses specs to drive shared ApiClientBase auth generation. |
| plugin/src/main/kotlin/com/avsystem/justworks/gradle/JustworksPlugin.kt | Wires each spec into the shared types task for security scheme extraction. |
| plugin/src/functionalTest/kotlin/com/avsystem/justworks/gradle/JustworksPluginFunctionalTest.kt | Functional coverage for security-aware vs backward-compatible ApiClientBase. |
| core/src/test/resources/security-schemes-spec.yaml | Fixture spec covering Bearer/apiKey/header+query/basic. |
| core/src/test/kotlin/com/avsystem/justworks/core/parser/SpecParserSecurityTest.kt | Unit tests for security scheme extraction/filtering. |
| core/src/test/kotlin/com/avsystem/justworks/core/gen/ClientGeneratorTest.kt | Constructor generation tests for various security scheme sets. |
| core/src/test/kotlin/com/avsystem/justworks/core/gen/ApiClientBaseGeneratorTest.kt | Tests for generated constructor params and applyAuth() body per scheme. |
| core/src/main/kotlin/com/avsystem/justworks/core/parser/SpecParser.kt | Extracts referenced security schemes from components + global security requirements. |
| core/src/main/kotlin/com/avsystem/justworks/core/model/ApiSpec.kt | Adds SecurityScheme model and ApiSpec.securitySchemes. |
| core/src/main/kotlin/com/avsystem/justworks/core/gen/Names.kt | Adds BASE64_CLASS for Basic auth generation. |
| core/src/main/kotlin/com/avsystem/justworks/core/gen/CodeGenerator.kt | Passes security schemes into shared-type generation. |
| core/src/main/kotlin/com/avsystem/justworks/core/gen/ClientGenerator.kt | Generates security-aware constructors and super-calls. |
| core/src/main/kotlin/com/avsystem/justworks/core/gen/ApiClientBaseGenerator.kt | Generates scheme-dependent auth params + dynamic applyAuth() implementation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
core/src/main/kotlin/com/avsystem/justworks/core/gen/shared/ApiClientBaseGenerator.kt
Show resolved
Hide resolved
plugin/src/main/kotlin/com/avsystem/justworks/gradle/JustworksSharedTypesTask.kt
Outdated
Show resolved
Hide resolved
Coverage Report
|
…tion Parse security schemes (Bearer, Basic, ApiKey) from OpenAPI specs and generate auth-aware ApiClientBase with corresponding constructor parameters and header/query injection. Wire spec files into JustworksSharedTypesTask for security scheme extraction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0c0cb14 to
2cd275d
Compare
# Conflicts: # core/src/main/kotlin/com/avsystem/justworks/core/gen/ClientGenerator.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/CodeGenerator.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/shared/ApiClientBaseGenerator.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ApiClientBaseGeneratorTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ClientGeneratorTest.kt
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
core/src/main/kotlin/com/avsystem/justworks/core/gen/CodeGenerator.kt
Outdated
Show resolved
Hide resolved
core/src/main/kotlin/com/avsystem/justworks/core/gen/shared/ApiClientBaseGenerator.kt
Outdated
Show resolved
Hide resolved
core/src/main/kotlin/com/avsystem/justworks/core/gen/shared/ApiClientBaseGenerator.kt
Show resolved
Hide resolved
core/src/main/kotlin/com/avsystem/justworks/core/gen/shared/ApiClientBaseGenerator.kt
Outdated
Show resolved
Hide resolved
…d replace `warn` with `accumulate` - Replace mutable property list with direct property creation in `classBuilder`. - Remove redundant `warn` function and centralize warning handling using `accumulate`. - Update context receiver parameter names in `ArrowHelpers` for clarity. - Enforce non-null checks and ensure consistent warning accumulation in `SpecParser`.
…syntax - Move `primaryConstructor` invocation back to `classBuilder`. - Adjust context receiver parameter syntax for improved consistency and readability. - Ensure `securitySchemes` are deduplicated by name in `CodeGenerator`.
…ng security schemes - Delete unused `no securitySchemes` test in `ClientGeneratorTest`. - Add warning for conflicting security scheme types in `JustworksSharedTypesTask`.
…cheme extraction Deduplicate SpecParser by extracting loadOpenApi() and parseSpec() helpers. Add parseSecuritySchemes() for lightweight extraction without full schema resolution. Make ParseResult generic to support both ApiSpec and List<SecurityScheme> results. Update JustworksSharedTypesTask to use the lightweight method, avoiding double full-parse of spec files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # core/src/main/kotlin/com/avsystem/justworks/core/gen/client/ClientGenerator.kt
# Conflicts: # core/src/main/kotlin/com/avsystem/justworks/core/gen/client/ClientGenerator.kt
…neration - Generate authentication handling for security schemes (Bearer, Basic, API Key). - Document security scheme support and configuration in README. - Refactor `ApiResponseGenerator` to include security scheme logic. - Update tests to validate security scheme handling.
|
|
||
| is SecurityScheme.Basic -> { | ||
| val usernameParam = "${scheme.name.toCamelCase()}Username" | ||
| val passwordParam = "${scheme.name.toCamelCase()}Password" |
There was a problem hiding this comment.
The parameter name derivation (scheme.name.toCamelCase() + suffix) is duplicated between buildAuthConstructorParams() and buildApplyAuth(). Consider extracting a
helper like SecurityScheme.paramName(): List so the mapping lives in one place
| } | ||
| } | ||
|
|
||
| val count = CodeGenerator.generateSharedTypes(outDir, allSchemes.distinctBy { it.name }) |
There was a problem hiding this comment.
Seems kinda fragile, if there will be two schemes with same name but with different config it will pick first one
| (scheme is SecurityScheme.ApiKey && scheme.location == ApiKeyLocation.HEADER) | ||
| } | ||
| val querySchemes = securitySchemes | ||
| .filterIsInstance<SecurityScheme.ApiKey>() |
There was a problem hiding this comment.
Nit: can we use is type check as we are using for headerScheme checks?
There was a problem hiding this comment.
but later the cast would be required
if (querySchemes.isNotEmpty()) {
builder.beginControlFlow("url")
for (scheme in querySchemes) {
scheme as SecurityScheme.ApiKey
val paramName = scheme.paramNames()
builder.addStatement(
"parameters.append(%S, $paramName())",
scheme.parameterName,
)
}
builder.endControlFlow()
}
core/src/main/kotlin/com/avsystem/justworks/core/ArrowHelpers.kt
Outdated
Show resolved
Hide resolved
core/src/main/kotlin/com/avsystem/justworks/core/parser/SpecParser.kt
Outdated
Show resolved
Hide resolved
…ArrowHelpers` and update `SpecParser` usage
…h parameter generation - Move `AuthParam` logic to a dedicated file. - Simplify `buildAuthConstructorParams` and authentication handling in `ApiClientBaseGenerator`.
Summary
SecuritySchemesealed interface model (Bearer, ApiKey with header/query, Basic)SpecParserto extractsecuritySchemesfrom OpenAPI spec and resolve globalsecurityreferencesapplyAuth()generation inApiClientBaseGenerator— conditional logic per scheme typeClientGenerator— backward-compatible (tokenfor single Bearer)JustworksSharedTypesTaskfor end-to-end security scheme generationSpecParser.parseSecuritySchemes()method for shared types task — avoids full spec re-parseTest plan
SpecParserSecurityTest— 8 tests for scheme extraction (bearer, apiKey header/query, basic, filtering)ApiClientBaseGeneratorTest— 24 tests including dynamic applyAuth for all scheme typesClientGeneratorTest— 28 tests including security-aware constructorsJustworksPluginFunctionalTest— 2 functional tests for on-disk ApiClientBase with security🤖 Generated with Claude Code