-
Notifications
You must be signed in to change notification settings - Fork 42
Add NameSpace Enum #749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add NameSpace Enum #749
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
3c983c9
add a namespace Enum along with a pydantic dataclass validator to enf…
ahouseholder 3a44a44
add validator to _Namespaced mixin class
ahouseholder 34ead88
refactor base classes to use NameSpace enum values
ahouseholder 8acba47
add optional "x_" prefix as valid namespace pattern
ahouseholder 5208b69
update unit tests
ahouseholder 9c36947
add docstrings
ahouseholder d49afbf
bump python test version to 3.12
ahouseholder e36ed00
Merge branch 'main' into add_namespace_enum
ahouseholder da21986
update the regex pattern for namespaces, add validation to pydantic f…
ahouseholder b57c735
refactor namespace validation methods
ahouseholder 4c5e9cd
add unit tests
ahouseholder d8f5a88
simplify regex to avoid inefficiencies
ahouseholder e5fe103
add length requirements to namespace patterns and fields
ahouseholder dd7efec
refactor regex again
ahouseholder 3b7f34a
add docstrings
ahouseholder 643f193
add docs, update docstrings
ahouseholder b02d228
Update Decision_Point-1-0-1.schema.json
sei-vsarvepalli 02bf023
Update Decision_Point-1-0-1.schema.json
sei-vsarvepalli 8b48275
we shouldn't mention nciss yet as it's still a draft PR
ahouseholder 2e229b2
missed an nciss
ahouseholder File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| #!/usr/bin/env python | ||
| """ | ||
| Provides a namespace enum | ||
| """ | ||
| # Copyright (c) 2025 Carnegie Mellon University and Contributors. | ||
| # - see Contributors.md for a full list of Contributors | ||
| # - see ContributionInstructions.md for information on how you can Contribute to this project | ||
| # Stakeholder Specific Vulnerability Categorization (SSVC) is | ||
| # licensed under a MIT (SEI)-style license, please see LICENSE.md distributed | ||
| # with this Software or contact [email protected] for full terms. | ||
| # Created, in part, with funding and support from the United States Government | ||
| # (see Acknowledgments file). This program may include and/or can make use of | ||
| # certain third party source code, object code, documentation and other files | ||
| # (“Third Party Software”). See LICENSE.md for more details. | ||
| # Carnegie Mellon®, CERT® and CERT Coordination Center® are registered in the | ||
| # U.S. Patent and Trademark Office by Carnegie Mellon University | ||
|
|
||
| import re | ||
| from enum import StrEnum, auto | ||
|
|
||
| # extensions / experimental namespaces should start with the following prefix | ||
| # this is to avoid conflicts with official namespaces | ||
| X_PFX = "x_" | ||
|
|
||
| # pattern to match | ||
| # `(?=.{3,25}$)`: 3-25 characters long | ||
| # `^(x_)`: `x_` prefix is optional | ||
| # `[a-z0-9]{3,4}`: must start with 3-4 alphanumeric characters | ||
| # `[/.-]?`: only one punctuation character is allowed between alphanumeric characters | ||
| # `[a-z0-9]+`: at least one alphanumeric character is required after the punctuation character | ||
| # `([/.-]?[a-z0-9]+)*`: zero or more occurrences of the punctuation character followed by at least one alphanumeric character | ||
| # `$`: end of the string | ||
| # last character must be alphanumeric | ||
| NS_PATTERN = re.compile(r"^(?=.{3,25}$)(x_)?[a-z0-9]{3,4}([/.-]?[a-z0-9]+)*$") | ||
|
|
||
|
|
||
| class NameSpace(StrEnum): | ||
| """ | ||
| Defines the official namespaces for SSVC. | ||
| """ | ||
|
|
||
| # auto() is used to automatically assign values to the members. | ||
| # when used in a StrEnum, auto() assigns the lowercase name of the member as the value | ||
| SSVC = auto() | ||
| CVSS = auto() | ||
|
|
||
| @classmethod | ||
| def validate(cls, value): | ||
| """ | ||
| Validate the namespace value. | ||
|
|
||
| Args: | ||
| value: the namespace value to validate | ||
|
|
||
| Returns: | ||
| the validated namespace value | ||
|
|
||
| Raises: | ||
| ValueError: if the value is not a valid namespace | ||
|
|
||
| """ | ||
| if value in cls.__members__.values(): | ||
| return value | ||
| if value.startswith(X_PFX) and NS_PATTERN.match(value): | ||
| return value | ||
| raise ValueError( | ||
| f"Invalid namespace: {value}. Must be one of {[ns.value for ns in cls]} or start with '{X_PFX}'." | ||
| ) | ||
|
|
||
|
|
||
| def main(): | ||
| for ns in NameSpace: | ||
| print(ns) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # Copyright (c) 2025 Carnegie Mellon University and Contributors. | ||
| # - see Contributors.md for a full list of Contributors | ||
| # - see ContributionInstructions.md for information on how you can Contribute to this project | ||
| # Stakeholder Specific Vulnerability Categorization (SSVC) is | ||
| # licensed under a MIT (SEI)-style license, please see LICENSE.md distributed | ||
| # with this Software or contact [email protected] for full terms. | ||
| # Created, in part, with funding and support from the United States Government | ||
| # (see Acknowledgments file). This program may include and/or can make use of | ||
| # certain third party source code, object code, documentation and other files | ||
| # (“Third Party Software”). See LICENSE.md for more details. | ||
| # Carnegie Mellon®, CERT® and CERT Coordination Center® are registered in the | ||
| # U.S. Patent and Trademark Office by Carnegie Mellon University | ||
|
|
||
| import unittest | ||
|
|
||
| from ssvc.namespaces import NS_PATTERN, NameSpace | ||
|
|
||
|
|
||
| class MyTestCase(unittest.TestCase): | ||
| def setUp(self): | ||
| pass | ||
|
|
||
| def tearDown(self): | ||
| pass | ||
|
|
||
| def test_ns_pattern(self): | ||
| should_match = [ | ||
| "foo", | ||
| "foo.bar", | ||
| "foo.bar.baz", | ||
| "foo/bar/baz/quux", | ||
| "foo.bar/baz.quux", | ||
| ] | ||
| should_match.extend([f"x_{ns}" for ns in should_match]) | ||
|
|
||
| for ns in should_match: | ||
| with self.subTest(ns=ns): | ||
| self.assertTrue(NS_PATTERN.match(ns), ns) | ||
|
|
||
| should_not_match = [ | ||
| "", | ||
| "ab", | ||
| ".foo", | ||
| "foo..bar", | ||
| "foo/bar//baz", | ||
| "foo/bar/baz/", | ||
| "(&(&" "foo\\bar", | ||
| "foo|bar|baz", | ||
| ] | ||
|
|
||
| should_not_match.extend([f"_{ns}" for ns in should_not_match]) | ||
|
|
||
| for ns in should_not_match: | ||
| with self.subTest(ns=ns): | ||
| self.assertFalse(NS_PATTERN.match(ns)) | ||
|
|
||
| def test_namspace_enum(self): | ||
| for ns in NameSpace: | ||
| self.assertEqual(ns.name.lower(), ns.value) | ||
|
|
||
| # make sure we have an SSVC namespace with the correct value | ||
| self.assertIn("SSVC", NameSpace.__members__) | ||
| values = [ns.value for ns in NameSpace] | ||
| self.assertIn("ssvc", values) | ||
|
|
||
| def test_namespace_validator(self): | ||
| for ns in NameSpace: | ||
| self.assertTrue(NameSpace.validate(ns.value)) | ||
|
|
||
| for ns in ["foo", "bar", "baz", "quux"]: | ||
| with self.assertRaises(ValueError): | ||
| NameSpace.validate(ns) | ||
|
|
||
| for ns in ["x_foo", "x_bar", "x_baz", "x_quux"]: | ||
| self.assertEqual(ns, NameSpace.validate(ns)) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.