How to use validation_messages and display_exceptions in Apigility? - error-handling

From the Apigility documentation (Error Reporting):
The API Problem specification allows you to compose any other additional fields that you feel would help further clarify the problem and why it occurred. Apigility uses this fact to provide more information in several ways:
Validation error messages are reported via a validation_messages key.
When the display_exceptions view configuration setting is enabled, stack traces are included via trace and exception_stack properties.
I don't understand this part of the docu. What is the purpose and how to use the settings validation_messages and display_exceptions?

The display_exceptions setting is from ZF2's view manager (see docs here). Turning this on will cause Apigiltiy to include a stack trace with any error response.
In Apigility itself the validation_messages key population is handled automatically. You configure an input filter which validates the incoming data payload and if the input filter fails the error messages it returns are automatically injected into the API response under the validation_messages key. This functionality is provided by the module zf-content-validation. You can "do it yourself" by returning an ApiProblemResponse from your resource like so:
return new ApiProblemResponse(
new ApiProblem(422, 'Failed Validation', null, null, array(
'validation_messages' => [ /* array of messages */ ]
))
);

Related

Error when checking for custom claims property on rules auth token

I receive an error in the emulator when I try to check for a custom claim field that does not exist on the request.auth.token object when checking storage.rules. The request fails which is correct if the property is missing but I am concerned about the error.
function isPlatformVerified() {
return request.auth.token.platformVerified == 'ok';
}
and this is the error shown in the emulator:
com.google.firebase.rules.runtime.common.EvaluationException: Error: /Users/marcel/git/dev/storage.rules line [68], column [14]. Property platformVerified is undefined on object.
I wish to check if the custom claims has this property and if it has that it contains the correct value. How do I do this without getting an error (or can I ignore this??)
Many thanks
Most likely the custom claim hasn't propagated to the client and rules yet.
Custom claims are part of the token that the client sends with its requests, and that token is only auto-refreshed once per hour. So it may take up to an hour before a new claim shows up in the client, and thus in the security rules.
You can force a refresh of the ID token on the client by calling user.reload(), to ensure that the new claims will be present before the auto-refresh.

attributes.headers getting lost after a http Request call in Mulesoft?

I am getting some attributes in an API but all getting lost after an HTTP request connector in mule4.
why is it happening?
Look in the connector's configuration properties -> advanced tab for the connector configuration (in this case the HTTP connector's "request" operation) and you'll find a target variable and target value. If you fill in the target with a name - this does an enrichment to avoid overwriting the Mule message. If you leave it blank (the default) it will save the message (attributes, payload) over the top of the existing one - which is what you're seeing now. This mirrors the old mule 3 functionality, but sometimes you want it to leave what you have there alone.
So for the target value you get to pick exactly what gets saved.. If you want just payload: put that in. If you want both payload and attributes - I'd use "message" as that will mean you get both payload and attributes saved in the variable. Of course you may not want as much saved, so feel free to put in whatever dataweave expression you like - so you could even create something with bits from anywhere like:
{
statusCode: attributes.statusCode,
headers: attributes.headers,
payload: payload
}
A connector operation may replace the attributes with those of the operation. If you need to preserve the previous attributes you need to save them to a variable.
This is a default behaviour of MuleSoft. Whenever request crosses to transport barrier it losses existing attributes. You need to preserve attribute before HTTP Request.

Overriding ModelBindingMessageProvider error messages

I have a .net core 2.2 webapi. There is a POST action that accepts a model. The model has a Guid as one of the properties. When I post this model but supply a string and not a Guid, I get a ModelState.IsValid = false, which is correct. The default model binding error message is "Error converting value \"string\" to type 'System.Guid'. Path 'memberId', line 3, position 22." This is not a friendly message that I want to return, also, this message needs to get localized to user's language. All the resources that I have read said I need to set the accessor for ModelBindingMessageProvider in the AddMvC() options. i.e.
services.AddMvc(options => options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => "blah blac");
I have set ALL of the accessors on there and it still doesn't change the default message. Anyone knows how to set those default values?
The issue is that the InputFormatter is throwing exception and the exception message is used for the modelstate entry. You can disable this in services.AddMvc().AddJsonOptions(options => options.AllowInputFormatterExceptionMessages = false;). This will add an empty string for the error message, which you can detect and then just display a generic message to user. I have not found a better way of doing this but this method will suffice for now.

Receiving "Invalid policy document or request headers!"

I am attempting to upload a file to S3 following the examples provided in your documentation and source files. Unfortunately, I'm receiving the following errors when attempting an upload:
[Fine Uploader 5.3.2] Invalid policy document or request headers!
[Fine Uploader 5.3.2] Policy signing failed. Invalid policy document
or request headers!
I found a few posts on here with similar errors, but those solutions didn't help me.
Here is my jQuery:
<script>
$('#fine-uploader').fineUploaderS3({
request: {
endpoint: "http://mybucket.s3.amazonaws.com",
accessKey: "changeme"
},
signature: {
endpoint: "endpoint.php"
},
uploadSuccess: {
endpoint: "success.html"
},
template: 'qq-template'
});
</script>
(Please note that I changed the keys/bucket names for security sake.)
I used your endpoint-cors.php as a model and have included the portions that I modified here:
require 'assets/aws/aws-autoloader.php';
use Aws\S3\S3Client;
// These assume you have the associated AWS keys stored in
// the associated system environment variables
$clientPrivateKey = $_ENV['changeme'];
// These two keys are only needed if the delete file feature is enabled
// or if you are, for example, confirming the file size in a successEndpoint
// handler via S3's SDK, as we are doing in this example.
$serverPublicKey = $_ENV['AWS_SERVER_PUBLIC_KEY'];
$serverPrivateKey = $_ENV['AWS_SERVER_PRIVATE_KEY'];
// The following variables are used when validating the policy document
// sent by the uploader.
$expectedBucketName = $_ENV['mybucket'];
// $expectedMaxSize is the value you set the sizeLimit property of the
// validation option. We assume it is `null` here. If you are performing
// validation, then change this to match the integer value you specified
// otherwise your policy document will be invalid.
// http://docs.fineuploader.com/branch/develop/api/options.html#validation-option
$expectedMaxSize = (isset($_ENV['S3_MAX_FILE_SIZE']) ? $_ENV['S3_MAX_FILE_SIZE'] : null);
I also changed this:
// Only needed in cross-origin setups
function handleCorsRequest() {
// If you are relying on CORS, you will need to adjust the allowed domain here.
header('Access-Control-Allow-Origin: http://test.mydomain.com');
}
The POST seems to work:
POST http://test.mydomain.com/somepath/endpoint.php 200 OK
318ms
...but that's where the success ends.
I think part of the problem is that I'm not sure what to enter for "clientPrivateKey". Is that my "Secret Access Key" I set up with IAM?
And I'm definitely unclear on where I get the serverPublicKey and serverPrivateKey. Where am I generating a key-pair on the S3? I've combed through the docs, and perhaps I missed it.
Thank you in advance for your assistance!
First off, you are using endpoint-cors.php in a non-CORS environment. Communication between the browser and your endpoint appears to be same-origin, based on the URL of your signature endpoint. Switch to the endpoint.php example.
Regarding your questions about the keys, you should have create two distinct IAM users: one for client-side operations (heavily restricted) and one for server-side operations (an admin user). For each user, you'll have an access key (public) and a secret key (private). You always supply Fine Uploader with your client-side public key, and use your client-side private key to sign requests server-side. To perform other, more restricted operations (such as deleting files), you should use your server user keys.

how to set a property globally in wso2 ESB

I am trying to figure out how to implement session management in wso2 esb.So i have written a class mediator which generates session_ID that i want to store.For storing the session id I am using following code as:
org.apache.axis2.context.ServiceContext serviceContext = org.apache.axis2.context.MessageContext
.getCurrentMessageContext().getServiceContext();
serviceContext.setProperty("SessionIDGlobal", uuid);
But while running it in my esb's proxy it throws null pointer exception at getCurrentMessageContext part.I have followed another approach where-in i am storing the sessionID in property mediator and tried to get its value but when i click postRequest operation after generateSessionID operation from try-it. all the property gets reset and my sessionID property gives me null value. What should i do to rectify this problem? Is there any alternate way?
You have to create servicecontext like this;
ConfigurationContext cfgCtx =(((Axis2MessageContext) synCtx).getAxis2MessageContext(). getConfigurationContext();
cfgCtx.getOperationContext().getServiceContext();
You should store in the Message context but you have stored in the service Context. please refer this to understand how you can set the properties at different scopes. Synapase (default), Axis2, Transport etc.
Please refer this blog post for complete details.
http://blog.facilelogin.com/2011/02/wso2-esb-property-mediator-different.html