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:
parent
90693595a6
commit
a33e4421a8
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='_/'):
|
def __init__(self, bucket_name, subdir='_/'):
|
||||||
gcs = Client()
|
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
|
self.subdir = subdir
|
||||||
|
|
||||||
|
|
||||||
def List(self, path=None):
|
def List(self, path=None):
|
||||||
"""Display the content of a subdir in the project bucket. If the path
|
"""Display the content of a subdir in the project bucket. If the path
|
||||||
points to a file the listing is simply empty.
|
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.
|
# Use a sensible default when running manage.py commands.
|
||||||
if not os.environ.get('EVE_SETTINGS'):
|
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
|
os.environ['EVE_SETTINGS'] = settings_path
|
||||||
|
|
||||||
from application import app
|
from application import app
|
||||||
|
from application.utils.gcs import GoogleCloudStorageBucket
|
||||||
from manage.node_types.asset import node_type_asset
|
from manage.node_types.asset import node_type_asset
|
||||||
from manage.node_types.blog import node_type_blog
|
from manage.node_types.blog import node_type_blog
|
||||||
from manage.node_types.comment import node_type_comment
|
from manage.node_types.comment import node_type_comment
|
||||||
@ -106,6 +108,45 @@ def setup_db():
|
|||||||
print("Created user {0}".format(user[0]['_id']))
|
print("Created user {0}".format(user[0]['_id']))
|
||||||
|
|
||||||
# TODO: Create a default project
|
# 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
|
@manager.command
|
||||||
|
@ -6,7 +6,7 @@ Eve==0.5.3
|
|||||||
Events==0.2.1
|
Events==0.2.1
|
||||||
Flask-Script==2.0.5
|
Flask-Script==2.0.5
|
||||||
flup==1.0.2
|
flup==1.0.2
|
||||||
gcloud==0.11.0
|
-e git+https://github.com/GoogleCloudPlatform/gcloud-python.git@dbb22a7fddcf12228bba7b191774f2c4a2adfe35#egg=gcloud
|
||||||
google-apitools==0.4.11
|
google-apitools==0.4.11
|
||||||
httplib2==0.9.2
|
httplib2==0.9.2
|
||||||
idna==2.0
|
idna==2.0
|
||||||
@ -22,3 +22,7 @@ simplejson==3.8.1
|
|||||||
WebOb==1.5.0
|
WebOb==1.5.0
|
||||||
wheel==0.24.0
|
wheel==0.24.0
|
||||||
zencoder==0.6.5
|
zencoder==0.6.5
|
||||||
|
|
||||||
|
# development requirements
|
||||||
|
httpretty==0.8.14
|
||||||
|
pytest==2.9.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user