Exemple #1
0
    def invoke(self, service_id, operation_id, input_value, ctx):
        """
        Invoke an API request

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        sec_ctx = ctx.security_context
        app_ctx = ctx.application_context
        authn_result = None

        request_scheme = sec_ctx.get(SCHEME_ID)
        if (self._authn_handlers and request_scheme
                and request_scheme != NO_AUTH):
            for handler in self._authn_handlers:
                # Call authenticate method and get the UserIdentity
                try:
                    authn_result = handler.authenticate(sec_ctx)
                except Exception as e:
                    logger.exception(
                        'Error in invoking authentication handler %s - %s',
                        handler, e)
                    error_value = make_error_value_from_msg_id(
                        self._internal_server_error_def,
                        'vapi.security.authentication.exception', str(e))
                    return MethodResult(error=error_value)

                # authn result false means authentication failed
                if authn_result is False:
                    error_value = make_error_value_from_msg_id(
                        self._unauthenticated_error_def,
                        'vapi.security.authentication.invalid')
                    return MethodResult(error=error_value)

                if authn_result is not None:
                    # Matching authN handler found
                    break

        if authn_result:
            # Add the authN identity to the security context to pass on to next
            # provider
            sec_ctx[AUTHN_IDENTITY] = authn_result
            ctx = ExecutionContext(app_ctx, sec_ctx)
        else:
            # No AuthN handler found pass an empty security context
            ctx = ExecutionContext(app_ctx, SecurityContext())

        return ApiProviderFilter.invoke(self, service_id, operation_id,
                                        input_value, ctx)
 def test_authn_op_without_sec_ctx(self):
     ctx = ExecutionContext(None, None)
     input_val = VoidValue()
     method_result = self.sec_ctx_filter.invoke('svc', 'op2', input_val,
                                                ctx)
     self.assertEqual(method_result.output, None)
     self.assertEqual(method_result.error, error_values[3])
 def test_op(self):
     ctx = ExecutionContext(ApplicationContext(), None)
     input_val = VoidValue()
     method_result = self.sec_ctx_filter.invoke('svc', 'op1', input_val,
                                                ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
Exemple #4
0
 def test_introspection_operation_get(self):
     ctx = ExecutionContext()
     input_val = StructValue(OPERATION_INPUT)
     input_val.set_field('service_id', StringValue('mockup_interface'))
     input_val.set_field('operation_id', StringValue('mock'))
     actual_output = self.local_provider.invoke(
         'com.vmware.vapi.std.introspection.operation', 'get', input_val,
         ctx)
     expected_output = StructValue(
         name='com.vmware.vapi.std.introspection.operation.info')
     input_def_value = StructValue(
         'com.vmware.vapi.std.introspection.operation.data_definition')
     input_def_value.set_field('fields',
                               OptionalValue(ListValue(values=[])))
     input_def_value.set_field('element_definition', OptionalValue())
     input_def_value.set_field('type', StringValue('STRUCTURE'))
     input_def_value.set_field('name',
                               OptionalValue(StringValue(OPERATION_INPUT)))
     expected_output.set_field('input_definition', input_def_value)
     output_def_value = StructValue(
         'com.vmware.vapi.std.introspection.operation.data_definition')
     output_def_value.set_field('fields', OptionalValue())
     output_def_value.set_field('element_definition', OptionalValue())
     output_def_value.set_field('type', StringValue('VOID'))
     output_def_value.set_field('name', OptionalValue())
     expected_output.set_field('output_definition', output_def_value)
     expected_output.set_field('error_definitions', error_values)
     self.assertEqual(actual_output.output, expected_output)
Exemple #5
0
    def invoke(self, service_id, operation_id, input_value, ctx):
        """
        Invoke an API request

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        app_ctx = ctx.application_context if ctx else None
        on_error = False
        for i in range(0, self.get_max_retries() + 1):
            # Typically get_security_context() should always return a valid
            # security context. In case of LegacySecurityContextFilter,
            # get_security_context() may return None if no security context is
            # set and hence needs to be handled.
            sec_ctx = (self.get_security_context(on_error) or
                       (ctx.security_context if ctx else None))
            new_ctx = ExecutionContext(app_ctx, sec_ctx)
            method_result = ApiProviderFilter.invoke(
                self, service_id, operation_id, input_value, new_ctx)
            if (method_result.error is None
                    or not self.should_retry(method_result.error)):
                return method_result
            on_error = True
 def test_noauth_op_unknown_op(self):
     sec_ctx = None
     app_ctx = ApplicationContext()
     ctx = ExecutionContext(app_ctx, sec_ctx)
     input_val = VoidValue()
     method_result = self.authz_filter.invoke('com', 'op', input_val, ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
 def test_invoke_error(self):
     ctx = ExecutionContext()
     input_ = StructValue(method_name)
     input_.set_field('message', IntegerValue(10))
     input_.set_field('throw', BooleanValue(True))
     actual_method_result = self.provider.invoke(interface_name,
                                                 method_name,
                                                 input_,
                                                 ctx)
     self.assertFalse(actual_method_result.success())
Exemple #8
0
    def test_success_2(self):
        ctx = ExecutionContext()
        service_id = interface_id.get_name()
        operation_id = mock_definition

        input_value = StructValue(OPERATION_INPUT)
        input_value.set_field(param_name, IntegerValue(10))
        method_result = self.local_provider.invoke(service_id, operation_id,
                                                   input_value, ctx)
        self.assertTrue(method_result.success())
        self.assertEqual(method_result.output, VoidValue())
Exemple #9
0
    def _test_operation_not_found(self, interface_name, method_name, error,
                                  message_id, *args):
        ctx = ExecutionContext()
        expected_msg = message_factory.get_message(message_id, *args)
        expected_error_value = make_error_value_from_msgs(error, expected_msg)

        method_result = self.local_provider.invoke(interface_name, method_name,
                                                   StructValue(), ctx)

        self.assertEquals(None, method_result.output)
        self.assertEquals(expected_error_value, method_result.error)
Exemple #10
0
    def test_success(self):
        ctx = ExecutionContext()
        service_id = interface_id.get_name()
        operation_id = mock_definition

        method_def = self.introspection.get_method(service_id, operation_id)
        input_value = method_def.get_input_definition().new_value()
        input_value.set_field(param_name, IntegerValue(10))
        method_result = self.local_provider.invoke(service_id, operation_id,
                                                   input_value, ctx)
        self.assertTrue(method_result.success())
        self.assertEqual(method_result.output, VoidValue())
 def test_invalid_user_pwd_scheme(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: OAUTH_SCHEME_ID,
         ACCESS_TOKEN: 'token'
     })
     app_ctx = ApplicationContext()
     ctx = ExecutionContext(app_ctx, sec_ctx)
     input_val = VoidValue()
     method_result = self.authn_filter.invoke('com.pkg.svc', 'op',
                                              input_val, ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
 def test_authn_op_with_sec_ctx(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: USER_PASSWORD_SCHEME_ID,
         USER_KEY: 'testuser',
         PASSWORD_KEY: 'password'
     })
     ctx = ExecutionContext(None, sec_ctx)
     input_val = VoidValue()
     method_result = self.sec_ctx_filter.invoke('svc', 'op2', input_val,
                                                ctx)
     self.assertEqual(method_result.output, IntegerValue(20))
     self.assertEqual(method_result.error, None)
 def get_service_info(self, service_id):
     provider = self._get_provider(service_id)
     if provider:
         ctx = ExecutionContext()
         struct_value = StructValue(name=OPERATION_INPUT,
                                    values={'id': StringValue(service_id)})
         return provider.invoke(Introspection.SERVICE_SVC, 'get',
                                struct_value, ctx)
     else:
         msg = message_factory.get_message(
             'vapi.introspection.operation.service.not_found', service_id)
         error_value = make_error_value_from_msgs(not_found_def, msg)
         return MethodResult(error=error_value)
 def test_session_security_context(self):
     input_val = StructValue(name='operation-input', values={})
     session_id = 'some-session-id'
     sec_ctx = create_session_security_context(session_id)
     _, actual_headers, actual_body, _ = RestSerializer.serialize_request(
         input_value=input_val,
         ctx=ExecutionContext(security_context=sec_ctx),
         rest_metadata=None,
         is_vapi_rest=True)
     expected_body = '{}'
     expected_headers = {REST_SESSION_ID_KEY: session_id}
     self.assertEqual(expected_headers, actual_headers)
     self.assertEqual(expected_body, actual_body)
 def test_op_with_sec_ctx_on_filter(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: USER_PASSWORD_SCHEME_ID,
         USER_KEY: 'testuser',
         PASSWORD_KEY: 'password'
     })
     self.sec_ctx_filter.set_security_context(sec_ctx)
     ctx = ExecutionContext(ApplicationContext(), None)
     input_val = VoidValue()
     method_result = self.sec_ctx_filter.invoke('svc', 'op1', input_val,
                                                ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
Exemple #16
0
    def new_context(self):
        """
        create new execution context object

        :rtype:  :class:`vmware.vapi.core.ExecutionContext`
        :return: execution context
        """
        app_ctx = self._application_context
        # Create a default application context only if
        # the user has not provided anything
        if app_ctx is None:
            app_ctx = create_default_application_context()
        return ExecutionContext(app_ctx)
 def test_user_pwd_scheme(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: USER_PASSWORD_SCHEME_ID,
         USER_KEY: 'testuser',
         PASSWORD_KEY: 'password'
     })
     app_ctx = ApplicationContext()
     ctx = ExecutionContext(app_ctx, sec_ctx)
     input_val = VoidValue()
     method_result = self.authn_filter.invoke('com.pkg.svc', 'op',
                                              input_val, ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
Exemple #18
0
    def execution_context(ctx):
        """
        get execution context from jsonrpc dict

        :type  ctx: :class:`dict`
        :param ctx: json execution context
        :rtype:  :class:`vmware.vapi.core.ExecutionContext`
        :return: execution context
        """
        app_ctx = JsonRpcDictToVapi.app_ctx(ctx.get('appCtx'))
        security_ctx = JsonRpcDictToVapi.security_ctx(ctx.get('securityCtx'))
        execution_context = ExecutionContext(app_ctx, security_ctx)
        return execution_context
 def test_invalid_user_pwd(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: USER_PASSWORD_SCHEME_ID,
         USER_KEY: 'testuser',
         PASSWORD_KEY: 'invalidpassword'
     })
     app_ctx = ApplicationContext()
     ctx = ExecutionContext(app_ctx, sec_ctx)
     input_val = VoidValue()
     method_result = self.authn_filter.invoke('com.pkg.svc', 'op',
                                              input_val, ctx)
     self.assertEqual(method_result.error.name,
                      'com.vmware.vapi.std.errors.unauthenticated')
 def test_noauth_op_with_valid_user(self):
     sec_ctx = SecurityContext({
         SCHEME_ID: USER_PASSWORD_SCHEME_ID,
         USER_KEY: 'testuser',
         PASSWORD_KEY: 'password',
         AUTHN_IDENTITY: UserIdentity('testuser')
     })
     app_ctx = ApplicationContext()
     ctx = ExecutionContext(app_ctx, sec_ctx)
     input_val = VoidValue()
     method_result = self.authz_filter.invoke('com.pkg.svc', 'op1',
                                              input_val, ctx)
     self.assertEqual(method_result.output, IntegerValue(10))
     self.assertEqual(method_result.error, None)
 def test_invoke_long_running_sync(self):
     ctx = ExecutionContext()
     input_ = StructValue(method_name)
     input_.set_field('message', StringValue('hello'))
     input_.set_field('throw', BooleanValue(False))
     actual_method_result = self.provider.invoke(interface_name,
                                                 task_method_name,
                                                 input_,
                                                 ctx)
     expected_method_result = MethodResult(output=StringValue('hello'))
     self.assertEqual(actual_method_result.output,
                      expected_method_result.output)
     self.assertEqual(actual_method_result.error,
                      expected_method_result.error)
Exemple #22
0
    def test_invalid_input(self):
        ctx = ExecutionContext()
        expected_msg = message_factory.get_message('vapi.method.input.invalid')
        expected_error_value = make_error_value_from_msgs(
            invalid_argument_def, expected_msg)

        method_result = self.local_provider.invoke(
            service_id=raise_python_exception_id.get_interface_identifier(
            ).get_name(),
            operation_id=raise_python_exception_id.get_name(),
            input_value=IntegerValue(),
            ctx=ctx)

        self.assertEquals(None, method_result.output)
        self.assertEquals(expected_error_value, method_result.error)
Exemple #23
0
 def setUpClass(cls):
     cls.task_manager = get_task_manager()
     msg_factory = MessageFactory(cls.msgs)
     cls.description = LocalizableMessage(id='msg1',
                                          default_message='task1',
                                          args=[])
     cls.progress_msg = LocalizableMessage(id='prog1',
                                           default_message='progress',
                                           args=[])
     cls.task_id = cls.task_manager.create_task(str(uuid.uuid4()),
                                                cls.description,
                                                'test.service', 'op1', True)
     app_ctx = create_default_application_context()
     app_ctx[TASK_ID] = cls.task_id
     sec_ctx = SecurityContext()
     TLS.ctx = ExecutionContext(app_ctx, sec_ctx)
     cls.task_handle = get_task_handle(Info, StringType())
 def get_checksum(self):
     # XXX: Resultant checksum does not include the data from the services
     # registered in the local provider of the aggregator. Since no one is
     # using Python aggregator, making this a low priority now.
     ctx = ExecutionContext()
     struct_value = StructValue(name=OPERATION_INPUT)
     providers = [
         provider for provider in list(self._service_data.values())
         if provider.__class__.__name__ != self._local_provider_class_name
     ]
     method_results = [
         provider.invoke(Introspection.PROVIDER_SVC, 'get', struct_value,
                         ctx) for provider in providers
     ]
     checksums = [
         result.output.get_field('checksum') for result in method_results
         if result.success()
     ]
     return generate_fingerprint(str(checksums))
 def test_username_security_context(self):
     input_val = StructValue(name='operation-input', values={})
     user, password = '******', 'pwd'
     sec_ctx = create_user_password_security_context(user, password)
     _, actual_headers, actual_body, _ = RestSerializer.serialize_request(
         input_value=input_val,
         ctx=ExecutionContext(security_context=sec_ctx),
         rest_metadata=None,
         is_vapi_rest=True)
     expected_body = '{}'
     if six.PY2:
         b64_credentials = base64.b64encode('%s:%s' % (user, password))
         authorization_val = 'Basic %s' % b64_credentials
     else:
         b64_credentials = base64.b64encode(
             bytes('%s:%s' % (user, password), 'utf-8'))
         authorization_val = b'Basic ' + b64_credentials
     expected_headers = {'Authorization': authorization_val}
     self.assertEqual(expected_headers, actual_headers)
     self.assertEqual(expected_body, actual_body)
 def test_invoke_long_running(self):
     ctx = ExecutionContext()
     input_ = StructValue(method_name)
     input_.set_field('message', StringValue('hello'))
     input_.set_field('throw', BooleanValue(False))
     actual_method_result = self.provider.invoke(interface_name,
                                                 '%s$task' % task_method_name,
                                                 input_,
                                                 ctx)
     expected_method_result = MethodResult(output=StringValue('hello'))
     try:
         id_split = actual_method_result.output.value.split(':')
         uuid.UUID(id_split[0], version=4)
         uuid.UUID(id_split[1], version=4)
     except ValueError:
         # There's no assertNotRaises so explicitly fail assert
         # in case a ValueError is thrown for invalid uuid.
         self.assertTrue(False)
     self.assertEqual(actual_method_result.error,
                      expected_method_result.error)
Exemple #27
0
    def new_context(self, runtime_data=None):
        """
        create new execution context object

        :type  runtime_data: :class:`vmware.vapi.core.RuntimeData`    # pylint: disable=line-too-long
        :param runtime_data: Http runtime data
        :rtype:  :class:`vmware.vapi.core.ExecutionContext`
        :return: execution context
        """
        app_ctx = self._application_context
        # Create a default application context only if
        # the user has not provided anything
        if app_ctx is None:
            app_ctx = create_default_application_context()

        if runtime_data is None:
            runtime_data = RuntimeData()

        return ExecutionContext(application_context=app_ctx,
                                runtime_data=runtime_data)
 def test_decimal_json_request(self):
     ctx = ExecutionContext()
     template_request = (
         '{"params":{"input":%s,"serviceId":"mock","ctx":{"appCtx":{}},' +
         '"operationId":"mock"},"jsonrpc":' +
         '"2.0","method":"invoke","id":1}'
     )
     template_response = (
         '{"jsonrpc":"2.0","id":1,"result":{"output": %s}}'
     )
     for val, canonical_val in [
                 ('-12.34e4', '-1.234E5'),
                 ('1E-130', '1.0E-130'),
                 ('0.0E-0', '0.0E0'),
                 ('1.2', '1.2E0'),
                 ('1111111.1111100021e-30', '1.1111111111100021E-24'),
                 ('12312423.0', '1.2312423E7'),
                 ('0.000234E-10', '2.34E-14'),
                 ('17', '1.7E1')]:
         decimal_val = decimal.Decimal(val)
         canonical_decimal_val = canonicalize_double(decimal_val)
         data_value = DoubleValue(decimal_val)
         params = {
             'ctx': ctx,
             'serviceId': 'mock',
             'operationId': 'mock',
             'input': data_value
         }
         actual_request = vapi_jsonrpc_request_factory(
             method=VAPI_INVOKE, params=params, id=1).serialize()
         expected_request = template_request % canonical_decimal_val
         self.assertEqual(
             json.loads(actual_request, parse_float=decimal.Decimal),
             json.loads(expected_request, parse_float=decimal.Decimal))
         response_msg = template_response % canonical_val
         response = deserialize_response(response_msg)
         method_result = JsonRpcDictToVapi.method_result(response.result)
         self.assertTrue(method_result.success())
         self.assertTrue(isinstance(method_result.output, DoubleValue))
         self.assertEqual(method_result.output,
                          DoubleValue(decimal.Decimal(canonical_val)))
Exemple #29
0
    def test_input_validation_failure(self):
        ctx = ExecutionContext()
        expected_msg0 = message_factory.get_message(
            'vapi.data.structure.field.invalid', 'param', OPERATION_INPUT)
        expected_msg1 = message_factory.get_message(
            'vapi.data.validate.mismatch', 'Integer', 'Structure')
        expected_error_value = make_error_value_from_msgs(
            invalid_argument_def, expected_msg0, expected_msg1)

        service_id = raise_python_exception_id.get_interface_identifier(
        ).get_name()
        operation_id = raise_python_exception_id.get_name()
        method_def = self.introspection.get_method(service_id, operation_id)
        input_value = method_def.get_input_definition().new_value()
        input_value.set_field(param_name, StructValue())
        method_result = self.local_provider.invoke(service_id=service_id,
                                                   operation_id=operation_id,
                                                   input_value=input_value,
                                                   ctx=ctx)

        self.assertEquals(None, method_result.output)
        self.assertEquals(expected_error_value, method_result.error)
    def test_json_loopback_positive(self):
        connector = self.get_loopback_connector(self.provider)
        remote = connector.get_api_provider()

        for method_def in [null_method_def, echo_method_def]:
            # invoke_method
            ctx = ExecutionContext()
            params = build_adhoc_data_value(method_def.get_input_definition())
            method_id = echo_method_def.get_identifier().get_name()
            remote_result = remote.invoke(fake_iface_id,
                                          method_id,
                                          params,
                                          ctx)

            local_result = self.provider.invoke(fake_iface_id, method_id, params, ctx)
            if remote_result.success():
                # Validate result output
                method_def.get_output_definition().validate(remote_result.output)
                # Validate direct call
                self.assertEqual(remote_result.output, local_result.output)
            else:
                self.assertTrue(remote_result.error, local_result.error)