示例#1
0
def update_filter(request, data=None):
    if len(data) != 1:
        raise errors.ClientError(
            "An attempt to update more than just the filter has been made.  The length of the data set exceeds 1."
        )

    if c.KEY_FILTERS not in data:
        raise errors.ClientError(
            "The '{}' key is not present in the data '{}'.".format(
                c.KEY_FILTERS, data))

    for filter in data[c.KEY_FILTERS]:
        if 'event' not in filter:
            raise errors.ClientError(
                "The filter '{}' is missing the attribute 'event'.".format(
                    filter))
        if 'attributes' not in filter:
            raise errors.ClientError(
                "The filter '{}' is missing the attribute 'attributes'.".
                format(filter))
        if 'type' not in filter:
            raise errors.ClientError(
                "The filter '{}' is missing the attribute 'type'.".format(
                    filter))

    update_context(request, data)
    return data
示例#2
0
def update_custom_partition(request, data=None):
    if len(data) != 1:
        raise errors.ClientError(
            "An attempt to update more than just the partitions has been made.  The length of the data set exceeds 1."
        )

    if c.KEY_PARTITIONS not in data:
        raise errors.ClientError(
            "The '{}' key is not present in the data '{}'.".format(
                c.KEY_PARTITIONS, data))

    for partition in data['partitions']:
        if 'key' not in partition:
            raise errors.ClientError(
                "The partition '{}' is missing the attribute 'key'.".format(
                    partition))
        if 'type' not in partition:
            raise errors.ClientError(
                "The partition '{}' is missing the attribute 'type'.".format(
                    partition))

        key = partition['key']
        if key in c.PREDEFINED_PARTITIONS:
            raise errors.ClientError(
                "The '{}' partition is a predefined partition and can't be updated with this API."
                .format(key))
    predefined = get_predefined_partition(request)
    data[c.KEY_PARTITIONS] = predefined + data[c.KEY_PARTITIONS]
    update_context(request, data)
    return data
def disable_survey_question(survey_id, question_id):
    survey_metadata = survey_utils.get_survey_metadata_by_id(
        survey_id, ['questions'], True)
    for i, question in enumerate(survey_metadata['questions']):
        if question['id'] == question_id:
            if question['active'] == True:
                try:
                    survey_utils.get_survey_table().update_item(
                        Key={'survey_id': survey_id},
                        UpdateExpression=
                        'SET questions[{}].active = :false ADD num_active_questions :minus_one'
                        .format(i),
                        ConditionExpression=
                        'questions[{}].id = :question_id and questions[{}].active = :true'
                        .format(i, i),
                        ExpressionAttributeValues={
                            ':true': True,
                            ':false': False,
                            ':question_id': question_id,
                            ':minus_one': -1
                        })
                except ClientError as e:
                    if e.response['Error'][
                            'Code'] == 'ConditionalCheckFailedException':
                        raise errors.ClientError(
                            'Survey has been modified before update')
                    else:
                        raise RuntimeError('Failed to update DynamoDB')
            break
    else:
        raise errors.ClientError(
            'No question with id [{}] found for survey [{}]'.format(
                question_id, survey_id))

    return 'success'
示例#4
0
def validate_answer_to_predefined_type_question(question, answer):
    if not validation_utils.is_num_str(answer):
        raise errors.ClientError(
            "answer to predefined type question is invalid: {}".format(answer))
    val = int(answer)
    if val < 0 or val >= len(question['predefines']):
        raise errors.ClientError(
            "answer to predefined type question is invalid: {}, number of options: {}"
            .format(answer, len(question['predefines'])))
示例#5
0
def validate_eligible_for_publishing(survey_metadata):
    questions = survey_metadata.get('questions')
    if validation_utils.is_empty(questions):
        raise errors.ClientError("Survey doesn't have question")

    if survey_metadata.get(
            'activation_start_time') is None and survey_metadata.get(
                'activation_end_time') is None:
        raise errors.ClientError("Survey doesn't have activation period yet")
示例#6
0
def update_priority(request, data = None):    
    if len(data) != 1:
        raise errors.ClientError("An attempt to update more than just the priority has been made.  The length of the data set exceeds 1.")

    if c.KEY_PRIORITIES not in data:
        raise errors.ClientError("The '{}' key is not present in the data '{}'.".format(c.KEY_PRIORITIES, data))
                 
    update_context(request, data)
    return data
def get_username_for_account(AccountId):
    account = get_account_table().get_item(Key = { 'AccountId': AccountId }, ConsistentRead = False)

    if not 'Item' in account:
        raise errors.ClientError("No account found for '{}'".format(AccountId))

    if not 'CognitoUsername' in account['Item']:
        raise errors.ClientError("Account {} is not linked to a Cognito user pool".format(AccountId))

    return account['Item']['CognitoUsername']
示例#8
0
def validate_account_update_request(account):
    if len(account.get('PlayerName', '')) > MAX_PLAYER_NAME_LENGTH:
        raise errors.ClientError(
            'PlayerName is longer than {} characters'.format(
                MAX_PLAYER_NAME_LENGTH))
    for key, value in account.get('IdentityProviders',
                                  {}).get(IDP_COGNITO, {}).iteritems():
        if len(value) > MAX_COGNITO_ATTRIBUTE_LENGTH:
            raise errors.ClientError('{} is longer than {} characters'.format(
                key, MAX_COGNITO_ATTRIBUTE_LENGTH))
示例#9
0
def put_service_interfaces(request, deployment_name, service_url, service_interfaces_body):

    items = service_interfaces_body.get('Items', None)
    if items is None:
        raise errors.ClientError('Missing required Items property in the request body.')

    try:
        impl.put_service_interfaces(deployment_name, service_url, items)
    except ValueError as e:
        raise errors.ClientError(e.message)
示例#10
0
def delete(request, survey_id, question_id):
    validation_utils.validate_param(survey_id, 'survey_id',
                                    validation_utils.is_not_blank_str)
    validation_utils.validate_param(question_id, 'question_id',
                                    validation_utils.is_not_blank_str)

    survey_metadata = survey_utils.get_survey_metadata_by_id(
        survey_id, ['questions'], True)
    for i, question in enumerate(survey_metadata['questions']):
        if question.get('id') == question_id:
            try:
                if question.get('active'):
                    survey_utils.get_survey_table().update_item(
                        Key={'survey_id': survey_id},
                        UpdateExpression=
                        'REMOVE questions[{}] ADD num_active_questions :minus_one'
                        .format(i),
                        ConditionExpression=
                        'questions[{}].id = :question_id and questions[{}].active = :true'
                        .format(i, i),
                        ExpressionAttributeValues={
                            ':question_id': question_id,
                            ':minus_one': -1,
                            ':true': True
                        })
                else:
                    survey_utils.get_survey_table().update_item(
                        Key={'survey_id': survey_id},
                        UpdateExpression='REMOVE questions[{}]'.format(i),
                        ConditionExpression=
                        'questions[{}].id = :question_id and questions[{}].active = :false'
                        .format(i, i),
                        ExpressionAttributeValues={
                            ':question_id': question_id,
                            ':false': False
                        })
            except ClientError as e:
                if e.response['Error'][
                        'Code'] == 'ConditionalCheckFailedException':
                    raise errors.ClientError(
                        'Survey has been modified before update')
                else:
                    raise RuntimeError('Failed to update DynamoDB')
            break
    else:
        raise errors.ClientError(
            'No question with id [{}] found for survey [{}]'.format(
                question_id, survey_id))

    survey_utils.get_question_table().delete_item(Key={
        'survey_id': survey_id,
        'question_id': question_id
    })

    return 'success'
示例#11
0
def __validate_number_of_posts(number_of_posts, maximum_number_of_posts):
    '''Validate the number of posts requested by the client.'''

    if number_of_posts is None:
        raise errors.ClientError('Invalid NumberOfEncryptedPosts (Empty)')

    if number_of_posts < 0:
        raise errors.ClientError('Invalid NumberOfEncryptedPosts (Number of posts requested is out of range.)')

    if number_of_posts > maximum_number_of_posts:
        raise errors.ClientError('Invalid request_content (Number of posts requested exceedes maximum limit of {}.)'.format(maximum_number_of_posts))
示例#12
0
 def __get_ref(self, path, name=None, params=None):
     if not params:
         params = {}
     if name is not None:
         params['name'] = name
     remote_obj = self.get(path, params=params)
     if len(remote_obj) > 1:
         raise errors.ClientError("Ambiguous result: " + json.dumps(remote_obj))
     if len(remote_obj) == 0:
         raise errors.ClientError("Ref not found: " + path + ' ' + name)
     return remote_obj[0]['_ref']
示例#13
0
def __validate_request_content(request_content):
    '''Validate request_content recieved from the client.'''

    if request_content is None:
        raise errors.ClientError('Invalid request_content (Empty)')

    if not request_content.has_key('NumberOfEncryptedPosts'):
        raise errors.ClientError('Invalid request_content (Does not contain necessary keys. Found these keys: {})'.format(request_content.keys()))

    if not request_content.has_key('NumberOfUnencryptedPosts'):
        raise errors.ClientError('Invalid request_content (Does not contain necessary keys. Found these keys: {})'.format(request_content.keys()))
示例#14
0
def __validate_data(data):

    if not isinstance(data.get('ExamplePropertyA', None), basestring):
        raise errors.ClientError(
            'Property ExamplePropertyA in provided data is missing or is not a string.'
        )

    if not isinstance(data.get('ExamplePropertyB', None), int):
        raise errors.ClientError(
            'Property ExamplePropertyB in provided data is missing or is not an integer.'
        )
示例#15
0
def get_index(s3_client):
    # Request the index file
    try:
        s3_index_obj_request = s3_client.get_object(Bucket=BUCKET_ID, Key=PROJECT_CGP_ROOT_FILE)
    except ClientError as e:
        print e
        raise errors.ClientError("Could not read from the key '{}' in the S3 bucket '{}'. Failed with: {}".format(PROJECT_CGP_ROOT_FILE, BUCKET_ID, e.message))

    # Does the lambda have access to it?
    if s3_index_obj_request['ResponseMetadata']['HTTPStatusCode'] != 200:
        raise errors.ClientError("The user does not have access to the file index.html file.")

    content = s3_index_obj_request['Body'].read().decode('utf-8')
    return content
示例#16
0
    def validate(self, columns):
        required_fields_ordered = self.schema_order.required_fields
        for field in required_fields_ordered:
            if field.id not in columns:
                raise errors.ClientError(
                    "[{}] The metric is missing the attribute '{}' in columns {}"
                    .format(code.Error.missing_attribute(), field.id, columns))

        for field in columns:
            if not field.islower():
                raise errors.ClientError(
                    "[{}] The metric attribute '{}' is not lowercase.  All attributes should be lowercase.  The columns were '{}'"
                    .format(code.Error.is_not_lower(), field, columns))

        return
示例#17
0
def put(request, survey_id, question_order):
    validation_common.validate_survey_id(survey_id)

    question_id_list = question_order.get('question_id_list')
    validation_utils.validate_param(question_id_list, 'question_id_list',
                                    validation_utils.is_not_none)

    survey_metadata = survey_utils.get_survey_metadata_by_id(
        survey_id, ['questions'], True)
    question_ids = [x['id'] for x in survey_metadata['questions']]
    if set(question_ids) != set(question_id_list):
        raise errors.ClientError(
            "Question IDs from input doesn't match existing question IDs")

    question_map = {}
    for question in survey_metadata['questions']:
        question_map[question['id']] = question

    new_question_list = [
        question_map[question_id] for question_id in question_id_list
    ]

    survey_utils.get_survey_table().update_item(
        Key={'survey_id': survey_id},
        UpdateExpression='SET questions = :new_question_list',
        ExpressionAttributeValues={':new_question_list': new_question_list})

    return "success"
示例#18
0
def validate_start_end_times(start_timeval, end_timeval):
    #Scheduling with start and end time
    if get_struct_time(end_timeval) <= get_struct_time(start_timeval):
        raise errors.ClientError('Invalid: End time ' + end_timeval + ' <= Start time ' + start_timeval)

	#Scheduling with no end time is always valid	
    return True
示例#19
0
def update_account(item, delete_keys=set(), existing_account=None):
    # Reads are cheaper than writes, check if a write is actually needed.
    account_key = {'AccountId': item['AccountId']}

    if not existing_account:
        get_account_response = get_account_table().get_item(
            Key=account_key, ConsistentRead=False)
        print 'Existing account row: ', get_account_response

        if 'Item' not in get_account_response:
            raise errors.ClientError('Account {} does not exist.'.format(
                item['AccountId']))

        existing_account = get_account_response['Item']

    updates = {}
    updated_item = existing_account.copy()
    for key, value in item.iteritems():
        if key not in existing_account or existing_account[key] != value:
            updates[key] = {'Value': value, 'Action': 'PUT'}
            updated_item[key] = value
    for key in delete_keys:
        updates[key] = {'Action': 'DELETE'}
        del updated_item[key]

    if not updates:
        print 'The account table is up to date.'
        return existing_account

    get_account_table().update_item(Key=account_key, AttributeUpdates=updates)
    print 'Updated the account table: ', updates
    return updated_item
示例#20
0
def ensure_question_belongs_to_survey(survey_id, question_id):
    question = survey_utils.get_question_by_id(survey_id, question_id,
                                               ['survey_id'], True)
    if survey_id != question['survey_id']:
        raise errors.ClientError(
            "Question {} doesn't belong to survey {}".format(
                question_id, survey_id))
示例#21
0
def get_submission_by_id(survey_id,
                         submission_id,
                         attributes=None,
                         raise_exception_if_not_found=False):
    if attributes is not None:
        projection_expression, expression_attribute_names_map = __create_projection_expression_and_attribute_names(
            attributes)
        get_result = get_answer_table().get_item(
            Key={
                'survey_id': survey_id,
                'submission_id': submission_id
            },
            ProjectionExpression=projection_expression,
            ExpressionAttributeNames=expression_attribute_names_map)
    else:
        get_result = get_answer_table().get_item(Key={
            'survey_id': survey_id,
            'submission_id': submission_id
        })

    submission = get_result.get('Item')
    if raise_exception_if_not_found and submission is None:
        raise errors.ClientError(
            'No submission found for survey_id: [{}], submission_id: [{}]'.
            format(survey_id, submission_id))

    return submission
示例#22
0
def post(request, cognitoUsername):
    try:
        account_utils.get_user_pool_client().admin_reset_user_password(UserPoolId=account_utils.get_user_pool_id(), Username=cognitoUsername)
    except botocore.exceptions.ClientError as e:
        message = e.response.get('Error', {}).get('Message')
        raise errors.ClientError(message)
    return {}
示例#23
0
def get(request, run_id, time):
    if time >= buffer_time:
        time -= buffer_time
    
    timestamp = datetime.datetime.utcfromtimestamp(time)
    
    if len(run_id) > 1:
        run_key = json.dumps(json.loads(run_id))
    else:
        run_key = run_id
    
    # Load the most recent events
    query_params = {
        'TableName': log_db,
        'ConsistentRead': True,
        'ScanIndexForward': True,
        'Select': "ALL_ATTRIBUTES",
        'KeyConditions': {
            'run-id': {
                'AttributeValueList': [
                    {
                        'S': run_key
                    }
                ],
                'ComparisonOperator': "EQ"
            },
            'event-id': {
                'AttributeValueList': [
                    {
                        'S': timestamp.isoformat()[:19]
                    }
                ],
                'ComparisonOperator': "GE"
            }
        }
    }
    
    events = []
    
    while True:
        response = {}
        try:
            response = dynamo_client.query(**query_params)
        except ClientError as e:
            raise errors.ClientError('Error querying LogDB. {}'.format(e.response['Error']['Message']))
        events.extend([_process_data({'M': item}) for item in response.get('Items',[])])
        
        next_key = response.get('LastEvaluatedKey', None)
        if next_key:
            query_params['ExclusiveStartKey'] = next_key
        else:
            break
            
    result = {
        'run-id': run_id,
        'events': events
    }
    
    return result
    
示例#24
0
def get(request, time=None, lang=None):

    #Validate the time that was provided to avoid spoofing.
    if time is not None:
        client_datetime = message_utils.get_struct_time(time)
        current_time = datetime.utcnow()

        time_diff = current_time - client_datetime

        time_diff_in_hours = time_diff.total_seconds() / 3600
        #No matter where you are in the world you should not have a time difference greater than 12 hours
        if time_diff_in_hours > 12 or time_diff_in_hours < -12:
            print('Time diff is {}'.format(time_diff_in_hours))
            raise errors.ClientError('Invalid client time')

    #This function will return UTC if no timestring is provided
    client_time_as_number = message_utils.get_time_as_number(time)

    response = message_utils.get_message_table().scan(
        ProjectionExpression='message, priority, startTime, endTime',
        FilterExpression=Attr('startTime').lte(client_time_as_number)
        & Attr('endTime').gte(client_time_as_number))

    data = []
    for i in response['Items']:
        conv = convert_table_entry(i)
        data.append(conv)
    return {"list": data}
示例#25
0
def message(request, compression_mode, sensitivity_type, payload_type, data):
    p_lambda = Lambda({})
    print "Target lambda {}".format(os.environ[c.ENV_LAMBDA_PRODUCER])
    util.debug_print(
        "Invoking lambda {} with payload size: {} Compression mode: {}, Sensitivity Type: {}, Payload Type: {}"
        .format(os.environ[c.ENV_LAMBDA_PRODUCER], len(data), compression_mode,
                sensitivity_type, payload_type))
    payload_data = {
        c.API_PARAM_SOURCE_IP: request.event[c.API_PARAM_SOURCE_IP],
        c.SQS_PARAM_SENSITIVITY_TYPE: sensitivity_type,
        c.SQS_PARAM_PAYLOAD_TYPE: payload_type,
        c.SQS_PARAM_COMPRESSION_TYPE: compression_mode,
        c.API_PARAM_PAYLOAD: data
    }

    response = p_lambda.invoke_sync(os.environ[c.ENV_LAMBDA_PRODUCER],
                                    payload_data)

    sb = response['Payload']
    sb = json.loads(sb.read().decode("utf-8"))
    error = sb.get('errorMessage', None)

    returnObj = {
        'StatusCode': response['StatusCode'],
        'PhysicalResourceId': os.environ[c.ENV_LAMBDA_PRODUCER]
    }

    if error and len(error) > 0:
        print "Error:", sb
        raise errors.ClientError(
            "An error occurred invoking the SQS event producer.  Please check the cloud watch logs."
        )

    return returnObj
示例#26
0
def update_settings(request, data = None):       
    for entry in data:        
        if entry in c.NON_SETTINGS:
            raise errors.ClientError("The '{}' key can not be updated through this API.  It is an object type and must be updated using its corresponding service API.".format(entry))     
        
    update_context(request, data)
    return data
示例#27
0
def put(request, survey_id, submission_id, answer_list):
    cognito_identity_id = request.event["cognitoIdentityId"]
    validation_common.validate_cognito_identity_id(cognito_identity_id)
    validation_common.validate_survey_id(survey_id)
    validation_common.validate_submission_id(submission_id)
    answers = answer_list.get('answers')
    validation_common.validate_answers(answers)

    survey_common.ensure_survey_active(survey_id)

    submission = survey_utils.get_submission_by_id(survey_id, submission_id,
                                                   ['user_id'], True)
    if submission.get('user_id') != cognito_identity_id:
        raise errors.ClientError(
            "Cognito identity ID [{}] doesn't own this submission".format(
                cognito_identity_id))

    question_ids = [answer['question_id'] for answer in answers]
    if len(question_ids) != len(set(question_ids)):
        raise errors.ClientError("Input has duplicate question IDs")

    questions = survey_common.get_questions(survey_id, question_ids)
    if len(questions) != len(question_ids):
        raise errors.ClientError("Some question IDs not found")
    question_map = {}
    for question in questions:
        question_map[question['question_id']] = question

    answers_map = {}
    for answer in answers:
        question = question_map[answer['question_id']]
        validate_answer_by_question_type(question, answer['answer'])
        # for empty text type answer, replace it with a single whitespace
        # as dynamo db doesn't allow empty string..
        if question['type'] == 'text' and len(answer['answer'][0]) == 0:
            answer['answer'][0] = " "
        answers_map[answer['question_id']] = answer['answer']

    survey_utils.get_answer_table().update_item(
        Key={
            'survey_id': survey_id,
            'submission_id': submission_id
        },
        UpdateExpression='SET answers=:answers',
        ExpressionAttributeValues={':answers': answers_map})

    return {'submission_id': submission_id}
示例#28
0
def describe_content(request, file_name):
    print 'Describing portal content'
    resultData = []

    staging_table = _get_staging_table()

    try:
        response_data = staging_table.get_item(Key={'FileName': file_name})
    except:
        raise errors.ClientError('Failed to retrieve data for ' + file_name)

    item_data = response_data.get('Item')

    if not item_data:
        raise errors.ClientError('No data for ' + file_name)

    return {'PortalFileInfo': item_data}
示例#29
0
def get(request):
    if not request.event["cognitoIdentityId"]:
        raise errors.ForbiddenRequestError('The credentials used did not contain Cognito identity information')

    account = account_utils.get_account_for_identity(request.event["cognitoIdentityId"])
    if not account:
        raise errors.ClientError("No account found for '{}'".format(request.event["cognitoIdentityId"]))

    if account.get('AccountBlacklisted'):
        raise errors.ForbiddenRequestError('The account is blacklisted')

    response = account_utils.get_account_table().get_item(Key = { 'AccountId': account['AccountId'] }, ConsistentRead = False)

    if not 'Item' in response:
        raise errors.ClientError("No account found for '{}'".format(account['AccountId']))

    return account_utils.convert_account_from_dynamo_to_player_model(response['Item'])
示例#30
0
 def validate_values(self, dict):
     required_fields_ordered = self.schema_order.required_fields
     for field in required_fields_ordered:
         value = dict[field.id]
         if value is None or len(str(value)) == 0:
             raise errors.ClientError(
                 "[{}] The metric attribute '{}' is null or empty.  Required fields can not be null or empty."
                 .format(code.Error.is_not_lower(), field.id))