authenticate HTTP request to /admin-ajax.php on wordpress - wordpress

I'm trying to download a file provided by a Wordpress plugin Pinpoint World. This plugin uses admin-ajax.php to retrieve that file in admin UI.
I want to periodically download it for backup. How can I download it using curl? It looks like it needs to authenticate the request using cookies (as the browser does while inspecting the requests). Anyway I can simulate that using curl in bash?
The following results in 400 Bad Request:
curl "https://${HOST}/wp-admin/admin-ajax.php" \
--data-raw 'action=dopbsp_reservations_get&type=xls&calendar_id=1&start_date=&end_date=&start_hour=00%3A00&end_hour=23%3A59&status_pending=false&status_approved=false&status_rejected=false&status_canceled=false&status_expired=false&payment_methods=&search=&page=1&per_page=25&order=ASC&order_by=check_in' \
-o /tmp/output.xls
Basic authentication (using --user) didn't work either.
How can I authenticate to wordpress' admin-ajax, using bash?

You can just pass the cookie from your authenticated logged-in user on your curl request
First, login to your wordpress site on your browser.
Then hit F12 and go to application tab, then cookies
then copy the cookies that looks like wordpress_logged_in_xxxxxxxxxxxx
then you can use it on your curl request
example to run basic test,
create a simple ajax request which return a user object if your request is authenticated. otherwise, it will return null
add_action( 'wp_ajax_sample_duh', 'sample_duh');
add_action( 'wp_ajax_nopriv_sample_duh', 'sample_duh');
function sample_duh() {
wp_send_json([
'user' => wp_get_current_user()
]);
}
run your curl request with the cookies you copied from the browser.
e.g.
curl -X POST --cookie "wordpress_logged_in_xxxxxxxxxxxxxx=xxxxxxxxxxx" http://mydomain.me/wp-admin/admin-ajax.php?action=sample_duh
You should get the user object in your response if you have a valid cookie,
then use the same cookie with your actual curl request

Related

Wordpress Gravity Form response issue

I am working on a WordPress site that uses a gravity form. The gravity form has 20 questions, after a user fills it out they press submit and then a page loads saying the form has been submitted. The form submits to an AWS API that checks the form and returns a percent correct to the gravity form inside the admin panel. I am trying to get that result to display on the website so that the user can see. I don't know how to get the response. When i try to access the AWS endpoint through curl or postman, I get forbidden errors. I am using the endpoint and the API key listed in the gravity forms settings
This is the latest curl I tried:(I changed the base64 code for this example)
curl -X GET \
https://reproductivehealth.adrianmiddletonfwd.co.uk/wp-json/gf/v2/entries \
-H 'Authorization: Basic WRThbTpaWlVZcEtoVlFQdndDMTVybktDZZz=' \
-H 'Content-Type: application/json'
I get this error:
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}
I've also tried to create a post using the API endpoint and API key provided within the form settings. I dont know what else to try, I just need to get that result.

Can't send POST request to Google Apps Script

I'm trying to deploy a Google Apps Script as a web app, but while I have no problem doing GET requests, I'm having trouble with POST requests.
My code is very simple:
function doGet(request) {
var result = JSON.stringify({ data: 'Thanks, I received the GET request' });
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
function doPost(request) {
var result = JSON.stringify({ data: 'Thanks, I received the POST request' });
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
I deployed the web app with "Execute the app as: Me" and "Who has access to the app: Anyone, even anonymous". Every time I do some change I re-deploy it with a new version ("Project version: New").
After publishing, my curl GET request works perfectly:
> curl -L https://script.google.com/macros/s/$SCRIPT_ID/exec
{"data":"Thanks, I received the GET request"}
However, my POST request (curl -L -XPOST https://script.google.com/macros/s/$SCRIPT_ID/exec) just shows me a generic Google HTML page saying "Sorry, unable to open the file at this time. Please check the address and try again".
I tried sending some data and providing a content type, but nothing changed. I also tried changing the output type to just ContentService.createTextOutput("OK"), but it didn't work either. Curiously, deleting doPost changes the error message to "Script function not found: doPost" as expected. If it makes any difference, this script is attached to a Google spreadsheet.
Are there any special permissions I need to give to the script for POST requests specifically?
It seems that the problem was with my usage of curl, on subtle differences between using -XPOST and not using it. As suggested by Tanaike, changing from:
curl -L -XPOST https://script.google.com/macros/s/$SCRIPT_ID/exec
to
curl -L -d '' https://script.google.com/macros/s/$SCRIPT_ID/exec
Solved the issue. Even though curl helpfully says "Unnecessary use of -X or --request, POST is already inferred" when I do a request with -XPOST and a payload, its behavior is different in the presence of redirects. -XPOST forces all subsequent requests after a redirect to be made using POST as a method. On the other hand, if I don't specify -XPOST, the requests after the first POST are made as GET requests. I don't know if this is curl's intended behavior, but it's certainly unintuitive.

Creating URL with headers

I can curl a website URL by passing on some header params. I am trying to get the same result on the browser but I cannot build the URL for the browser in the right way.
My curl looks something similar
curl -X GET -u 'xyz#gmail.com' -H "app-key: some-keys" -H "account-email: procurement#gmail.com" -H 'Content-Type: application/json' -d 'paused=false' https://api.pingdom.com/api/2.1/checks
When prompted for the password, i can give the password and Iget the JSON response.
Now I try to build the same URL on my browser. The browser prompts for user name and password which I have already given.
Now my URL looks like this.
https://api.pingdom.com/api/2.1/users?account-email=procurement#gmail.com&app-key=some-key
I get a forbidden (as JSON reponse) when I try from the browser and from Curl I get the proper JSON response.
How can I add header params to a URL when pinging from the browser?
How can I add header params to a URL when pinging from the browser?
That's not possible. Besides it, from the browser address bar you won't be able to use HTTP methods other than GET.
So I advise you to you proper tools to target/test your Web API such as Postman or Paw.

Login and post using curl in one command

I am configuring a solar device on the field that runs a small web server to upload data to a web service.
However the web service needs to have authentication and ssl. There is a way to configure an upload url endpoint but not a way to save the headers to a file etc.
Is it possible to login pass the headers to the next request and post data all in one request?
Something like
curl -d "email=sadf#yahoo.com&password=asds&submit=Login" --dump-header headers http://localhost:3000/users/login **>** curl -X POST http://localhost:3000/test --data-urlencode point="<status>A note</status>" -H 'Content-Type: application/xml'

Request parameters are not passed to the backend service

I configured a REST webservice (a Spring Boot webapplication) on WSO2 AM and used the default /* mapping for resources. My webservice takes an assignee (text) and file parameters.
When I perform the calls, I've noticed that request parameters are not forwarded (HTTP Headers are) to the backed services. For example:
curl -i -X POST -H "Content-Type: multipart/form-data" -H "X-PD20-BillingSubscriptionId: e87d4400-b05f-4f40-9c39-06ae4d28cf4d" -H "Authorization: Bearer rrxRV5F6jdkSBcEPXv7I1yFl2x8a" -F "documentFile=#src/test/resources/sample-files/test-fea-1firma.pdf" -F "assignee=bla.bla#gmail.com" http://api.linksmt.it:8280/fea/1.0.0/signRequest
As you can see, It's a form that posts 2 fields, one of them being a file and another a simple text field.
The call is succesfully forwarded to the backed service but without the actual fields values (the headers instead are correctly passed, though their keys are lower-cased, that is "X-PD20-BillingSubscriptionId" is passed as "x-pd20-billingsubscriptionid").
Any hint on why is this happening?
Thanks
Ok, the problem was the same as described in multipart form data file upload using WSO2 API manger ? and I had to uncomment the declarations for
within the $WSO2_AM/repository/conf/axis2/axis2.xml file (and restart the server).

Resources