Store is_subclient_token bool in token collection.
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
@@ -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):
|
||||||
|
@@ -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 = {
|
||||||
|
@@ -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."""
|
||||||
|
|
||||||
|
@@ -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'])
|
||||||
|
Reference in New Issue
Block a user