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_register_permissions_missing_group_create_new_entries(self): utils.TestSetup.create_TestService( self, override_service_name=self.test_perm_svc_name, override_service_type=ServiceAPI.service_type) utils.TestSetup.delete_TestGroup( self, override_group_name=self.test_perm_grp_name) session = get_db_session_from_settings(self.app.app.registry.settings) svc_perm = Permission.READ_MATCH res1_perm = Permission.READ res2_perm = Permission.WRITE res1_name = "test-resource" res2_name = "sub-test-resource" perm_config = { "permissions": [ { "service": self.test_perm_svc_name, "permission": svc_perm.value, "action": "create", "group": self.test_perm_grp_name, }, { "service": self.test_perm_svc_name, "resource": res1_name, "permission": res1_perm.value, "action": "create", "group": self.test_perm_grp_name, }, { "service": self.test_perm_svc_name, "resource": res1_name + "/" + res2_name, "permission": res2_perm.value, "action": "create", "group": self.test_perm_grp_name, }, ] } utils.check_no_raise( lambda: register.magpie_register_permissions_from_config( perm_config, db_session=session)) # check that all service, resources, group are created correctly services = utils.TestSetup.get_RegisteredServicesList(self) utils.check_val_is_in(self.test_perm_svc_name, [s["service_name"] for s in services]) groups = utils.TestSetup.get_RegisteredGroupsList(self) utils.check_val_is_in(self.test_perm_grp_name, groups) resp = utils.test_request( self.app, "GET", "/services/{}/resources".format(self.test_perm_svc_name)) body = utils.check_response_basic_info(resp) svc_res = body[self.test_perm_svc_name]["resources"] svc_res_id = body[self.test_perm_svc_name]["resource_id"] utils.check_val_is_in(res1_name, [svc_res[r]["resource_name"] for r in svc_res]) res1_id = [ svc_res[r]["resource_id"] for r in svc_res if svc_res[r]["resource_name"] == res1_name ][0] res1_sub = svc_res[str(res1_id)]["children"] utils.check_val_is_in(res2_name, [res1_sub[r]["resource_name"] for r in res1_sub]) res2_id = [ res1_sub[r]["resource_id"] for r in res1_sub if res1_sub[r]["resource_name"] == res2_name ][0] # check that all permissions are created correctly path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, svc_res_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_is_in(svc_perm.value, body["permission_names"]) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res1_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_is_in(res1_perm.value, body["permission_names"]) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res2_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_is_in(res2_perm.value, body["permission_names"])
def test_register_permissions_existing_group_without_intermediate_entries( self): utils.TestSetup.create_TestService( self, override_service_name=self.test_perm_svc_name, override_service_type=ServiceAPI.service_type) utils.TestSetup.create_TestGroup( self, override_group_name=self.test_perm_grp_name) session = get_db_session_from_settings(self.app.app.registry.settings) res1_name = "test-resource" res2_name = "sub-test-resource" res3_name = "sub-sub-test-resource" res3_perm = Permission.WRITE_MATCH perm_config = { "permissions": [ { "service": self.test_perm_svc_name, # exists "resource": res1_name + "/" + res2_name + "/" + res3_name, # none exist, all created for perm "permission": res3_perm.value, # perm only to lowest child "action": "create", "group": self.test_perm_grp_name, }, ] } utils.check_no_raise( lambda: register.magpie_register_permissions_from_config( perm_config, db_session=session)) # check that all service, resources, group are created correctly services = utils.TestSetup.get_RegisteredServicesList(self) utils.check_val_is_in(self.test_perm_svc_name, [s["service_name"] for s in services]) groups = utils.TestSetup.get_RegisteredGroupsList(self) utils.check_val_is_in(self.test_perm_grp_name, groups) resp = utils.test_request( self.app, "GET", "/services/{}/resources".format(self.test_perm_svc_name)) body = utils.check_response_basic_info(resp) svc_res = body[self.test_perm_svc_name]["resources"] svc_res_id = body[self.test_perm_svc_name]["resource_id"] utils.check_val_is_in(res1_name, [svc_res[r]["resource_name"] for r in svc_res]) res1_id = [ svc_res[r]["resource_id"] for r in svc_res if svc_res[r]["resource_name"] == res1_name ][0] res1_sub = svc_res[str(res1_id)]["children"] utils.check_val_is_in(res2_name, [res1_sub[r]["resource_name"] for r in res1_sub]) res2_id = [ res1_sub[r]["resource_id"] for r in res1_sub if res1_sub[r]["resource_name"] == res2_name ][0] res2_sub = res1_sub[str(res2_id)]["children"] utils.check_val_is_in(res3_name, [res2_sub[r]["resource_name"] for r in res2_sub]) res3_id = [ res2_sub[r]["resource_id"] for r in res2_sub if res2_sub[r]["resource_name"] == res3_name ][0] # check that all permissions are created correctly (only for final item) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, svc_res_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_equal(body["permission_names"], []) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res1_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_equal(body["permission_names"], []) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res2_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_equal(body["permission_names"], []) path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res3_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_all_equal(body["permission_names"], [res3_perm.value])
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_register_permissions_multiple_resource_type_possible(self): """ Verify that service that allows multiple resource-types children retrieves ``type`` field for their creation. """ svc_type = ServiceTHREDDS.service_type svc_name = "unittest-service-thredds-register-children-resources" utils.TestSetup.create_TestService(self, override_service_name=svc_name, override_service_type=svc_type) utils.TestSetup.create_TestGroup( self, override_group_name=self.test_perm_grp_name) session = get_db_session_from_settings(self.app.app.registry.settings) res1_name = "test-resource" res2_name = "sub-test-resource" res3_name = "sub-sub-test-resource" res3_perm = "write-deny-recursive" res3_path = res1_name + "/" + res2_name + "/" + res3_name # none exist, all created for final permission perm_config = { "permissions": [ { "service": svc_name, # exists "resource": res3_path, "permission": res3_perm, # perm only on lowest child "type": Directory. resource_type_name, # without this, fails because cannot infer Directory/File "action": "create", "group": self.test_perm_grp_name, }, ] } utils.check_no_raise( lambda: register.magpie_register_permissions_from_config( perm_config, db_session=session)) # check that all service, resources, group are created correctly services = utils.TestSetup.get_RegisteredServicesList(self) utils.check_val_is_in(svc_name, [s["service_name"] for s in services]) groups = utils.TestSetup.get_RegisteredGroupsList(self) utils.check_val_is_in(self.test_perm_grp_name, groups) resp = utils.test_request(self.app, "GET", "/services/{}/resources".format(svc_name)) body = utils.check_response_basic_info(resp) svc_res = body[svc_name]["resources"] # type: JSON utils.check_val_is_in(res1_name, [svc_res[r]["resource_name"] for r in svc_res]) res1_id = [ svc_res[r]["resource_id"] for r in svc_res if svc_res[r]["resource_name"] == res1_name ][0] res1_sub = svc_res[str(res1_id)]["children"] # type: JSON utils.check_val_is_in(res2_name, [res1_sub[r]["resource_name"] for r in res1_sub]) res2_id = [ res1_sub[r]["resource_id"] for r in res1_sub if res1_sub[r]["resource_name"] == res2_name ][0] res2_sub = res1_sub[str(res2_id)]["children"] # type: JSON utils.check_val_is_in(res3_name, [res2_sub[r]["resource_name"] for r in res2_sub]) res3_id = [ res2_sub[r]["resource_id"] for r in res2_sub if res2_sub[r]["resource_name"] == res3_name ][0] path = "/groups/{}/resources/{}/permissions".format( self.test_perm_grp_name, res3_id) resp = utils.test_request(self.app, "GET", path) body = utils.check_response_basic_info(resp) utils.check_val_is_in(res3_perm, body["permission_names"]) # validate that without the 'type', similar resource would not be created due to missing information res_missing_type_name = "missing-type" res_missing_type_path = res3_path.replace("/" + res3_name, "/" + res_missing_type_name) missing_type_perm_config = copy.deepcopy(perm_config) # type: JSON missing_type_perm_config["permissions"][0].pop("type") missing_type_perm_config["permissions"][0][ "resource"] = res_missing_type_path utils.check_no_raise( lambda: register.magpie_register_permissions_from_config( missing_type_perm_config, db_session=session)) resp = utils.test_request(self.app, "GET", "/resources/{}".format(res2_id)) body = utils.check_response_basic_info(resp) res_children = body["resource"]["children"] res_found = [ res for _, res in res_children.items() if res["resource_name"] == res_missing_type_name ] utils.check_val_equal(res_found, [])