Example #1
0
 def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
     if self.tests[0].evaluate(message, state):
         result = self.block.evaluate(message, state)
         state.last_if = True
         return result
     state.last_if = False
     return None
Example #2
0
    def evaluate(self, message: Message, state: EvaluationState) -> bool:
        state.check_required_extension('body', 'tests against the email body')
        if not self.body_transform:  # RAW
            # Flatten message, match header / body separator (two new-lines);
            #     if there are no headers, we match ^\n, which is guaranteed to be there
            (_, bodystr) = re.split(r'^\r?\n|\r?\n\r?\n',
                                    message.as_string(False), 1)
            return self.evaluate_part(bodystr, state)

        for msgpart in message.walk():
            if msgpart.is_multipart():
                # TODO: If "multipart/*" extract prologue and epilogue and make that searcheable
                # TODO: If "message/rfc822" extract headers and make that searchable
                # Insetad we skip multipart objects and descend into its children
                continue
            msgtxt = msgpart.get_payload()
            for mimetype in self.body_transform:
                if not mimetype:  # empty body_transform matches all
                    if self.evaluate_part(msgtxt, state):
                        return True
                match = re.match(r'^([^/]+)(?:/([^/]+))?$', mimetype)
                if not match:
                    continue  # malformed body_transform is skipped
                (maintype, subtype) = match.groups()
                if maintype == msgpart.get_content_maintype() and (
                        not subtype
                        or subtype == msgpart.get_content_subtype()):
                    if self.evaluate_part(msgtxt, state):
                        return True
        return False
Example #3
0
 def evaluate(self, message: Message, state: EvaluationState) -> None:
     state.check_required_extension('rewrite', 'REWRITE')
     search = self.positional_args[0][0]  # type: ignore
     replace = self.positional_args[1][0]  # type: ignore
     search = expand_variables(search, state)
     replace = expand_variables(replace, state)
     state.actions.append('rewrite', (search, replace))  # type: ignore
Example #4
0
    def evaluate(self, message: Message, state: EvaluationState) -> None:
        state.check_required_extension('fileinto', 'FILEINTO')

        file_dest = self.positional_args[0]
        file_dest = list(map(lambda s: expand_variables(s, state), file_dest))  # type: ignore

        state.actions.append('fileinto', file_dest)
        state.actions.cancel_implicit_keep()
Example #5
0
    def evaluate(self, message: Message, state: EvaluationState) -> bool:
        state.check_required_extension('ihave',
                                       'conditions on installed extensions')
        extension_list = self.positional_args[0]

        ret_val = True
        for ext_name in extension_list:  # type: ignore
            if ExtensionRegistry.has_extension(ext_name):
                state.require_extension(ext_name)
            else:
                ret_val = False
        return ret_val
Example #6
0
    def evaluate(self, message: Message, state: EvaluationState) -> None:
        notify_from = notify_importance = self.notify_message = None
        notify_options = []  # type: ignore
        if 'from' in self.tagged_args:
            notify_from = self.tagged_args['from'][1][0]  # type: ignore
        if 'importance' in self.tagged_args:
            notify_importance = self.tagged_args['importance'][1][
                0]  # type: ignore
        if 'options' in self.tagged_args:
            notify_options = self.tagged_args['options'][1]  # type: ignore
        notify_message = None
        if 'message' in self.tagged_args:
            notify_message = self.tagged_args['message'][1][0]  # type: ignore
        notify_method = self.positional_args[0][0]  # type: ignore

        state.check_required_extension('enotify', 'NOTIFY')
        notify_from = expand_variables(notify_from, state)  # type: ignore
        notify_importance = expand_variables(notify_importance,
                                             state)  # type: ignore
        notify_options = list(
            map(lambda s: expand_variables(s, state), notify_options))
        notify_message = expand_variables(notify_message,
                                          state)  # type: ignore
        notify_method = expand_variables(notify_method, state)

        m = re.match('^([A-Za-z][A-Za-z0-9.+-]*):', notify_method)
        if not m:
            raise RuleSyntaxError(
                "Notification method must be an URI, e.g. 'mailto:[email protected]'"
            )
        if notify_importance and notify_importance not in ["1", "2", "3"]:
            raise RuleSyntaxError(
                "Illegal notify importance '%s' encountered" %
                notify_importance)
        notify_method_cls = ExtensionRegistry.get_notification_method(
            m.group(1).lower())
        if not notify_method_cls:
            raise RuleSyntaxError("Unsupported notification method '%s'" %
                                  m.group(1))
        (res, msg) = notify_method_cls.test_valid(notify_method)
        if not res:
            raise RuleSyntaxError(msg)

        state.actions.append(
            'notify',
            (notify_method, notify_from, notify_importance, notify_options,
             notify_message)  # type: ignore
        )
Example #7
0
    def evaluate(self, message: Message, state: EvaluationState) -> bool:
        notify_methods = self.positional_args[0]
        state.check_required_extension('enotify', 'NOTIFY')
        notify_methods = list(
            map(lambda s: sifter.grammar.string.expand_variables(s, state),
                notify_methods))  # type: ignore

        for notify_method in notify_methods:
            m = re.match('^([A-Za-z][A-Za-z0-9.+-]*):', notify_method)
            if not m:
                return False
            notify_method_cls = ExtensionRegistry.get_notification_method(
                m.group(1).lower())
            if not notify_method_cls:
                return False
            (res, _) = notify_method_cls.test_valid(notify_method)
            return res
        return False
Example #8
0
 def evaluate(self,
              message: Message,
              state: Optional[EvaluationState] = None) -> Optional[Actions]:
     if state is None:
         state = EvaluationState()
     for command in self.commands:
         command.evaluate(message, state)
         # don't bother processing more commands if we hit a STOP. this
         # isn't required by the standard, but we might as well.
         if len(state.actions) > 0 and state.actions[-1][0] == 'stop':
             break
     if state.actions.implicit_keep:
         state.actions.append('keep')
     return state.actions