def test_invalid_parse_missing_opening_bracket(): """Test exception handling for missing or too few opening brackets.""" with pytest.raises(PermissionException) as exc_info: parse(tokenise('obj allow user edit )')) assert exc_info.value.message == 'Too many closing brackets' with pytest.raises(PermissionException) as exc_info: parse(tokenise('obj allow user edit and (obj has_role admin))')) assert exc_info.value.message == 'Too many closing brackets'
def test_combined_parse(): """Test parsing an expression that contains an operator.""" instructions = parse( tokenise('obj allow user edit or user has_role admin')) assert len(instructions) == 3 assert instructions == [('obj', 'allow', 'user', 'edit'), ('user', 'has_role', 'admin'), 'or'] instructions = parse( tokenise('obj allow user edit and user has_role admin')) assert len(instructions) == 3 assert instructions == [('obj', 'allow', 'user', 'edit'), ('user', 'has_role', 'admin'), 'and']
def test_and_or_evaluate(): """Test evaluating three expressions joined by and and or.""" instructions = parse( tokenise( 'obj allow user edit and user has_role admin or user has_role superuser' )) result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'admin') }) assert result is False result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(True, 'superuser') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'superuser') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'nobody') }) assert result is False
def test_bracket_evaluate(): """Test evaluating three expressions in a complex structure using a bracket.""" instructions = parse( tokenise( 'obj allow user edit and (user has_role admin or user has_role superuser)' )) result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(True, 'superuser') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'admin') }) assert result is False result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'superuser') }) assert result is False
def test_invalid_evaluate_missing_expression_1(): """Test exception handling for an invalid boolean permission expression.""" with pytest.raises(PermissionException) as exc_info: evaluate(parse(tokenise('obj allow user edit and')), { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert exc_info.value.message == 'Missing expression for boolean operator'
def test_invalid_evaluate_missing_function(): """Test exception handling for a missing function.""" with pytest.raises(PermissionException) as exc_info: evaluate(parse(tokenise('obj allowed user edit')), { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert exc_info.value.message == 'Object "obj" has no method "allowed"'
def test_invalid_evaluate_too_few_parameters(): """Test exception handling for too few function parameters.""" with pytest.raises(PermissionException) as exc_info: evaluate(parse(tokenise('obj allow user')), { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert exc_info.value.message == 'Too few parameters for method "allow" on "obj"'
def test_none_evaluate(): """Test evaluating three expressions in a complex structure using a bracket.""" instructions = parse(tokenise('obj allow user edit')) result = evaluate(instructions, { 'obj': None, 'user': ExampleUser(True, 'admin') }) assert result is False
def test_bracket_parse(): """Test parsing an expression that contains a bracket.""" instructions = parse( tokenise( 'obj allow user edit and (user has_role admin or user has_role ' + 'superuser)')) assert len(instructions) == 5 assert instructions == [('obj', 'allow', 'user', 'edit'), ('user', 'has_role', 'admin'), ('user', 'has_role', 'superuser'), 'or', 'and']
def test_basic_evaluate(): """Test evaluating a basic single expression.""" instructions = parse(tokenise('obj allow user edit')) result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(True, 'admin') }) assert result result = evaluate(instructions, { 'obj': ExampleObject(), 'user': ExampleUser(False, 'admin') }) assert result is False
def process_permission(permission): """Process the ``permission``, return the instructions and substitution values.""" instructions = parse(tokenise(permission)) values = {} for instruction in instructions: if isinstance(instruction, tuple): for part in instruction: match = OBJ_PATTERN.match(part) if match: if match.group(3) is None: values[part] = (class_mapper(match.group(1)), 'id', match.group(2)) else: values[part] = (class_mapper(match.group(1)), match.group(2), match.group(3)) elif part == '$current_user': values[part] = 'current_user' return instructions, values
def test_empty_evaluate(): """Test evaluating an empty expression.""" result = evaluate(parse(tokenise('')), {}) assert result is False
def test_empty_parse(): """Test parsing an empty expression.""" instructions = parse(tokenise('')) assert len(instructions) == 0
def test_invalid_parse_missing_closing_bracket(): """Test exception handling for missing closing brackets.""" with pytest.raises(PermissionException) as exc_info: parse(tokenise('obj allow user edit and (user has_role admin')) assert exc_info.value.message == 'Missing closing bracket'
def test_invalid_missing_object(): """Test exception handling for a missing subsitution object.""" with pytest.raises(PermissionException) as exc_info: evaluate(parse(tokenise('obj allow user edit')), {'user': ExampleUser(True, 'admin')}) assert exc_info.value.message == 'Object "obj" not found in the values'
def test_invalid_evaluate_missing_expression_2(): """Test exception handling for an invalid boolean permission expression.""" with pytest.raises(PermissionException) as exc_info: evaluate(parse(tokenise('and')), {}) assert exc_info.value.message == 'Missing expression for boolean operator'
def test_basic_parse(): """Test parsing a basic expression.""" instructions = parse(tokenise('obj allow user edit')) assert len(instructions) == 1 assert instructions == [('obj', 'allow', 'user', 'edit')]