Passing array of object from response to body of another request - postman

I have a API response as below, wherein I need to send the 'JobSalesPersons' array block from the response to another API's calls body (see below body section below).
Response:
"Data": {
"AllowTranslationValue": "No",
"NumberOfOutstandinPages": 0,
"JobSalesPersons": [
{
"JobSalesPersonId": 5204,
"SalesPersonId": 769,
"JobIdentity": 7013,
"Ownership": 100.00,
"SalesPersonName": "test",
"JobName": "PostmanAPIJob_2022-06-02_12_53_09",
"JobID": "HIP22060007",
"isShowOwnership": false
}
],
"JobDescription": "Testing for API1"
}
Body:
{
"Attachments": [],
"AllowPrintSchedule": true,
"IsPDFConvertible": false,
"AllowTranslation": false,
"JobSalesPersons": [
{
"JobSalesPersonId": 5204,
"SalesPersonId": 769,
"JobIdentity": 7013,
"Ownership": 100.00,
"SalesPersonName": "test",
"JobName": "PostmanAPIJob_2022-06-02_12_53_09",
"JobID": "HIP22060007",
"isShowOwnership": false
}
}

This would work for you.
Request 1:
Tab Tests
pm.environment.set("JobSalesPersons", JSON.stringify(pm.response.json().Data.JobSalesPersons));
Request 2:
Tab Body
{
"Attachments": [],
"AllowPrintSchedule": true,
"IsPDFConvertible": false,
"AllowTranslation": false,
"JobSalesPersons": {{JobSalesPersons}}
}

Related

How to completely exclude sub-rule from managed rule in AWS WAF v2?

I trying to implement WAF protection at AWS and using WAS WAF v2.
What I need:
Add custom responses when request is blocked
Exclude payload body size check (SizeRestrictions_BODY) from AWS-AWSManagedRulesCommonRuleSet rule
Block request if any other check is positive
What I tried:
Here is JSON of my example WEB ACL:
{
"Name": "example",
"Id": "uuiduuid-uuid-uuid-uuiduuid",
"ARN": "arn:aws:wafv2:ap-northeast-1:0123456789:regional/webacl/example/uuiduuid-uuid-uuid-uuiduuid",
"DefaultAction": {
"Allow": {}
},
"Description": "WAF example",
"Rules": [
{
"Name": "AWS-AWSManagedRulesAmazonIpReputationList",
"Priority": 0,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesAmazonIpReputationList"
}
},
"OverrideAction": {
"Count": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "AWS-AWSManagedRulesAmazonIpReputationList"
}
},
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 1,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet",
"ExcludedRules": [
{
"Name": "SizeRestrictions_BODY"
}
]
}
},
"OverrideAction": {
"Count": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "AWS-AWSManagedRulesCommonRuleSet"
}
},
{
"Name": "BlockLabeledRequests",
"Priority": 2,
"Statement": {
"OrStatement": {
"Statements": [
{
"LabelMatchStatement": {
"Scope": "NAMESPACE",
"Key": "awswaf:managed:aws:"
}
},
{
"NotStatement": {
"Statement": {
"LabelMatchStatement": {
"Scope": "LABEL",
"Key": "awswaf:managed:aws:core-rule-set:SizeRestrictions_Body"
}
}
}
}
]
}
},
"Action": {
"Block": {
"CustomResponse": {
"ResponseCode": 499,
"CustomResponseBodyKey": "custom-response-body",
"ResponseHeaders": [
{
"Name": "x-custom-header",
"Value": "hello-world"
}
]
}
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "BlockLabeledRequests"
}
}
],
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": true,
"MetricName": "waf-example"
},
"Capacity": 727,
"ManagedByFirewallManager": false,
"LabelNamespace": "awswaf:0123456789:webacl:example:",
"CustomResponseBodies": {
"custom-response-body": {
"ContentType": "APPLICATION_JSON",
"Content": "{\n \"error\": \"oops, something wrong\"\n}"
}
}
}
What is happening here:
Request go through AWSManagedRulesAmazonIpReputationList rule. If this check is not passed (positive) awswaf:managed:aws:rule-set-name:rule-name label will be added.
Because of default action overridden to Count request go to next rule in any way. (Why I can't block bad request immediately? Because default block action of the rule returning standard response, but I have to customize it. And that is not possible to override Block response. Only Count may be overridden. And that is stupid limitation N1.)
Request go through AWS-AWSManagedRulesCommonRuleSet rule and even if SizeRestrictions_BODY's action overridden to Count, the rule still adding own label awswaf:managed:aws:core-rule-set:SizeRestrictions_Body to request but not blocks it (It is not possible to disable rule at all, at least Count should be triggered. Stupid limitation N2.)
Rule set action overridden to Count, so request goes to final rule
Final rule BlockLabeledRequests checks if any label starting from awswaf:managed:aws: exists in request and blocks it if YES. But SizeRestrictions_Body adding own label starting from awswaf:managed:aws: and that makes impossible to use awswaf:managed:aws: existence check. Because of it I set two conditions: Request will be blocked if has label starting from awswaf:managed:aws: or doesn't have label awswaf:managed:aws:core-rule-set:SizeRestrictions_Body. In most cases it working correct, but if we add to request big sized payload SizeRestrictions_Body will be triggered and request will be passed even if we have another rules triggered, and that is a security hole. WAF if statements logic is pretty dumb and only one possible way to exclude SizeRestrictions_Body is to check all awswaf:managed:aws:rule-set-name:rule-name one by one with if and statement and exclude SizeRestrictions_Body from it. But it is inconvenient because number of rules is pretty big. (stupid limitation N3.)
QUESTION: So is here any way to set thing What I need by any another logic? Or just exclude only awswaf:managed:aws:core-rule-set:SizeRestrictions_Body label check but use wildcard label check awswaf:managed:aws: at same time? Or may be here is some way to force remove awswaf:managed:aws:core-rule-set:SizeRestrictions_Body label from request before label checking?
AWS WAF limitations making it pretty useless

Problem with Post action on Strapi via Postman

The problem is I can't perform PUT or POST with Postman app. But DELETE is possible. And yes I enabled all actions for public users.
Here is GET request result:
{
"data": [
{
"id": 2,
"attributes": {
"title": "23123",
"game": "1231",
"players": "2312313",
"createdAt": "2022-02-19T16:36:34.221Z",
"updatedAt": "2022-02-19T16:36:34.971Z"
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
And here is my entries for POST request:
finally after requesting POST here is result:
{
"data": null,
"error": {
"status": 400,
"name": "ValidationError",
"message": "Missing \"data\" payload in the request body",
"details": {}
}
}
What is the problem?
I finally found the solution. u need to put Body in raw and set it as Json! default is Text.
and POST example is :
{
"data": {
"title": "Hello",
"relation": 2,
"relations": [2, 4]
}
}

Google action request for grant_type=refresh_token does not update conversation object with new access token

I'm developing a google action which is configured for account linking using Linking Type: "OAuth" / "Authorization code". The OAuth2 authorization server functions are hosted in the same place as the linked business application server, so I have full visibility of the traffic in both regards.
The initial linking process works perfectly every time; however, a problem arises when the original access token expires, and a new one is requested grant_type=refresh_token. Included below are the sanitized log contents from our server's execution logic generated by invocation of the google action using Actions Console "Test" simulator, after the original access token has expired. As expected, the google action first requests a new access token by calling the Token Url with grant_type=refresh_token. Our server then returns content to the caller
shown below under SmartAssistOAuthToken: result= as
{"expires_in":600,"token_type":"Bearer","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA"}
Having received the new token, the Google action proceeds to the main intent / webhook handler which contains a REST request back to the same server to retrieve some information about the current user's account.
This is shown below as: >****> 2021/07/15 12:16:18 (-05:00) - /cgi-bin/w2w.dll/sa_anon?cmd=login...
>********> 2021/07/15 12:16:15 (-05:00) - /cgi-bin/w2w.dll/AoG_token?
----------------------------------------------------------------------------------------------------
SmartAssistOAuthToken: contentfields=
grant_type=refresh_token
refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.65URfGpCL4s9nZiUc2pvYRZydK6jKanI5DZAZm04BtM
client_id=xxxx
client_secret=xxxx
----------------------------------------------------------------------------------------------------
SmartAssistOAuthToken: result= (...using 600 to speed things up a bit)
{"expires_in":600,"token_type":"Bearer","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA"}
----------------------------------------------------------------------------------------------------
>********> 2021/07/15 12:16:18 (-05:00) - /cgi-bin/w2w.dll/sa_anon?cmd=login&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
----------------------------------------------------------------------------------------------------
SmartAssistLogin: QueryFields=
cmd=login
access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
----------------------------------------------------------------------------------------------------
ValidAccessTokenInfo: AccessToken's JWT has expired.
----------------------------------------------------------------------------------------------------
SmartAssistError: Error={"error_uri":"https:xxxx","error_description":"Invalid authorization credential.","error":"invalid_request"}
At the end of the "login" REST request is the access token which I read from conv.session.params.bearerToken, and then add to the url.
/cgi-bin/w2w.dll/sa_anon?cmd=login&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4
However, the value provided by conv.session.params.bearerToken (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4) is not the new one returned to the refresh token request (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.5XRFvkrBr7PCfyyqSMW1nNJBI0EceQgFrMA-6I04sQA). As such, my server returns an error for the request because the original token is no longer valid / expired.
The entire (sanitized) incoming conv object is as follows, wherein all references to bearerToken are the same recently expired token:
{
"overwrite": false,
"digested": false,
"request": {
"handler": {
"name": "main"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": "Talk to work assistant"
},
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"home": {
"params": {}
},
"device": {
"capabilities": ["SPEECH", "RICH_RESPONSE", "LONG_FORM_AUDIO"],
"timeZone": {
"id": "America/Chicago",
"version": ""
}
}
},
"headers": {
"host": "us-central1-work-assistant-b9910.cloudfunctions.net",
"user-agent": "Google-ActionsOnGoogle/1.0",
"transfer-encoding": "chunked",
"accept-encoding": "gzip, deflate, br",
"content-type": "application/json;charset=UTF-8",
"forwarded": "for=\"66.249.83.57\";proto=https",
"function-execution-id": "zn46t5q3mkfr",
"google-actions-api-version": "3",
"google-assistant-signature": "xxxx",
"traceparent": "00-6b5c4d0aa670f39009910ec1f7e908ee-2abd7ee7886b286d-00",
"x-appengine-country": "ZZ",
"x-appengine-default-version-hostname": "d1c092144ed53556ap-tp.appspot.com",
"x-appengine-https": "on",
"x-appengine-request-log-id": "60f06d6200ff0c6741e353b4fb0001737e6431633039323134346564353335353661702d7470000133343061346661353033613135323331626363326539303833646463386639313a310001010c",
"x-appengine-timeout-ms": "599998",
"x-appengine-user-ip": "66.249.83.57",
"x-cloud-trace-context": "6b5c4d0aa670f39009910ec1f7e908ee/3079757253082556525",
"x-forwarded-for": "66.249.83.57",
"x-forwarded-proto": "https",
"connection": "close"
},
"handler": {
"name": "main"
},
"intent": {
"name": "actions.intent.MAIN",
"query": "Talk to work assistant",
"params": {}
},
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"device": {
"capabilities": ["SPEECH", "RICH_RESPONSE", "LONG_FORM_AUDIO"],
"currentLocation": {},
"timeZone": {
"id": "America/Chicago",
"version": ""
}
},
"home": {
"params": {}
},
"expected": {},
"context": {},
"prompt": {
"override": false
},
"_internal": {
"promptSet": false,
"orig": {
"scene": {
"name": "Main",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {}
},
"session": {
"id": "ABwppHFsSDza7b0R74-kOOBCudqHWhrjIMma8mnaLjTDFg55O68MIjBIPRgaSEyAH31RPOJGG9VhrIl283LWY6xXZsw",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"AccountLinkingSlot": "LINKED",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxx.FfUGlS71IaIU3LdkiJtUKfBBZwjSaN5D0s1ECpzxop4",
},
"accountLinkingStatus": "LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-07-15T16:15:48Z"
},
"home": {
"params": {}
}
}
}
}
The relevant google action webhook code looks something like this:
const {conversation,
Suggestion,
Simple,
Card,
Image
} = require('#assistant/conversation');
const functions = require('firebase-functions');
const app = conversation();
...
const getAccessToken = (conv) => {
return conv.session.params.bearerToken;
};
...
app.handle('main', async conv => {
...
console.log("main: >>>>>>>>>>>>>> conv=",JSON.stringify(conv));
...
if (conv.user.verificationStatus !== 'VERIFIED') {
conv.add('Sorry, your account is not verified yet so you cannot be here.');
return;
}
...
await getRemoteData(`${getFullredirectpath()}sa_anon?cmd=login&access_token=${getAccessToken(conv)}`)
.then((response) => {
(success handling...)
})
.catch((err) => {
(Error handling...)
return;
});
...
}
This problem doesn't happen every time a token is refreshed, but it does happen frequently, and seemingly more so, the longer the time between sessions. I can almost always count on it to happen overnight.

SSRS Subscription using REST API

Can we create/modify SSRS Subscription using REST API as SQL Server Reporting services 2017 supports REST API calls?
here is an online swagger example they built, but some properties are invalid or missing. Ex: Schedule property is missing and ExtensionSettings.ParameterValues is an array instead of an object
https://app.swaggerhub.com/apis/microsoft-rs/SSRS/2.0#/Subscriptions/GetSubscriptions
here is an example of a body message that works for me when posting:
{ "DataQuery": null, "DeliveryExtension": "Report Server Email", "Description": "test3", "EventType": "TimedSubscription", "ExtensionSettings": { "Extension": "Report Server Email", "ParameterValues": [ { "IsValueFieldReference": false, "Name": "TO", "Value": "userName" }, { "IsValueFieldReference": false, "Name": "IncludeReport", "Value": "True" }, { "IsValueFieldReference": false, "Name": "RenderFormat", "Value": "PDF" }, { "IsValueFieldReference": false, "Name": "Subject", "Value": "#ReportName was executed at #ExecutionTime" }, { "IsValueFieldReference": false, "Name": "IncludeLink", "Value": "True" }, { "IsValueFieldReference": false, "Name": "Priority", "Value": "NORMAL" } ] }, "IsActive": true, "IsDataDriven": false, "LastRunTime": null, "LastStatus": "New Subscription", "LocalizedDeliveryExtensionName": "E-Mail", "ModifiedBy": "userName", "ModifiedDate": "2020-09-04T13:45:51.343-05:00", "Owner": "userName", "ParameterValues": [], "Report": "/Folder Name/Report Name", "Schedule": { "Definition": { "EndDate": "0001-01-01T00:00:00Z", "EndDateSpecified": false, "Recurrence": { "DailyRecurrence": { "DaysInterval": 1 }, "MinuteRecurrence": null, "MonthlyDOWRecurrence": null, "MonthlyRecurrence": null, "WeeklyRecurrence": null }, "StartDateTime": "2020-09-04T02:00:00-05:00" }, "ScheduleID": null }, "ScheduleDescription": "At 2:00 AM every day, starting 9/4/2020" }

How to send a request?

I need to send a request with the following data
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
I need to send them to https://api.fondy.eu/api/settlement
But I never did that. I am not familiar with DRF at all. Tell me how to implement it, please.
If we visit the endpoint, it says that only POST methods are allowed. We can make a POST request for example with the requests package.
import requests
data = {
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.post('https://api.fondy.eu/api/settlement', data=data, headers=headers)
The header can be important, since it tells you in what format you make your reqest, and some APIs do not work if you do not set the Content-type properly.
The response is here a Response object, and you can parse the response to a Python dictionary with:
response.json()
locally this gives me:
{'response': {'error_code': 1002,
'error_message': 'Application error',
'request_id': 'iUxQzJfyBuxdI'}}
The status code is 200, so that probably means that the callback you specified was not valid (or some other items in your request).
You could use DRF as the documentation :
https://www.django-rest-framework.org/tutorial/2-requests-and-responses/
Or without DRF :
# importing the requests library
import requests
# api-endpoint
URL = "https://api.fondy.eu/api/settlement"
# defining a params dict for the parameters to be sent to the API
data =
"order": {
"server_callback_url": "http://site.id/callback",
"currency": "UAH",
"amount": "1400",
"order_type": "settlement",
"response_url": "http://site.id/test/responsepage/",
"order_id": "test1234561467462099.19",
"operation_id": "test1234561467462099.19",
"order_desc": "test order",
"merchant_id": 700001,
"receiver": [
{
"requisites": {
"amount": 100,
"merchant_id": 500001
},
"type": "merchant"
},{
"requisites": {
"amount": 200,
"merchant_id": 600001
},
"type": "merchant"
},
]
}
# sending get request and saving the response as response object
r = requests.POST(url = URL, data= data)
# extracting data in json format
data = r.json()
Maybe you would like to try the API before writing code, there is tool like postman to do this quickly :)