spring cloud contract - use the request's body as the response body - spring-cloud

in spring cloud contract (v1.2.5) using this contract:
Contract.make {
description "update sthg"
request {
method PUT()
url value($(consumer('/path/to/sthg'),
producer(execute('somePutPathPath(0,\"xxx\")'))))
body(producer(
file('files/givens/my-body.json')
))
}
response {
status 200
headers {
contentType(applicationJson())
}
body(fromRequest().body())
}
}
I get an error when generating the tests
org.springframework.cloud:spring-cloud-contract-maven-plugin:1.2.5.RELEASE:generateTests failed:net.minidev.json.parser.ParseException: Unexpected character ({) at position 1. -> [Help 1]
but everything is fine if i use: body(someProp: fromRequest().body())
Contract.make {
description "update sthg"
request {
method PUT()
url value($(consumer('/path/to/sthg'),
producer(execute('somePutPathPath(0,\"xxx\")'))))
body(producer(
file('files/givens/my-body.json')
))
}
response {
status 200
headers {
contentType(applicationJson())
}
body(someProp: fromRequest().body())
}
}
How could I set the body response to be the request's body.

I solved this by using request.getBody() instead of : body(fromRequest().body())
body($(
c(request.getBody()),
p(file('some.json'))
))

Related

HTTP header authentication not working with gradle publish

The following documentation describes how to use HTTP header authentication:
https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:authentication_schemes
I did as described, answer: Received status code 401 from server: Unauthorized
publishing {
repositories {
maven {
url "my-url-does-not-matter-now"
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token my-token"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
Interesting enough, if i change to password protected works.
publishing {
repositories {
maven {
url "my-url-does-not-matter-now"
credentials {
username "user"
password "my-token"
}
}
}
}
I can assume my url and token works.
Thoughts please? thanks in advance

axios DELETE request with body in Nuxt.js

I have an app built with Nuxt.js. To get data from the API I use axios, namely #nuxtjs/axios. All request work fine but for the DELETE method.
My syntax is the following:
async removeItemFromCart(productId) {
const accessKey = await this.$store.dispatch('fetchUserAccessKey');
try {
this.$axios.delete(`/api/baskets/products?userAccessKey=${ accessKey }`, {
data: {
productId: productId
}
})
} catch (error) {
console.log(error);
}
},
However, in the console I always get the following error: createError.js?2d83:16 Uncaught (in promise) Error: Request failed with status code 400
I tried to use params instead of data, but to no avail. What am I missing here?
It seems that there's an issue with axios: when you use delete method with body, it either doesn't include payload, or deletes Content-type: 'application/json' from headers. To solve the issue, I used .request instead of .delete (according to https://github.com/nuxt-community/axios-module/issues/419)
this.$axios.request(`/api/baskets/products?userAccessKey=${ accessKey }`, {
data: {
productId: productId
},
method: 'delete'
}).

akka http handleNotFound rejection is only working for POST method

i have the following akka http rejection handling code taken from https://doc.akka.io/docs/akka-http/current/routing-dsl/rejections.html
val message = "The requested resource could not be found."
implicit def myRejectionHandler = RejectionHandler.newBuilder()
.handleNotFound {
complete(HttpResponse(NotFound
,entity = HttpEntity(ContentTypes.`application/json`, s"""{"rejection": "$message"}"""
)))
}.result()
val route: Route = handleRejections(myRejectionHandler) {
handleExceptions(myExceptionHandler) {
concat(
path("event-by-id") {
get {
parameters('id.as[String]) {
id =>
complete("id")
}
}
}
,
post {
path("create-event") {
entity(as[Event]) {
event =>
complete(OK, "inserted")
}
}
}
)
}
}
}
val bindingFuture = Http().bindAndHandle(route, hostName, port)
when i hit localhost:8080/random
i got the message
HTTP method not allowed, supported methods: POST
and when i select POST and hit localhost:8080/random
i got the message
{
"rejection": "The requested resource could not be found."
}
why i did not get the same message when my route request was GET ?
in the docs the handleNotFound was working with GET request https://doc.akka.io/docs/akka-http/current/routing-dsl/rejections.html
This is happens, probably because of order of directives, you are using: in your configuration if incoming request does not match with event-by-id URL path, then it goes to the next handler, which expects that request should have POST method first of all, because post directive goes first, before path("create-event").
What you can try to do is change directives order to the next one, for second route:
path("create-event") {
post {
entity(as[Event]) { event =>
complete(OK, "inserted")
}
}
}
Hope this helps!

How to get Authenticated with spring security rest plugin in Grails

I'm using Grails version 2.4.3 . I am creating an application that supports RESTful APIs. Since access to these APIs should be authenticated , I tried out the Spring Security REST plugin. I checked out this example and what I could understand is , the /api/login controller is the authentication point which receives the user credentials in JSON format and after successful authentication it provides the acces token as response. I tried sending a POST request to /api/login/ with valid JSON data using the POSTMAN Rest Client. But it gives me the following error.
401 Unauthorized , Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
I also tried using IntellijIDEA's REST Client but doesn't work.
Then i tried by sending AJAX Request to /api/login/ with valid JSON data
, but getting 401 on console. What is the problem here? Is this the correct login end point? How can i get authenticated using JQuery?
Try this
$.ajax({
url: " http://localhost:8080/AppName/api/login",
type: "POST",
crossDomain: true,
data: JSON.stringify({"username":"yourusername" , "password":"yourpassword"}),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (response) {
console.log(response);
},
error: function (xhr, status) {
alert("error");
}
}) });
You can try this code for authentication,I am sending user id and password in request header you can try as you wish :-
inject following services:-
def springSecurityService
def authenticationManager
and use following code
def login = {
final String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.startsWith("Basic")) {
boolean authResult = authenticateUser(authorization)
if (authResult) {
render response.status
} else {
render authFailed(response)
}
} else {
render authFailed(response)
}
}
protected boolean authenticateUser(String authorization) {
// Authorization: Basic base64credentials
def base64Credentials = authorization.substring("Basic".length()).trim();
byte[] credentials = base64Credentials.decodeBase64()
String actualCredential = new String(credentials)
// credentials format like username:password
final String[] values = actualCredential.split(":", 2);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(values[0], values[1]);
try {
def authentication = authenticationManager.authenticate(authRequest);
def securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
def session = request.session;
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}
catch (BadCredentialsException exception) {
return false
}
return true
}
protected HttpServletResponse authFailedResponse(HttpServletResponse response) {
response.setStatus(401)
response.setHeader("WWW-Authenticate", "Basic realm=\"nmrs_m7VKmomQ2YM3:\"")
return response;
}

AngularJS ngResrouce REST Authentication

I'm trying to learn AngularJS. I'm try to make a simple authenticated get request to a REST api. At this point, i'm just trying to get a response back. I keep getting invalid key because I can't seem to send the headers properly.
angular.module('App', ['ngResource']);
function AppCtrl($scope, $resource){
$scope.app = $resource('https://theapiurl.com/parameter=:action',
{action:'My Parameter works fine!'},
{method: 'GET'},
{headers: 'auth-key' : 'key'});
$scope.app.get();
}
I just can't seem to get the header to send. Thanks for reading.
If you are using angular-resource 1.1.x+ the following should work:
angular.module('App', ['ngResource']);
function AppCtrl($scope, $resource){
$scope.app = $resource('https://theapiurl.com/parameter=:action',
{
action:'My Parameter works fine!'
},
{
get: {
method: 'GET',
headers : { 'auth-key' : 'key' }
}
});
$scope.app.get();
}
If you are using 1.0.x branch this won't work. I believe the only alternative is to set global default headers in $httpProvider, or to user $http directly (not using $resource). Here's how you would set the headers globally:
$httpProvider.defaults.headers.get['auth-key'] = 'key';
To avoid setting the header in every resource you could use an interceptor:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function($q) {
return {
'request': function(config) {
config.headers['auth-key'] = 'key';
return $q.when(config);
}
};
});
});