Browse Source

token is not part of the URL anymore

master
Julio Biason 10 years ago
parent
commit
a4f4d314b6
  1. 17
      luncho/blueprints/users.py
  2. 34
      luncho/helpers.py
  3. 28
      tests/base.py
  4. 23
      tests/users_tests.py

17
luncho/blueprints/users.py

@ -12,7 +12,7 @@ from flask import jsonify
from sqlalchemy.exc import IntegrityError
from luncho.helpers import ForceJSON
from luncho.helpers import user_from_token
from luncho.helpers import auth
from luncho.server import User
from luncho.server import db
@ -53,15 +53,16 @@ def create_user():
return jsonify(status='OK')
@users.route('<token>/', methods=['POST'])
@users.route('/', methods=['POST'])
@ForceJSON()
def update_user(token):
@auth
def update_user():
"""Update user information. Request can have the following fields:
{ "full_name": "Full name", "password": "hash" }
Any other field will be ignored; only fields that need to be changed
must be send."""
json = request.get_json(force=True)
user = user_from_token(token)
user = request.user
if 'full_name' in json:
LOG.debug('Fullname = {fullname}'.format(fullname=json['full_name']))
@ -75,10 +76,10 @@ def update_user(token):
return jsonify(status='OK')
@users.route('<token>/', methods=['DELETE'])
def delete_user(token):
@users.route('/', methods=['DELETE'])
@auth
def delete_user():
"""Delete a user. No confirmation is send."""
user = user_from_token(token)
db.session.delete(user)
db.session.delete(request.user)
db.session.commit()
return jsonify(status='OK')

34
luncho/helpers.py

@ -3,6 +3,8 @@
"""Helper functions."""
import logging
from functools import wraps
from flask import request
@ -15,6 +17,8 @@ from luncho.exceptions import MissingFieldsException
from luncho.exceptions import UserNotFoundException
from luncho.exceptions import AuthorizationRequiredException
LOG = logging.getLogger('luncho.helpers')
class ForceJSON(object):
"""Decorator to check if the request is in JSON format."""
@ -41,24 +45,26 @@ class ForceJSON(object):
return check_json
class Auth(object):
"""Validate the token in the Basic Auth header."""
def auth(func):
@wraps(func)
def check_auth(*args, **kwargs):
if not request.authorization:
LOG.debug('There is no basic auth in the headers')
raise AuthorizationRequiredException
def __call__(self, func):
@wraps(func)
def check_auth(*args, **kwargs):
if not request.authorization:
raise AuthorizationRequiredException
token = request.authorization.username
user = User.query.filter_by(token=token).first()
if not user:
LOG.debug('No user with token {token}'.format(token=token))
raise UserNotFoundException()
token = request.authorization.username
user = User.query.filter_by(token=token).first()
if not user:
raise UserNotFoundException()
if not user.valid_token(token):
raise InvalidTokenException()
if not user.valid_token(token):
raise InvalidTokenException()
request.user = user
return func(*args, **kwargs)
return func(*args, **kwargs)
return check_auth
def user_from_token(token):

28
tests/base.py

@ -3,10 +3,22 @@
import unittest
import json
import base64
from luncho import server
def _token_header(token=None):
"""Generate the headers required for using the token as an auth."""
if not token:
return None
message = '{token}:Ignored'.format(token=token)
headers = {'Authorization': 'Basic {code}'.format(
code=base64.b64encode(message))}
return headers
class LunchoTests(unittest.TestCase):
"""Base testing for all Lunch-o tests."""
@ -75,22 +87,26 @@ class LunchoTests(unittest.TestCase):
# Easy way to convert the data to JSON and do requests
# ------------------------------------------------------------
def post(self, url, data):
def post(self, url, data, token=None):
"""Send a POST request to the URL."""
return self.app.post(url,
data=json.dumps(data),
headers=_token_header(token),
content_type='application/json')
def put(self, url, data):
def put(self, url, data, token=None):
"""Send a PUT request to the URL."""
return self.app.put(url,
data=json.dumps(data),
headers=_token_header(token),
content_type='application/json')
def delete(self, url):
def delete(self, url, token=None):
"""Send a DELETE request to the URL. There is no data to be send."""
return self.app.delete(url)
return self.app.delete(url,
headers=_token_header(token))
def get(self, url):
def get(self, url, token=None):
"""Send a GET request to the URL. There is no data to be send."""
return self.app.get(url)
return self.app.get(url,
headers=_token_header(token))

23
tests/users_tests.py

@ -2,7 +2,6 @@
# -*- encoding: utf-8 -*-
import unittest
import json
from luncho import server
@ -67,10 +66,10 @@ class TestExistingUsers(LunchoTests):
"""Update user details."""
request = {'full_name': 'New User Name',
'password': 'newhash'}
rv = self.post('/user/{token}/'.format(token=self.user.token),
request)
rv = self.post('/user/',
request,
self.user.token)
expected = {'status': 'OK'}
self.assertJsonOk(rv)
# check in the database
@ -82,8 +81,9 @@ class TestExistingUsers(LunchoTests):
"""Send a request with an unexisting token."""
request = {'full_name': 'New User Name',
'password': 'newhash'}
rv = self.post('/user/{token}/'.format(token='no-token'),
request)
rv = self.post('/user/',
request,
'no-token')
self.assertJsonError(rv, 404, 'User not found (via token)')
@ -96,14 +96,15 @@ class TestExistingUsers(LunchoTests):
request = {'full_name': 'New User Name',
'password': 'newhash'}
rv = self.post('/user/{token}/'.format(token=self.user.token),
request)
rv = self.post('/user/',
request,
self.user.token)
self.assertJsonError(rv, 400, 'Invalid token')
def test_delete_user(self):
"""Delete a user."""
rv = self.delete('/user/{token}/'.format(token=self.user.token))
rv = self.delete('/user/', token=self.user.token)
self.assertJsonOk(rv)
# check the database
@ -112,7 +113,7 @@ class TestExistingUsers(LunchoTests):
def test_delete_wrong_token(self):
"""Send a delete to a non-existing token."""
rv = self.delete('/user/{token}/'.format(token='no-token'))
rv = self.delete('/user/', token='no-token')
self.assertJsonError(rv, 404, 'User not found (via token)')
@ -122,7 +123,7 @@ class TestExistingUsers(LunchoTests):
self.user.token = 'expired'
server.db.session.commit()
rv = self.delete('/user/{token}/'.format(token=self.user.token))
rv = self.delete('/user/', token=self.user.token)
self.assertJsonError(rv, 400, 'Invalid token')

Loading…
Cancel
Save