Translating an API post instruction to R httr - r

I have been given the following POST instruction, and I am trying to translate it into httr:
<form method="POST" action="https://this.website.com/foldername>
<input type="hidden" name="ExternalAction" value="AgetAscii">
File Type <input type="text" name="filechar" value="0">
<input type="submit" value="Click here to Retrieve the File"/>
</form>
I am having trouble getting the right syntax for httr. I would welcome suggestions. The initial input type, name and value seem straight forward, but I don't see how I bring the File Type arguments into httr, nor am I confident I am handling the final "submit" and value items properly.
I'd welcome suggestions.
Many thanks

If I paste that example html into an local html file and substitute the action to be http://bin.org/post like so:
<form method="POST" action="http://httpbin.org/post">
<input type="hidden" name="ExternalAction" value="AgetAscii">
File Type <input type="text" name="filechar" value="0">
<input type="submit" value="Click here to Retrieve the File"/>
</form>
Then the only form data reported back by httpbin.org as having been received are for ExternalAction and filechar. Therefore, to send this data via httr::POST() you would do:
library(httr)
action <- "https://this.website.com/foldername"
body <- list(ExternalAction = "AgetAscii",
filechar = "0")
POST(url = action, body = body)

Related

Replicating remote site "attack" by force sending specific form data to a page

I have this simple form:
<form method="post" id="theForm" action="user-password.asp">
<input type="hidden" name="what" value="process" />
<fieldset>
<div>
<label for="email">Username or Email</label>
<input type="text" class="form-control" id="email" name="email" placeholder="Username or Email" />
</div>
<div>
<button type="submit" class="btn btn-success top10">Submit</button>
</div>
</fieldset>
</form>
I have a script which emails me when my Classic ASP pages error - I use this to get all of the form contents:
For ix = 1 to Request.Form.Count
fieldName = Request.Form.Key(ix)
fieldValue = Request.Form.Item(ix)
bb = bb & fieldName & ": " & fieldValue & vbcrlf
Next
bb = newstr(bb)
For the above page, the page errored with:
A trappable error (C0000005) occurred in an external object. The script cannot continue running.
The form contents were like this:
form: email[$acunetix]: 1
what: process
In order to improve the error handling on the page, I'd like to be able to replicate loading the form with whatever it was that was used to generate the form input which made the page error - in the above example the form field name is not email but is email[$acunetix], which seems to have broken the page when it tries to process the form.
However, I don't know what was done to do that. The same IP address spent about 40 minutes forcing all kinds of stuff onto my pages which eventually crashed my site requiring a server reboot.
I realise that is down to me not writing robust enough code - but - I wondered how I can replicate sending the form data shown above to the page, as I'm stuck trying to work out how to do that.

How to pass the arguments to the request from the form template

I'd like to pass additional argument next (it should be endpoint) to the request when submitting the form. I've tried:
<form method="post" action="" next="/apply"> but it doesn't work.
Later when receiving the form I just need to read it from request.args. How to do it correctly?
You can use a hidden form field.
<form method="post" action="">
<input type="hidden" name="next" value="/apply">
<!-- the rest of your form code -->
In your Flask function:
next = request.form.get('next')

ASP.NET Core using two models in single form

I am using Tuple to pass two models inside the view like code given below.
#model Tuple<AdvanceSearchModel, List<SearchUserModel>>
<form role="search" method="post" action="/Public/AdvanceSearch">
<div class="form-group">
<label>Name</label>
<input name="FullNames" type="text" class="form-control" value=""/>
</div>
<div class="form-group">
<label>Product</label>
<input name="Products" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Location:</label>
<input name="Location" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>State</label>
<input name="States" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Country</label>
<input name="Countries" type="text" class="form-control" value=""/>
</div>
</form>
All the name attributes inside inputs are of AdvanceSearchModel. How do I use tag helper such as asp-for when passing multiple model to the views containing one or multiple forms? Also how do I retain values of the form after submitting the form in above scenario?
As you can see in the source code of InputTagHelper
You can see it creates the name attribute based on the (lambda) expression in html-tag:asp-for.
what you need
You need a form name tag like this SearchUserModel[0].Location
Where:
SearchUserModel is the property name on the model which is in the controller method you post to
[0] is the index in the list
Location is the property on the iten in the list the SearchUserModel instance
My suggestion
Not to do
Extend the InputTagHelper and add a prefix option (which adds a prefex to the name).
Use a view model Not a tuple!
Create a partial view that only takes SearchUserModel + a prefix (like an int for which row in the list it is for example: usermodel[1])
In your view loop over the list and call the partial.
result
#model SearchUserModel
<input asp-for="Location" my-prefix="ListItem[#Model.Id]" class="form-control" />
Better longterm option
Make a HTML template on how SearchUserModel part of the form should look.
Do ajax call to get the data or put the data as json in your view. (or take step 3 from what not to do)
Generate the form with well structured javascript.
On submit Instead of submitting the form, parse the from to json and send this as json ajax call.
Why do i say this? It is easier to debug if you get weird databindings in your controller.
That said, option 1 is perfectly fine but it might lead to problems later, as it is very static template, you wont be able to add or remove rows easily.
References for proper html name tags for lists:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
How does MVC 4 List Model Binding work?

scrape website with hidden csrf token at login with R

As part of a late night project I am working on out of interest, I am trying to scrape my Uber trip data off of their website.
I have had a look at the code of the login page on
https://login.uber.com/login
and have seen that they use POST method in their form setup as follows:
<form method="post" class="form" novalidate="">
<input type="hidden" name="_csrf_token" value="1452201446-01-hujzoBTxkYPrJessd6zQwnD2ZOFxMOVgIYN8iXntr6c=">
<input type="hidden" data-js="access-token" name="access_token">
<a href="#" class="btn btn--full btn--facebook" data-js="facebook-connect">
<span class="push--ends flush">Continue with Facebook</span>
</a>
<p class="primary-font primary-font--semibold text-uber-white background-line push--top push--bottom">
<span>or use email</span>
</p>
<div class="form-group push-tiny--top flush--bottom">
<input type="email" name="email" class="text-input square--bottom " placeholder="Email Address" value="" id="email">
</div>
<div class="form-group push--bottom">
<input type="password" name="password" class="text-input square--top " placeholder="Password" id="password">
</div>
What I have read up is that one needs to send csrf token along when trying to scrape
library(RCurl)
library(XML)
URL_str<-"https://login.uber.com/login"
URL_str2<-"https://riders.uber.com/trips"
email<-"exampleMail#gmail.com"
pass<-"thisisalong"
token<- "1452201446-01-hujzoBTxkYPrJessd6zQwnD2ZOFxMOVgIYN8iXntr6c="
params <- list('email' = email,
'password' = pass,
'_csrf_token'=token)
URL_doc = postForm(URL_str2, style="POST",
.params=params)
If I now try and scrape the site, I get
ERROR: FORBIDDEN
I have seen some examples in python with similar websites. Can the same be done in R?
The final answer ended up being quite simple:
library(rvest)
library(RCurl)
library(XML)
session <-html_session("https://login.uber.com/login")
email<-"exampleMail#gmail.com"
pass<-"thisisalong"
#Handling the html_form
form<-html_form(session)[[1]]
form<-set_values(form, email=email, password=pass)
#Found that unless I explicitly assigned the value to empty it created errors
form$url<-""
session_open<-submit_form(session,form)
session_open<-jump_to(session_open,URL_str2)
From here on in its straight forward pulling tables using html_table and isolating nodes using html_nodes. Hope this helps

Google Oauth-2.0 returns url with hash instead of question mark

I using this form to request Google Offline Token
<form action="https://accounts.google.com/o/oauth2/auth" methode="POST">
<input type="hidden" name="access_type" value="offline" />
<input type="hidden" name="client_id" value="XXX" />
<input type="hidden" name="scope" value="https://www.googleapis.com/auth/analytics https://www.googleapis.com/auth/analytics.edit https://www.googleapis.com/auth/analytics.manage.users https://www.googleapis.com/auth/analytics.manage.users.readonly https://www.googleapis.com/auth/analytics.readonly" />
<input type="hidden" name="response_type" value="code token gsession" />
<input type="hidden" name="redirect_uri" value="http://example.com/analytics" />
<input type="hidden" name="approval_prompt" value="force" />
<button>Get or Refresh token</button>
</form>
How come Google sends me back an URL like :
http://example.com/analytics#access_token=XXX&token_type=Bearer&expires_in=3600&code=YYY&authuser=0&num_sessions=1&prompt=consent&session_state=ZZZ
Please notice we have an hash code # instead of a question mark ? after main url part.
I was expecting to get above variables with PHP $_GET but I can't because that hash code.
My question is how can I get an url with question mark instead ?
You're using a response_type of code token gsession that triggers a so-called Implicit flow in which the access_token will be returned in the URL fragment. Use response_type=code to get a code value as a query parameter that you can use at the token endpoint to exchange it for an access_token as described in: https://developers.google.com/accounts/docs/OAuth2WebServer#handlingtheresponse

Resources