Delete the auth token when logging out.
Before this, authentication tokens were kept in the database, even when someone logged out. This is unwanted behaviour, as logging in will create yet another token anyway there is no reason to keep the token around.
This commit is contained in:
parent
491c5e1b8c
commit
49a6a6a758
@ -83,13 +83,19 @@ def update_subscription():
|
||||
"""
|
||||
|
||||
import pprint
|
||||
from pillar import auth
|
||||
from pillar.api import blender_id, service
|
||||
from pillar.api.utils import authentication
|
||||
|
||||
my_log: logging.Logger = log.getChild('update_subscription')
|
||||
user_id = authentication.current_user_id()
|
||||
|
||||
bid_user = blender_id.fetch_blenderid_user()
|
||||
try:
|
||||
bid_user = blender_id.fetch_blenderid_user()
|
||||
except blender_id.LogoutUser:
|
||||
auth.logout_user()
|
||||
return '', 204
|
||||
|
||||
if not bid_user:
|
||||
my_log.warning('Logged in user %s has no BlenderID account! '
|
||||
'Unable to update subscription status.', user_id)
|
||||
|
@ -20,6 +20,13 @@ blender_id = Blueprint('blender_id', __name__)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LogoutUser(Exception):
|
||||
"""Raised when Blender ID tells us the current user token is invalid.
|
||||
|
||||
This indicates the user should be immediately logged out.
|
||||
"""
|
||||
|
||||
|
||||
@blender_id.route('/store_scst', methods=['POST'])
|
||||
def store_subclient_token():
|
||||
"""Verifies & stores a user's subclient-specific token."""
|
||||
@ -180,6 +187,8 @@ def fetch_blenderid_user() -> dict:
|
||||
}
|
||||
}
|
||||
|
||||
:raises LogoutUser: when Blender ID tells us the current token is
|
||||
invalid, and the user should be logged out.
|
||||
"""
|
||||
|
||||
import httplib2 # used by the oauth2 package
|
||||
@ -201,6 +210,10 @@ def fetch_blenderid_user() -> dict:
|
||||
log.exception('Error getting %s from BlenderID', bid_url)
|
||||
return {}
|
||||
|
||||
if bid_resp.status_code == 403:
|
||||
log.warning('Error %i from BlenderID %s, logging out user', bid_resp.status_code, bid_url)
|
||||
raise LogoutUser()
|
||||
|
||||
if bid_resp.status_code != 200:
|
||||
log.warning('Error %i from BlenderID %s: %s', bid_resp.status_code, bid_url, bid_resp.text)
|
||||
return {}
|
||||
|
@ -177,11 +177,23 @@ def validate_this_token(token, oauth_subclient=None):
|
||||
return db_user
|
||||
|
||||
|
||||
def remove_token(token: str):
|
||||
"""Removes the token from the database."""
|
||||
|
||||
|
||||
tokens_coll = current_app.db('tokens')
|
||||
token_hashed = hash_auth_token(token)
|
||||
|
||||
# TODO: remove matching on unhashed tokens once all tokens have been hashed.
|
||||
lookup = {'$or': [{'token': token}, {'token_hashed': token_hashed}]}
|
||||
del_res = tokens_coll.delete_many(lookup)
|
||||
log.debug('Removed token %r, matched %d documents', token, del_res.deleted_count)
|
||||
|
||||
|
||||
def find_token(token, is_subclient_token=False, **extra_filters):
|
||||
"""Returns the token document, or None if it doesn't exist (or is expired)."""
|
||||
|
||||
tokens_collection = current_app.data.driver.db['tokens']
|
||||
|
||||
tokens_coll = current_app.db('tokens')
|
||||
token_hashed = hash_auth_token(token)
|
||||
|
||||
# TODO: remove matching on unhashed tokens once all tokens have been hashed.
|
||||
@ -190,7 +202,7 @@ def find_token(token, is_subclient_token=False, **extra_filters):
|
||||
'expire_time': {"$gt": datetime.datetime.now(tz=tz_util.utc)}}
|
||||
lookup.update(extra_filters)
|
||||
|
||||
db_token = tokens_collection.find_one(lookup)
|
||||
db_token = tokens_coll.find_one(lookup)
|
||||
return db_token
|
||||
|
||||
|
||||
|
@ -202,8 +202,6 @@ def config_login_manager(app):
|
||||
def login_user(oauth_token: str, *, load_from_db=False):
|
||||
"""Log in the user identified by the given token."""
|
||||
|
||||
from flask import g
|
||||
|
||||
if load_from_db:
|
||||
user = _load_user(oauth_token)
|
||||
else:
|
||||
@ -212,6 +210,20 @@ def login_user(oauth_token: str, *, load_from_db=False):
|
||||
g.current_user = user
|
||||
|
||||
|
||||
def logout_user():
|
||||
"""Forces a logout of the current user."""
|
||||
|
||||
from ..api.utils import authentication
|
||||
|
||||
token = get_blender_id_oauth_token()
|
||||
if token:
|
||||
authentication.remove_token(token)
|
||||
|
||||
session.clear()
|
||||
flask_login.logout_user()
|
||||
g.current_user = AnonymousUser()
|
||||
|
||||
|
||||
def get_blender_id_oauth_token() -> str:
|
||||
"""Returns the Blender ID auth token, or an empty string if there is none."""
|
||||
|
||||
@ -231,6 +243,9 @@ def get_blender_id_oauth_token() -> str:
|
||||
if request.authorization and request.authorization.username:
|
||||
return request.authorization.username
|
||||
|
||||
if current_user.is_authenticated and current_user.id:
|
||||
return current_user.id
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ import logging
|
||||
|
||||
from flask import abort, Blueprint, redirect, render_template, request, session, \
|
||||
url_for
|
||||
from flask_login import login_required, logout_user
|
||||
from flask_login import login_required
|
||||
from werkzeug import exceptions as wz_exceptions
|
||||
|
||||
import pillar.api.blender_cloud.subscription
|
||||
@ -108,8 +108,7 @@ def login_local():
|
||||
|
||||
@blueprint.route('/logout')
|
||||
def logout():
|
||||
logout_user()
|
||||
session.clear()
|
||||
pillar.auth.logout_user()
|
||||
return redirect('/')
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user