Retrieve #Authorization swagger codegen java - spring

I work with swagger 2.0 to define a back end and trying to define security.
I end up with :
---
swagger: "2.0"
info:
version: 1.0.0
title: Foo test
schemes:
- https
paths:
/foo:
get:
security:
- Foo: []
responses:
200:
description: Ok
securityDefinitions:
Foo:
type: apiKey
name: X-BAR
in: header
Everything good till now, java codegen give me :
#ApiOperation(value = "", nickname = "fooGet", notes = "", authorizations = {
#Authorization(value = "Foo")
}, tags={ })
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Ok") })
#RequestMapping(value = "/foo",
method = RequestMethod.GET)
default ResponseEntity<Void> fooGet() {
if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
} else {
log.warn("ObjectMapper or HttpServletRequest not configured in default FooApi interface so no example is generated");
}
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
I'm wondering, in the interface, how to retrieve "properly" the X-BAR header value.
I end up with :
#Autowired
private HttpServletRequest httpServletRequest;
httpServletRequest.getHeader("X-BAR")
which works , but is there a more proper way ?
Define a class "Foo" ? a doFilter ?
Thanks

Related

Spring doc openapi oauth2 resource server not working

Although I have successfully authorize but when I get api 401 is there any way to fix it.
Authorize swagger
Execute api swageer
Swagger config application.yml
springdoc:
version: 'v1.0'
swagger-ui:
oauth:
use-basic-authentication-with-access-code-grant: true
use-pkce-with-authorization-code-grant: true
client-id: USER_CLIENT_APP
client-secret: password
oAuthFlow:
authorizationUrl: ${OAUTH2_SERVER:http://localhost:8080}/oauth/authorize
tokenUrl: ${OAUTH2_SERVER:http://localhost:8080}/oauth/token
OpenApiConfig.class
#OpenAPIDefinition(info = #Info(title = "User",
description = "description", version = "v1"))
#SecurityScheme(name = "security_auth", type = SecuritySchemeType.OAUTH2,
flows = #OAuthFlows(password = #OAuthFlow(
authorizationUrl = "${springdoc.oAuthFlow.authorizationUrl}",
tokenUrl = "${springdoc.oAuthFlow.tokenUrl}",
scopes = {
#OAuthScope(name = "trust", description = "trust scope"),
#OAuthScope(name = "read", description = "read scope"),
#OAuthScope(name = "write", description = "write scope")
})))
public class OpenApiConfig {}
get token
post-man get /oauth/token
I want to access oauth2 in springdoc openapi.

Adding body to Http request with Spock

I'm developing a Spring Boot application and I'm trying to do some authorization/authentication testing using Spock and groovyx.net.http.RESTClient. I'm trying to pass username and password inside body block like this:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class AuthorizationTest extends Specification {
#Shared
def client = new RESTClient("http://localhost:8080")
def "something should happen"() {
when:
def response = client.post(
path: "/login",
body: [ password : "1234", username : "admin"],
requestContentType: ContentType.JSON
)
then:
response.status == 200
}
Sadly, something's not working, and when I'm debugging I don't see the two parameters (username and password) inside the request.
What am I doing wrong?
It turned out I need to use different encoding, requestContentType: ContentType.URLENC, which is of type application/x-www-form-urlencoded.

consume/return a JSON response when executing flow using Spring boot API

I'm a beginner in corda and I'm trying to execute flows using Spring boot API. When I used:
#PostMapping(value = [ "create-iou" ], produces = [ TEXT_PLAIN_VALUE ] , headers = [ "Content-Type=application/x-www-form-urlencoded" ])
my flow is getting executed (by testing it using insomnia). But When I changed it to
#PostMapping(value = [ "create-iou" ], produces = [ APPLICATION_JSON_VALUE ], headers = [ "Content-Type=application/json" ])
It gives me a 406 not acceptable error: No body returned for response.
Here's the API I've created/copied:
#PostMapping(value = [ "create-iou" ], produces = [ TEXT_PLAIN_VALUE ] , headers = [ "Content-Type=application/x-www-form-urlencoded" ])
fun createIOU(request: HttpServletRequest): ResponseEntity<String> {
val iouValue = request.getParameter("iouValue").toInt()
val partyName = request.getParameter("partyName")
?: return ResponseEntity.badRequest().body("Query parameter 'partyName' must not be null.\n")
if (iouValue <= 0 ) {
return ResponseEntity.badRequest().body("Query parameter 'iouValue' must be non-negative.\n")
}
val partyX500Name = CordaX500Name.parse(partyName)
val otherParty = proxy.wellKnownPartyFromX500Name(partyX500Name) ?: return ResponseEntity.badRequest().body("Party named $partyName cannot be found.\n")
return try {
val signedTx = proxy.startTrackedFlow(::Initiator, iouValue, otherParty).returnValue.getOrThrow()
ResponseEntity.status(HttpStatus.CREATED).body("Transaction id ${signedTx.id} committed to ledger.\n")
} catch (ex: Throwable) {
logger.error(ex.message, ex)
ResponseEntity.badRequest().body(ex.message!!)
}
}
I would like to return something like this:
{
iouValue: 99,
lender: PartyA,
borrower: PartyB
}
When executing the flow using http endpoint.
You need to use the RPC connection libraries provided by Corda:
import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection
Take a look to this example to see how to use them.
You are not showing how your proxy is instantiate, but you need to instantiate a proxy to connect via RPC to the node, like so:
val rpcAddress = NetworkHostAndPort(host, rpcPort)
val rpcClient = CordaRPCClient(rpcAddress)
val rpcConnection = rpcClient.start(username, password)
proxy = rpcConnection.proxy
and once you have the proxy, you can create SpringBoot APIs to call that proxy that makes the RPC calls:
#RestController
#RequestMapping("/")
class StandardController(rpc: NodeRPCConnection) {
private val proxy = rpc.proxy
#GetMapping(value = ["/addresses"], produces = arrayOf("text/plain"))
private fun addresses() = proxy.nodeInfo().addresses.toString()
#GetMapping(value = ["/identities"], produces = arrayOf("text/plain"))
private fun identities() = proxy.nodeInfo().legalIdentities.toString()

Method Not Allowed 405, when hitting POST request after grails uprgade from 2.5.2 to 3.3.11

After upgrading grails 2.5.2 to 3.3.11, I am getting Method Not Allowed response while hitting POST request. The GET method works fine.
Controller:
package omapi
import grails.rest.RestfulController
import org.springframework.http.HttpStatus
import static org.springframework.http.HttpStatus.NOT_FOUND
import static org.springframework.http.HttpStatus.NO_CONTENT
class PhaseController extends RestfulController {
PhaseController(){
super(Phase)
}
static responseFormats = ['json', 'xml']
static allowedMethods = [show: 'GET', index:'GET',productAcronym:'GET', phaseByName: 'GET',save:'POST',update:'PUT',delete:'DELETE', deleteGroup: 'DELETE', deletePhase: 'DELETE']
def phaseService
def index(){
def phases = phaseService.getAllPhases()
respond phases
}
def show(){
def phase = phaseService.getPhaseById(params.id)
respond phase
}
def phaseByName(){
def phase = phaseService.getPhaseByName(params?.name)
respond phase
}
def productAcronym() {
def phase = phaseService.getPhaseByProductAcronym(params?.acronym)
log.info("==== phase by product Acronym =====$params.acronym==");
respond phase;
}
}
URL Mapping:
package omapi
import grails.core.GrailsApplication
import java.nio.file.AccessDeniedException
class UrlMappings {
static mappings = {
"/applications/$id/processingGroup"(controller: "application",action: "processingGroup")
"/accounts/$id/applications/"(controller: "accounts", action: "applications")
"/accounts/$aId/application/$id/products/"(controller: "application", action: "products")
"/ftpServer/connection"(controller: 'ftpServer', action: 'testConnection')
"/application/$id/jobs/"(controller: "job",action: "jobByApplication")
"/application/cycleDates"(controller: "cycleDates",action: "getCycleDatesByApplication")
"/ProcessingBranch/branch/"(controller: "processingTicketBranch",action: "branch")
"/application/$appCode/Offset"(controller: "ReportClientOffset",action: "offsetValue")
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/$controller/$id"(parseRequest: true){
action = [GET:"show",PUT:"update",POST:"404",DELETE:"delete"]
constraints {
id matches: /\d+/
}
}
"/$controller"{
action = [GET:"index",POST: "save",PUT:"update",DELETE:"delete"]
constraints {
}
}
"/"(view:"/index")
"403"(controller: "error", action: "error403")
"404"(controller: "error", action: "error404")
"409"(controller: "error", action: "error409")
"500"(controller: "error", action: "error500")
"500"(controller: "error", action: "error403", exception: AccessDeniedException)
}
}
Request: [POST] localhost:5555/OMApi/phase
Response:
{
"timestamp": 1594295030496,
"status": 405,
"error": "Method Not Allowed",
"message": "No message available",
"path": "/OMApi/phase"
}
For grails 2.5.2, everything works fine. It looks like a Spring related issue. All the searches on this matter provided no results. Any idea? Is it due to some error in UrlMapping or other problems like CORS Interceptor not working?
After upgrading grails 2.5.2 to 3.3.11, I am getting Method Not
Allowed response while hitting POST request. The GET method works
fine.
It looks like you have /OMApi/phase mapped to the index action in PhaseController which is configured with index: 'GET' in allowedMethods which means the index action is only accessible via a 'GET' request. Any other verb should result in a 405 for that action. If you want to allow both GET and POST for the index action (unclear why you want to do that) then change your allowedMethods to include index: ['GET', 'POST'] instead of index: 'GET'.
I hope that helps.

OpenApi - Is there a way to have a ComposedSchema with a discriminator part in a contract generated with springdoc-openapi-maven-plugin?

I have a sample SpringBoot API with the following features:
1 controller that exposes a single endpoint invokable with a GET request and that returns a custom class (ContainerClass in my example)
ContainerClass contains a property List
ParentClass is an abstract class that has 2 sub-classes: ChildA and ChildB
I try to generate an OpenApi contract from this API with springdoc-openapi-maven-plugin.
In my pom.xml, I have the following elements:
SpringBoot version: 2.2.6
org.springdoc:springdoc-openapi-ui:1.4.1
org.springdoc:springdoc-openapi-maven-plugin:1.0
Here are my classes I generate schema from.
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
public class ContainerClass {
#ArraySchema(
arraySchema = #Schema(discriminatorProperty = "classType"),
schema = #Schema(implementation = ParentClass.class)
)
public List<ParentClass> elements;
// + Getter/Setter
}
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "classType",
defaultImpl = ParentClass.class,
visible = true)
#JsonSubTypes({
#JsonSubTypes.Type(value = ChildA.class, name = "CHILD_A"),
#JsonSubTypes.Type(value = ChildB.class, name = "CHILD_B")})
#Schema(
description = "Parent description",
discriminatorProperty = "classType",
discriminatorMapping = {
#DiscriminatorMapping(value = "CHILD_A", schema = ChildA.class),
#DiscriminatorMapping(value = "CHILD_B", schema = ChildB.class)
}
)
public abstract class ParentClass {
public String classType;
// + Getter/Setter
}
#io.swagger.v3.oas.annotations.media.Schema(description = " Child A", allOf = ParentClass.class)
public class ChildA extends ParentClass{
}
#io.swagger.v3.oas.annotations.media.Schema(description = " Child B", allOf = ParentClass.class)
public class ChildB extends ParentClass{
}
When I run springdoc-openapi-maven-plugin, I get the following contract file.
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: http://localhost:8080
description: Generated server url
paths:
/container:
get:
tags:
- hello-controller
operationId: listElements
responses:
"200":
description: OK
content:
'*/*':
schema:
$ref: '#/components/schemas/ContainerClass'
components:
schemas:
ChildA:
type: object
description: ' Child A'
allOf:
- $ref: '#/components/schemas/ParentClass'
ChildB:
type: object
description: ' Child B'
allOf:
- $ref: '#/components/schemas/ParentClass'
ContainerClass:
type: object
properties:
elements:
type: array
description: array schema description
items:
oneOf:
- $ref: '#/components/schemas/ChildA'
- $ref: '#/components/schemas/ChildB'
ParentClass:
type: object
properties:
classType:
type: string
description: Parent description
discriminator:
propertyName: classType
mapping:
CHILD_A: '#/components/schemas/ChildA'
CHILD_B: '#/components/schemas/ChildB'
Actually, in my context, in order to have not any breaking change with existing consumers, I need items property in ContainerClass schema to contain the discriminator part that is contained in ParentClass schema, like this:
ContainerClass:
type: object
properties:
elements:
type: array
description: array schema description
items:
discriminator:
propertyName: classType
mapping:
CHILD_A: '#/components/schemas/ChildA'
CHILD_B: '#/components/schemas/ChildB'
oneOf:
- $ref: '#/components/schemas/ChildA'
- $ref: '#/components/schemas/ChildB'
When I try to set properties in annotation, I don't manage to do that. And when I debug code of io.swagger.v3.core.jackson.ModelResolver, I don't manage to find a way to do that.
And so far I have not found an example of code that help me.
Is there a way so that a ComposedSchema (array contained in ContainerClass in my case) has a disciminator part generated by springdoc-openapi-maven-plugin execution?
This the default generation structure. Handled directly by swagger-api (and not springdoc-openapi.
The generated OpenAPI description looks coorect.
With springdoc-openapi, you can define an OpenApiCustomiser Bean, where you can change the elements of the components element defined on the OpenAPI level:
https://springdoc.org/faq.html#how-can-i-customise-the-openapi-object-
Here is my solution by defining an OpenApiCustomiser Bean:
#Bean
public OpenApiCustomiser myCustomiser() {
Map<String, String> classTypeMapping = Map.ofEntries(
new AbstractMap.SimpleEntry<String, String>("CHILD_A", "#/components/schemas/ChildA"),
new AbstractMap.SimpleEntry<String, String>("CHILD_B", "#/components/schemas/ChildB")
);
Discriminator classTypeDiscriminator = new Discriminator().propertyName("classType")
.mapping(classTypeMapping);
return openApi -> openApi.getComponents().getSchemas().values()
.stream()
.filter(schema -> "ContainerClass".equals(schema.getName()))
.map(schema -> schema.getProperties().get("elements"))
.forEach(arraySchema -> ((ArraySchema)arraySchema).getItems().discriminator(classTypeDiscriminator));
}
I get the expected result in my contract file.

Resources