Merge branch 'master' of git.blender.org:pillar into elastic

This commit is contained in:
2017-12-29 12:19:47 +01:00
28 changed files with 529 additions and 217 deletions

View File

@@ -1,6 +1,7 @@
import logging
import typing
import blinker
from flask import Blueprint, Response
import requests
from requests.adapters import HTTPAdapter
@@ -21,6 +22,10 @@ ROLES_BID_TO_PILLAR = {
'cloud_has_subscription': 'has_subscription',
}
user_subscription_updated = blinker.NamedSignal(
'user_subscription_updated',
'The sender is a UserClass instance, kwargs includes "revoke_roles" and "grant_roles".')
@blueprint.route('/update-subscription')
@authorization.require_login()
@@ -31,7 +36,7 @@ def update_subscription() -> typing.Tuple[str, int]:
"""
my_log: logging.Logger = log.getChild('update_subscription')
current_user = auth.get_current_user()
real_current_user = auth.get_current_user() # multiple accesses, just get unproxied.
try:
bid_user = blender_id.fetch_blenderid_user()
@@ -41,10 +46,10 @@ def update_subscription() -> typing.Tuple[str, int]:
if not bid_user:
my_log.warning('Logged in user %s has no BlenderID account! '
'Unable to update subscription status.', current_user.user_id)
'Unable to update subscription status.', real_current_user.user_id)
return '', 204
do_update_subscription(current_user, bid_user)
do_update_subscription(real_current_user, bid_user)
return '', 204
@@ -157,6 +162,14 @@ def do_update_subscription(local_user: auth.UserClass, bid_user: dict):
user_id, email, ', '.join(sorted(revoke_roles)))
service.do_badger('revoke', roles=revoke_roles, user_id=user_id)
# Let the world know this user's subscription was updated.
final_roles = (plr_roles - revoke_roles).union(grant_roles)
local_user.roles = list(final_roles)
local_user.collect_capabilities()
user_subscription_updated.send(local_user,
grant_roles=grant_roles,
revoke_roles=revoke_roles)
# Re-index the user in the search database.
from pillar.api.users import hooks
hooks.push_updated_user_to_search({'_id': user_id}, {})

View File

@@ -376,6 +376,13 @@ class OrgManager:
return bool(org_count)
def user_is_unknown_member(self, member_email: str) -> bool:
"""Return True iff the email is an unknown member of some org."""
org_coll = current_app.db('organizations')
org_count = org_coll.count({'unknown_members': member_email})
return bool(org_count)
def setup_app(app):
from . import patch, hooks

View File

@@ -2,7 +2,6 @@ import copy
import logging
from flask import request, abort, current_app
from gcloud import exceptions as gcs_exceptions
from pillar.api.node_types.asset import node_type_asset
from pillar.api.node_types.comment import node_type_comment
@@ -10,7 +9,6 @@ from pillar.api.node_types.group import node_type_group
from pillar.api.node_types.group_texture import node_type_group_texture
from pillar.api.node_types.texture import node_type_texture
from pillar.api.file_storage_backends import default_storage_backend
from pillar.api.file_storage_backends.gcs import GoogleCloudStorageBucket
from pillar.api.utils import authorization, authentication
from pillar.api.utils import remove_private_keys
from pillar.api.utils.authorization import user_has_role, check_permissions

View File

@@ -198,8 +198,9 @@ def after_inserting_users(user_docs):
user_email = user_doc.get('email')
if not user_id or not user_email:
log.warning('User created with _id=%r and email=%r, unable to check organizations',
user_id, user_email)
# Missing emails can happen when creating a service account, it's fine.
log.info('User created with _id=%r and email=%r, unable to check organizations',
user_id, user_email)
continue
om.make_member_known(user_id, user_email)

View File

@@ -69,19 +69,19 @@ def find_user_in_db(user_info: dict, provider='blender-id'):
users = current_app.data.driver.db['users']
user_id = user_info['id']
query = {'$or': [
{'auth': {'$elemMatch': {
'user_id': str(user_info['id']),
'user_id': str(user_id),
'provider': provider}}},
{'email': user_info['email']},
]}
]}
log.debug('Querying: %s', query)
db_user = users.find_one(query)
if db_user:
log.debug('User with {provider} id {user_id} already in our database, '
'updating with info from {provider}.'.format(
provider=provider, user_id=user_info['id']))
log.debug('User with %s id %s already in our database, updating with info from %s',
provider, user_id, provider)
db_user['email'] = user_info['email']
# Find out if an auth entry for the current provider already exists
@@ -89,13 +89,13 @@ def find_user_in_db(user_info: dict, provider='blender-id'):
if not provider_entry:
db_user['auth'].append({
'provider': provider,
'user_id': str(user_info['id']),
'user_id': str(user_id),
'token': ''})
else:
log.debug('User %r not yet in our database, create a new one.', user_info['id'])
log.debug('User %r not yet in our database, create a new one.', user_id)
db_user = create_new_user_document(
email=user_info['email'],
user_id=user_info['id'],
user_id=user_id,
username=user_info['full_name'],
provider=provider)
db_user['username'] = make_unique_username(user_info['email'])
@@ -118,9 +118,13 @@ def validate_token():
from pillar.auth import AnonymousUser
auth_header = request.headers.get('Authorization') or ''
if request.authorization:
token = request.authorization.username
oauth_subclient = request.authorization.password
elif auth_header.startswith('Bearer '):
token = auth_header[7:].strip()
oauth_subclient = ''
else:
# Check the session, the user might be logged in through Flask-Login.
from pillar import auth
@@ -180,7 +184,6 @@ def validate_this_token(token, oauth_subclient=None):
def remove_token(token: str):
"""Removes the token from the database."""
tokens_coll = current_app.db('tokens')
token_hashed = hash_auth_token(token)
@@ -261,13 +264,13 @@ def create_new_user(email, username, user_id):
def create_new_user_document(email, user_id, username, provider='blender-id',
token=''):
token='', *, full_name=''):
"""Creates a new user document, without storing it in MongoDB. The token
parameter is a password in case provider is "local".
"""
user_data = {
'full_name': username,
'full_name': full_name or username,
'username': username,
'email': email,
'auth': [{
@@ -371,6 +374,10 @@ def upsert_user(db_user):
raise wz_exceptions.InternalServerError(
'Non-ObjectID string found in user.groups: %s' % db_user)
if not db_user['full_name']:
# Blender ID doesn't need a full name, but we do.
db_user['full_name'] = db_user['username']
r = {}
for retry in range(5):
if '_id' in db_user: