dkm / python-vimeo

Python module for using Vimeo's API v2
http://www.kataplop.net/pub/projets/python
58 stars 10 forks source link

400 Errors coming back from Vimeo #4

Closed evz closed 12 years ago

evz commented 12 years ago

So, I don't know if this is something new, because I'm just now dusting off some code that I haven't touched since last fall, but I've been running into issues using this API wrapper today and wondered if there was something missing here.

First a bit of context. I'm using this inside a Django application to create a decorator for views that need to access the Vimeo API. The code I was using looks a bit like this:

import oauth2 as oauth
from django.conf import settings
from django.http import HttpResponseRedirect

def require_vimeo_auth(view):
    """View decorator, redirects users to Vimeo when no valid
    authentication token is available."""

    def protected_view(request, *args, **kwargs):
        request.session['next'] = request.path
        if 'vimeo_access_token' in request.session:
            vimeo_access_token = request.session['vimeo_access_token']
            vimeo_access_secret = request.session['vimeo_access_secret']
        else:
            vimeo_access_token = None
            vimeo_access_secret = None

        v = vimeo.VimeoClient(key=settings.VIMEO_API_KEY, secret=settings.VIMEO_API_SECRET, token=vimeo_access_token, token_secret=vimeo_access_secret)
        if vimeo_access_token:
            # We have a token, but it might not be valid
            try:
                v.oauth_checkAccessToken()
            except vimeo.VimeoAPIError:
                vimeo_access_token = None
                vimeo_access_secret = None
                del request.session['vimeo_access_token']
                del request.session['vimeo_access_secret']
        if not vimeo_access_token:
            # No valid token, so redirect to Vimeo
            v.get_request_token()
            request.session['vimeo_token'] = v.token.key
            request.session['vimeo_token_secret'] = v.token.secret
            url = v.get_authorization_url()
            return HttpResponseRedirect(url)

        # If the token is valid, we can call the decorated view.
        return view(request, *args, **kwargs)

    return protected_view

It's basically lifted directly from the excellent python flickrapi docs and worked fine until I started poking around in there this morning. Whenever I call the get_request_token method, Vimeo is giving me a 400 error back. I did a bit of digging and it seems that the reason it's a 400 and not something like a 401, is because the Vimeo OAuth process now requires that you send the callback url as part of the body of the request as well as in the authorization header. In fact, the specific error message that I was getting said as much.

However, it seems that there may be something larger going on here because whenever I try the authentication process using the oauth2 module, I'm unable to put the signature for the request together in a way that Vimeo likes. It returns a 401 saying that the signature is bad.

Using the python-requests module, I was able to get an oath_token and secret back from Vimeo, but it only worked once and I haven't tracked down what it was that I changed. Here's how that worked:

import requests
import random
import hmac
import time
import oauth2 as oauth
from django.conf import settings

url = 'http://vimeo.com/oauth/request_token'
callback = 'http://stage.bahai.us/apps/terrace/vimeo-callback'
nonce = str(random.randint(0, 100000000))
timestamp = str(int(time.time()))

params = {
    'oauth_callback': callback,
    'oauth_nonce': nonce,
    'oauth_signature_method': 'HMAC-SHA1',
    'oauth_timestamp': timestamp,
    'oauth_version': '1.0'
}
consumer = oauth.Consumer(key=settings.VIMEO_API_KEY, secret=settings.VIMEO_API_SECRET)
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method='GET', url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, None)
header_list = []
for k,v in req.items():
    header_list.append(k + '=' + v + '')
headers = {'Authorization': ','.join(header_list)}
r = requests.get(url, headers=headers)

It's a bit weird but it worked. Anyways, I'm starting to think Vimeo may be having issues but before I start bombing them, I'd like to get some kind of verification one way or the other.

Thanks!

dkm commented 12 years ago

Hey, thanks for the feedback and the very detailed study of your problem. Unfortunately, I'm not really maintaining this module anymore (lack of usefulness...). I've just pulled a merge from someone linking to your ticket with a patch dealing with the callback during the oauth process. Maybe this patch will also fix your problem ?

evz commented 12 years ago

It looks like that addresses the issue I was having. I went ahead and forked this repo and will go ahead and submit a pull request the next time I run into an issue.