Пример #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)
Пример #2
0
 def invoke(self, service_id, operation_id, input_value, ctx):
     logger.debug(
         'Operation started: Service: %s, Operation: %s, Ctx: %s, Input: %s',
         service_id, operation_id, ctx, input_value)
     try:
         method_result = self._invoke_int(service_id, operation_id,
                                          input_value, ctx)
         if method_result.success():
             method_result = augment_method_result_with_errors(
                 service_id, operation_id, method_result,
                 self._error_values_to_augment)
     except Exception as e:
         logger.exception("Error in invoking %s in %s - %s", service_id,
                          operation_id, e)
         error_value = make_error_value_from_msg_id(
             self._internal_server_error_def,
             'vapi.method.invoke.exception', str(e))
         method_result = MethodResult(error=error_value)
     logger.debug(
         'Operation finished: Service: %s, Operation %s, Ctx: %s, '
         'Output: %s', service_id, operation_id, ctx, method_result)
     return method_result
Пример #3
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
        """
        try:
            veto_error = self.execute(
                'veto', service_id, operation_id, ctx, input_value)
            if veto_error is not None:
                return MethodResult(error=veto_error)
            else:
                self.execute('pre', service_id, operation_id, ctx, input_value)
                method_result = ApiProviderFilter.invoke(
                    self, service_id, operation_id, input_value, ctx)
                self.execute('post', service_id, operation_id, ctx, input_value)
                return method_result
        except Exception as e:
            logger.exception('service: %s, operation: %s, input_value: %s',
                             service_id, operation_id, input_value)
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.invoke.exception',
                str(e))
            method_result = MethodResult(error=error_value)
            return method_result
Пример #4
0
    def _invoke_int(self, service_id, operation_id, input_value, ctx):  # pylint: disable=R0911
        """
        Internal implementation of InvokeMethod

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

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        # Step 0: Verify input types
        if (input_value and not (input_value.type == Type.STRUCTURE)):
            logger.error("Invalid inputs")
            error_value = make_error_value_from_msg_id(
                self._invalid_argument_def, 'vapi.method.input.invalid')
            return MethodResult(error=error_value)

        iface_id = InterfaceIdentifier(service_id)
        method_id = MethodIdentifier(iface_id, operation_id)

        # Step 1: Get method definition
        iface = self._service_map.get(service_id)
        if not iface:
            logger.error('Could not find service: %s', service_id)
            error_value = make_error_value_from_msg_id(
                self._operation_not_found_def,
                'vapi.method.input.invalid.interface', service_id)
            return MethodResult(error=error_value)

        method_def = iface.get_method_definition(method_id)
        if not method_def:
            logger.error("Could not find method %s", method_id.get_name())
            error_value = make_error_value_from_msg_id(
                self._operation_not_found_def,
                'vapi.method.input.invalid.method', method_id.get_name())
            return MethodResult(error=error_value)

        input_def = method_def.get_input_definition()
        if not isinstance(input_def, StructDefinition):
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.input.invalid.definition')
            return MethodResult(error=error_value)

        output_def = method_def.get_output_definition()
        if not isinstance(output_def, DataDefinition):
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.method.output.invalid.definition')
            return MethodResult(error=error_value)

        # Step 2: Validate input with input def
        input_def.complete_value(input_value)
        messages = input_def.validate(input_value)
        if messages:
            logger.error("Input validation failed for method %s",
                         method_id.get_name())
            error_value = make_error_value_from_msgs(
                self._invalid_argument_def, *messages)
            return MethodResult(error=error_value)

        # Step 3: Execute method
        method_result = iface.invoke(ctx, method_id, input_value)

        # Step 4: Validate output with output def or error against errors set
        if method_result.success():
            messages = output_def.validate(method_result.output)
            if messages:
                logger.error("Output validation failed for method %s",
                             method_id.get_name())
                error_value = make_error_value_from_msgs(
                    self._internal_server_error_def, *messages)
                return MethodResult(error=error_value)
        else:
            error_value = method_result.error
            messages = self._validate_error(error_value, method_def)
            if messages:
                new_error_value = make_error_value_from_error_value_and_msgs(
                    self._internal_server_error_def, error_value, *messages)
                return MethodResult(error=new_error_value)

        return method_result
Пример #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
        """
        sec_ctx = ctx.security_context
        authn_result = sec_ctx.get(AUTHN_IDENTITY)

        try:
            allowed_authn_schemes = self._allowed_schemes(
                service_id, operation_id)
        except Exception:
            error_value = make_error_value_from_msg_id(
                self._internal_server_error_def,
                'vapi.security.authentication.metadata.invalid', operation_id,
                service_id)
            return MethodResult(error=error_value)

        if allowed_authn_schemes is None or NO_AUTH in allowed_authn_schemes:
            is_no_auth_allowed = True
        else:
            is_no_auth_allowed = False

        # No valid AuthN info received from AuthN filter for an
        # operation which requires authentication
        if (authn_result is None and not is_no_auth_allowed):
            error_value = make_error_value_from_msg_id(
                self._unauthorized_error_def,
                'vapi.security.authorization.invalid')
            return MethodResult(error=error_value)

        if is_no_auth_allowed:
            return ApiProviderFilter.invoke(self, service_id, operation_id,
                                            input_value, ctx)
        else:
            result = None
            for handler in self._authz_handlers:
                # Call authorize method and validate authZ info
                try:
                    result = handler.authorize(service_id, operation_id,
                                               sec_ctx)
                except Exception as e:
                    logger.exception(
                        'Error in invoking authorization handler %s - %s',
                        handler, e)
                    error_value = make_error_value_from_msg_id(
                        self._internal_server_error_def,
                        'vapi.security.authorization.exception', str(e))
                    return MethodResult(error=error_value)

                if result:
                    return ApiProviderFilter.invoke(self, service_id,
                                                    operation_id, input_value,
                                                    ctx)

            error_value = make_error_value_from_msg_id(
                self._unauthorized_error_def,
                'vapi.security.authorization.invalid')
            return MethodResult(error=error_value)