Example #1
0
    def test_jsonify_code(self):
        """
        Test paths in py:function:`archelond.util.jsonify_code`
        """
        with app.test_request_context():
            # Check expected path
            response = jsonify_code({'test': 1}, 400)
            self.assertTrue(response.status_code, 400)
            self.assertTrue(isinstance(response, Response))
            self.assertEqual(
                response.get_data(as_text=True),
                json.dumps({'test': 1}, indent=2)
            )

            # Verify jsonify not accepting a root valued json object
            with self.assertRaisesRegexp(
                ValueError,
                'dictionary update sequence element #0 .+'
            ):

                jsonify_code('asdf', 200)

            # Verify bad status_code
            with self.assertRaisesRegexp(
                TypeError,
                'a number is required'
            ):
                jsonify_code({'test': 1}, 'foo')
Example #2
0
def history_item(user, cmd_id):
    """Actions for individual command history items.

    Updates, gets, or deletes a command from the active data store.

    PUT: Takes a payload in either form or JSON request, and runs the
    add routine by passing the dictinoary minus ``command``,
    ``username``, and ``host`` as kwargs to the data stores ``add``
    routine.
    """
    # We have to handle several methods, which requires branches and
    # extra returns.  Until/when we switch to pluggable views, let
    # pylint know that is ok for this view.
    # pylint: disable=too-many-return-statements,too-many-branches
    if request.method == 'GET':
        log.debug('Retrieving %s for %s', cmd_id, user)
        try:
            cmd = app.data.get(cmd_id, user, request.remote_addr)
        except KeyError:
            return jsonify_code({'error': 'No such history item'}, 404)
        return jsonify(cmd)

    if request.method == 'PUT':
        # This will only update kwargs since we
        # have a deduplicated data structure by command.
        log.debug('Updating %s for %s', cmd_id, user)
        try:
            cmd = app.data.get(cmd_id, user, request.remote_addr)
        except KeyError:
            return jsonify_code({'error': 'No such history item'}, 404)
        from_form = True
        if request.json:
            data = request.json
            from_form = False
        else:
            data = request.form
        if not data:
            return jsonify_code(
                {'error': 'Data is required, received empty PUT'},
                422
            )
        put_command = data.get('payload')
        if not put_command:
            return jsonify_code(
                {'error': 'Request must contain ``payload`` parameter'},
                422
            )
        if from_form:
            put_command = json.loads(put_command)

        # Make sure we don't let them overwrite server side params
        try:
            del put_command['command']
            del put_command['username']
            del put_command['host']
        except KeyError:
            pass
        app.data.add(
            cmd['command'], user, request.remote_addr, **put_command
        )
        return '', 204

    if request.method == 'DELETE':
        log.debug('Deleting %s for %s', cmd_id, user)
        try:
            app.data.delete(cmd_id, user, request.remote_addr)
        except KeyError:
            return jsonify_code({'error': 'No such history item'}, 404)
        return jsonify(message='success')
    else:  # pragma: no cover
        log.critical('Unsupported method used')
        raise Exception('Unsupported http method used')
Example #3
0
def history(user):
    """
    POST=Add entry
    GET=Get entries with query
    """
    # We have a lot of logic here since we are doing query string
    # handling, so let pylint know that is ok.
    # pylint: disable=too-many-return-statements,too-many-branches
    if request.method == 'GET':
        query = request.args.get('q')
        order = request.args.get('o')
        page = int(request.args.get('p', 0))

        order_type = None
        if order:
            if order not in ORDER_TYPES:
                return jsonify_code(
                    {'error': 'Order specified is not an option'},
                    422
                )
            else:
                order_type = order

        if query:
            results = app.data.filter(
                query, order_type, user, request.remote_addr, page=page
            )
        else:
            results = app.data.all(
                order_type, user, request.remote_addr, page=page
            )
        return jsonify({'commands': results})

    if request.method == 'POST':
        # Accept json or form type
        from_form = True
        if request.json:
            data = request.json
            from_form = False
        else:
            data = request.form
        command = data.get('command')
        commands = data.get('commands')
        if not (command or commands):
            return jsonify_code({'error': 'Missing command(s) parameter'}, 422)

        # Allow bulk posting to speedup imports with commands parameter
        if commands:
            if from_form:
                commands = json.loads(commands)
            results_list = []
            if not isinstance(commands, list):
                return jsonify_code({'error': 'Commands must be list'}, 422)
            for command in commands:
                cmd_id = app.data.add(command, user, request.remote_addr)
                results_list.append(
                    {
                        'response': '',
                        'status_code': 201,
                        'headers': {
                            'location': url_for('history_item', cmd_id=cmd_id)
                        },
                    }
                )
            return jsonify({'responses': results_list})
        if not isinstance(command, string_types):
            return jsonify_code({'error': 'Command must be a string'}, 422)

        cmd_id = app.data.add(command, user, request.remote_addr)
        return '', 201, {'location': url_for('history_item', cmd_id=cmd_id)}
    else:  # pragma: no cover
        log.critical('Unsupported method used')
        raise Exception('Unsupported http method used')