Mask Headers in spring restdocs - spring-restdocs

So I was trying to follow this example:
Spring REST Docs: how to replace parameters
What I'm trying to do is to mask the JWT token in the header of my request and I have an OperationPreprocessor that looks like this:
import org.springframework.http.HttpHeaders
import org.springframework.restdocs.operation.OperationRequest
import org.springframework.restdocs.operation.OperationRequestFactory
import org.springframework.restdocs.operation.OperationResponse
import org.springframework.restdocs.operation.preprocess.OperationPreprocessor
class AuthHeaderPreprocessor implements OperationPreprocessor {
#Override
OperationRequest preprocess(OperationRequest request) {
HttpHeaders headers = new HttpHeaders()
headers.putAll(request.getHeaders())
headers.set('Authorization', 'Bearer 12345')
return new OperationRequestFactory().create(
request.getUri(),
request.getMethod(),
request.getContent(),
headers,
request.getParameters(),
request.getParts()
)
}
#Override
OperationResponse preprocess(OperationResponse response) {
return response
}
}
When I run the test they run without error but I don't see any change to the header. I'm using the OperationPreprocessor like this
RestAssuredRestDocumentation.document(
'event-list', preprocessRequest(new AuthHeaderPreprocessor()), ...
Any ideas what I may be missing.

The code I had actually worked and is a good example of how to filter headers. For some reason when testing it initially I wasn't working, but that seems like it was maybe just something cached in the build not getting cleared, as it works now.

Related

How to pass json data to aws lambda through API Gateway?

I am trying to send the JSON to AWS lambda to trigger lambda handler. I am using Flutter web for this project and my API end point is as below. Below is my code to hit AWS lambda endpoint.
Future<String> getResponse(jsonData) async {
var response =
await http.post(Uri.parse("https://7jua06h1r4.execute-api.ap-south-1.amazonaws.com/stage1/calc"), headers: header, body: jsonData);
if (response.statusCode == 200) {
print("Success");
} else {
print("Error");
}
}
When I try to hit and get response using postman, everything works fine and i get 200 status with response as well. But when i test it using my browser, it display the body is empty. Can you help me out please? How can i pass JSON data through API Gateway to lambda?
{"statusCode": 200, "body": {}}
When i try using Postman, it works as expected. you can see in the image below:
[1]: https://i.stack.imgur.com/Tczfw.png
My Lambda function:
import json
import boto3
def lambda_handler(event, context):
print(event['body'])
# TODO implement
return {
'statusCode': 200,
'body': event['body']
}
Here, i am not able to get the body i.e. JSON Data from my app.
I think that in your code need to replace it:
print(event['body'])
by
print(event.body.body)
Event is not the call body, body is inside of that object and you have an attribute called body.
When you tested it using your browser, did you pass body to the url? Assuming that you just typed your url
https://7jua06h1r4.execute-api.ap-south-1.amazonaws.com/stage1/calc
into the browser, you would have gotten an empty body in response, which is the correct behaviour.

scalaj etag get can't parse

Using scalaj.http 2.4 I cannot get the correct code for a If-None-Match etag for this simple call:
import scalaj.http.Http
object EtagTest extends App {
  val firstResponse = Http("https://api.github.com/users/octocat/orgs")
// get correct etag ...
  val response = Http("https://api.github.com/users/octocat/orgs").header("If-None-Match", "\"98f0c1b396a4e5d54f4d5fe561d54b44\"").asString
  println(response.code)
}
I'm expecting a 304 Not Modified but I get a 200.
I tried the following and it worked for me. It looks like the ETag you get with this program is not the ETag you've hard coded in your program. The strange thing is that when I send a cURL request to it, the ETag returned is the one you have hard coded.
import scalaj.http.Http
object ETagTest extends App {
val firstResponse = Http("https://api.github.com/users/octocat/orgs").asString
val response = Http("https://api.github.com/users/octocat/orgs").header("If-None-Match", firstResponse.header(key = "ETag").get).asString
println(response.code)
println(response.header(key = "ETag").get)
}
Output of the above:
304
"80b190627d4c87e9a37c34e20ea246a1"

Angular 2 api call responds with 404 even though service works when tested

I am trying to call a web service from my Angular 2 app.
private baseUrl: string = 'http://localhost:3000/api';
getPatterns(): Observable<Pattern[]> {
const patterns$ = this.http
.get(`${this.baseUrl}/pattern`, {headers: this.getHeaders()})
.map(this.mapPatterns)
.catch(this.handleError);
return patterns$;
}
private getHeaders() {
const headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
This gives me a 404 error for URL: http://localhost:3000/api/pattern even though I get a valid response when I open the URL in browser or try to call it from POSTMAN.
Any help pointing out why this doesn't work would be appreciated.
Thanks!
Vetemi's answer solved the first step of this issue for me. I had built my Angular App following along with the Angular Tour Of Heroes tutorial and removing the dependencies on the In Memory web api service resolved the 404 error. After that I was getting a CORS error, specifically the error read:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
My API is a .Net Core 2.0 API, so I needed to enable CORS which I did following the steps at this link
https://learn.microsoft.com/en-us/aspnet/core/security/cors
This is a trimmed down version of my Startup.cs file
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder => builder.AllowAnyOrigin());
app.UseMvc();
}
In case, you haven't found the problem and for those who have the same problem.
Have you used the in memory database from the tutorial Angular Tour of Heroes? If yes, then this may be the problem. The dependency
"angular-in-memory-web-api": "~0.2.4",
intercepts your http requests. Removing this dependency might help. Solution was found here.
Your header contains nothing, so the response is 404. See the below change
private getHeaders() : Headers {
const headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
Reason: Default return type of the methods are void, so when you are returning you need to explicitly have the return type

Adding authentication headers to ImageLoader for NetworkImageView picture loading

On a listView, in its adapters' getView method, I need to request an image per ListView item in order to load a picture by item thanks to NetworkImageView. The problem is that I need to add authentication header to the request to allow the user the get pictures from server. I've read some solutions which are not possible to put in practice.
First solution
Second solution
Does someone has faced this issue ?
Thanks in advance...
I've find out how to set a Basic Authentication header into an ImageLoader. I was misunderstanding the answer on that link same topic. So credit goes to the real answerer.
Anyway the trick was to add an HurlStack into the getRequestQueue method as follows:
public RequestQueue getRequestQueue()
{
if (mRequestQueue == null) {
HurlStack stack = new HurlStack() {
#Override
public HttpResponse performRequest(Request<?> request, Map<String, String> headers)
throws IOException, AuthFailureError {
String auth = "Basic " + Base64.encodeToString((GlobalVariables.getInstance().getWS_KEY()+":").getBytes(),
Base64.NO_WRAP);
headers.put("Authorization", auth);
return super.performRequest(request, headers);
}
};
mRequestQueue = Volley.newRequestQueue(getApplicationContext(),stack);
}
return mRequestQueue;
}
The RequestQueue object is placed into a Global class and a singleton pattern is applied, so it means that whenever you request the RequestQueue, the authorization header will be in it. Hope it helps !

Play2-mini and Akka2 for HTTP gateway

I'm evaluating the possibility of using Play2-mini with Scala to develop a service that will sit between a mobile client and existing web service. I'm looking for the simplest possible example of a piece of code where Play2-mini implements a server and a client. Ideally the client will use Akka2 actors.
With this question, I'm trying to find out how it is done, but also to see how Play2-Mini and Akka2 should co-operate. Since Play2-Mini appears to be the replacement for the Akka HTTP modules.
Play2-mini contains the following code example, in which I created two TODO's. If someone can help me with some sample code to get started, I will be really grateful.
package com.example
import com.typesafe.play.mini._
import play.api.mvc._
import play.api.mvc.Results._
object App extends Application {
def route = {
case GET(Path("/testservice")) & QueryString(qs) => Action{ request=>
println(request.body)
//TODO Take parameter and content from the request them pass it to the back-end server
//TODO Receive a response from the back-end server and pass it back as a response
Ok(<h1>Server response: String {result}</h1>).as("text/html")
}
}
}
Here's the implementation of your example.
Add the following imports:
import play.api.libs.ws.WS
import play.api.mvc.BodyParsers.parse
import scala.xml.XML
Add the following route:
case GET(Path("/testservice")) & QueryString(qs) => Action{ request =>
Async {
val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
val tokenData = QueryString(qs,"data") map (_.get(0)) getOrElse("<auth>john</auth>")
WS.url(backendUrl).post(XML loadString tokenData).map { response =>
Ok(<html><h1>Posted to {backendUrl}</h1>
<body>
<div><p><b>Request body:</b></p>{tokenData}</div>
<div><p><b>Response body:</b></p>{response.body}</div>
</body></html>).as("text/html") }
}
}
All it does, is forwarding a GET request to a back-end serivce as a POST request. The back-end service is specified in the request parameter as target and the body for the POST request is specified in the request parameter as data (must be valid XML). As a bonus the request is handled asynchronously (hence Async). Once the response from the back-end service is received the front-end service responds with some basic HTML showing the back-end service response.
If you wanted to use request body, I would suggest adding the following POST route rather than GET (again, in this implementation body must be a valid XML):
case POST(Path("/testservice")) & QueryString(qs) => Action(parse.tolerantXml){ request =>
Async {
val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
WS.url(backendUrl).post(request.body).map { response =>
Ok(<html><h1>Posted to {backendUrl}</h1>
<body>
<div><p><b>Request body:</b></p>{request.body}</div>
<div><p><b>Response body:</b></p>{response.body}</div>
</body></html>).as("text/html") }
}
}
So as you can see, for your HTTP Gateway you can use Async and play.api.libs.ws.WS with Akka under the hood working to provide asynchronous handling (no explicit Actors required). Good luck with your Play2/Akka2 project.
Great answer by romusz
Another way to make a (blocking) HTTP GET request:
import play.api.libs.ws.WS.WSRequestHolder
import play.api.libs.ws.WS.url
import play.api.libs.concurrent.Promise
import play.api.libs.ws.Response
val wsRequestHolder: WSRequestHolder = url("http://yourservice.com")
val promiseResponse: Promise[Response] = wsRequestHolder.get()
val response = promiseResponse.await.get
println("HTTP status code: " + response.status)
println("HTTP body: " + response.body)