Why does this twitter oauth API token request fail - oauth

[Note: all oauth tokens/secrets below were created randomly; they are
NOT my actual tokens/secrets]
curl -o /tmp/test.txt 'https://api.twitter.com/oauth/request_token?
oauth_timestamp=1345141469&
consumer_key=UEIUyoBjBRomdvrVcUTn&oauth_access_token_secret=YePiEkSDFdYAOgscijMCazcSfBflykjsEyaaVbuJeO&oauth_access_token=47849378%2drZlzmwutYqGypbLsQUoZUsGdDkVVRkjkOkSfikNZC&oauth_nonce=1345141469&
consumer_secret=rUOeZMYraAapKmXqYpxNLTOuGNmAQbGFqUEpPRlW&
oauth_version=1%2e0&
oauth_signature_method=HMAC%2dSHA1&oauth_signature=H0KLLecZNAAz%2bXoyrPRiUs37X3Zz%2bAcabMa5M4oDLkM'
[I added newlines for clarity; actual command is one single line]
Assuming all the other data is valid, why does the command above yield
"Failed to validate oauth signature and token" (even when I use my
real data)?
In particular, is my signature
"H0KLLecZNAAz%2bXoyrPRiUs37X3Zz%2bAcabMa5M4oDLkM" invalid, or am I
doing something more fundamentally wrong.
The program I used to generate this:
#!/bin/perl
use Digest::SHA;
%twitter_auth_hash = (
"oauth_access_token" => "47849378-rZlzmwutYqGypbLsQUoZUsGdDkVVRkjkOkSfikNZC",
"oauth_access_token_secret" => "YePiEkSDFdYAOgscijMCazcSfBflykjsEyaaVbuJeO",
"consumer_key" => "UEIUyoBjBRomdvrVcUTn",
"consumer_secret" => "rUOeZMYraAapKmXqYpxNLTOuGNmAQbGFqUEpPRlW"
);
# if uncommented, pull my actual data
# require "bc-private.pl";
$twitter_auth_hash{"oauth_signature_method"} = "HMAC-SHA1";
$twitter_auth_hash{"oauth_version"} = "1.0";
$twitter_auth_hash{"oauth_timestamp"} = time();
$twitter_auth_hash{"oauth_nonce"} = time();
for $i (keys %twitter_auth_hash) {
push(#str,"$i=".urlencode($twitter_auth_hash{$i}));
}
$str = join("&",#str);
# thing to sign
$url = "GET $str";
# signing it
$sig = urlencode(Digest::SHA::hmac_sha256_base64($url, "rUOeZMYraAapKmXqYpxNLTOuGNmAQbGFqUEpPRlW&YePiEkSDFdYAOgscijMCazcSfBflykjsEyaaVbuJeO"));
# full URL incl sig
$furl = "https://api.twitter.com/oauth/request_token?$str&oauth_signature=$sig";
# system("curl -o /tmp/testing.txt '$furl'");
print "FURL: $furl\n";
print "STR: $str\n";
print "SIG: $sig\n";
sub urlencode {
my($str) = #_;
$str=~s/([^a-zA-Z0-9])/"%".unpack("H2",$1)/iseg;
$str=~s/ /\+/isg;
return $str;
}
Note: I realize there are many other possible reasons this is failing,
but current question is: am I sending the parameters correctly and am
I computing the signature correctly.

Twitter asks that you do a POST for the request token.

Related

How can I get JWT with Ruby?

I am currently working on the project that I am going to integrate the application of my company and salesforce.
In my case, it seemed that using the JWT for authentication is better.
So, I wanted to try it.
but I don't know how to generate JWT on Ruby though I researched a lot.
So if anyone knows how to make jwt, I would love you to tell me how to do it.
What I wanted to do is that
1, create application on salesforce (done)
2, create X509 certification and set it on the application on salesforce. (done)
3, create JWT by using the secret key of X509 certification. (don't know how)
I have been looking for the way to solve this but I couldn't.
I guess I should be doing something like this.
require 'jwt'
payload = { data: 'test' }
# The secret must be a string. A JWT::DecodeError will be raised if it isn't provided.
hmac_secret = 'my$ecretK3y'
token = JWT.encode payload, hmac_secret, 'HS256'
# eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y
puts token
decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' }
# Array
# [
# {"data"=>"test"}, # payload
# {"alg"=>"HS256"} # header
# ]
puts decoded_token
but this doesn't work on my local.
When I run this file, it says
`require': cannot load such file -- jwt
I think PHP version of what I want to do is this.
<?php
require_once './vendor/autoload.php';
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
// ログインURL
// 本番: https://login.salesforce.com
// Sandbox: https://test.login.salesforce.com
// スクラッチ組織: https://test.saleforce.com
define('LOGIN_URL', 'https://test.salesforce.com');
// コンシューマ鍵
define('CLIENT_ID', <<接続アプリケーションのコンシューマ鍵>>);
// ユーザID
define('USER_ID', 'xxxxx#example.com');
function createjwt() {
$signer = new Sha256();
$privateKey = new Key('file://cert/server.key');
$time = time();
$token = (new Builder())->issuedBy(CLIENT_ID) // iss: コンシューマ鍵
->permittedFor(LOGIN_URL) // aud: SalesforceログインURL
->relatedTo(USER_ID) // sub: SalesforceユーザID
->expiresAt($time + 3 * 60) // exp: 3分以内
->getToken($signer, $privateKey);
return $token;
}
$jwt = createjwt();
echo $jwt;
If you have any clue please help me.
references are here:
https://help.salesforce.com/articleView?id=sf.remoteaccess_oauth_jwt_flow.htm&type=5
https://github.com/jwt/ruby-jwt
It was not the error of JWT but that I couldn't install get properly.
I tried once because of shortage of memory.
and this solved this problem.
gem install jwt
thank you.

requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read, 512 more expected)', IncompleteRead

I wanted to write a program to fetch tweets from Twitter and then do sentiment analysis. I wrote the following code and got the error even after importing all the necessary libraries. I'm relatively new to data science, so please help me.
I could not understand the reason for this error:
class TwitterClient(object):
def __init__(self):
# keys and tokens from the Twitter Dev Console
consumer_key = 'XXXXXXXXX'
consumer_secret = 'XXXXXXXXX'
access_token = 'XXXXXXXXX'
access_token_secret = 'XXXXXXXXX'
api = Api(consumer_key, consumer_secret, access_token, access_token_secret)
def preprocess(tweet, ascii=True, ignore_rt_char=True, ignore_url=True, ignore_mention=True, ignore_hashtag=True,letter_only=True, remove_stopwords=True, min_tweet_len=3):
sword = stopwords.words('english')
if ascii: # maybe remove lines with ANY non-ascii character
for c in tweet:
if not (0 < ord(c) < 127):
return ''
tokens = tweet.lower().split() # to lower, split
res = []
for token in tokens:
if remove_stopwords and token in sword: # ignore stopword
continue
if ignore_rt_char and token == 'rt': # ignore 'retweet' symbol
continue
if ignore_url and token.startswith('https:'): # ignore url
continue
if ignore_mention and token.startswith('#'): # ignore mentions
continue
if ignore_hashtag and token.startswith('#'): # ignore hashtags
continue
if letter_only: # ignore digits
if not token.isalpha():
continue
elif token.isdigit(): # otherwise unify digits
token = '<num>'
res += token, # append token
if min_tweet_len and len(res) < min_tweet_len: # ignore tweets few than n tokens
return ''
else:
return ' '.join(res)
for line in api.GetStreamSample():
if 'text' in line and line['lang'] == u'en': # step 1
text = line['text'].encode('utf-8').replace('\n', ' ') # step 2
p_t = preprocess(text)
# attempt authentication
try:
# create OAuthHandler object
self.auth = OAuthHandler(consumer_key, consumer_secret)
# set access token and secret
self.auth.set_access_token(access_token, access_token_secret)
# create tweepy API object to fetch tweets
self.api = tweepy.API(self.auth)
except:
print("Error: Authentication Failed")
Assume all the necessary libraries are imported. The error is on line 69.
for line in api.GetStreamSample():
if 'text' in line and line['lang'] == u'en': # step 1
text = line['text'].encode('utf-8').replace('\n', ' ') # step 2
p_t = preprocess(text)
I tried checking on the internet the reason for the error but could not get any solution.
Error was:
requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read, 512 more expected)', IncompleteRead(0 bytes read, 512 more expected))
I'm using Python 2.7 and requests version 2.14, the latest one.
If you set stream to True when making a request, Requests cannot release the connection back to the pool unless you consume all the data or call Response.close. This can lead to inefficiency with connections. If you find yourself partially reading request bodies (or not reading them at all) while using stream=True, you should make the request within a with statement to ensure it’s always closed:
with requests.get('http://httpbin.org/get', stream=True) as r:
# Do things with the response here.
I had the same problem but without stream, and as stone mini said, just apply "with" clause before to make sure your request is closed before a new request.
with requests.request("POST", url_base, json=task, headers=headers) as report:
print('report: ', report)
actually the problem with your django2.7 or earlier version based application. that django versions by default allowed 2.5mb data upload memory size of request body.
I was facing the same issue with django2.7 based application, I just updated the setting.py file of my django application where my urls(endpoints) were working.
DATA_UPLOAD_MAX_MEMORY_SIZE = None
I just add the above variable in my application's settings.py file.
you can also readout about that from here
I'm pretty sure this will work for you.

using python to send POST request

I'm trying to send a POST request to a site (https://get.cbord.com/dartmouth/full/login.php) to log in. I think I'm running into issues with the format of the data I'm passing in, but truthfully I'm just getting started so I don't understand this very well. I tried deciphering the POST request using Chrome dev tools and this is what I came up with.
#!/usr/bin/env python
import requests
import sys
EMAIL = 'xxx'
PASSWORD = 'xxx'
LOGIN_URL = 'https://get.cbord.com/dartmouth/full/login.php'
FULL_URL = 'https://get.cbord.com/dartmouth/full/funds_home.php'
def main():
# Start a session so we can have persistant cookies
#session = requests.session(config={'verbose': sys.stderr})
session = requests.session()
# This is the form data that the page sends when logging in
login_data = {
'username': EMAIL,
'password': PASSWORD,
'submit': 'Login',
}
# Authenticate
r = session.post(LOGIN_URL, data=login_data)
# Try accessing a page that requires you to be logged in
r = session.get(FULL_URL)
if __name__ == '__main__':
main()
The majority of the code is directly copy pasted from a response to a similar question. I guess I just don't understand how to figure out what the login_data dictionary should be.
Thanks for the help!
Pat
I examined this page and found that there is one more parameter: formToken.
You can get its value from webpage source. It looks like these
So first you need to get https://get.cbord.com/dartmouth/full/login.php page
login_page = session.get(LOGIN_URL)
login_page_text = login_page.text
then parse the page to retrieve formToken value from it and finally authenticate
login_data = {
'username': EMAIL,
'password': PASSWORD,
'submit': 'Login',
'formToken': formToken_value
}
# Authenticate
r = session.post(LOGIN_URL, data=login_data)

How can I access a raw private paste from pastebin?

I know how to generate a user key using the pastebin API, but how can I use this userkey to access a raw private paste?
I am using Lua for this.
Obtaining the raw paste bin output is not part of of the Pastebin API:
This option is actually not part of our API, but you might still want to use it. To get the RAW output of a paste you can use our RAW data output URL:
http://pastebin.com/raw.php?i=
Simply add the paste_key at the end of that URL and you will get the RAW output.
Since private pastes can only be seen by the user who created them, my guess is that they use the logincookie for authentication. In that case, you'll need to send it with the HTTP request.
In respect to implementing this in Lua, (since you haven't said which library you're using) I'm gonna go forth and recommend the HTTP module in LuaSocket or the wonderful Luvit (http://luvit.io).
Here is a ready example of the code for you:
local https = require('ssl.https')
https.TIMEOUT= 15
local private_raw_url="https://pastebin.com/raw/YOURPAGE" -- Change raw link
local user_name, user_password = "USER", "PASS" -- and user with password
local request_body = "submit_hidden=submit_hidden&user_name=".. user_name .. "&user_password=" .. user_password .. "&submit=Login"
local resp = {}
local res, code, headers, status = https.request ( {
method = 'POST',
url = "https://pastebin.com/login",
headers = {
Host = "pastebin.com",
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = string.len(request_body),
Connection = "keep-alive",
},
source = ltn12.source.string(request_body),
sink = ltn12.sink.table(resp),
protocol = "tlsv1",
verify = "none",
verifyext = {"lsec_continue", "lsec_ignore_purpose"},
options = { "all", "no_sslv2", "no_sslv3" }
} )
if not headers['set-cookie']:find('pastebin_user') then
print('bad login')
return
end
resp={}
local cookie = headers['set-cookie'] or ''
local cookie1, cookie2, cookie3 = cookie:match("(__cfduid=%w+; ).*(PHPSESSID=%w+; ).*(pastebin_user=%w+; )" )
if cookie1 and cookie2 and cookie3 then
cookie = cookie1 .. cookie2 .. cookie3
body, code, headers= https.request{
url = private_raw_url ,
headers = {
--Host = "pastebin.com",
['Cookie'] = cookie,
['Connection'] = 'keep-alive'
},
sink = ltn12.sink.table(resp)
}
if code~=200 then return end
print( table.concat(resp) )
else
print("error match cookies!" )
end
I know that this is a little late to answer the question but I hope this will help someone later on.
If you want to access raw private pastes, you will first need to list the pastes that the user has created. This is a part of the API. This requires the user to be logged in.
With this API you can list all the pastes created by a certain user.
You will need send a valid POST request to the URL below to access the
data:
http://pastebin.com/api/api_post.php
The response that you will get will be an XML response, as follows:
<paste>
<paste_key>0b42rwhf</paste_key>
<paste_date>1297953260</paste_date>
<paste_title>javascript test</paste_title>
<paste_size>15</paste_size>
<paste_expire_date>1297956860</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_long>JavaScript</paste_format_long>
<paste_format_short>javascript</paste_format_short>
<paste_url>http://pastebin.com/0b42rwhf</paste_url>
<paste_hits>15</paste_hits>
</paste>
Once you have that, parse the XML to get the paste_key and the paste_private. You need to check the value of paste_private because you want private pastes only. The documentation says:
We have 3 valid values available which you can use with the
'api_paste_private' parameter:
0 = Public
1 = Unlisted
2 = Private (only allowed in combination with api_user_key, as you have to be logged into your account to access the paste)
So, if your paste has paste_private set to 2, get the paste_key for it.
Once you have the paste_key, use the API call to get the RAW paste. No username or password required once you have the paste key for the private paste.
Have fun!

Google Docs: Cannot export/download user's document using administrative access/impersonation (forbidden 403) in python

I have read this thoroughly: https://developers.google.com/google-apps/documents-list/#using_google_apps_administrative_access_to_impersonate_other_domain_users
I have googled this to death.
So far I have been able to:
Authorise with:
clientLogin
OAuth tokens (using my domain key)
retrieve document feeds for all users in the domain (authorised either way in #1)
I am using the "entry" from the feed to Export/Download documents and always get forbidden for other users for documents not shared with admin. The feed query I am using is like:
https://docs.google.com/feeds/userid#mydomain.com/private/full/?v=3
(I have tried with and without the ?v=3)
I have also tried adding the xoauth_requestor_id (which I have also seen in posts as xoauth_requestor), both on the uri, and as a client property: client.xoauth_requestor_id = ...
Code fragments:
Client Login (using administrator credentials):
client.http_client.debug = cfg.get('HTTPDEBUG')
client.ClientLogin( cfg.get('ADMINUSER'), cfg.get('ADMINPASS'), 'HOSTED' )
OAuth:
client.http_client.debug = cfg.get('HTTPDEBUG')
client.SetOAuthInputParameters( gdata.auth.OAuthSignatureMethod.HMAC_SHA1, cfg.get('DOMAIN'), cfg.get('APPS.SECRET') )
oatip = gdata.auth.OAuthInputParams( gdata.auth.OAuthSignatureMethod.HMAC_SHA1, cfg.get('DOMAIN'), cfg.get('APPS.SECRET') )
oat = gdata.auth.OAuthToken( scopes = cfg.get('APPS.%s.SCOPES' % section), oauth_input_params = oatip )
oat.set_token_string( cfg.get('APPS.%s.TOKEN' % section) )
client.current_token = oat
Once the feed is retrieved:
# pathname eg whatever.doc
client.Export(entry, pathname)
# have also tried
client.Export(entry, pathname, extra_params = { 'v': 3 } )
# and tried
client.Export(entry, pathname, extra_params = { 'v': 3, 'xoauth_requestor_id': 'admin#mydomain.com' } )
Any suggestions, or pointers as to what I am missing here?
Thanks
You were very close to having a correct implementation. In your example above, you had:
client.Export(entry, pathname, extra_params = { 'v': 3, 'xoauth_requestor_id': 'admin#mydomain.com' } )
xoauth_requestor_id must be set to the user you're impersonating. Also what you need is to use 2-Legged OAuth 1.0a with the xoauth_requestor_id set either in the token or in the client.
import gdata.docs.client
import gdata.gauth
import tempfile
# Replace with values from your Google Apps domain admin console
CONSUMER_KEY = ''
CONSUMER_SECRET = ''
# Set this to the user you're impersonating, NOT the admin user
username = 'userid#mydomain.com'
destination = tempfile.mkstemp()
token = gdata.gauth.TwoLeggedOAuthHmacToken(
consumer_key, consumer_secret, username)
# Setting xoauth_requestor_id in the DocsClient constructor is not required
# because we set it in the token above, but I'm showing it here in case your
# token is constructed via some other mechanism and you need another way to
# set xoauth_requestor_id.
client = gdata.docs.client.DocsClient(
auth_token=token, xoauth_requestor_id=username)
# Replace this with the resource your application needs
resource = client.GetAllResources()[0]
client.DownloadResource(resource, path)
print 'Downloaded %s to %s' % (resource.title.text, destination)
Here is the reference in the source code to the TwoLeggedOAuthHmacToken class:
http://code.google.com/p/gdata-python-client/source/browse/src/gdata/gauth.py#1062
And here are the references in the source code that provide the xoauth_requestor_id constructor parameter (read these in order):
http://code.google.com/p/gdata-python-client/source/browse/src/atom/client.py#42
http://code.google.com/p/gdata-python-client/source/browse/src/atom/client.py#179
http://code.google.com/p/gdata-python-client/source/browse/src/gdata/client.py#136

Resources