9

everyone. I am trying to write tests for RESTful API implemented using django-tastypie with http basic auth. So, I have the following code:

def http_auth(username, password): credentials = base64.encodestring('%s:%s' % (username, password)).strip() auth_string = 'Basic %s' % credentials return auth_string class FileApiTest(TestCase): fixtures = ['test/fixtures/test_users.json'] def setUp(self): self.extra = { 'HTTP_AUTHORIZATION': http_auth('testuser', 'qwerty') } def test_folder_resource(self): response = self.client.get('/api/1.0/folder/', **self.extra) self.assertEqual(response.status_code, 200) def test_folder_resource_post(self): response = self.client.post('/api/1.0/folder/', **self.extra) self.assertNotEqual(response.status_code, 401) 

GET request is done well, returning status code 200. But POST request always returns 401. I am sure I am doing something wrong. Any advice?

4
  • Maybe check your Meta: authorization on your resource? What does it say? Commented May 21, 2011 at 14:05
  • authorization = DjangoAuthorization() Commented May 25, 2011 at 18:19
  • 2
    aw, crap, I meant "Authentication" That's what you're testing here. THe difference is Authentication == "Who are you", Authorization == "Can you do this?" Commented May 25, 2011 at 18:38
  • authentication = BasicAuthentication(realm=settings.SOCIAL_API_REALM) Commented May 25, 2011 at 19:15

3 Answers 3

8

Check out this question. I've used that code for tests using both GET and POST and it worked. The only difference I can see is that you have used base64.encodestring instead of base64.b64encode.

Otherwise, if that doesn't work, how are you performing the HTTP Authentication? I wrote and use this function decorator:

import base64 from django.http import HttpResponse from django.contrib.auth import authenticate, login def http_auth(view, request, realm="", must_be='', *args, **kwargs): if 'HTTP_AUTHORIZATION' in request.META: auth = request.META['HTTP_AUTHORIZATION'].split() if len(auth) == 2: if auth[0].lower() == "basic": uname, passwd = base64.b64decode(auth[1]).split(':') if must_be in ('', uname): user = authenticate(username=uname, password=passwd) if user is not None and user.is_active: login(request, user) request.user = user return view(request, *args, **kwargs) # They mustn't be logged in response = HttpResponse('Failed') response.status_code = 401 response['WWW-Authenticate'] = 'Basic realm="%s"' % realm return response def http_auth_required(realm="", must_be=''): """ Decorator that requires HTTP Basic authentication, eg API views. """ def view_decorator(func): def wrapper(request, *args, **kwargs): return http_auth(func, request, realm, must_be, *args, **kwargs) return wrapper return view_decorator 
Sign up to request clarification or add additional context in comments.

2 Comments

I use django-tastypie, it has built-in bash http authentication and it works fine. I can't only make post requests with django test client and i have no idea where problem is
This file seems to handle the authentication. Have a look through it and see if you can trace what is going wrong? github.com/toastdriven/django-tastypie/blob/master/tastypie/…
1

I've found a reason of my problem. DjangoAuthorization checks permissions with django premissions framework, since I don't use it in my project — all post/put/delete requests from non superuser are unauthorized. My bad.

Anyway, thanks a lot to you, guys, for responses.

Comments

0

On Python 3

@staticmethod def http_auth(username, password): """ Encode Basic Auth username:password. :param username: :param password: :return String: """ data = f"{username}:{password}" credentials = base64.b64encode(data.encode("utf-8")).strip() auth_string = f'Basic {credentials.decode("utf-8")}' return auth_string def post_json(self, url_name: AnyStr, url_kwargs: Dict, data: Dict): """ Offers a shortcut alternative to doing this manually each time """ header = {'HTTP_AUTHORIZATION': self.http_auth('username', 'password')} return self.post( reverse(url_name, kwargs=url_kwargs), json.dumps(data), content_type="application/json", **header ) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.