tastypie post authentication issues - authorization

I'm having trouble with tastypie and posting data to it. I only am able to retrieve a 401 error code.
For clarification, I am able to successfully retrieve data from the tastypie api.
Attached are the code snippets, and maybe someone can help me out get behind this.
Before I get started, a little background: I am using a custom authorization class.
class CustomAuthorization(Authorization):
def is_authorized(self, request, object=None):
if request.user.username == 'custom_user':
return True
return False
Here is the actual resource:
class CustomObjectResource(ModelResource):
class Meta:
queryset = CustomObject.objects.all()
authentication = ApiKeyAuthentication()
authorization = CustomAuthorization()
list_allowed_methods = ['get', 'post', ]
detail_allowed_methods = ['get', 'post', 'put']
include_resource_uri = False
resource_name = 'customobject'
always_return_data = True
def obj_create(self, bundle, request=None, **kwargs):
try:
print "request"
except:
raise BadRequest('I couldnt save your information.')
return True
I know the obj_create method is bogus, but it should still be called and do something, or is this already the issue?
The following curl command is used to post the data to the tastypie API.
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"body": "This will prbbly be my lst post.", "pub_date": "2011-05-22T00:46:38", "slug": "another-post", "title": "Another Post"}' http://local.com:8000/api/v1/customobject/?format=json&username=custom_user&api_key=123456789012345
The api_key is correct, but bogus in this case!
As previously mentioned, the get method works but the post just wont work.
Anyone have an idea on how to solve this or have a workaround?

I would try a couple of things to debug this issue.
1) Try adding: allowed_methods = ['get', 'post', 'put']
2) Add print statements in the custom_authorization to check if that is causing the problems due to the request.user.username being different.
3) Do (2) in the source of APIKeyAuthentication too.
This should be sufficient for you to debug the issue.
Remember to remove the print statements once youre done!
Best of luck.

This is COULD be due to a known issue. On the background tastypie at the moment converts the POST to PUT and as Nikunj pointed since in list_allowed_methods you don't have PUT the POST gets blocked too... Not sure there though cause you should get method not allowed in that case. I would suggest debug in the method "is_authorized" and check what is happening there.

Related

karate.prevRequest does not work inside scenarios tagged #report=false

As an example, this scenario will fail with an error, "cannot convert, not a json string: [type: NULL, value: null]":
#report=false
Scenario: POST request; 200 response
Given url 'http://localhost:8080'
And request { "id": "123" }
When method post
* def requestBody = karate.prevRequest.body
* json requestJson = requestBody
However, if you remove the #report=false tag (or set it to 'true'), the request body is captured just fine.
Is this a bug or am I missing something obvious here?
Thanks!
This has been resolved with v0.9.9
It may be a bug, but can you please use the 1.0 series: https://github.com/intuit/karate/wiki/1.0-upgrade-guide
All development is focusing on that, and as of now you should be able to test 0.9.9.RC4 - and if you still see an issue, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

How to obtain response to be used on hooks

I am trying to make a simplified version of test report where I am generating a single HTML file report containing only assertion and error response message when there is any (attempting to not publish all the logs and steps).
I understand that we have hooks in karate. However I have looked for karate objects in the github but unable to found any objects where I can extract the response from (to be passed to the js function called on hook)
What I am doing right now is this:
Config:
//karate-config.js
karate.configure('afterScenario', karate.call('classpath:hooks.js'));
Hook:
//hooks.js
//Looking on how to extract the response and log it here
function(){
var info = karate.tags;
karate.log('Tags', info);
}
Am I missing anything on the karate objects? Or this should be achieved in another way?
Thanks a lot!
Try this:
var response = karate.get('response');
EDIT better example:
Background:
* configure afterScenario = function(){ karate.log('***', karate.get("response.headers['X-Karate']")) }
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = 'test'
When method get
# this will fail
Then status 400
I have tried with both karate.get('response') and response directly, and both work. If you use karate.call() pass the response as a parameter.

Interact with password protected Jupyter /api

A friend is trying to run a script to check which notebooks are using the most memory, but their server is password protected. I'm trying to figure out how to configure authentication using urllib2 since I don't believe there is a username, only a password.
The #aiguofer answer did not work for me because jupyter now uses '_xsrf' in cookie. The follwoing woked for me:
s = requests.Session()
url='http://127.0.0.1:8888/login/'
resp=s.get(url)
xsrf_cookie = resp.cookies['_xsrf']
params={'_xsrf':xsrf_cookie,'password': password}
s.post(url, data=params)
After that s can be used to call the apis.
After digging into the notebook code and through some trial and error, I figured out how to do this (and I switched to using requests).
I can't guarantee that this is the best way to do it, but it certainly worked for me. I actually set my vars elsewhere in the code but included here for completeness
import requests
hostname = '127.0.0.1'
port = '8888'
password = 'mypassword'
base_url = 'http://{0}:{1}/'.format(hostname, port)
h = {}
if password:
r = requests.post(base_url + 'login', params={
'password': password
})
h = r.request.headers
sessions = requests.get(base_url + 'api/sessions', headers=h).json()
I believe this works because when you hit the /login endpoint, it redirects you with the right headers set. I guess requests keeps the headers of the redirect, so we can reuse those for the other call. It might be better to extract only the cookies and use those, but this works for now :)
It seems there are some changes with new version. url '/login' does not work for me, I need to add next parameters
url='http://localhost:8050/login?next=%2F'
For the login request. The rest just like Hassan answer
i found when use jupyter put api upload file response 403,
need add "X-XSRFToken" header can solve it..
data= json.dumps({
"name": "test.jpg",
"path": "path",
"type":"file",
"format": "base64",
"content": "base64 data"
})
headers["X-XSRFToken"] = xsrf_cookie
s.put(url, data=data, headers=headers)

Authenticating the cobrand

I created a new developer account and I am having a problem authenticating with the REST API.
POST https://rest.developer.yodlee.com/services/srest/restserver/v1.0/authenticate/coblogin
{ cobrandLogin: 'sbCob*****',
cobrandPassword: '**********' }
the system responds with:
{ Error: [ { errorDetail: 'Internal Core Error has occurred' } ] }
am I doing something wrong?
I am testing the API with Postman and apparently I need to send the params with x-www-form-urlencoded to make it work. Using the default form-data lead to the above mentioned error.
In my case, this was solved by changing the content-type as per http://developer.yodlee.com/Aggregation_API/Aggregation_Services_Guide/Aggregation_REST_API_Reference
require 'rest-client'
module Yodlee
def self.login_to_yodlee
site = self.site_resource
login_hash = {
cobrandLogin: 'yourlogin',
cobrandPassword: 'yourpassword'
}
begin
response = site["/authenticate/coblogin"].post login_hash, :'content-type' => 'application/x-www-form-urlencoded'
puts response
rescue RestClient::ResourceNotFound => ex
raise Exception.new(ex.response)
rescue Exception => ex
raise Exception.new(ex)
end
end
def self.site_resource
RestClient::Resource.new('https://rest.developer.yodlee.com/services/srest/restserver/v1.0')
end
end
Yodlee.login_to_yodlee
Generally, this error comes when you do not provide the input parameter's name correctly; while in this mentioned code above I could see that both of them are correct. I'd suggest you to please double check the input parameter name(case sensitive) as well properly. And just to mention you should be sending it as two different parameters i.e., 'cobrandLogin' and cobrandPassword.

Posting to Facebook OG with HTTParty only works from the rails console?

I'm having a really weird problem with my rails app and facebook's open graph beta. Whenever I post an action to an object, Facebook returns an error that seems to indicate the URL of the object can't be reached, or the og scraper isn't scraping the URL correctly.
However, when I take the URL the app is generating for the post to Facebook and manually use the HTTParty gem to post it, it works.
Here's my code:
class Post < ActiveRecord::Base
FB_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/facebook.yml")[Rails.env]
def self.to_facebook_og(obj, obj_id, verb, auth, extra)
#requires that a user has granted `publish_actions`
found_obj = obj.classify.constantize.find(obj_id) #find the actual object we're talking about
post_url = self.construct_facebook_action_url(obj, found_obj, verb, auth, extra) #create the URL
begin
ret = HTTParty.post(post_url)
logger.info "Facebook Post Action Response = #{ret}"
rescue HTTParty::ResponseError => e #handle any errors
logger.error {"FACEBOOK Response #{ret.code} / #{e.inspect}"}
flash.alert {"There was a Facebook problem. Please try again."}
return
end
end
def self.construct_facebook_action_url(obj, found_obj, verb, auth, extra)
base = 'https://graph.facebook.com/'
uid = auth.uid
namespace = FB_CONFIG['namespace']
token = "?access_token=#{auth.token}"
og_url = "#{obj}=http://theshortestfiction.com/#{obj.pluralize}/#{found_obj.id}"
fb_url = base + uid + '/' + namespace + ':' + verb + token + '&' + og_url + extra
logger.info fb_url
fb_url
end
def self.lint_og_object(obj_url)
lint_ret = HTTParty.post("https://developers.facebook.com/tools/lint/?url=#{obj_url}&format=json")
logger.info "Facebook Linter Response = #{lint_ret}"
end
end
When an object is read via its controller's show method, the app calls Post.to_facebook. From my logs, I can see that that Post.construct_facebook_action_url is constructing the proper url (because like I said, I can pull the URL from the logs and manually post it from the console). So, I'm assuming there's so problem with how I'm passing the URL to HTTParty? Facebook seems able to tell what object URL it should be looking at. Why does the code I've written not work, but manually in the console, it does?
Even weirder -- once there's been a sucessful post action on the object once, the code seems to work consistently. Facebook insists the problem is that the objects' URLs aren't reachable, but I can't understand how they're not, since I can browse to them.
I think this is actually a timeout issue.
I had the exact same issue as you, using HTTParty and getting the URL can't be reached error.
I moved the code to a background process using Resque and it fixed the problem.