Skip to content
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

Enforce SUMMARY field for codemod; add to codetf2 output #30

Merged
merged 1 commit into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/codemodder/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ def compile_results(codemods):
continue
data = {
"codemod": f"pixee:python/{name}",
"summary": codemod_kls.METADATA.DESCRIPTION,
"summary": codemod_kls.SUMMARY,
"description": codemod_kls.METADATA.DESCRIPTION,
"references": [],
"properties": {},
"failedFiles": [],
Expand Down
11 changes: 11 additions & 0 deletions src/codemodder/codemods/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ def __init_subclass__(cls):
# TODO: if we intend to continue to check class-level attributes
# using this mechanism, we should add checks (or defaults) for
# NAME, DESCRIPTION, and REVIEW_GUIDANCE here.
missing_fields = []
for field in ["SUMMARY", "DESCRIPTION", "REVIEW_GUIDANCE"]:
try:
assert hasattr(cls, field)
except AssertionError:
missing_fields.append(field)

if missing_fields:
raise AssertionError(
f"{cls.__name__} is missing the following fields: {missing_fields}"
)

cls.METADATA = CodemodMetadata(
cls.DESCRIPTION, # pylint: disable=no-member
Expand Down
8 changes: 6 additions & 2 deletions src/codemodder/codemods/base_codemod.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CodemodMetadata:
class BaseCodemod:
# Implementation borrowed from https://stackoverflow.com/a/45250114
METADATA: ClassVar[CodemodMetadata] = NotImplemented
SUMMARY: ClassVar[str] = NotImplemented
IS_SEMGREP = False

def __init_subclass__(cls, **kwargs):
Expand All @@ -32,8 +33,11 @@ def __init_subclass__(cls, **kwargs):
# classes will.
return

if cls.METADATA is NotImplemented:
raise NotImplementedError("You forgot to define METADATA")
for attr in ["SUMMARY", "METADATA"]:
if getattr(cls, attr) is NotImplemented:
raise NotImplementedError(
f"You forgot to define {attr} for {cls.__name__}"
)
for k, v in asdict(cls.METADATA).items():
if v is NotImplemented:
raise NotImplementedError(f"You forgot to define METADATA.{k}")
Expand Down
2 changes: 1 addition & 1 deletion src/codemodder/codemods/django_debug_flag_on.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class DjangoDebugFlagOn(SemgrepCodemod, Codemod):
NAME="django-debug-flag-on",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW,
)
CHANGE_DESCRIPTION = "Flips django's debug flag to off."
SUMMARY = CHANGE_DESCRIPTION = "Flips django's debug flag to off."
YAML_FILES = [
"django-debug-flag-on.yaml",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class DjangoSessionCookieSecureOff(SemgrepCodemod, Codemod):
NAME="django-session-cookie-secure-off",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_AFTER_REVIEW,
)
SUMMARY = "Sets Django's `SESSION_COOKIE_SECURE` flag if off or missing."
CHANGE_DESCRIPTION = METADATA.DESCRIPTION
YAML_FILES = [
"detect-django-settings.yaml",
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/harden_pyyaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class HardenPyyaml(SemgrepCodemod):
NAME = "harden-pyyaml"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Use SafeLoader when loading YAML"
DESCRIPTION = "Ensures all calls to yaml.load use `SafeLoader`."

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/harden_ruamel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class HardenRuamel(SemgrepCodemod):
NAME = "harden-ruamel"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Use safe YAML loading in ruamel.yaml"
DESCRIPTION = "Ensures all unsafe calls to ruamel.yaml.YAML use `typ='safe'`."

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/limit_readline.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class LimitReadline(SemgrepCodemod):
NAME = "limit-readline"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW
SUMMARY = "Limit the size of readline() calls"
DESCRIPTION = "Adds a size limit argument to readline() calls."

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/order_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class OrderImports(BaseCodemod, Codemod):
NAME="order-imports",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_WITHOUT_REVIEW,
)
SUMMARY = "Formats and orders imports by categories"
CHANGE_DESCRIPTION = "Ordered and formatted import block below this line"

METADATA_DEPENDENCIES = (PositionProvider,)
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/process_creation_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class ProcessSandbox(SemgrepCodemod):
NAME = "sandbox-process-creation"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW
SUMMARY = "Use safe_command library to sandbox process creation."
DESCRIPTION = (
"Replaces subprocess.{func} with more secure safe_command library functions."
)
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/remove_unnecessary_f_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
class RemoveUnnecessaryFStr(BaseCodemod, UnnecessaryFormatString):
NAME = "remove-unnecessary-f-str"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Remove unnecessary f-strings."
DESCRIPTION = UnnecessaryFormatString.DESCRIPTION

def __init__(self, codemod_context: CodemodContext, file_context: FileContext):
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/remove_unused_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class RemoveUnusedImports(BaseCodemod, Codemod):
NAME="unused-imports",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_WITHOUT_REVIEW,
)
SUMMARY = "Remove unused imports from a module."
CHANGE_DESCRIPTION = "Unused import."

METADATA_DEPENDENCIES = (PositionProvider, ScopeProvider, QualifiedNameProvider)
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/requests_verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class RequestsVerify(SemgrepCodemod):
NAME = "requests-verify"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW
SUMMARY = "Verify SSL certificates when making requests."
DESCRIPTION = (
"Makes any calls to requests.{func} with `verify=False` to `verify=True`"
)
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/secure_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class SecureRandom(SemgrepCodemod):
NAME = "secure-random"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Use secrets.SystemRandom() instead of random"
DESCRIPTION = "Replaces random.{func} with more secure secrets library functions."

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/tempfile_mktemp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class TempfileMktemp(SemgrepCodemod):
NAME = "secure-tempfile"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Use `tempfile.mkstemp` instead of `tempfile.mktemp`."
DESCRIPTION = "Replaces `tempfile.mktemp` with `tempfile.mkstemp`."

@classmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class UpgradeSSLContextMinimumVersion(SemgrepCodemod):
NAME = "upgrade-sslcontext-minimum-version"
REVIEW_GUIDANCE = ReviewGuidance.MERGE_WITHOUT_REVIEW
SUMMARY = "Upgrade minimum SSL/TLS version for SSLContext"
DESCRIPTION = "Replaces minimum SSL/TLS version for SSLContext"

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/upgrade_sslcontext_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class UpgradeSSLContextTLS(SemgrepCodemod, BaseTransformer):
NAME="upgrade-sslcontext-tls",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW,
)
SUMMARY = "Replaces known insecure TLS/SSL protocol versions in SSLContext with secure ones"
CHANGE_DESCRIPTION = "Upgrade to use a safe version of TLS in SSLContext"
YAML_FILES = [
"upgrade_sslcontext_tls.yaml",
Expand Down
1 change: 1 addition & 0 deletions src/codemodder/codemods/url_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class UrlSandbox(SemgrepCodemod, Codemod):
NAME="url-sandbox",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW,
)
SUMMARY = "Ensures that requests are made safely."
CHANGE_DESCRIPTION = "Switch use of requests for security.safe_requests"
YAML_FILES = [
"sandbox_url_creation.yaml",
Expand Down
1 change: 1 addition & 0 deletions tests/codemods/test_base_codemod.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class DoNothingCodemod(SemgrepCodemod, Codemod):
NAME="do-nothing",
REVIEW_GUIDANCE=ReviewGuidance.MERGE_WITHOUT_REVIEW,
)
SUMMARY = "An identity codemod for testing purposes."
YAML_FILES = []

def __init__(self, context: CodemodContext, results_by_id):
Expand Down