Example #1
0
    def __init__(self, next_provider=None, provider_config=None):
        """
        Initialize AuthorizationFilter

        :type  next_provider: :class:`vmware.vapi.core.ApiProvider`
        :param next_provider: API Provider to invoke the requests
        :type  provider_config:
            :class:`vmware.vapi.settings.config.ProviderConfig` or :class:`None`
        :param provider_config: Provider configuration object
        """
        handler_names = []
        self._metadata = None
        if provider_config:
            # Get the registered AuthN handlers from config file
            (handler_names, metadata_file) = \
                provider_config.get_authorization_handlers_and_file()
            self._metadata = get_metadata(metadata_file)

        from vmware.vapi.lib.load import dynamic_import
        self._authz_handlers = []
        for handler_name in handler_names:
            # Dynamically load the AuthZ handler
            handler_constructor = dynamic_import(handler_name)
            if handler_constructor is None:
                raise ImportError('Could not import %s' % handler_name)

            self._authz_handlers.append(handler_constructor())

        self._internal_server_error_def = make_std_error_def(
            'com.vmware.vapi.std.errors.internal_server_error')
        self._unauthorized_error_def = make_std_error_def(
            'com.vmware.vapi.std.errors.unauthorized')
        ApiProviderFilter.__init__(
            self, next_provider,
            [self._internal_server_error_def, self._unauthorized_error_def])
Example #2
0
    def __init__(self, next_provider=None):
        """
        Initialize SecurityContextFilter

        :type  next_provider: :class:`vmware.vapi.core.ApiProvider`
        :param next_provider: API Provider to invoke the requests
        """
        ApiProviderFilter.__init__(self, next_provider)
Example #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
        """
        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
Example #4
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)
Example #5
0
    def __init__(self, next_provider=None):
        """
        Initializer InterposerProvider.

        :type  next_provider: :class:`vmware.vapi.core.ApiProvider` or ``None``
        :param next_provider: API Provider to invoke the requests
        """
        ApiProviderFilter.__init__(self, next_provider,
                                   [self._internal_server_error_def])
        # Key: Interposer type, Value: set of interposer ids of that type
        self._interposers = {}

        # Key: Interposer Id, Value: Interposer Map
        self._interposer_map = {}

        # Key: Interposer Id, Value: Method Identifier
        self._interposer_def = {}

        # Method identifiers of all the interposers
        self._interposer_methods = set()

        connector = LocalConnector(self.next_provider)
        self._introspection = IntrospectableApiProvider(connector)
Example #6
0
    def _execute_int(self,
                     interposer_id,
                     interposer_type,
                     ctx,
                     service_name,
                     operation_name,
                     opeartion_input):
        """
        Execute an interposer

        :type  interposer_id: :class:`str`
        :param interposer_id: Interposer id
        :type  interposer_type: :class:`InterposerType`
        :param interposer_type: Interposer type
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for the invocation
        :type  service_name: :class:`str`
        :param service_name: Name of the service that is being interposed
        :type  operation_name: :class:`str`
        :param operation_name: Name of the operation that is being interposed
        :type  opeartion_input: :class:`vmware.vapi.data.value.DataValue`
        :param opeartion_input: Input for the operation that is being interposed
        :rtype: :class:`vmware.vapi.data.value.ErrorValue`
        :return: Error is returned if the veto interposer execution
                 reported an error, else None
        """
        in_method_def = self._interposer_def.get(interposer_id)
        if in_method_def:
            interposer_input = in_method_def.get_input_definition().new_value()
            interposer_input.set_field(SERVICE_NAME,
                                       StringValue(service_name))
            interposer_input.set_field(OPERATION_NAME,
                                       StringValue(operation_name))
            interposer_input.set_field(OPERATION_INPUT,
                                       opeartion_input)
            in_method_id = in_method_def.get_identifier()
            method_result = ApiProviderFilter.invoke(
                self, in_method_id.get_interface_identifier().get_name(),
                in_method_id.get_name(),
                interposer_input, ctx)

            # Only veto interposers can break the control flow
            if interposer_type == InterposerType.VETO and \
                    not method_result.success():
                return method_result.error
Example #7
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
Example #8
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)
Example #9
0
 def invoke(self, service_id, operation_id, input_value, ctx):
     return ApiProviderFilter.invoke(self, service_id, operation_id,
                                     input_value, ctx)