diff --git a/pypanther/base.py b/pypanther/base.py index 4086363b..559dbd66 100644 --- a/pypanther/base.py +++ b/pypanther/base.py @@ -242,6 +242,10 @@ def __init_subclass__(cls, **kwargs): child.tags.append("Foo") parent.tags.append("Foo") # not inherited by children of parent """ + # Set the id to the class name if it's not explicitly set + if "id" not in cls.__dict__ or not cls.__dict__["id"]: + cls.id = cls.__name__ + for attr in RULE_ALL_ATTRS: if attr not in cls.__dict__: try: diff --git a/pypanther/generate.py b/pypanther/generate.py index e7913971..3e562b2d 100644 --- a/pypanther/generate.py +++ b/pypanther/generate.py @@ -122,7 +122,7 @@ def convert_rule(filepath: Path, helpers: Set[str]) -> Optional[str]: ) value = ast.List(elts=log_type_elts) if k == "RuleID": - value = ast.Constant(value=v + ID_POSTFIX) + continue assignments.append( ast.Assign( diff --git a/tests/test_base.py b/tests/test_base.py index 8cb0d1cb..3c634bc8 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -13,7 +13,6 @@ TRUNCATED_STRING_SUFFIX, TYPE_RULE, ) -from pydantic import ValidationError from pypanther.base import RULE_ALL_ATTRS, Rule, RuleModel, panther_managed from pypanther.cache import data_model_cache @@ -353,20 +352,18 @@ def rule(self, event): class TestValidation: - def test_rule_missing_id(self): - class rule(Rule): + def test_rule_id_is_class_name(self): + """Test that a rule's id is automatically set to its class name.""" + + class TestRule(Rule): default_severity = Severity.INFO log_types = ["test"] def rule(self, event): return False - with pytest.raises(ValidationError) as e: - rule.validate() - errors = e.value.errors() - assert len(errors) == 1 - assert errors[0]["loc"] == ("id",) - assert errors[0]["msg"] == "Field required" + # Verify that id is set to the class name + assert TestRule.id == "TestRule" def test_create_rule_missing_method(self) -> None: class rule(Rule):