Is there any way to create custom aws lambda authorizer using Spring Boot Function? - spring-boot

I am trying to create a custom API Gateway lambda authorizer using Spring Cloud Function.
But when I am trying to return policy document as Map<String,Object> from Spring Function, Spring returning it as body along with some extra metadata. So ApiGateway treating it as invalid json. How to return only policy document.
This is what the String Function returning when I return Map<String,Object>. My Map Object data is in body.
{
"isBase64Encoded":false,
"headers":{
"id":"6b9da9d5-23a7-b555-aecf-90e6134779b8",
"contentType":"application/json",
"timestamp":"1630300611676"
},
"body":"{\"policyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn-value\",\"Effect\":\"Allow\"}]},\"context\":{\"name\":\"test\"},\"principalId\":\"813bf219-6039-4065-bcce-3e03b6996872\"}",
"statusCode":200
}
But it should actually return only body part for ApiGateway to work correctly.
{
"policyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Action":"execute-api:Invoke",
"Resource":"arn-value",
"Effect":"Allow"
}
]
},
"context":{
"name":"test"
},
"principalId":"813bf219-6039-4065-bcce-3e03b6996872"
}
My Spring Cloud Function code is below. It is only test function without proper logic.
#Bean
public Function<APIGatewayProxyRequestEvent, Map<String,Object>> authorise() {
return request -> {
String token = request.getHeaders().get("Authorization");
String arn = String.format("arn:aws:execute-api:%s:%s:%s/%s/%s/",
System.getenv("AWS_REGION"),
request.getRequestContext().getAccountId(),
request.getRequestContext().getApiId(),
request.getRequestContext().getStage(),
request.getRequestContext().getHttpMethod());
// Policy policy = jwtToken.getPolicy(token, arn);
try{
String allow = request.getHttpMethod().equalsIgnoreCase("GET")?"Allow":"Deny";
JSONObject json = new JSONObject();
json.put("principalId", UUID.randomUUID().toString())
.put("policyDocument",
new JSONObject()
.put("Version", "2012-10-17")
.put("Statement",
new JSONArray()
.put(new JSONObject()
.put("Action", "execute-api:Invoke")
.put("Effect", allow)
.put("Resource", arn)
)
)
)
.put("context", new JSONObject().put("name", "test"));
return json.toMap();
}catch(Exception e){
logger.error("",e);
}
return null;
};
}

Related

Simple Spring GraphQL Subscription returning error

I'm trying to create a simple Spring GraphQL subscription handler. Here's my controller:
#Controller
public class GreetingController {
#QueryMapping
String sayHello() {
return "Hello!";
}
#SubscriptionMapping
Flux<String> greeting(#Argument int count) {
return Flux.fromStream(Stream.generate(() -> "Hello # " + Instant.now()))
.delayElements(Duration.ofSeconds(1))
.take(count);
}
}
Here's the GraphQL schema:
type Query {
sayHello: String
}
type Subscription {
greeting(count: Int): String
}
Spring configuration:
spring:
graphql:
graphiql:
enabled: true
path: /graphiql
When I try to run above subscription using graphiql hosted by the spring I receive following error:
{
"errors": [
{
"isTrusted": true
}
]
}
When I run the same graphql request using Postman I receive following response:
{
"data": {
"upstreamPublisher": {
"scanAvailable": true,
"prefetch": -1
}
}
}
What is causing the subscription not to return data from my controller?
As explained in the linked GitHub issue, a subscription requires the ability to stream data within a persistent transport connection - this is not available other plain HTTP.
You'll need to enable WebSocket support in your application first. The GraphiQL UI should use the WebSocket transport transparently for this.

Calling .Net Odata API from GraphQL API Query and Mutation

my requirement is to call Odata .net API from GraphQL service.
My GQL query
query
{
cARequests {
id
cARequestStatus
reviewedBy {
name
email
}
assignedTo {
name
email
}
reviewedBy {
name
}
requestDate
reasonIfRejected
mPxN
mPxN
account {
accountNumber
}
}
}
My ODATA Request
[HttpGet(Name = "GetCARequest")]
[EnableQuery(PageSize=10)]
public IQueryable<GQLOdata> Get()
{
return Enumerable.Range(1, 5).Select(index => new GQLOdata
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.AsQueryable();
}
I dont know how to call this ODATA API from GraphQL API. What configuration I have to make and what services I have to add. Please guide me in the right direction

Call GraphQL api from Rest endpoint in spring boot returning null value

From my rest endpoint I am trying to call 3rd party graphql api but in response I am getting null values.
Request:
{
"query": "query($id: String!) { hiringOrganization (id: $id) { name } }",
"variables": {
"id": "seekAnzPublicTest:organization:seek:93WyyF1h"
}
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"hiringOrganization": {
"name": "Acme Corp"
}
}
}
Inside the resource folder I have placed Query and variable request:
query($id: String!) { hiringOrganization (id: $id) { name } }
Variables:
{
"id": "hiringId"
}
From Postman I am getting the below response:
[![enter image description here][3]][3]
Calling the Query and variables from resource folder:
public static String getSchemaFromFileName(final String fileName) throws IOException {
if(fileName.contains("Variables")){
log.info("inside variables::"+fileName);
return new String(
GraphqlSchemaReaderUtil.class.getClassLoader()
.getResourceAsStream("seekGraphQL/variables/"+fileName+".graphql")
.readAllBytes()
);
} else {
log.info("inside query::"+fileName);
return new String(
GraphqlSchemaReaderUtil.class.getClassLoader()
.getResourceAsStream("seekGraphQL/query/" + fileName + ".graphql")
.readAllBytes()
);
}
}
Calling the graphql endpoint:
public Mono<HiringDTO> getHirerDetails(final String id) throws IOException {
GraphqlRequestBody requestBody=new GraphqlRequestBody();
final String query= GraphqlSchemaReaderUtil.getSchemaFromFileName("hiringQuery");
final String variables= GraphqlSchemaReaderUtil.getSchemaFromFileName("hiringVariables");
log.info("before id::"+id);
requestBody.setQuery(query);
requestBody.setVariables(variables.replace("hiringId",id));
log.info("id::"+id);
return webclient.post()
.uri(url)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(HiringDTO.class);
}
My rest end point is a post request which has hiring Id in request body . I don't know why I am getting the null values. Please assist me to find out the issues.
Postman request/response:

EasyPost Create Webhook returns null

I tried to create an easy post webhook using easy post in asp.net core API project. it returns a null value in webhook creations.
i tried this
using EasyPost;
EasyPost.ClientManager.SetCurrent("<YOUR_TEST/PRODUCTION_API_KEY>");
Webhook webhook = Webhook.Create(
new Dictionary<string, object>() {
{ "url", "https://www.foobar.com" }
}
);
I was able to have the webhook create method return JSON properly by using the most current version of the C# client library. This is the code snippet I used:
using System;
using System.Collections.Generic;
using EasyPost;
using Newtonsoft.Json;
namespace create_webhook
{
class createWebhook
{
static void Main(string[] args)
{
EasyPost.ClientManager.SetCurrent(Environment.GetEnvironmentVariable("EASYPOST_API_KEY"));
Webhook webhook = Webhook.Create(
new Dictionary<string, object>() {
{ "url", "https://www.foobar.com" }
}
);
Console.WriteLine(JsonConvert.SerializeObject(webhook, Formatting.Indented));
}
}
}
Response:
{
"id": "hook_123...",
"mode": "test",
"url": "https://www.foobar.com",
"disabled_at": null
}
For reference, the API docs related to creating a webhook for C# do not specifically mention to print what is returned which is why in my example I added a print statement.

Spring ModelAndView to RestController json response

I have a legacy spring code where they use ModelAndView and they add the objects to it as below.
ModelAndView result = new ModelAndView();
result.addObject("folders", folders);
return result;
for the above i am getting response as
{
"folders": [
{
"recordCount": 0,
"folderContentType": "Reports",
"folderId": 34,
},
{
"recordCount": 2,
"folderContentType": "SharedReports",
"folderId": 88,
}
]
}
I have changed these to use Spring's RestController with a POJO backing the results returned from DB.
#GetMapping("/folders")
public List<Folder> getAllFolders() {
return Service.findAllFolders(1,2);
}
This returns a JSON as below
[
{
"folderId": 359056,
"folderName": "BE Shared Report Inbox",
"folderDescription": "BE Shared Report Inbox",
},
{
"folderId": 359057,
"folderName": "BE Shared Spec Inbox",
}]
How could i return this as exactly as my legacy code response. I know i can convert the List to Map and display. But, is there any equivalent
way.
Thanks.
You can put your result into a map.
#GetMapping("/folders")
public List<Folder> getAllFolders() {
return Service.findAllFolders(1,2);
}
Change to:
#GetMapping("/folders")
public Map<String,List<Folder>> getAllFolders() {
Map<String,List<Folder>> map = new HashMap<>();
map.put("folders",Service.findAllFolders(1,2));
return map;
}

Resources