What is the best way to validate input parameters? - rest

I'm creating a simple Rest Api with the basic layering Controller-Service-Repository.
I have the following questions:
Where should I check if the correct parameters are given?
How should I validate thiese parameters e.g throw Response error?

You could validate your parameters on the first middleware (or after the authorization middleware). For example, in an express application you could pass your request body into a joi validation scheme.
Depends on your business logic. You can either set default values for parameters not defined by user or throw error. For example, if a user has not given any username or password parameter, then you should throw an error. All errors should be handled by the last middleware and return a relevant status code (401, 402, etc) with an information message if needed.

Related

Using OAuth2 how do I pull the access token into a variable?

I am trying to make a call to an authorization endpoint using OAuth2 with grant type Client Credentials - my call is successful - that is not an issue. However, I, now, want to take the access token that is returned and put it in a variable so I may use it in subsequent calls without having to manually cut-and-paste to my other calls.
When the call returns I see the token I desire to copy in the Access Token field at the bottom of the OAuth2 window (the one shown below that says expires in 42 minutes) AND I see it in the Authorization field on the Timeline tab of the results. I just can't figure out how to get access to it so I may dump it into variable.
The gif on the FAQ goes really fast, and does not provide step by step. Also, I didnt find any answer on YouTube or other websites, so I thought to share step by step for chaining requests on Insomnia.
Create a POST query to obtain your access token. Notice that my access token is returned in the field called "access_token", we will use this in step 3. Your return field may be different.
Create a second GET request for the API that would return the data for you. In my case, I wanted to get all users from a SCIM interface. In the Bearer tab, type in Response => Body Attribute (Insomnia will autofill).
Mouse click on the Request => Body Attribute (the one you just typed in), and select the authentication post in the dropdown "Request" (this is the one you created in step 1), and in the "Filter (JSONPath)" field, type in the $.[attribute name] - where attribute name is the response that returns from authentication call. In my case, it was access_token, see step 1 for yours.
Enjoy!!
Click No Environment > Manage Environments and you will see a base environment in JSON.
Since this is in JSON, create a { "jwt_token": "Response => Body Attribute" }" pair for your token variable. Please note that "Response => Body Attribute" needs to be configured. When you type response, hit space and this option should be available.
Once done choosing "Response => Body Attribute", it will show with some gibberish content and with red background, no worries... just click it to configure. Make sure you have the same setup.
However... you need to change your request to the route where you get the token from the server and another thing is the Filter (JSONPath or XPath) change it depending on your setup.
You should have the token, stored in jwt_token variable and can use the variable on a route that you like.
Example:
If you want to save a token that is returned in a response into an environment variable, you can use request chaining in your environment variable. Take a look at this url for more details on that https://support.insomnia.rest/article/43-chaining-requests...
Here is what you could do (what I did)
Create an environment variable
For the value of the variable, use the Response => Body Attribute and under Filter (JSONPath or XPath), choose the attribute of the token in your response body (if it is "token" then put $.token).
After that just put the token environment variable wherever you need it in the following requests.
I was not able to resolve this question but was able to get around it by defining the fields in the body of the request and bypassing the OAuth2 tab completely.
You can add it as a header, by referencing the outputs of the OAuth2 request:

Invalid_request_parameter (create and sending envelopes)

I'm trying to use a service of DocuSign API in an abap project. I want to send a document to a specific email so it can be signed. But im getting the following error:
"errorCode": "INVALID_REQUEST_PARAMETER",## "message": "The request contained at least one invalid parameter. Query parameter 'from_date' must be set to a valid DateTime, or 'envelope_ids' or 'transaction_ids' must be specified.
I tried the following:
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = l_url (https://demo.docusign.net/restapi/v2/accounts/XXXXXX')
proxy_host = co_proxy_host
proxy_service = co_proxy_service
IMPORTING
client = lo_http_client
lo_http_client->request->set_method( method = 'POST').
CALL METHOD lo_http_client->request->set_header_field
EXPORTING
name = 'Accept'
value = 'application/json'.
CALL METHOD lo_http_client->request->set_header_field
EXPORTING
name = 'X-DocuSign-Authentication'
value = get_auth_header( ). (json auth header)
CALL METHOD lo_http_client->request->set_cdata
EXPORTING
data = create_body( ).
This is my body:
CONCATENATE
`{`
`"emailSubject": "DocuSign REST API Quickstart Sample",`
`"emailBlurb": "Shows how to create and send an envelope from a document.",`
`"recipients": {`
`"signers": [{`
`"email": "test#email",`
`"name": "test",`
`"recipientId": "1",`
`"routingOrder": "1"`
`}]`
`},`
`"documents": [{`
`"documentId": "1",`
`"name": "test.pdf",`
`"documentBase64":` `"` l_encoded_doc `"`
`}],`
`"status": "sent"`
`}` INTO re_data.
The api request to get the Baseurl is working fine. (I know the error is quite specific what the problem is, but i cant find any sources on the docusign api documentation that one of the mentioned parameters should be added to the request)
Thank you in regards
The error message seems to indicate that you're Posting to an endpoint that requires certain query string parameters -- but you're not specifying them as expected in the query string. I'd suggest you check the DocuSign API documentation for the operation you are using, to determine what query string parameters it requires, and then ensure that you're including those parameters in your request URL.
If you can't figure this out using the documentation, then I'd suggest that you update your post to clarify exactly what URL (endpoint) you are using for the request, including any querystring parameters you're specifying in the URL. You can put fake values for things like Account ID, of course -- we just need to see the endpoint you are calling, and what qs params you're sending.
To create an envelope, use
https://demo.docusign.net/restapi/v2/accounts/XXXXXX/envelopes
instead of
https://demo.docusign.net/restapi/v2/accounts/XXXXXX
Thank you for all the answers, i found the mistake. Creating the request wasn´t the problem. I was using the wrong "sending"-method -_-.
now its working :)
lo_rest_client->post( EXPORTING io_entity = lo_request_entity ).

Why does one HTTP GET request retrieve the required data and another retrieve []

I'm currently working on ng-admin.
I'm having a problem retrieving user data from my REST API (connected to a MongoDB) and displaying it.
I have identified the problem as the following:
When I enter http://localhost:3000/users into my browser, I get a list of all users in my database.
When I enter http://localhost:3000/users?_page=1&_perPage=30&_sortDir=DESC&_sortField=id,
I get [] as a result.
I am quite new to this, I used both my browser and the POSTMAN Chrome extension to test this and get the same result.
http://localhost:3000/users_end=30&_order=DESC&_sort=id&_start=0
This (/users_end) is a different request than /users.
It should be:
http://localhost:3000/users?end=30&_order=DESC&_sort=id&_start=0
Or, by looking at the other parameters:
http://localhost:3000/users?_end=30&_order=DESC&_sort=id&_start=0
with end or _end being the first parameter (mark the ?).
Update (it is ? and before the _, I have edited.):
If adding parameters to the request returns an empty list, try adding only one at a time to narrow down the problem (there's probably an error in the usage of those parameters - are you sure you need those underscores?).
Your REST API must have a way to handle pagination, sorting, and filtering. But ng-admin cannot determine exactly how, because REST is a style and not a standard. So ng-admin makes assumptions about how your API does that by default, that's why it adds these _end and _sort query parameters.
In order to transform these parameters into those that your API understands, you'll have to add an interceptor. This is all thoroughly explained in the ng-admin documentation: http://ng-admin-book.marmelab.com/doc/API-mapping.html

Client context validation of data

As for tracking in AEM I am using CQ_Analytics for a scenario. We have a requirement like, I have to capture a value called "sort type" which is on the page when a user clicks on a button on that page and store it in ClientContext. I have written the below Javascript function which accepts a name argument. Using some code I am able to get hold of sort type value and passing it to the below function. Now my query is, how do I validate whether the name variable is assigned to the Client Context???
I have kept an alert statement and tried checking with multiple combinations but I am unable to figure out what is the correct way to conclude that my name value has been assigned to Client Context or not. Please help with my query.
function myFunction(name) {
CQ_Analytics.record({event: 'sorttype',
values: {'sortSelectedOption': name },
componentPath: '<%=resource.getResourceType()%>'
});
alert(CQ_Analytics.record.sorttype.sortSelectedOption);
}
You can see this post how to make your custom client context and how to store your data. http://blogs.adobe.com/aemtutorials/2013/07/24/customize-the-client-context/
After you create your client context, you have in the example CQ_Analytics.CustomStoreMgr.setTraitValue function that will save your parameter into client context.

Linkedin API oAuth 2.0 REST Query parameters

I'm running into a problem with adding a query to the callback URL. I'm getting an invalid URI scheme error attempting to authorize the following string:
https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=75df1ocpxohk88&scope=rw_groups%20w_messages%20r_basicprofile%20r_contactinfo%20r_network&state=7a6c697d357e4921aeb1ba3793d7af5a&redirect_uri=http://marktest.clubexpress.com/basic_modules/club_admin/website/auth_callback.aspx?type=linkedin
I've read some conflicting information in forum posts here. Some say that it's possible to add query strings to callbacks, and others say that it results in error.
If I remove ?type=linkedin, I can authorize just fine and receive the token. It would make my life so much easier if I could use a query string on the callback url, as I need to do some additional processing in the callback.
In short, can I append a query string to the end of the callback url?
For fun, I tried encoding the callback url in the request (obviously this is a no-no according to their documentation):
https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=75df1ocpxohk88&scope=rw_groups%20w_messages%20r_basicprofile%20r_contactinfo%20r_network&state=5cabef71d89149d48df523558bd12121&redirect_uri=http%3a%2f%2fmarktest.clubexpress.com%2fbasic_modules%2fclub_admin%2fwebsite%2fauth_callback.aspx%3ftype%3dlinkedin
This also resulted in an error but was worth a shot.
The documetation here: https://developer.linkedin.com/forum/oauth-20-redirect-url-faq-invalid-redirecturi-error indicates that you CAN use query parameters. And in the first request, it appears that I'm doing it correctly. Post #25 on this page - https://developer.linkedin.com/forum/error-while-getting-access-token indicates that you have to remove the query parameters to make it work
Anyone have experience with successfully passing additional query paramaters in the callback url for the linkedin API using oAuth2.0? If so, what am I doing wrong?
I couldn't wait around for the Linkedin rep's to respond. After much experimentation, I can only surmise that the use of additional query parameters in the callback is not allowed (thanks for making my application more complicated). As it's been suggested in post #25 from the question, I've tucked away the things I need in the "state=" parameter of the request so that it's returned to my callback.
In my situation, I'm processing multiple API's from my callback and requests from multiple users, so I need to know the type and user number. As a solution, I'm attaching a random string to a prefix, so that I can extract the query parameter in my callback and process it. Each state= will therefore be unique as well as giving me a unique key to cache/get object from cache..
so state="Linkedin-5hnx5322d3-543"
so, on my callback page (for you c# folks)
_stateString=Request["state"];
_receivedUserId = _stateString.Split('-')[2];
_receivedCacheKeyPrefix = _stateString.Split('-')[0];
if(_receivedCacheKeyPrefix == "Linkedin") {
getUserDomain(_receivedUserId);
oLinkedIn.AccessTOkenGet(Request["code"],_userDomain);
if (oLinkedin.Token.Length > 0) {
_linkedinToken = oLinkedin.Token;
//now cache token using the entire _statestring and user id (removed for brevity)
}
You not allowed to do that.
Refer to the doc: https://developer.linkedin.com/docs/oauth2
Please note that:
We strongly recommend using HTTPS whenever possible
URLs must be absolute (e.g. "https://example.com/auth/callback", not "/auth/callback")
URL arguments are ignored (i.e. https://example.com/?id=1 is the same as https://example.com/)
URLs cannot include #'s (i.e. "https://example.com/auth/callback#linkedin" is invalid)