New authentication logic
We are replacing the existing mixed BaseAuth TokenAuth authentication logic and permissions system with a more streamlined solution, based on user id and groups checking against node_type stored permissions. Such permissions can be overridden on the node level (and complement the public GET operations on the node entry point).
This commit is contained in:
parent
474ddfc7af
commit
018ddfa20b
@ -17,14 +17,15 @@ from bson import ObjectId
|
|||||||
from flask import g
|
from flask import g
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
|
from flask import abort
|
||||||
|
|
||||||
from pre_hooks import pre_GET
|
from pre_hooks import pre_GET
|
||||||
from pre_hooks import pre_PUT
|
from pre_hooks import pre_PUT
|
||||||
from pre_hooks import pre_PATCH
|
from pre_hooks import pre_PATCH
|
||||||
from pre_hooks import pre_POST
|
from pre_hooks import pre_POST
|
||||||
from pre_hooks import pre_DELETE
|
from pre_hooks import pre_DELETE
|
||||||
from pre_hooks import check_permissions
|
# from pre_hooks import check_permissions
|
||||||
from pre_hooks import compute_permissions
|
# from pre_hooks import compute_permissions
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
@ -47,9 +48,13 @@ class SystemUtility():
|
|||||||
|
|
||||||
|
|
||||||
def validate(token):
|
def validate(token):
|
||||||
"""Validate a Token against Blender ID server
|
"""Validate a token against the Blender ID server. This simple lookup
|
||||||
"""
|
returns a dictionary with the following keys:
|
||||||
|
|
||||||
|
- message: a success message
|
||||||
|
- valid: a boolean, stating if the token is valid
|
||||||
|
- user: a dictionary with information regarding the user
|
||||||
|
"""
|
||||||
payload = dict(
|
payload = dict(
|
||||||
token=token)
|
token=token)
|
||||||
try:
|
try:
|
||||||
@ -59,41 +64,55 @@ def validate(token):
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
message = r.json()['message']
|
response = r.json()
|
||||||
valid = r.json()['valid']
|
validation_result = dict(
|
||||||
user = r.json()['user']
|
message=response['message'],
|
||||||
|
valid=response['valid'],
|
||||||
|
user=response['user'])
|
||||||
else:
|
else:
|
||||||
message = ""
|
validation_result = dict(valid=False)
|
||||||
valid = False
|
return validation_result
|
||||||
user = None
|
|
||||||
return dict(valid=valid, message=message, user=user)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_token():
|
def validate_token():
|
||||||
|
"""Validate the token provided in the request and populate the current_user
|
||||||
|
flask.g object, so that permissions and access to a resource can be defined
|
||||||
|
from it.
|
||||||
|
"""
|
||||||
if not request.authorization:
|
if not request.authorization:
|
||||||
|
# If no authorization headers are provided, we are getting a request
|
||||||
|
# from a non logged in user. Proceed accordingly.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
current_user = {}
|
||||||
|
|
||||||
token = request.authorization.username
|
token = request.authorization.username
|
||||||
tokens = app.data.driver.db['tokens']
|
tokens = app.data.driver.db['tokens']
|
||||||
users = app.data.driver.db['users']
|
|
||||||
lookup = {'token': token, 'expire_time': {"$gt": datetime.now()}}
|
lookup = {'token': token, 'expire_time': {"$gt": datetime.now()}}
|
||||||
dbtoken = tokens.find_one(lookup)
|
db_token = tokens.find_one(lookup)
|
||||||
if not dbtoken:
|
if not db_token:
|
||||||
|
# If no valid token is found, we issue a new request to the Blender ID
|
||||||
|
# to verify the validity of the token. We will get basic user info if
|
||||||
|
# the user is authorized and we will make a new token.
|
||||||
validation = validate(token)
|
validation = validate(token)
|
||||||
if validation['valid']:
|
if validation['valid']:
|
||||||
|
users = app.data.driver.db['users']
|
||||||
email = validation['user']['email']
|
email = validation['user']['email']
|
||||||
dbuser = users.find_one({'email': email})
|
db_user = users.find_one({'email': email})
|
||||||
tmpname = email.split('@')[0]
|
tmpname = email.split('@')[0]
|
||||||
if not dbuser:
|
if not db_user:
|
||||||
user_data = {
|
user_data = {
|
||||||
'first_name': tmpname,
|
'first_name': tmpname,
|
||||||
'last_name': tmpname,
|
'last_name': tmpname,
|
||||||
'email': email,
|
'email': email,
|
||||||
'role': ['admin'],
|
|
||||||
}
|
}
|
||||||
r = post_internal('users', user_data)
|
r = post_internal('users', user_data)
|
||||||
user_id = r[0]["_id"]
|
user_id = r[0]['_id']
|
||||||
|
groups = None
|
||||||
else:
|
else:
|
||||||
user_id = dbuser['_id']
|
user_id = db_user['_id']
|
||||||
|
groups = db_user['groups']
|
||||||
|
|
||||||
token_data = {
|
token_data = {
|
||||||
'user': user_id,
|
'user': user_id,
|
||||||
@ -101,20 +120,27 @@ def validate_token():
|
|||||||
'expire_time': datetime.now() + timedelta(hours=1)
|
'expire_time': datetime.now() + timedelta(hours=1)
|
||||||
}
|
}
|
||||||
post_internal('tokens', token_data)
|
post_internal('tokens', token_data)
|
||||||
return token_data
|
current_user = dict(
|
||||||
|
user_id=user_id,
|
||||||
|
token=token,
|
||||||
|
groups=groups,
|
||||||
|
token_expire_time=datetime.now() + timedelta(hours=1))
|
||||||
|
#return token_data
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
token_data = {
|
users = app.data.driver.db['users']
|
||||||
'user': dbtoken['user'],
|
db_user = users.find_one(db_token['user'])
|
||||||
'token': dbtoken['token'],
|
current_user = dict(
|
||||||
'expire_time': dbtoken['expire_time']
|
user_id=db_token['user'],
|
||||||
}
|
token=db_token['token'],
|
||||||
return token_data
|
groups=db_user['groups'],
|
||||||
|
token_expire_time=db_token['expire_time'])
|
||||||
|
|
||||||
|
setattr(g, 'current_user', current_user)
|
||||||
|
|
||||||
|
|
||||||
class TokensAuth(TokenAuth):
|
class TokensAuth(TokenAuth):
|
||||||
|
|
||||||
def check_auth(self, token, allowed_roles, resource, method):
|
def check_auth(self, token, allowed_roles, resource, method):
|
||||||
if not token:
|
if not token:
|
||||||
return False
|
return False
|
||||||
@ -127,21 +153,13 @@ class TokensAuth(TokenAuth):
|
|||||||
|
|
||||||
# return validation['valid']
|
# return validation['valid']
|
||||||
return True
|
return True
|
||||||
"""
|
|
||||||
users = app.data.driver.db['users']
|
|
||||||
lookup = {'first_name': token['username']}
|
|
||||||
if allowed_roles:
|
|
||||||
lookup['role'] = {'$in': allowed_roles}
|
|
||||||
user = users.find_one(lookup)
|
|
||||||
if not user:
|
|
||||||
return False
|
|
||||||
return token
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class BasicsAuth(BasicAuth):
|
class BasicsAuth(BasicAuth):
|
||||||
def check_auth(self, username, password, allowed_roles, resource, method):
|
def check_auth(self, username, password, allowed_roles, resource, method):
|
||||||
# return username == 'admin' and password == 'secret'
|
# return username == 'admin' and password == 'secret'
|
||||||
|
print username
|
||||||
|
print password
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -157,12 +175,29 @@ class CustomTokenAuth(BasicsAuth):
|
|||||||
return self.authorized_protected(
|
return self.authorized_protected(
|
||||||
self, allowed_roles, resource, method)
|
self, allowed_roles, resource, method)
|
||||||
else:
|
else:
|
||||||
|
print 'is auth'
|
||||||
return self.token_auth.authorized(allowed_roles, resource, method)
|
return self.token_auth.authorized(allowed_roles, resource, method)
|
||||||
|
|
||||||
def authorized_protected(self):
|
def authorized_protected(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NewAuth(TokenAuth):
|
||||||
|
def check_auth(self, token, allowed_roles, resource, method):
|
||||||
|
if not token:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print '---'
|
||||||
|
print 'validating'
|
||||||
|
print token
|
||||||
|
print resource
|
||||||
|
print method
|
||||||
|
print '---'
|
||||||
|
validate_token()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ValidateCustomFields(Validator):
|
class ValidateCustomFields(Validator):
|
||||||
def convert_properties(self, properties, node_schema):
|
def convert_properties(self, properties, node_schema):
|
||||||
for prop in node_schema:
|
for prop in node_schema:
|
||||||
@ -229,11 +264,10 @@ def post_item(entry, data):
|
|||||||
# automatically. The default path (which work in Docker) can be overriden with
|
# automatically. The default path (which work in Docker) can be overriden with
|
||||||
# an env variable.
|
# an env variable.
|
||||||
settings_path = os.environ.get('EVE_SETTINGS', '/data/dev/pillar/pillar/settings.py')
|
settings_path = os.environ.get('EVE_SETTINGS', '/data/dev/pillar/pillar/settings.py')
|
||||||
app = Eve(settings=settings_path, validator=ValidateCustomFields, auth=CustomTokenAuth)
|
app = Eve(settings=settings_path, validator=ValidateCustomFields, auth=NewAuth)
|
||||||
|
|
||||||
import config
|
import config
|
||||||
app.config.from_object(config.Deployment)
|
app.config.from_object(config.Deployment)
|
||||||
app.config['MONGO_HOST'] = os.environ.get('MONGO_HOST', 'localhost')
|
|
||||||
|
|
||||||
client = MongoClient(app.config['MONGO_HOST'], 27017)
|
client = MongoClient(app.config['MONGO_HOST'], 27017)
|
||||||
db = client.eve
|
db = client.eve
|
||||||
@ -243,8 +277,10 @@ def global_validation():
|
|||||||
token_data = validate_token()
|
token_data = validate_token()
|
||||||
if token_data:
|
if token_data:
|
||||||
setattr(g, 'token_data', token_data)
|
setattr(g, 'token_data', token_data)
|
||||||
setattr(g, 'validate', validate(token_data['token']))
|
#setattr(g, 'validate', validate(token_data['token']))
|
||||||
check_permissions(token_data['user'], app.data.driver)
|
check_permissions(token_data['user'], app.data.driver)
|
||||||
|
else:
|
||||||
|
print 'NO TOKEN'
|
||||||
|
|
||||||
|
|
||||||
def pre_GET_nodes(request, lookup):
|
def pre_GET_nodes(request, lookup):
|
||||||
@ -270,11 +306,13 @@ def pre_PATCH_nodes(request):
|
|||||||
|
|
||||||
|
|
||||||
def pre_POST_nodes(request):
|
def pre_POST_nodes(request):
|
||||||
global_validation()
|
# global_validation()
|
||||||
# print ("Post")
|
# print ("Post")
|
||||||
# print ("World: {0}".format(g.get('world_permissions')))
|
# print ("World: {0}".format(g.get('world_permissions')))
|
||||||
# print ("Group: {0}".format(g.get('groups_permissions')))
|
# print ("Group: {0}".format(g.get('groups_permissions')))
|
||||||
return pre_POST(request, app.data.driver)
|
# return pre_POST(request, app.data.driver)
|
||||||
|
print 'pre posting'
|
||||||
|
print request
|
||||||
|
|
||||||
|
|
||||||
def pre_DELETE_nodes(request, lookup):
|
def pre_DELETE_nodes(request, lookup):
|
||||||
@ -287,20 +325,80 @@ def pre_DELETE_nodes(request, lookup):
|
|||||||
return pre_DELETE(request, lookup, app.data.driver)
|
return pre_DELETE(request, lookup, app.data.driver)
|
||||||
|
|
||||||
|
|
||||||
app.on_pre_GET_nodes += pre_GET_nodes
|
#app.on_pre_GET_nodes += pre_GET_nodes
|
||||||
app.on_pre_POST_nodes += pre_POST_nodes
|
app.on_pre_POST_nodes += pre_POST_nodes
|
||||||
app.on_pre_PATCH_nodes += pre_PATCH_nodes
|
# app.on_pre_PATCH_nodes += pre_PATCH_nodes
|
||||||
app.on_pre_PUT_nodes += pre_PUT_nodes
|
#app.on_pre_PUT_nodes += pre_PUT_nodes
|
||||||
app.on_pre_DELETE_nodes += pre_DELETE_nodes
|
app.on_pre_DELETE_nodes += pre_DELETE_nodes
|
||||||
|
|
||||||
|
|
||||||
|
def check_permissions(resource, method):
|
||||||
|
"""Check user permissions to access a node. We look up node permissions from
|
||||||
|
world to groups to users and match them with the computed user permissions.
|
||||||
|
If there is not match, we return 403.
|
||||||
|
"""
|
||||||
|
current_user = g.get('current_user', None)
|
||||||
|
|
||||||
|
if 'permissions' in resource:
|
||||||
|
# If permissions are embedde in the node (this overrides any other
|
||||||
|
# permission previously set)
|
||||||
|
resource_permissions = resource['permissions']
|
||||||
|
elif type(resource['node_type']) is dict:
|
||||||
|
# If the node_type is embedded in the document, extract permissions
|
||||||
|
# from there
|
||||||
|
resource_permissions = resource['node_type']['permissions']
|
||||||
|
else:
|
||||||
|
# If the node_type is referenced with an ObjectID (was not embedded on
|
||||||
|
# request) query for if from the database and get the permissions
|
||||||
|
node_types_collection = app.data.driver.db['node_types']
|
||||||
|
node_type = node_types_collection.find_one(resource['node_type'])
|
||||||
|
resource_permissions = node_type['permissions']
|
||||||
|
|
||||||
|
if current_user:
|
||||||
|
# If the user is authenticated, proceed to compare the group permissions
|
||||||
|
for permission in resource_permissions['groups']:
|
||||||
|
if permission['group'] in current_user['groups']:
|
||||||
|
if method in permission['methods']:
|
||||||
|
return
|
||||||
|
|
||||||
|
for permission in resource_permissions['users']:
|
||||||
|
if current_user['user_id'] == permission['user']:
|
||||||
|
if method in permission['methods']:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if the node is public or private. This must be set for non logged
|
||||||
|
# in users to see the content. For most BI projects this is on by default,
|
||||||
|
# while for private project this will not be set at all.
|
||||||
|
if 'world' in permissions and method in permissions['world']:
|
||||||
|
return
|
||||||
|
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
def before_returning_node(response):
|
||||||
|
# Run validation process, since GET on nodes entry point is public
|
||||||
|
validate_token()
|
||||||
|
check_permissions(response, 'GET')
|
||||||
|
|
||||||
|
def before_replacing_node(item, original):
|
||||||
|
check_permissions(original, 'PUT')
|
||||||
|
|
||||||
|
def before_inserting_nodes(items):
|
||||||
|
for item in items:
|
||||||
|
check_permissions(item, 'POST')
|
||||||
|
|
||||||
|
app.on_fetched_item_nodes += before_returning_node
|
||||||
|
app.on_replace_nodes += before_replacing_node
|
||||||
|
app.on_insert_nodes += before_inserting_nodes
|
||||||
|
|
||||||
|
|
||||||
def post_GET_user(request, payload):
|
def post_GET_user(request, payload):
|
||||||
|
print 'computing permissions'
|
||||||
json_data = json.loads(payload.data)
|
json_data = json.loads(payload.data)
|
||||||
# Check if we are querying the users endpoint (instead of the single user)
|
# Check if we are querying the users endpoint (instead of the single user)
|
||||||
if json_data.get('_id') is None:
|
if json_data.get('_id') is None:
|
||||||
return
|
return
|
||||||
json_data['computed_permissions'] = \
|
# json_data['computed_permissions'] = \
|
||||||
compute_permissions(json_data['_id'], app.data.driver)
|
# compute_permissions(json_data['_id'], app.data.driver)
|
||||||
payload.data = json.dumps(json_data)
|
payload.data = json.dumps(json_data)
|
||||||
|
|
||||||
app.on_post_GET_users += post_GET_user
|
app.on_post_GET_users += post_GET_user
|
||||||
|
149
pillar/manage.py
149
pillar/manage.py
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from eve.methods.put import put_internal
|
||||||
from application import app
|
from application import app
|
||||||
from application import db
|
from application import db
|
||||||
from application import post_item
|
from application import post_item
|
||||||
@ -48,25 +49,6 @@ def clear_db():
|
|||||||
db.drop_collection('users')
|
db.drop_collection('users')
|
||||||
|
|
||||||
|
|
||||||
@manager.command
|
|
||||||
def remove_properties_order():
|
|
||||||
"""Removes properties.order
|
|
||||||
"""
|
|
||||||
from pymongo import MongoClient
|
|
||||||
client = MongoClient(MONGO_HOST, 27017)
|
|
||||||
db = client.eve
|
|
||||||
nodes = db.nodes.find()
|
|
||||||
for node in nodes:
|
|
||||||
new_prop = {}
|
|
||||||
for prop in node['properties']:
|
|
||||||
if prop == 'order':
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
new_prop[prop] = node['properties'][prop]
|
|
||||||
db.nodes.update({"_id": node['_id']},
|
|
||||||
{"$set": {"properties": new_prop}})
|
|
||||||
|
|
||||||
|
|
||||||
@manager.command
|
@manager.command
|
||||||
def upgrade_node_types():
|
def upgrade_node_types():
|
||||||
"""Wipes node_types collection
|
"""Wipes node_types collection
|
||||||
@ -410,14 +392,6 @@ def populate_node_types(old_ids={}):
|
|||||||
scene_node_type = {
|
scene_node_type = {
|
||||||
'name': 'scene',
|
'name': 'scene',
|
||||||
'description': 'Scene node type',
|
'description': 'Scene node type',
|
||||||
'dyn_schema': {
|
|
||||||
'order': {
|
|
||||||
'type': 'integer',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'form_schema': {
|
|
||||||
'order': {},
|
|
||||||
},
|
|
||||||
'parent': {
|
'parent': {
|
||||||
"node_types": ["act"]
|
"node_types": ["act"]
|
||||||
}
|
}
|
||||||
@ -426,49 +400,11 @@ def populate_node_types(old_ids={}):
|
|||||||
act_node_type = {
|
act_node_type = {
|
||||||
'name': 'act',
|
'name': 'act',
|
||||||
'description': 'Act node type',
|
'description': 'Act node type',
|
||||||
'dyn_schema': {
|
|
||||||
'order': {
|
|
||||||
'type': 'integer',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'form_schema': {
|
|
||||||
'order': {},
|
|
||||||
},
|
|
||||||
'parent': {}
|
'parent': {}
|
||||||
}
|
}
|
||||||
|
|
||||||
comment_node_type = {
|
|
||||||
'name': 'comment',
|
|
||||||
'description': 'Comment node type',
|
|
||||||
'dyn_schema': {
|
|
||||||
'text': {
|
|
||||||
'type': 'string',
|
|
||||||
'maxlength': 256
|
|
||||||
},
|
|
||||||
'attachments': {
|
|
||||||
'type': 'list',
|
|
||||||
'schema': {
|
|
||||||
'type': 'objectid',
|
|
||||||
'data_relation': {
|
|
||||||
'resource': 'files',
|
|
||||||
'field': '_id',
|
|
||||||
'embeddable': True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'form_schema': {
|
|
||||||
'text': {},
|
|
||||||
'attachments': {
|
|
||||||
'items': [("File", "name")]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'parent': {
|
|
||||||
"node_types": ["shot", "task"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project_node_type = {
|
node_type_project = {
|
||||||
'name': 'project',
|
'name': 'project',
|
||||||
'parent': {},
|
'parent': {},
|
||||||
'description': 'The official project type',
|
'description': 'The official project type',
|
||||||
@ -567,9 +503,17 @@ def populate_node_types(old_ids={}):
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'permissions': {
|
||||||
|
'groups': [{
|
||||||
|
'group': '5596e975ea893b269af85c0e',
|
||||||
|
'methods': ['GET', 'PUT', 'POST']
|
||||||
|
}],
|
||||||
|
'users': [],
|
||||||
|
'world': ['GET']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group_node_type = {
|
node_type_group = {
|
||||||
'name': 'group',
|
'name': 'group',
|
||||||
'description': 'Generic group node type',
|
'description': 'Generic group node type',
|
||||||
'parent': {},
|
'parent': {},
|
||||||
@ -594,9 +538,17 @@ def populate_node_types(old_ids={}):
|
|||||||
'status': {},
|
'status': {},
|
||||||
'notes': {},
|
'notes': {},
|
||||||
},
|
},
|
||||||
|
'permissions': {
|
||||||
|
'groups': [{
|
||||||
|
'group': '5596e975ea893b269af85c0e',
|
||||||
|
'methods': ['GET', 'PUT', 'POST']
|
||||||
|
}],
|
||||||
|
'users': [],
|
||||||
|
'world': ['GET']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asset_node_type = {
|
node_type_asset = {
|
||||||
'name': 'asset',
|
'name': 'asset',
|
||||||
'description': 'Assets for Elephants Dream',
|
'description': 'Assets for Elephants Dream',
|
||||||
# This data type does not have parent limitations (can be child
|
# This data type does not have parent limitations (can be child
|
||||||
@ -633,6 +585,14 @@ def populate_node_types(old_ids={}):
|
|||||||
'status': {},
|
'status': {},
|
||||||
'content_type': {},
|
'content_type': {},
|
||||||
'file': {},
|
'file': {},
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'groups': [{
|
||||||
|
'group': '5596e975ea893b269af85c0e',
|
||||||
|
'methods': ['GET', 'PUT', 'POST']
|
||||||
|
}],
|
||||||
|
'users': [],
|
||||||
|
'world': ['GET']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +626,14 @@ def populate_node_types(old_ids={}):
|
|||||||
},
|
},
|
||||||
'parent': {
|
'parent': {
|
||||||
"node_types": ["group", "project"]
|
"node_types": ["group", "project"]
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'groups': [{
|
||||||
|
'group': '5596e975ea893b269af85c0e',
|
||||||
|
'methods': ['GET', 'PUT', 'POST']
|
||||||
|
}],
|
||||||
|
'users': [],
|
||||||
|
'world': ['GET']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,6 +702,14 @@ def populate_node_types(old_ids={}):
|
|||||||
},
|
},
|
||||||
'parent': {
|
'parent': {
|
||||||
'node_types': ['asset',]
|
'node_types': ['asset',]
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'groups': [{
|
||||||
|
'group': '5596e975ea893b269af85c0e',
|
||||||
|
'methods': ['GET', 'PUT', 'POST']
|
||||||
|
}],
|
||||||
|
'users': [],
|
||||||
|
'world': ['GET']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,10 +733,16 @@ def populate_node_types(old_ids={}):
|
|||||||
node_name = node_type['name']
|
node_name = node_type['name']
|
||||||
if node_name in old_ids:
|
if node_name in old_ids:
|
||||||
node_type = mix_node_type(old_ids[node_name], node_type)
|
node_type = mix_node_type(old_ids[node_name], node_type)
|
||||||
# Remove old node_type
|
node_id = node_type['_id']
|
||||||
db.node_types.remove({'_id': old_ids[node_name]})
|
|
||||||
# Insert new node_type
|
# Removed internal fields that would cause validation error
|
||||||
db.node_types.insert(node_type)
|
internal_fields = ['_id', '_etag', '_updated', '_created']
|
||||||
|
for field in internal_fields:
|
||||||
|
node_type.pop(field, None)
|
||||||
|
|
||||||
|
p = put_internal('node_types', node_type, **{'_id': node_id})
|
||||||
|
print p
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Making the node")
|
print("Making the node")
|
||||||
print(node_type)
|
print(node_type)
|
||||||
@ -770,9 +752,9 @@ def populate_node_types(old_ids={}):
|
|||||||
# upgrade(task_node_type, old_ids)
|
# upgrade(task_node_type, old_ids)
|
||||||
# upgrade(scene_node_type, old_ids)
|
# upgrade(scene_node_type, old_ids)
|
||||||
# upgrade(act_node_type, old_ids)
|
# upgrade(act_node_type, old_ids)
|
||||||
# upgrade(comment_node_type, old_ids)
|
upgrade(node_type_project, old_ids)
|
||||||
upgrade(project_node_type, old_ids)
|
upgrade(node_type_group, old_ids)
|
||||||
upgrade(asset_node_type, old_ids)
|
upgrade(node_type_asset, old_ids)
|
||||||
upgrade(node_type_storage, old_ids)
|
upgrade(node_type_storage, old_ids)
|
||||||
upgrade(node_type_comment, old_ids)
|
upgrade(node_type_comment, old_ids)
|
||||||
|
|
||||||
@ -1037,6 +1019,23 @@ def make_thumbnails():
|
|||||||
t = build_thumbnails(file_path=f['path'])
|
t = build_thumbnails(file_path=f['path'])
|
||||||
print t
|
print t
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def add_node_permissions():
|
||||||
|
import codecs
|
||||||
|
import sys
|
||||||
|
UTF8Writer = codecs.getwriter('utf8')
|
||||||
|
sys.stdout = UTF8Writer(sys.stdout)
|
||||||
|
nodes_collection = app.data.driver.db['nodes']
|
||||||
|
node_types_collection = app.data.driver.db['node_types']
|
||||||
|
nodes = nodes_collection.find()
|
||||||
|
for node in nodes:
|
||||||
|
print u"{0}".format(node['name'])
|
||||||
|
if 'permissions' not in node:
|
||||||
|
node_type = node_types_collection.find_one(node['node_type'])
|
||||||
|
# nodes_collection.update({'_id': node['_id']},
|
||||||
|
# {"$set": {'permissions': node_type['permissions']}})
|
||||||
|
print node['_id']
|
||||||
|
break
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
manager.run()
|
manager.run()
|
||||||
|
@ -11,8 +11,6 @@ ITEM_METHODS = ['GET', 'PUT', 'DELETE', 'PATCH']
|
|||||||
|
|
||||||
PAGINATION_LIMIT = 25
|
PAGINATION_LIMIT = 25
|
||||||
|
|
||||||
# To be implemented on Eve 0.6
|
|
||||||
# RETURN_MEDIA_AS_URL = True
|
|
||||||
|
|
||||||
users_schema = {
|
users_schema = {
|
||||||
'first_name': {
|
'first_name': {
|
||||||
@ -147,6 +145,56 @@ organizations_schema = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
permissions_embedded_schema = {
|
||||||
|
'groups': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': {
|
||||||
|
'group': {
|
||||||
|
'type': 'objectid',
|
||||||
|
'required': True,
|
||||||
|
'data_relation': {
|
||||||
|
'resource': 'groups',
|
||||||
|
'field': '_id',
|
||||||
|
'embeddable': True
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'methods': {
|
||||||
|
'type': 'list',
|
||||||
|
'required': True,
|
||||||
|
'allowed': ['GET', 'PUT', 'POST', 'DELETE']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'users': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': {
|
||||||
|
'user' : {
|
||||||
|
'type': 'objectid',
|
||||||
|
'required': True,
|
||||||
|
},
|
||||||
|
'methods': {
|
||||||
|
'type': 'list',
|
||||||
|
'required': True,
|
||||||
|
'allowed': ['GET', 'PUT', 'POST', 'DELETE']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'world': {
|
||||||
|
'type': 'list',
|
||||||
|
#'required': True,
|
||||||
|
'allowed': ['GET',]
|
||||||
|
},
|
||||||
|
'is_free': {
|
||||||
|
'type': 'boolean',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes_schema = {
|
nodes_schema = {
|
||||||
'name': {
|
'name': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
@ -200,11 +248,15 @@ nodes_schema = {
|
|||||||
'embeddable': True
|
'embeddable': True
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'properties': {
|
'properties': {
|
||||||
'type' : 'dict',
|
'type' : 'dict',
|
||||||
'valid_properties' : True,
|
'valid_properties' : True,
|
||||||
'required': True,
|
'required': True,
|
||||||
},
|
},
|
||||||
|
'permissions': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': permissions_embedded_schema
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_types_schema = {
|
node_types_schema = {
|
||||||
@ -229,6 +281,11 @@ node_types_schema = {
|
|||||||
'parent': {
|
'parent': {
|
||||||
'type': 'dict',
|
'type': 'dict',
|
||||||
'required': True,
|
'required': True,
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'type': 'dict',
|
||||||
|
'required': True,
|
||||||
|
'schema': permissions_embedded_schema
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +389,6 @@ files_schema = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
groups_schema = {
|
groups_schema = {
|
||||||
'name': {
|
'name': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
@ -364,11 +420,15 @@ groups_schema = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
'schema': nodes_schema
|
'schema': nodes_schema,
|
||||||
|
'public_methods': ['GET'],
|
||||||
|
'public_item_methods': ['GET']
|
||||||
}
|
}
|
||||||
|
|
||||||
node_types = {
|
node_types = {
|
||||||
'resource_methods': ['GET', 'POST'],
|
'resource_methods': ['GET', 'POST'],
|
||||||
|
'public_methods': ['GET'],
|
||||||
|
'public_item_methods': ['GET'],
|
||||||
'schema': node_types_schema,
|
'schema': node_types_schema,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +439,6 @@ users = {
|
|||||||
'cache_control': 'max-age=10,must-revalidate',
|
'cache_control': 'max-age=10,must-revalidate',
|
||||||
'cache_expires': 10,
|
'cache_expires': 10,
|
||||||
|
|
||||||
# most global settings can be overridden at resource level
|
|
||||||
'resource_methods': ['GET', 'POST'],
|
'resource_methods': ['GET', 'POST'],
|
||||||
|
|
||||||
'public_methods': ['GET', 'POST'],
|
'public_methods': ['GET', 'POST'],
|
||||||
@ -399,7 +458,9 @@ tokens = {
|
|||||||
|
|
||||||
files = {
|
files = {
|
||||||
'resource_methods': ['GET', 'POST'],
|
'resource_methods': ['GET', 'POST'],
|
||||||
'schema': files_schema,
|
'public_methods': ['GET'],
|
||||||
|
'public_item_methods': ['GET'],
|
||||||
|
'schema': files_schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -423,5 +484,5 @@ DOMAIN = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if os.environ.get('MONGO_HOST'):
|
MONGO_HOST = os.environ.get('MONGO_HOST', 'localhost')
|
||||||
MONGO_HOST = os.environ.get('MONGO_HOST')
|
MONGO_PORT = os.environ.get('MONGO_PORT', 27017)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user