How do I test if provider credentials are valid in apache libcloud? - apache

I was trying to create a driver for openstack using apache libcloud. It doesn't raise any error even if the user credentials are wrong. So When i checked the faq i found an answer as given in the link
Apache libcloud FAQ
But it doesn't seem to be effective since querying each time to check whether the user is authenticated will reduce the performance if the query returns a bulk of data.
When i checked the response i got from the api there is a field called driver.connection.auth_user_info and i found that the field is empty if the user is not authenticated. So can i use this method as a standard? Any help is appreciated

An openstack driver for libcloud is already available:
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
os = get_driver(Provider.OPENSTACK)
params = {'key': 'username', 'ex_force_service_region':'regionOne',
'ex_force_service_name':'nova', 'ex_force_auth_version':'2.0_password',
'ex_force_auth_url':'http://127.0.0.1:5000',
'ex_force_service_type':'compute', 'secret':'password',
'ex_tenant_name':'tenant'}
driver = os(**params)
But libcloud does not check the credentials by just creating the driver object. Instead, the creds will be validated only when a request is sent. If the internal exception InvalidCredsError is thrown the credentials are invalid, and an own variable could be set:
from libcloud.common.types import InvalidCredsError
validcreds = False
try:
nodes = driver.list_nodes()
if nodes.count >= 0:
validcreds = True
except InvalidCredsError:
print "Invalid credentials"
except Exception as e:
print str(e)
I would not rely on the internal variable auth_user_info because it could change over time.

Related

python requests login with redirect

I'd like to automate my log in to my bank to automatically fetch my transactions to stay up-to-date with spendings and earnings, but I am stuck.
The bank's login webpage is: https://login.bancochile.cl/bancochile-web/persona/login/index.html#/login
I am using python's request module with sessions:
urlLoginPage = 'https://login.bancochile.cl/bancochile-web/persona/login/index.html'
urlLoginSubmit = 'https://login.bancochile.cl/oam/server/auth_cred_submit'
username = '11.111.111-1' # this the format of a Chilean National ID ("RUT")
usernameFormatted = '111111111' # same id but formatted
pw = "password"
payload = [
("username2", usernameFormatted),
("username2", username),
("userpassword", pw),
("request_id", ''),
("ctx", "persona"),
("username", usernameFormatted),
("password", pw),
]
with requests.Session() as session:
login = session.get(urlLoginPage)
postLogin = session.post(
urlLoginSubmit,
data=payload,
allow_redirects=False,
)
redirectUrl = postLogin.headers["Location"]
First I find that the form data has duplicated keys, so I am using the payload as a list of tuples. From Chrome's inspect I find the form data to be like this:
username2=111111111&username2=11.111.111-1&userpassword=password&request_id=&ctx=persona&username=111111111&password=password
I've checked the page's source code to look for the use of a csrf token, but couldn't find any hint of it.
What happens is that the site does a redirect upon submitting the login data. I set allow_redirects=False to catch the redirect url of the post under the Location-header. However, here is the problem. Using the web-browser I know that the redirect url should be https://portalpersonas.bancochile.cl/mibancochile/rest/persona/perfilamiento/home, but I always end up on an error page when using the above method (https://login.bancochile.cl/bancochile-web/contingencia/error404.html). (I am using my own, correct login credentials to try this)
If I submit the payload in a wrong format (e.g. by dropping a key) I am redirected to the same error-page. This tells me that probably something with the payload is incorrect, but I don't know how to find out what may be wrong.
I am kind of stuck and don't know how I can figure out where/how to look for errors and possible solutions. Any suggestions on how to debug this and continue or ideas for other approaches would be very welcome!
Thanks!

how to figure out how to authenticate myself using http requests

I am trying to log in to a site using requests as follows:
s = requests.Session()
login_data = {"userName":"username", "password":"pass", "loginPath":"/d2l/login"}
resp = requests.post("https://d2l.pima.edu/d2l/login?login=1", login_data)
although I am getting a 200 response, when I say
print(resp.content)
b"<!DOCTYPE html><html><head><meta charset='utf-8' /><script>var hash = window.location.hash;if( hash ) hash = '%23' + hash.substring( 1 );window.location.replace('/d2l/login?sessionExpired=0&target=%2fd2l%2ferror%2f404%2flog%3ftargetUrl%3dhttp%253A%252F%252Fd2l.pima.edu%253A80%252Fd2l%252Flogin%253Flogin%253D1' + hash );</script><title></title></head><body></body></html>"
notice it says session expired.
What I've tried:
logging back out and in in the actual browser, no success.
http basic auth, no success.
I'm thinking maybe I need to authenticate myself to this site using cookies?
If so how do I determine which cookies to send it?
I tried figuring this out by saying
resp.cookies
Out[4]: <RequestsCookieJar[]>
shouldn't this be giving me names of cookies? I'm not sure what to do with such output.
Main Point: HOW DO I FIGURE OUT HOW TO AUTHENTICATE MYSLEF TO THIS WEBSITE?
Help is appreciated.
I would rather not use selenium.
From loading this page https://d2l.pima.edu/d2l/login and viewing its source, you'll notice the POST target path is /d2l/lp/auth/login/login.d2l. Try using that as your POST path. Your other fields look consistent with the form's expectations.
Note: with python requests if you create a session object use it to make your requests:
resp = s.post(<blah blah>, login_data)
The session will hold any cookies set by the login server, and you can continue to use the s object to make requests in the authenticated session.

intermittent error from rally 'Not authorized to perform action: Invalid key' for POST request in chrome extension

I developed a chrome extension using Rally's WSAPI v2.0, and it basically does the following things:
get user and project, and store them
get current iteration everytime
send a post request to create a workitem
For the THIRD step, I sometimes get error ["Not authorized to perform action: Invalid key"] since end of last month.
[updated]Error can be reproduced everytime if I log in Rally website via SSO before using the extension to send requests via apikey.
What's the best practice to send subsequent requests via apikey in my extension since I can't control end users' habits?
I did see some similar posts but none of them is helpful... and in case it helps:
I'm adding ZSESSIONID:apikey in my request header, instead of user /
password to authenticate, so I believe no security token is needed
(https://comm.support.ca.com/kb/api-key-and-oauth-client-faq/kb000011568)
url starts with https://rally1.rallydev.com/slm/webservice/v2.0/
issue is fixed after clearing cookies for
https://rally1.rallydev.com/, but somehow it appears again some time
later
I checked the cookie when the issue was reproduced, and found one with name of ZSESSIONID and its value became something else rather than the apikey. Not sure if that matters though...
code for request:
function initXHR(method, url, apikey, cbFunc) {
let httpRequest = new XMLHttpRequest();
...
httpRequest.open(method, url);
httpRequest.setRequestHeader('Content-Type', ' application\/json');
httpRequest.setRequestHeader('Accept', ' application\/json');
httpRequest.setRequestHeader('ZSESSIONID', apikey);
httpRequest.onreadystatechange = function() {
...
};
return httpRequest;
}
...
usReq = initXHR ('POST', baseURL+'hierarchicalrequirement/create', apikey, function(){...});
Anyone has any idea / suggestion? Thanks a million!
I've seen this error when the API key had both read-only and full-access grants configured. I would start by making sure your key only has the full-access grant.

Fetch defect from rally using rally rest api v2.0

I am getting the following exception whenever i try to fetch defects from rally:
com.google.gson.JsonSyntaxException:
com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 12
at com.google.gson.JsonParser.parse(JsonParser.java:65)
at com.google.gson.JsonParser.parse(JsonParser.java:45)
at com.rallydev.rest.response.Response.<init>(Response.java:25)
at com.rallydev.rest.response.QueryResponse.<init>(QueryResponse.java:16)
at com.rallydev.rest.RallyRestApi.query(RallyRestApi.java:168)
at Test.main(Test.java:86)
Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 12
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:531)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:414)
at com.google.gson.JsonParser.parse(JsonParser.java:60)
... 5
What intrigues me most is the code works perfectly fine on few machines and throws the above exception on few.
code snippet :
RallyRestApi restApi =
new RallyRestApi(new URI("http://rally1.rallydev.com"),apiKey);
QueryRequest queryRequest = new QueryRequest("defects");
queryRequest.setFetch(new Fetch("Project","FormattedID","Release"));
QueryFilter filter1 = new QueryFilter("FormattedID", "=", defetctID);
QueryResponse queryResponse1 = restApi.query(queryRequest);
Try a curl command to read the same defect using the same apiKey (in zsessionid header) on the same machine from which your java code fails.
curl --header "ZSESSIONID: _abc123" "https://rally1.rallydev.com/slm/webservice/v2.0/defect/123456789"
At least you will know if this is specific to java or not. Yes, it is strange that it fails on some machines and works on others, but the timing of those tests is not obvious from your post, and I wonder if this has anything to do with the underlying user credentials. (A user gets disabled for a period of time after a number of unsuccessful attempts). I am not positive that this is the issue you experience but I have seen when expired password caused the exact same error. API Keys are tied to a user, so when a user's password is expired, or when a user is inactivated (disabled) the same permissions(or the lack of them) is reflected in the key. For example, a user did not know that the password was expired because in the Rally UI they used SSO authentiation, but in the code they used either username/password or APIKey since the toolkit does not support SSO at this point. A 401 error would be more helpful, but instead a malformed JSON is generated.

Error getting twitter request token using OAuth and PEAR Services_Twitter

I am moving from the basic authentication method using username
and password to the OAuth based authentication.
I was using an old version of the pear package Services_Twitter, that
did not support OAuth.
The latest version of this package supports OAuth authentications, it
has a few dependencies (HTTP_Request2, HTTP_OAuth).
It was very simple to install them and upgrade the package. I did all
this my local machine and had no trouble getting the authentication up
and running.
I committed this code to the test site, but every time the code
request a "request token" I get the following error message "Unable to
connect to ssl://api.twitter.com:443. Error #0"
I have spend 6 hours making sure that all the pear packages where up
to date, checking the customer token and token secret, making sure
port 443 is not closed... in addition to various other test.
I have exhausted my resources and I come to you in hope to find some
answers.
Thank you
PD: One of the things I do not understand is why does the message says
that the url is ssl://api.twitter.com:443 rather than
https://api.twitter.com/request_token? the former one is the one I am
using to get the request token.
"Unable to connect to ssl://_______:443. Error #0" generally means that there is a ssl_verify_peer or certificate match issue - and the twitter API doesn't require you to provide a certificate!
HTTP_Request2 sets the ssl_verify_peer option to true by default - which is fine if you are specifying a certificate for establishing a connection so perhaps you need to check that setting is switched off?
This is checked for you in Services_Twitter if the use_ssl config setting is enabled so at a guess you may need to check that is set?
e.g.:
$twitter = Services_Twitter_factory('statuses/update', true, array('use_ssl' => true));
Here is the implementation of the code for kguest answer.
$httpRequest = new HTTP_Request2( null,
HTTP_Request2::METHOD_GET ,
array ('ssl_verify_peer' => false,
'ssl_verify_host' => false)
);
$httpRequest->setHeader('Accept-Encoding', '.*');
$request = new HTTP_OAuth_Consumer_Request;
$request->accept($httpRequest);
$oauth = new HTTP_OAuth_Consumer('twitterConsumerKey','twitterConsumerSecret');
$oauth->accept($request);
$oauth->getRequestToken('https://api.twitter.com/oauth/request_token',
"path/to/call/back/file.php");
$_SESSION['token'] = $oauth->getToken();
$_SESSION['token_secret'] = $oauth->getTokenSecret();
$authorize_link_twitter = $oauth->getAuthorizeUrl('https://api.twitter.com/oauth/authorize');
and something very similar was done to get the access token once you get back from twitter.
$httpRequest = new HTTP_Request2( null,
HTTP_Request2::METHOD_GET ,
array ('ssl_verify_peer' => false,
'ssl_verify_host' => false)
);
$httpRequest->setHeader('Accept-Encoding', '.*');
$request = new HTTP_OAuth_Consumer_Request;
$request->accept($httpRequest);
$oauth = new HTTP_OAuth_Consumer('twitterConsumerKey',
'twitterConsumerSecret',
$_SESSION['token'],
$_SESSION['token_secret']);
$oauth->accept($request);
$oauth->getAccessToken('https://api.twitter.com/oauth/access_token',
$_GET['oauth_verifier']);
// you can get the final tokens like this.
$oauth->getToken());
$oauth->getTokenSecret();
All the credit goes to kguest for the idea that lead to the solution of this problem. this is just the code.
Checkout this bug report http://pear.php.net/bugs/bug.php?id=18061 I have added resources to solve the issues of SSL and the Services_Twitter package.
But basically you should follow the instructions at http://curl.haxx.se/docs/sslcerts.html
Disabling ssl_verify_peer and ssl_verify_host makes you vulnerable to the security attacks that SSL tries to solve ( Verifying peer in SSL using python ). So don't ;)