def test_permission_convert_from_acl(self): """ Conversion from Pyramid ACL definition. Validate various implicit conversion of permission elements to explicit definition. """ utils.warn_version(__meta__.__version__, "permission set conversion", "3.0", skip=True) perm = PermissionSet((Allow, 1, "write-deny-match")) utils.check_val_equal(perm.name, Permission.WRITE) utils.check_val_equal( perm.access, Access.DENY, msg="Explicit permission name prioritized over ACL access") utils.check_val_equal(perm.scope, Scope.MATCH) utils.check_val_equal(perm.type, PermissionType.DIRECT, msg="Should infer direct from user ID.") perm = PermissionSet((Deny, "group:1", "read")) utils.check_val_equal(perm.name, Permission.READ) utils.check_val_equal(perm.access, Access.DENY) utils.check_val_equal(perm.scope, Scope.RECURSIVE) utils.check_val_equal( perm.type, PermissionType.INHERITED, msg="Should infer inherited from group specifier.") utils.check_raises( lambda: PermissionSet((Allow, "group:1", ALL_PERMISSIONS)), TypeError, msg= "Don't allow any object that makes the permission name not explicitly defined." )
def test_generate_response_http_format_invalid_usage(self): utils.check_raises( lambda: ax.generate_response_http_format(None, {}, {}, "", {} ), # noqa HTTPInternalServerError, msg= "invalid arguments resulting in error during response generation should raise" )
def test_evaluate_call_callable_incorrect_usage(self): """ Verifies that incorrect usage of utility is raised accordingly. """ utils.check_raises(lambda: ax.evaluate_call(int), HTTPInternalServerError, msg="invalid callable non-lambda 'call' should raise") utils.check_raises(lambda: ax.evaluate_call(lambda: int, fallback=int), # noqa HTTPInternalServerError, msg="invalid callable non-lambda 'fallback' should raise")
def test_format_content_json_str_invalid_usage(self): non_json_serializable_content = {"key": HTTPInternalServerError()} utils.check_raises( lambda: ax.format_content_json_str( 200, "", non_json_serializable_content, CONTENT_TYPE_JSON), HTTPInternalServerError, msg= "invalid content format expected as JSON serializable should raise" )
def test_permission_resolve_raised_invalid(self): """ Ensure that resolution with completely invalid/impossible cases are raised instead of failing silently. """ perm_r = PermissionSet(Permission.READ, Access.ALLOW, Scope.RECURSIVE, PermissionType.DIRECT) res1 = MockObject(resource_name="mock-resource1", resource_id=987) res2 = MockObject(resource_name="mock-resource2", resource_id=101) usr = MockObject(user_name="mock-user", user_id=123) grp = MockObject(group_name="mock-group", user_id=456) usr_tup = PermissionTuple(usr, perm_r.explicit_permission, "user", None, res1, False, True) usr_perm = PermissionSet(usr_tup) # two same user permissions of identical name cannot exist utils.check_raises( lambda: PermissionSet.resolve(usr_perm, usr_perm), ValueError, msg= "Should raise permissions corresponding by name and user, cannot exist simultaneously." ) # various values that are valid to create 'PermissionSet', but insufficient for resolution valid_only_for_repr = [ Permission.READ.value, Permission.READ.value + "-" + Scope.MATCH.value, Permission.READ.value + "-" + Access.ALLOW.value + "-" + Scope.MATCH.value, { "name": Permission.READ, "access": Access.DENY, "scope": Scope.MATCH }, PermissionSet(Permission.READ.value, Access.ALLOW.value, Scope.MATCH.value) # missing 'perm_tuple' ] for perm1, perm2 in itertools.permutations(valid_only_for_repr, 2): utils.check_raises( lambda: PermissionSet.resolve(perm1, perm2), ValueError, msg= "Permission that do not provide comparison elements for resolution must be raised, " "although they are normally valid for simple permission representation." ) # valid user and group tuples (both provide tuples, point to same resource, and don't refer to same user-perm) # but mismatching permission names perm_w = PermissionSet(Permission.WRITE, Access.ALLOW, Scope.RECURSIVE, PermissionType.DIRECT) grp_tup = PermissionTuple(usr, perm_w.explicit_permission, "group", grp, res1, False, True) grp_perm = PermissionSet(grp_tup) utils.check_raises( lambda: PermissionSet.resolve(usr_perm, grp_perm), ValueError, msg= "Mismatching permission names should be raised as they cannot be resolved together." ) # same perm name (read), both tuple provided, not both user-perms, but not referring to same resource grp_tup = PermissionTuple(usr, perm_r.explicit_permission, "group", grp, res2, False, True) grp_perm = PermissionSet(grp_tup) utils.check_raises( lambda: PermissionSet.resolve(usr_perm, grp_perm), ValueError, msg= "Mismatching resources should be raised as they cannot be resolved together." ) utils.check_no_raise( lambda: PermissionSet.resolve( usr_perm, grp_perm, context=PermissionType.EFFECTIVE), msg= "Mismatching resources should resolved when requested explicitly (effective)." )
def test_verify_param_compare_types(self): """ Arguments ``param`` and ``param_compare`` must be of same type for valid comparison, except for ``is_type`` where compare parameter must be the type directly. .. versionchanged:: 2.0 Since ``param`` can come from user input, we should **NOT** raise ``HTTPInternalServerError`` because the whole point of the method is to ensure that values are compared accordingly in a controlled fashion. Therefore, error to be raised is an 'expected' validation failure (``HTTPBadRequest`` or whichever ``http_error`` provided) instead of runtime 'unexpected' processing error. On the other hand, when ``is_type`` flag is requested, we know that ``param_compare`` must be a type. Inversely, ``param_compare`` must not be a type if ``is_type`` is not requested, but other flags require some form of comparison between values. We evaluate these use cases here. .. seealso:: - :func:`test_verify_param_args_incorrect_usage` for invalid input use-cases """ # compare flags expecting a value (can only consider it bad request because comparison values are valid) utils.check_raises( lambda: ax.verify_param("1", param_compare=1, is_equal=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param("1", param_compare=True, is_equal=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param(1, param_compare="1", is_equal=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param(1, param_compare=True, is_equal=True), HTTPBadRequest) # when compare flags expect a value but type is provided, should still detect incorrect input utils.check_raises( lambda: ax.verify_param(1, param_compare=int, is_equal=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param("1", param_compare=str, is_equal=True), HTTPInternalServerError) # compare flags expecting param_compare to be a type while value provided is not utils.check_raises( lambda: ax.verify_param(1, param_compare="x", is_type=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param(1, param_compare=True, is_type=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param("1", param_compare=None, is_type=True), HTTPInternalServerError) # compare flags expecting param_compare to be some container instance while value provided is not utils.check_raises( lambda: ax.verify_param(1, param_compare=1, is_in=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param(1, param_compare=list, is_in=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param("1", param_compare=str, is_in=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param(1, param_compare=1, not_in=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param(1, param_compare=list, not_in=True), HTTPInternalServerError) utils.check_raises( lambda: ax.verify_param("1", param_compare=str, not_in=True), HTTPInternalServerError) # strings cases handled correctly (no raise) utils.check_no_raise( lambda: ax.verify_param("1", param_compare="1", is_equal=True))
def test_verify_param_args_incorrect_usage(self): """ Invalid usage of function raises internal server error instead of 'normal HTTP error'. """ utils.check_raises( lambda: ax.verify_param("b", param_compare=["a", "b"]), HTTPInternalServerError, msg="missing any flag specification should be caught") utils.check_raises( lambda: ax.verify_param("b", param_compare=["a", "b"], not_in=None ), # noqa HTTPInternalServerError, msg="flag specified with incorrect type should be caught") utils.check_raises( lambda: ax.verify_param("b", not_in=True), HTTPInternalServerError, msg="missing 'param_compare' for flag needing it should be caught") utils.check_raises( lambda: ax.verify_param( "b", param_compare=["b" ], not_in=True, http_error=HTTPOk), # noqa HTTPInternalServerError, msg="incorrect HTTP class to raise error should be caught") utils.check_raises( lambda: ax.verify_param([1], param_compare=1, is_in=True), HTTPInternalServerError, msg="incorrect non-iterable compare should raise invalid type") for flag in [ "not_none", "not_empty", "not_in", "not_equal", "is_none", "is_empty", "is_in", "is_equal", "is_true", "is_false", "is_type", "matches" ]: utils.check_raises( lambda: ax.verify_param("x", **{flag: 1}), HTTPInternalServerError, msg="invalid flag '{}' type should be caught".format(flag))
def test_verify_param_proper_verifications_raised(self): # with default error utils.check_raises( lambda: ax.verify_param("b", param_compare=["a", "b"], not_in=True ), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param("x", param_compare=["a", "b"], is_in=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param("1", param_compare=int, is_type=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param( 1.0, param_compare=six.string_types, is_type=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param("x", param_compare="x", not_equal=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param("x", param_compare="y", is_equal=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param(False, is_true=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param(True, is_false=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param(None, not_none=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param(1, is_none=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param("", not_empty=True), HTTPBadRequest) utils.check_raises(lambda: ax.verify_param("abc", is_empty=True), HTTPBadRequest) utils.check_raises( lambda: ax.verify_param( "abc", matches=True, param_compare=r"[A-Z]+"), HTTPBadRequest) # with requested error utils.check_raises( lambda: ax.verify_param("b", param_compare=["a", "b"], not_in=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param("x", param_compare=["a", "b"], is_in=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( "1", param_compare=int, is_type=True, http_error=HTTPForbidden ), HTTPForbidden) utils.check_raises( lambda: ax.verify_param("x", param_compare="x", not_equal=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param("x", param_compare="y", is_equal=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( False, is_true=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( True, is_false=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( None, not_none=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param(1, is_none=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( "", not_empty=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param( "abc", is_empty=True, http_error=HTTPForbidden), HTTPForbidden) utils.check_raises( lambda: ax.verify_param("abc", matches=True, param_compare=r"[A-Z]+", http_error=HTTPForbidden), HTTPForbidden)