Reputation: 729
Package versioning
Flask 1.0.2
Flask-HTTPAuth 3.2.4
Flask-RESTful 0.3.8
itsdangerous 0.24
I'm working on a API project where a POST
request to a Todo resource requires an user to have a token. Upon trying to test for this scenario, I'm getting the following assertion error: AssertionError: 401 != 201
. Both BasicHTTPAuth
and TokenHTTPAutth
from flask-HTTPAuth are handling Authorization credentials.
Based on a User having a token to access this resource, I'm not clear on why I'm getting an Unauthorized
error.
tests.py
class TestAuthenicatedUserPostTodo(ApiTestCase):
'''Verify that an API user successfully adds a Todo'''
def setUp(self):
super().setUp()
previous_todo_count = Todo.select().count()
user = User.get(User.id == 1)
token_serializer = Serializer(SECRET_KEY)
self.token = token_serializer.dumps({'id': user.id})
def test_todo_collection_post_todo_success(self):
with app.test_client() as client:
http_response = client.post(
"/api/v1/todos/",
headers={
'Authorization': f"Bearer {self.token}"
},
content_type="application/json",
data={
"name": "Must do a todo",
"user": 1
}
)
current_todo_count = Todo.select().count()
self.assertEqual(http_response.status_code, 201)
self.assertGreater(current_todo_count, previous_todo_count)
auth.py
basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth(scheme="Bearer")
auth = MultiAuth(token_auth, basic_auth)
@basic_auth.verify_password
def verify_password(username, password):
try:
api_user = User.get(User.username == username)
except User.DoesNotExist:
return False
user_verified = api_user.check_password(password)
if user_verified:
g.user = api_user
return True
return False
@token_auth.verify_token
def verify_token(token):
timed_serializer = Serializer(SECRET_KEY)
try:
user = timed_serializer.loads(token)
api_user = User.get_by_id(user['id'])
except (SignatureExpired, BadSignature) as e:
abort(400, description=str(e))
return True
todo.py
@auth.error_handler
def errorhandler():
return jsonify(unauthorized="Cannot add Todo. Login required."), 401
class TodoCollection(Resource):
@auth.login_required
def post(self):
import pdb; pdb.set_trace()
args = self.request_parser.parse_args()
if not args['name']:
return make_response(
{'invalid_request': "Invalid todo provided"}, 400
)
new_todo = Todo.create(**args)
return (
marshal(set_todo_creator(new_todo), todo_fields, 'new_todo'),
201, {'Location': f'{new_todo.location}'}
)
Upvotes: 1
Views: 691