How to emulate curl requests in rails app? - ruby-on-rails

I want to test that a PUT to an endpoint (products/:id) works, but when I try
curl -X PUT -d listing_id_created=True localhost:3000/products/27
it gives ActionController::InvalidAuthenticityToken, which I now realise is the expected result (since there's no authenticity token provided since the PUT is coming from curl and curl doesn't know anything about it).
So my question is how do I run some simple curl PUTs (or any other verbs) to check that endpoints work correctly? Is the only solution to simply disable/skip the authenticity token?

Related

Jenkins "Error 403 No valid crumb was included in the request"

I am trying to trigger a Jenkins build by post request from my Windows computer, using the following commands.
First, I obtain the crumb using...
curl http://JENKINS-URL/crumbIssuer/api/xml?xpath=//crumb
The response is this...
<crumb>string-of-digits<\crumb>
I then use the command
curl -u USERNAME:PASSWORD -X POST -H "Jenkins-Crumb:string-of-digits" http://JENKINS-URL/job/my-job/buildWithParameters?token=my-token
The username is correct, the password is correct, the crumb is exactly the string of digits that I got from the first command (everything between the crumb> at the beginning and <\crumb> at the end), the token matches the token I have specified in Jenkins. But still, I am getting the response
Error 403 No valid crumb was included in the request
In Configure Global Security -> CSRF Protection, I also have "Enable proxy compatibility" checked and am using "Default Crumb Issuer".
Does it look like I am missing anything here? Forgetting any steps? Improperly formatted commands? Anything else you might be able to think of?
I have followed the steps and formatted my command like the solution here as well, and still no luck..
https://linuxacademy.com/community/posts/show/topic/28964-no-valid-crumb-was-included-in-the-request
In addition to this, I have also tried saving the cookies from the first request to get the crumb, and then I pass the file I saved the cookies to into the second curl command, see below for the command. Still I am getting the 403 No valid crumb...
Here are the commands using cookies...
wget --keep-session-cookies --save-cookies cookies.txt --auth-no-challenge --user admin --password my_password -q --output-document - http://JENKINS-URL/crumbIssuer/api/xml?xpath=//crumb
curl --cookie cookies.txt -u admin:my_password -H "JenkinsCrumb: string-of-digits-from-stdout" -X POST http://JENKINS-URL/job/my-job/buildWithParameters?token=my-token
I have finally discovered the answer. I thought that I could specify my actual account password, but it turns out that I needed to use an API token to authenticate. Using the API token instead of my password on the above commands with cookies allowed me to trigger my build remotely.
enter image description here
I finally resolved this issue by selecting the jenkins own user database in security realm

Can't get HTTP PATCH to work on Google Cloud Run instance

I have running a webserver called Postgrest which generates a REST API on top of a postgres DB. I have this running in Google Cloud run, and have it working for the most part. The HTTP actions I need to take are POST, GET, DELETE and PATCH.
Everything works correctly except PATCH, which I use to update an existing value in the DB.
When I run the command from curl command prompt, no error is given, but it doesnt'w work.
https://postgrest-q5mmtshbma-uc.a.run.app/notes?noteid=eq.3 -X PATCH -H "Authorization: Bearer $TOKEN" -H "Conte nt-Type: application/json" -d '{"note" : "updated it!"}'
When I run this against same postgrest version running locally, everything works correctly, so it has me thinking there might be an issue with Google Cloud run and not allowing/accepting PATCH requests? Again, POST, DELETE, GET all work fine.
Anyone have any insight what might be happening here?
I ultimately found the issue with this was related to using RLS (Row level security) in the PostGres DB, and I had setup specific policy's for insert, update, delete, and select.
The "update" policy I believe was incorrectly setup, so the update failed, but both postgre DB and the postgrest WebServer did not provide an errors to this effect.
Ultimately, when I re-created the update policy on this table, the PATCH (update) command ran successfully.

Convert curl request to Rails Net::HTTP

An API I am using is telling me to make a GET request as follows:
curl -s \
-X GET \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3/REST/template/$template_ID/detailcontent
and I am trying to convert this to Rails' NET::HTTP. I've tried adding a req.body, adding ?user=TOKEN and keep getting a 401 Unauthorized response. I've tested it in curl and my credentials are valid.
How do I include the --user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" portion in my GET request?
--user in curl is used for server authentication. In your case, after --user you provide username and password separated with colon. This will be used for the http basic authentication.
Since you know that, you can check how to do the basic authentication with NET::HTTP here or here.

How to get Openshift session token using rest api calls

As part of an automated tests suite I have to use OpenShift's REST APIs to send commands and get OpenShift's status. To authenticate these API calls I need to embed an authorization token in every call.
Currently, I get this token by executing the following commands with ssh on the machine where OpenShift is installed:
oc login --username=<uname> --password=<password>
oc whoami --show-token
I would like to stop using the oc tool completely and get this token using HTTP calls to the APIs but am not really able to find a document that explains how to use it. If I use the option --loglevel=10 when calling oc commands I can see the HTTP calls made by oc when logging in but it is quite difficult for me to reverse-engineer the process from these logs.
Theoretically this is not something specific to OpenShift but rather to the OAuth protocol, I have found some documentation like the one posted here but I still find it difficult to implement without specific examples.
If that helps, I am developing this tool using ruby (not rails).
P.S. I know that normally for this type of job one should use Service Account Tokens but since this is a testing environment the OpenShift installation gets removed and reinstalled fairly often. This would force me to re-create the service account every time with the oc command line tool and again prevent me from automatizing the process.
I have found the answer in this GitHub issue.
Surprisingly, one curl command is enough to get the token:
curl -u joe:password -kv -H "X-CSRF-Token: xxx" 'https://master.cluster.local:8443/oauth/authorize?client_id=openshift-challenging-client&response_type=token'
The response is going to be an HTTP 302 trying to redirect to another URL. The redirection URL will contain the token, for example:
Location: https://master.cluster.local:8443/oauth/token/display#access_token=VO4dAgNGLnX5MGYu_wXau8au2Rw0QAqnwq8AtrLkMfU&expires_in=86400&token_type=bearer
You can use token or combination user/password.
To use username:password in header, you can use Authorizartion: Basic. The oc client commands are doing simple authentication with your user and password in header. Like this
curl -H "Authorization: Basic <SOMEHASH>"
where the hash is exactly base64 encoded username:password. (try it with echo -n "username:password" | base64).
To use token, you can obtain the token here with curl:
curl -H Authorization: Basic $(echo -n username:password | base64)" https://openshift.example.com:8443/oauth/authorize\?response_type\=token\&client_id\=openshift-challenging-client
But the token is replied in the ugly format format. You can try to grep it
... | grep -oP "access_token=\K[ˆ&]*"
You need to use the correct url for your oauth server. In my case, I use openshift 4.7 and this is the url:
https://oauth-openshift.apps.<clustername><domain>/oauth/authorize\?response_type\=token\&client_id\=openshift-challenging-client
oc get route oauth-openshift -n openshift-authentication -o json | jq .spec.host
In case you are using OpenShift CRC:
Then the URL is: https://oauth-openshift.apps-crc.testing/oauth/authorize
Command to get the Token:
curl -v --insecure --user developer:developer --header "X-CSRF-Token: xxx" --url "https://oauth-openshift.apps-crc.testing/oauth/authorize?response_type=token&client_id=openshift-challenging-client" 2>&1 | grep -oP "access_token=\K[^&]*"
Note:
2>&1 is required, because curl writes to standard error
--insecure: because I have not set up TLS certificate
Adjust the user and password developer as needed (crc developer/developer is standard user in crc, therefore good for testing.)
Token is per default 24h vaild
Export the Token to an environment Variable
export TOKEN=$(curl -v --insecure --user developer:developer --header "X-CSRF-Token: xxx" --url "https://oauth-openshift.apps-crc.testing/oauth/authorize?response_type=token&client_id=openshift-challenging-client" 2>&1 | grep -oP "access_token=\K[^&]*")
And Use the token then in, e.g., oc login:
oc login --token=$TOKEN --server=https://api.crc.testing:6443

DELETE requests directly from the command line

I'm following this tutorial http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#fnref-9_4 and after the code in Listing 9.44 author says that in that specific moment any user can be deleted with a direct DELETE request from the command line, of course I believe that it's true but I don't know how to check this one
any sufficiently sophisticated attacker could simply issue DELETE requests directly from the command line to delete any user on the site.
Here's an example of a command line DELETE call using cURL
$ curl -X DELETE http://localhost:3000/users/1
http://localhost:3000/ is the path to your app, 1 is the ID of the record to delete.
With cURL you can simulate the same requests you will perform using your browser. You can use any other HTTP client.
You can use cURL from the command line to make HTTP requests, including DELETE requests.
curl -i -H "Accept: application/json" -X DELETE http://localhost:3000/persons/person/1
** Adapted from this blog post

Resources