Introducing Project creation
Authorised users can now create projects. The before and after insert projects hooks take care of stripping unwanted urls and attaching default node_type and permissions, as well as initialising a storage bucket per project. We are temporarily switching to the development version of the gcloud library, since it allows the creation of EU-based buckets.
This commit is contained in:
85
pillar/application/modules/projects.py
Normal file
85
pillar/application/modules/projects.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import logging
|
||||
from flask import g
|
||||
from flask import abort
|
||||
from eve.methods.put import put_internal
|
||||
from eve.methods.post import post_internal
|
||||
from application import app
|
||||
from application.utils import remove_private_keys
|
||||
from application.utils.gcs import GoogleCloudStorageBucket
|
||||
from manage.node_types.asset import node_type_asset
|
||||
from manage.node_types.group import node_type_group
|
||||
from manage.node_types.page import node_type_page
|
||||
from manage.node_types.comment import node_type_comment
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def before_inserting_projects(items):
|
||||
"""Strip unwanted properties, that will be assigned after creation. Also,
|
||||
verify permission to create a project (check quota, check role).
|
||||
|
||||
:param items: List of project docs that have been inserted (normally one)
|
||||
"""
|
||||
for item in items:
|
||||
item.pop('url', None)
|
||||
|
||||
|
||||
def after_inserting_projects(items):
|
||||
"""After inserting a project in the collection we do some processing such as:
|
||||
- apply the right permissions
|
||||
- define basic node types
|
||||
- optionally generate a url
|
||||
- initialize storage space
|
||||
|
||||
:param items: List of project docs that have been inserted (normally one)
|
||||
"""
|
||||
current_user = g.get('current_user', None)
|
||||
users_collection = app.data.driver.db['users']
|
||||
user = users_collection.find_one({'_id': current_user['user_id']})
|
||||
|
||||
for item in items:
|
||||
# Create a project specific group (with name matching the project id)
|
||||
project_group = dict(name=str(item['_id']))
|
||||
group = post_internal('groups', project_group)
|
||||
# If Group creation failed, stop
|
||||
# TODO: undo project creation
|
||||
if group[3] != 201:
|
||||
abort(group[3])
|
||||
else:
|
||||
group = group[0]
|
||||
# Assign the current user to the group
|
||||
if 'groups' in user:
|
||||
user['groups'].append(group['_id'])
|
||||
else:
|
||||
user['groups'] = [group['_id']]
|
||||
put_internal('users', remove_private_keys(user), _id=user['_id'])
|
||||
# Assign the group to the project with admin rights
|
||||
permissions = dict(
|
||||
world=['GET'],
|
||||
users=[],
|
||||
groups=[
|
||||
dict(group=group['_id'],
|
||||
methods=['GET', 'PUT', 'POST'])
|
||||
]
|
||||
)
|
||||
# Assign permissions to the project itself, as well as to the node_types
|
||||
item['permissions'] = permissions
|
||||
node_type_asset['permissions'] = permissions
|
||||
node_type_group['permissions'] = permissions
|
||||
node_type_page['permissions'] = permissions
|
||||
node_type_comment['permissions'] = permissions
|
||||
# Assign the basic 'group', 'asset' and 'page' node_types
|
||||
item['node_types'] = [
|
||||
node_type_group,
|
||||
node_type_asset,
|
||||
node_type_page,
|
||||
node_type_comment]
|
||||
# TODO: Depending on user role or status, assign the url attribute
|
||||
# Initialize storage page (defaults to GCS)
|
||||
gcs_storage = GoogleCloudStorageBucket(str(item['_id']))
|
||||
if gcs_storage.bucket.exists():
|
||||
log.debug("Created CGS bucket {0}".format(item['_id']))
|
||||
# Assign a url based on the project id
|
||||
item['url'] = "p-{}".format(item['_id'])
|
||||
# Commit the changes
|
||||
put_internal('projects', remove_private_keys(item), _id=item['_id'])
|
@@ -26,9 +26,17 @@ class GoogleCloudStorageBucket(object):
|
||||
|
||||
def __init__(self, bucket_name, subdir='_/'):
|
||||
gcs = Client()
|
||||
self.bucket = gcs.get_bucket(bucket_name)
|
||||
try:
|
||||
self.bucket = gcs.get_bucket(bucket_name)
|
||||
except NotFound:
|
||||
self.bucket = gcs.bucket(bucket_name)
|
||||
# Hardcode the bucket location to EU
|
||||
self.bucket.location = 'EU'
|
||||
self.bucket.create()
|
||||
|
||||
self.subdir = subdir
|
||||
|
||||
|
||||
def List(self, path=None):
|
||||
"""Display the content of a subdir in the project bucket. If the path
|
||||
points to a file the listing is simply empty.
|
||||
|
@@ -9,10 +9,12 @@ from flask.ext.script import Manager
|
||||
|
||||
# Use a sensible default when running manage.py commands.
|
||||
if not os.environ.get('EVE_SETTINGS'):
|
||||
settings_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settings.py')
|
||||
settings_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'settings.py')
|
||||
os.environ['EVE_SETTINGS'] = settings_path
|
||||
|
||||
from application import app
|
||||
from application.utils.gcs import GoogleCloudStorageBucket
|
||||
from manage.node_types.asset import node_type_asset
|
||||
from manage.node_types.blog import node_type_blog
|
||||
from manage.node_types.comment import node_type_comment
|
||||
@@ -106,6 +108,45 @@ def setup_db():
|
||||
print("Created user {0}".format(user[0]['_id']))
|
||||
|
||||
# TODO: Create a default project
|
||||
groups_collection = app.data.driver.db['groups']
|
||||
admin_group = groups_collection.find_one({'name': 'admin'})
|
||||
|
||||
default_permissions = dict(
|
||||
world=['GET'],
|
||||
users=[],
|
||||
groups=[
|
||||
dict(group=admin_group['_id'],
|
||||
methods=['GET', 'PUT', 'POST'])
|
||||
]
|
||||
)
|
||||
|
||||
node_type_blog['permissions'] = default_permissions
|
||||
node_type_post['permissions'] = default_permissions
|
||||
node_type_comment['permissions'] = default_permissions
|
||||
|
||||
project = dict(
|
||||
owners=dict(users=[], groups=[]),
|
||||
description='Default Project',
|
||||
name='Default Project',
|
||||
node_types=[
|
||||
node_type_blog,
|
||||
node_type_post,
|
||||
node_type_comment
|
||||
],
|
||||
status='published',
|
||||
user=user[0]['_id'],
|
||||
is_private=False,
|
||||
permissions=default_permissions,
|
||||
url='default-project',
|
||||
summary='Default Project summary',
|
||||
category='training'
|
||||
)
|
||||
project = post_internal('projects', project)
|
||||
print("Created default project {0}".format(project[0]['_id']))
|
||||
gcs_storage = GoogleCloudStorageBucket(str(project[0]['_id']))
|
||||
|
||||
if gcs_storage.bucket.exists():
|
||||
print("Created CGS instance")
|
||||
|
||||
|
||||
@manager.command
|
||||
|
Reference in New Issue
Block a user