class TSValidationError(Exception):
    pass def validate_request(collection, json_in):
    validator(requests_schema[collection], format_checker=jsonschema.FormatChecker()).validate(json_in) def recursive_merge(container, container_override):
    """merges container_override into container and return merged result.
    If keep is set, only items already present in container are modified."""
    
    key = None
    try:
        if not isinstance(container, (types.DictType, types.ListType)):
            # border case for first run or if container is container primitive
            container = container_override
        elif isinstance(container, types.ListType):
            # lists can be only replaced
            if isinstance(container_override, types.ListType):
                # replace list
                container = container_override[:]
            else:
                # append to list
                container.append(container_override)
                    
        elif isinstance(container, types.DictType):
            # dicts must be merged
            if isinstance(container_override, types.DictType):
                for key in container_override:
                    if key in container:
                        container[key] = recursive_merge(container[key], container_override[key])
                    else:
                        container[key] = container_override[key]
            else:
                raise ValueError('Cannot merge non-dict "%s" into dict "%s"' % (container_override, container))
        else:
            raise ValueError('Not implemented "%s" into "%s"' % (container_override, container))
    except TypeError, e:
        raise ValueError('TypeError "%s" in key "%s" when merging "%s" into "%s"' % (e, key, container_override, container))
    return container def update_password_salt_user_list(collection, list_in):
    
    if collection == 'user':
        for json_in in list_in:
            update_password_salt_user_json(json_in)
        
    return list_in def validate_json_list(collection, list_in):
    
    for json_in in list_in:    
        # Validate json schema
        validator(schema[collection], format_checker=jsonschema.FormatChecker()).validate(json_in) def sanitize_objectify_json(json_in):
    """Sanitize string and convert _ids to ObjectId in JSON"""
    return recursive_replace(json_in, _replace_function_sanitize_objectify_json) def stringify_objectid_cursor(cursor_in):
    """Convert ObjectId to string in JSON"""
    
    stringified = []
    for json_in in cursor_in:
        stringified.append(recursive_replace(json_in, _replace_function_stringify_objectid_json))
    return stringified def stringify_objectid_list(list_in):
    """Convert an ObjectId list to string list"""
    return recursive_replace(list_in, _replace_function_stringify_objectid_list) def check_get_permissions(collection, criteria, projection, sort):

    # Get criteria permissions
    try:
        criteria_restrictions = cherrypy.session['_ts_user']['restrictions'][collection]['get']['criteria']
    except (KeyError, TypeError):
        criteria_restrictions = None
        
    # Get projection permissions
    try:
        projections_restrictions = cherrypy.session['_ts_user']['restrictions'][collection]['get']['projections']
    except (KeyError, TypeError):
        projections_restrictions = None

    # If there are no restrictions, check if is set to True
    if not criteria_restrictions and not projections_restrictions:
        # If collection.get is not set to True, the access is denied
        try:
            get_permissions = cherrypy.session['_ts_user']['restrictions'][collection]['get']
        except (KeyError, TypeError):
            get_permissions = None        
            
        if get_permissions != True:
            raise TSValidationError("Access to 'get.%s' is restricted for current user" % (collection))
        
        # Else, returns as allowed
        else:
            return
    
    # Validate projections and sort
    if projections_restrictions:
        restricted_field = next((p for p in projection if p in projections_restrictions), None)
        
        if not restricted_field:
            restricted_field = next((p for p in sort if p in projections_restrictions), None)
            
        if restricted_field:
            raise TSValidationError("Field 'get.%s.%s' is restricted for current user" % (collection, restricted_field))

    
    # Validate criteria
    if criteria_restrictions:
        validator(criteria_restrictions, format_checker=jsonschema.FormatChecker()).validate(criteria) def check_upsert_permissions(action, collection, document):
    
    # Get add/update permissions
    try:
        restrictions = cherrypy.session['_ts_user']['restrictions'][collection][action]
    except (KeyError, TypeError):
        restrictions = None
        
    if not restrictions:
        raise TSValidationError("Access to '%s.%s' is restricted for current user" % (action, collection))
    elif restrictions != True:       
        validator(restrictions, format_checker=jsonschema.FormatChecker()).validate(document) def check_remove_permissions(collection, document):
    
    # Get remove permissions
    try:
        restrictions = cherrypy.session['_ts_user']['restrictions'][collection]['remove']
    except (KeyError, TypeError):
        restrictions = None
        
    if not restrictions:
        raise TSValidationError("Access to 'remove.%s' is restricted for current user" % (collection))
    elif restrictions != True:       
        validator(restrictions, format_checker=jsonschema.FormatChecker()).validate(document)
    from pymongo import MongoClient as Connection
    from pymongo import Connection
from core.validation.validation import TSValidationError, validate_request, recursive_merge, update_password_salt_user_list, validate_json_list, sanitize_objectify_json, stringify_objectid_cursor, stringify_objectid_list
from core.validation.permissions import check_get_permissions, check_upsert_permissions, check_remove_permissions
from bson.objectid import ObjectId
from core.config import collections, conf_mongodb, conf_auth, conf_auth_db
import string, hashlib, random, types, cherrypy, logging
try:
except ImportError as e:


connection = Connection(conf_mongodb['hostname'], conf_mongodb['port'])
db = connection[conf_mongodb['db']]

db_log_severity = logging.INFO

def get(collection, criteria_projection_order):
    """Get selected records from collection, and return it as json
    Called by GET /<collection>/"""
      
    # Check request format

    validate_request('get', criteria_projection_order)