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
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
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
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
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()
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()