Esempio n. 1
0
def _load_rules(
    rawrules: List[JsonDict],
    enabled_map: Dict[str, bool],
    experimental_config: ExperimentalConfig,
) -> List[JsonDict]:
    ruleslist = []
    for rawrule in rawrules:
        rule = dict(rawrule)
        rule["conditions"] = db_to_json(rawrule["conditions"])
        rule["actions"] = db_to_json(rawrule["actions"])
        rule["default"] = False
        ruleslist.append(rule)

    # We're going to be mutating this a lot, so copy it. We also filter out
    # any experimental default push rules that aren't enabled.
    rules = [
        rule for rule in list_with_base_rules(ruleslist)
        if _is_experimental_rule_enabled(rule["rule_id"], experimental_config)
    ]

    for i, rule in enumerate(rules):
        rule_id = rule["rule_id"]

        if rule_id not in enabled_map:
            continue
        if rule.get("enabled", True) == bool(enabled_map[rule_id]):
            continue

        # Rules are cached across users.
        rule = dict(rule)
        rule["enabled"] = bool(enabled_map[rule_id])
        rules[i] = rule

    return rules
Esempio n. 2
0
def format_push_rules_for_user(user, rawrules, enabled_map):
    """Converts a list of rawrules and a enabled map into nested dictionaries
    to match the Matrix client-server format for push rules"""

    ruleslist = []
    for rawrule in rawrules:
        rule = dict(rawrule)
        rule["conditions"] = json.loads(rawrule["conditions"])
        rule["actions"] = json.loads(rawrule["actions"])
        ruleslist.append(rule)

    # We're going to be mutating this a lot, so do a deep copy
    ruleslist = copy.deepcopy(list_with_base_rules(ruleslist))

    rules = {'global': {}, 'device': {}}

    rules['global'] = _add_empty_priority_class_arrays(rules['global'])

    for r in ruleslist:
        rulearray = None

        template_name = _priority_class_to_template_name(r['priority_class'])

        # Remove internal stuff.
        for c in r["conditions"]:
            c.pop("_id", None)

            pattern_type = c.pop("pattern_type", None)
            if pattern_type == "user_id":
                c["pattern"] = user.to_string()
            elif pattern_type == "user_localpart":
                c["pattern"] = user.localpart

        rulearray = rules['global'][template_name]

        template_rule = _rule_to_template(r)
        if template_rule:
            if r['rule_id'] in enabled_map:
                template_rule['enabled'] = enabled_map[r['rule_id']]
            elif 'enabled' in r:
                template_rule['enabled'] = r['enabled']
            else:
                template_rule['enabled'] = True
            rulearray.append(template_rule)

    return rules
Esempio n. 3
0
def format_push_rules_for_user(user, rawrules, enabled_map):
    """Converts a list of rawrules and a enabled map into nested dictionaries
    to match the Matrix client-server format for push rules"""

    ruleslist = []
    for rawrule in rawrules:
        rule = dict(rawrule)
        rule["conditions"] = json.loads(rawrule["conditions"])
        rule["actions"] = json.loads(rawrule["actions"])
        ruleslist.append(rule)

    # We're going to be mutating this a lot, so do a deep copy
    ruleslist = copy.deepcopy(list_with_base_rules(ruleslist))

    rules = {'global': {}, 'device': {}}

    rules['global'] = _add_empty_priority_class_arrays(rules['global'])

    for r in ruleslist:
        rulearray = None

        template_name = _priority_class_to_template_name(r['priority_class'])

        # Remove internal stuff.
        for c in r["conditions"]:
            c.pop("_id", None)

            pattern_type = c.pop("pattern_type", None)
            if pattern_type == "user_id":
                c["pattern"] = user.to_string()
            elif pattern_type == "user_localpart":
                c["pattern"] = user.localpart

        rulearray = rules['global'][template_name]

        template_rule = _rule_to_template(r)
        if template_rule:
            if r['rule_id'] in enabled_map:
                template_rule['enabled'] = enabled_map[r['rule_id']]
            elif 'enabled' in r:
                template_rule['enabled'] = r['enabled']
            else:
                template_rule['enabled'] = True
            rulearray.append(template_rule)

    return rules
Esempio n. 4
0
def _load_rules(rawrules, enabled_map):
    ruleslist = []
    for rawrule in rawrules:
        rule = dict(rawrule)
        rule["conditions"] = json.loads(rawrule["conditions"])
        rule["actions"] = json.loads(rawrule["actions"])
        ruleslist.append(rule)

    # We're going to be mutating this a lot, so do a deep copy
    rules = list(list_with_base_rules(ruleslist))

    for i, rule in enumerate(rules):
        rule_id = rule["rule_id"]
        if rule_id in enabled_map:
            if rule.get("enabled", True) != bool(enabled_map[rule_id]):
                # Rules are cached across users.
                rule = dict(rule)
                rule["enabled"] = bool(enabled_map[rule_id])
                rules[i] = rule

    return rules
Esempio n. 5
0
def _load_rules(rawrules, enabled_map):
    ruleslist = []
    for rawrule in rawrules:
        rule = dict(rawrule)
        rule["conditions"] = json.loads(rawrule["conditions"])
        rule["actions"] = json.loads(rawrule["actions"])
        ruleslist.append(rule)

    # We're going to be mutating this a lot, so do a deep copy
    rules = list(list_with_base_rules(ruleslist))

    for i, rule in enumerate(rules):
        rule_id = rule['rule_id']
        if rule_id in enabled_map:
            if rule.get('enabled', True) != bool(enabled_map[rule_id]):
                # Rules are cached across users.
                rule = dict(rule)
                rule['enabled'] = bool(enabled_map[rule_id])
                rules[i] = rule

    return rules
Esempio n. 6
0
    def on_GET(self, request):
        user, _ = yield self.auth.get_user_by_req(request)

        # we build up the full structure and then decide which bits of it
        # to send which means doing unnecessary work sometimes but is
        # is probably not going to make a whole lot of difference
        rawrules = yield self.hs.get_datastore().get_push_rules_for_user(
            user.to_string()
        )

        ruleslist = []
        for rawrule in rawrules:
            rule = dict(rawrule)
            rule["conditions"] = json.loads(rawrule["conditions"])
            rule["actions"] = json.loads(rawrule["actions"])
            ruleslist.append(rule)

        ruleslist = baserules.list_with_base_rules(ruleslist, user)

        rules = {'global': {}, 'device': {}}

        rules['global'] = _add_empty_priority_class_arrays(rules['global'])

        enabled_map = yield self.hs.get_datastore().\
            get_push_rules_enabled_for_user(user.to_string())

        for r in ruleslist:
            rulearray = None

            template_name = _priority_class_to_template_name(r['priority_class'])

            if r['priority_class'] > PRIORITY_CLASS_MAP['override']:
                # per-device rule
                profile_tag = _profile_tag_from_conditions(r["conditions"])
                r = _strip_device_condition(r)
                if not profile_tag:
                    continue
                if profile_tag not in rules['device']:
                    rules['device'][profile_tag] = {}
                    rules['device'][profile_tag] = (
                        _add_empty_priority_class_arrays(
                            rules['device'][profile_tag]
                        )
                    )

                rulearray = rules['device'][profile_tag][template_name]
            else:
                rulearray = rules['global'][template_name]

            template_rule = _rule_to_template(r)
            if template_rule:
                if r['rule_id'] in enabled_map:
                    template_rule['enabled'] = enabled_map[r['rule_id']]
                elif 'enabled' in r:
                    template_rule['enabled'] = r['enabled']
                else:
                    template_rule['enabled'] = True
                rulearray.append(template_rule)

        path = request.postpath[1:]

        if path == []:
            # we're a reference impl: pedantry is our job.
            raise UnrecognizedRequestError(
                PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR
            )

        if path[0] == '':
            defer.returnValue((200, rules))
        elif path[0] == 'global':
            path = path[1:]
            result = _filter_ruleset_with_path(rules['global'], path)
            defer.returnValue((200, result))
        elif path[0] == 'device':
            path = path[1:]
            if path == []:
                raise UnrecognizedRequestError(
                    PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR
                )
            if path[0] == '':
                defer.returnValue((200, rules['device']))

            profile_tag = path[0]
            path = path[1:]
            if profile_tag not in rules['device']:
                ret = {}
                ret = _add_empty_priority_class_arrays(ret)
                defer.returnValue((200, ret))
            ruleset = rules['device'][profile_tag]
            result = _filter_ruleset_with_path(ruleset, path)
            defer.returnValue((200, result))
        else:
            raise UnrecognizedRequestError()
Esempio n. 7
0
    def on_GET(self, request):
        user, _ = yield self.auth.get_user_by_req(request)

        # we build up the full structure and then decide which bits of it
        # to send which means doing unnecessary work sometimes but is
        # is probably not going to make a whole lot of difference
        rawrules = yield self.hs.get_datastore().get_push_rules_for_user(
            user.to_string())

        ruleslist = []
        for rawrule in rawrules:
            rule = dict(rawrule)
            rule["conditions"] = json.loads(rawrule["conditions"])
            rule["actions"] = json.loads(rawrule["actions"])
            ruleslist.append(rule)

        ruleslist = baserules.list_with_base_rules(ruleslist, user)

        rules = {'global': {}, 'device': {}}

        rules['global'] = _add_empty_priority_class_arrays(rules['global'])

        enabled_map = yield self.hs.get_datastore().\
            get_push_rules_enabled_for_user(user.to_string())

        for r in ruleslist:
            rulearray = None

            template_name = _priority_class_to_template_name(
                r['priority_class'])

            if r['priority_class'] > PRIORITY_CLASS_MAP['override']:
                # per-device rule
                profile_tag = _profile_tag_from_conditions(r["conditions"])
                r = _strip_device_condition(r)
                if not profile_tag:
                    continue
                if profile_tag not in rules['device']:
                    rules['device'][profile_tag] = {}
                    rules['device'][profile_tag] = (
                        _add_empty_priority_class_arrays(
                            rules['device'][profile_tag]))

                rulearray = rules['device'][profile_tag][template_name]
            else:
                rulearray = rules['global'][template_name]

            template_rule = _rule_to_template(r)
            if template_rule:
                if r['rule_id'] in enabled_map:
                    template_rule['enabled'] = enabled_map[r['rule_id']]
                elif 'enabled' in r:
                    template_rule['enabled'] = r['enabled']
                else:
                    template_rule['enabled'] = True
                rulearray.append(template_rule)

        path = request.postpath[1:]

        if path == []:
            # we're a reference impl: pedantry is our job.
            raise UnrecognizedRequestError(
                PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR)

        if path[0] == '':
            defer.returnValue((200, rules))
        elif path[0] == 'global':
            path = path[1:]
            result = _filter_ruleset_with_path(rules['global'], path)
            defer.returnValue((200, result))
        elif path[0] == 'device':
            path = path[1:]
            if path == []:
                raise UnrecognizedRequestError(
                    PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR)
            if path[0] == '':
                defer.returnValue((200, rules['device']))

            profile_tag = path[0]
            path = path[1:]
            if profile_tag not in rules['device']:
                ret = {}
                ret = _add_empty_priority_class_arrays(ret)
                defer.returnValue((200, ret))
            ruleset = rules['device'][profile_tag]
            result = _filter_ruleset_with_path(ruleset, path)
            defer.returnValue((200, result))
        else:
            raise UnrecognizedRequestError()