Store is_subclient_token bool in token collection.

This commit is contained in:
2016-04-15 16:27:24 +02:00
parent 15dffa3d28
commit d808b76d65
5 changed files with 88 additions and 6 deletions

View File

@@ -85,7 +85,7 @@ def validate_create_user(blender_id_user_id, token, oauth_subclient_id):
return abort(500) return abort(500)
# Store the token in MongoDB. # Store the token in MongoDB.
authentication.store_token(db_id, token, token_expiry) authentication.store_token(db_id, token, token_expiry, oauth_subclient_id)
return db_user, status return db_user, status

View File

@@ -42,7 +42,7 @@ def validate_token():
token = request.authorization.username token = request.authorization.username
oauth_subclient = request.authorization.password oauth_subclient = request.authorization.password
db_token = find_token(token) db_token = find_token(token, oauth_subclient)
if not db_token: if not db_token:
log.debug('Token %s not found in our local database.', token) log.debug('Token %s not found in our local database.', token)
@@ -68,13 +68,14 @@ def validate_token():
return True return True
def find_token(token, **extra_filters): def find_token(token, is_subclient_token=False, **extra_filters):
"""Returns the token document, or None if it doesn't exist (or is expired).""" """Returns the token document, or None if it doesn't exist (or is expired)."""
tokens_collection = app.data.driver.db['tokens'] tokens_collection = app.data.driver.db['tokens']
# TODO: remove expired tokens from collection. # TODO: remove expired tokens from collection.
lookup = {'token': token, lookup = {'token': token,
'is_subclient_token': True if is_subclient_token else {'$in': [False, None]},
'expire_time': {"$gt": datetime.now(tz=tz_util.utc)}} 'expire_time': {"$gt": datetime.now(tz=tz_util.utc)}}
lookup.update(extra_filters) lookup.update(extra_filters)
@@ -82,7 +83,7 @@ def find_token(token, **extra_filters):
return db_token return db_token
def store_token(user_id, token, token_expiry): def store_token(user_id, token, token_expiry, oauth_subclient_id):
"""Stores an authentication token. """Stores an authentication token.
:returns: the token document from MongoDB :returns: the token document from MongoDB
@@ -91,6 +92,7 @@ def store_token(user_id, token, token_expiry):
token_data = { token_data = {
'user': user_id, 'user': user_id,
'token': token, 'token': token,
'is_subclient_token': bool(oauth_subclient_id),
'expire_time': token_expiry, 'expire_time': token_expiry,
} }
r, _, _, status = post_internal('tokens', token_data) r, _, _, status = post_internal('tokens', token_data)
@@ -99,7 +101,8 @@ def store_token(user_id, token, token_expiry):
log.error('Unable to store authentication token: %s', r) log.error('Unable to store authentication token: %s', r)
raise RuntimeError('Unable to store authentication token.') raise RuntimeError('Unable to store authentication token.')
return r token_data.update(r)
return token_data
def create_new_user(email, username, user_id): def create_new_user(email, username, user_id):

View File

@@ -357,6 +357,11 @@ tokens_schema = {
'type': 'datetime', 'type': 'datetime',
'required': True, 'required': True,
}, },
'is_subclient_token': {
'type': 'boolean',
'required': False,
'default': False,
}
} }
files_schema = { files_schema = {

View File

@@ -4,10 +4,12 @@ import json
import copy import copy
import sys import sys
import logging import logging
import datetime
import os import os
import base64 import base64
from bson import ObjectId from bson import ObjectId, tz_util
from eve.tests import TestMinimal from eve.tests import TestMinimal
import pymongo.collection import pymongo.collection
from flask.testing import FlaskClient from flask.testing import FlaskClient
@@ -93,6 +95,28 @@ class AbstractPillarTest(TestMinimal):
return found['_id'], found return found['_id'], found
def create_user(self):
with self.app.test_request_context():
users = self.app.data.driver.db['users']
assert isinstance(users, pymongo.collection.Collection)
result = users.insert_one({
'_id': ObjectId('cafef00dc379cf10c4aaceaf'),
'_updated': datetime.datetime(2016, 4, 15, 13, 15, 11, tzinfo=tz_util.utc),
'_created': datetime.datetime(2016, 4, 15, 13, 15, 11, tzinfo=tz_util.utc),
'username': 'tester',
'groups': [],
'roles': ['subscriber'],
'settings': {'email_communications': 1},
'auth': [{'token': '',
'user_id': unicode(BLENDER_ID_TEST_USERID),
'provider': 'blender-id'}],
'full_name': u'คนรักของผัดไทย',
'email': TEST_EMAIL_ADDRESS
})
return result.inserted_id
def mock_blenderid_validate_unhappy(self): def mock_blenderid_validate_unhappy(self):
"""Sets up Responses to mock unhappy validation flow.""" """Sets up Responses to mock unhappy validation flow."""

View File

@@ -1,4 +1,6 @@
import datetime
import responses import responses
from bson import tz_util
from common_test_class import AbstractPillarTest, TEST_EMAIL_USER, TEST_EMAIL_ADDRESS from common_test_class import AbstractPillarTest, TEST_EMAIL_USER, TEST_EMAIL_ADDRESS
@@ -43,3 +45,51 @@ class AuthenticationTests(AbstractPillarTest):
with self.app.test_request_context( with self.app.test_request_context(
headers={'Authorization': self.make_header('knowntoken')}): headers={'Authorization': self.make_header('knowntoken')}):
self.assertTrue(auth.validate_token()) self.assertTrue(auth.validate_token())
@responses.activate
def test_find_token(self):
"""Test finding of various tokens."""
from application.utils import authentication as auth
user_id = self.create_user()
now = datetime.datetime.now(tz_util.utc)
future = now + datetime.timedelta(days=1)
past = now - datetime.timedelta(days=1)
subclient = self.app.config['BLENDER_ID_SUBCLIENT_ID']
with self.app.test_request_context():
auth.store_token(user_id, 'nonexpired-main', future, None)
auth.store_token(user_id, 'nonexpired-sub', future, subclient)
token3 = auth.store_token(user_id, 'expired-sub', past, subclient)
with self.app.test_request_context(
headers={'Authorization': self.make_header('nonexpired-main')}):
self.assertTrue(auth.validate_token())
with self.app.test_request_context(
headers={'Authorization': self.make_header('nonexpired-main', subclient)}):
self.assertFalse(auth.validate_token())
with self.app.test_request_context(
headers={'Authorization': self.make_header('nonexpired-sub')}):
self.assertFalse(auth.validate_token())
with self.app.test_request_context(
headers={'Authorization': self.make_header('nonexpired-sub', subclient)}):
self.assertTrue(auth.validate_token())
with self.app.test_request_context(
headers={'Authorization': self.make_header('expired-sub', subclient)}):
self.assertFalse(auth.validate_token())
self.mock_blenderid_validate_happy()
with self.app.test_request_context(
headers={'Authorization': self.make_header('expired-sub', subclient)}):
self.assertTrue(auth.validate_token())
# We now should be able to find a new token for this user.
found_token = auth.find_token('expired-sub', subclient)
self.assertIsNotNone(found_token)
self.assertNotEqual(token3['_id'], found_token['_id'])