This was in Pillar, and is now moved to Blender Cloud. It's used to obtain the subscription expiration date from Blender Store.
138 lines
4.1 KiB
Python
138 lines
4.1 KiB
Python
import logging
|
|
|
|
import flask
|
|
from werkzeug.local import LocalProxy
|
|
|
|
from pillar.api.utils import authorization
|
|
from pillar.extension import PillarExtension
|
|
|
|
EXTENSION_NAME = 'cloud'
|
|
ROLES_TO_BE_SUBSCRIBER = {'demo', 'subscriber', 'admin'} # TODO: get rid of this, use 'subscriber' cap
|
|
|
|
|
|
class CloudExtension(PillarExtension):
|
|
has_context_processor = True
|
|
user_roles = {'subscriber-pro', 'has_subscription'}
|
|
user_roles_indexable = {'subscriber-pro', 'has_subscription'}
|
|
|
|
user_caps = {
|
|
'has_subscription': {'can-renew-subscription'},
|
|
}
|
|
|
|
def __init__(self):
|
|
self._log = logging.getLogger('%s.CloudExtension' % __name__)
|
|
|
|
@property
|
|
def name(self):
|
|
return EXTENSION_NAME
|
|
|
|
def flask_config(self):
|
|
"""Returns extension-specific defaults for the Flask configuration.
|
|
|
|
Use this to set sensible default values for configuration settings
|
|
introduced by the extension.
|
|
|
|
:rtype: dict
|
|
"""
|
|
|
|
# Just so that it registers the management commands.
|
|
from . import cli
|
|
|
|
return {
|
|
'EXTERNAL_SUBSCRIPTIONS_MANAGEMENT_SERVER': 'https://store.blender.org/api/',
|
|
'EXTERNAL_SUBSCRIPTIONS_TIMEOUT_SECS': 10,
|
|
}
|
|
|
|
def eve_settings(self):
|
|
"""Returns extensions to the Eve settings.
|
|
|
|
Currently only the DOMAIN key is used to insert new resources into
|
|
Eve's configuration.
|
|
|
|
:rtype: dict
|
|
"""
|
|
|
|
return {}
|
|
|
|
def blueprints(self):
|
|
"""Returns the list of top-level blueprints for the extension.
|
|
|
|
These blueprints will be mounted at the url prefix given to
|
|
app.load_extension().
|
|
|
|
:rtype: list of flask.Blueprint objects.
|
|
"""
|
|
from . import routes
|
|
import cloud.stats.routes
|
|
return [
|
|
routes.blueprint,
|
|
cloud.stats.routes.blueprint,
|
|
]
|
|
|
|
@property
|
|
def template_path(self):
|
|
import os.path
|
|
return os.path.join(os.path.dirname(__file__), 'templates')
|
|
|
|
@property
|
|
def static_path(self):
|
|
import os.path
|
|
return os.path.join(os.path.dirname(__file__), 'static')
|
|
|
|
def context_processor(self):
|
|
return {
|
|
'current_user_is_subscriber': authorization.user_has_cap('subscriber')
|
|
}
|
|
|
|
def setup_app(self, app):
|
|
"""Links certain roles to the subscriber role.
|
|
|
|
This means that users who get the subscriber role also get this linked
|
|
role, and when the subscriber role is revoked, the linked role is also
|
|
revoked.
|
|
"""
|
|
|
|
from pillar.api.service import signal_user_changed_role
|
|
from . import routes
|
|
|
|
signal_user_changed_role.connect(self._user_changed_role)
|
|
routes.setup_app(app)
|
|
|
|
def _user_changed_role(self, sender, user: dict):
|
|
from pillar.api import service
|
|
|
|
linked_roles = {'flamenco-user', 'attract-user'}
|
|
link_to = {'subscriber', 'demo'}
|
|
user_roles = set(user.get('roles', []))
|
|
|
|
# Determine what to do
|
|
has_linked_roles = not (linked_roles - user_roles)
|
|
has_link_to = bool(link_to.intersection(user_roles))
|
|
action = ''
|
|
if has_link_to and not has_linked_roles:
|
|
self._log.info('Granting roles %s to user %s', linked_roles, user['_id'])
|
|
action = 'grant'
|
|
elif not has_link_to and has_linked_roles:
|
|
self._log.info('Revoking roles %s from user %s', linked_roles, user['_id'])
|
|
action = 'revoke'
|
|
|
|
if not action:
|
|
return
|
|
|
|
# Avoid infinite loops while we're changing the user's roles.
|
|
service.signal_user_changed_role.disconnect(self._user_changed_role)
|
|
try:
|
|
if linked_roles:
|
|
service.do_badger(action, roles=linked_roles, user_id=user['_id'])
|
|
finally:
|
|
service.signal_user_changed_role.connect(self._user_changed_role)
|
|
|
|
|
|
def _get_current_cloud():
|
|
"""Returns the Cloud extension of the current application."""
|
|
return flask.current_app.pillar_extensions[EXTENSION_NAME]
|
|
|
|
|
|
current_cloud = LocalProxy(_get_current_cloud)
|
|
"""Cloud extension of the current app."""
|