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

Add bandit, remove pyroma #278

Merged
merged 2 commits into from
Oct 4, 2021
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
5 changes: 5 additions & 0 deletions .bandit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
skips:
- B101 # Use of assert detected.
- B603 # subprocess call - check for execution of untrusted input
- B607 # Starting a process with a partial executable path
- B108 # Probable insecure usage of temp file/directory.
5 changes: 5 additions & 0 deletions .prospector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,10 @@ pep257:
mypy:
run: true

bandit:
run: true
options:
config: .bandit.yaml

mccabe:
run: false
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ google-auth-oauthlib = "==0.4.6"
jsonschema = "==3.2.0"
jsonschema-gentypes = "==0.9.4"
node-vm2 = "==0.4.0"
defusedxml = "==0.7.1"

[dev-packages]
prospector = {version = "==1.5.1", extras = ["with_bandit", "with_pyroma"]}
prospector = {version = "==1.5.1", extras = ["with_bandit", "with_mypy"]}
types-requests = "==2.25.6"
types-pyyaml = "==5.4.10"
types-setuptools = "==57.0.2"
Expand Down
10 changes: 9 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions c2cciutils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
import os.path
import pkgutil
import re
import subprocess
import subprocess # nosec
import sys
from typing import Any, Dict, List, Match, Optional, Pattern, Tuple, TypedDict, cast

import jsonschema_gentypes.validate
import magic
import requests
import ruamel.yaml

import c2cciutils.configuration
import jsonschema_gentypes.validate


def get_repository() -> str:
Expand Down Expand Up @@ -191,7 +191,16 @@ def get_config() -> c2cciutils.configuration.Configuration:
"print_config": True,
"print_environment_variables": True,
"print_github_event": True,
"black_config": {"propertires": {"line-length": 110}},
"black_config": {"properties": {"line-length": 110}},
"prospector_config": {
"properties": {
"strictness": "veryhigh",
"max-line-length": 110,
"doc-warnings": True,
"mypy": {"run": True},
"bandit": {"run": True},
}
},
"editorconfig": {
"properties": editorconfig_full_properties,
},
Expand Down
2 changes: 1 addition & 1 deletion c2cciutils/audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import json
import os.path
import re
import subprocess
import subprocess # nosec
import sys
from argparse import Namespace
from typing import Any, Callable, Dict, List
Expand Down
89 changes: 83 additions & 6 deletions c2cciutils/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import glob
import os
import re
import subprocess
import subprocess # nosec
import sys
from argparse import Namespace
from io import StringIO
Expand All @@ -17,6 +17,7 @@
import ruamel.yaml
import yaml
from editorconfig import EditorConfigError, get_properties
from ruamel.yaml.comments import CommentedMap

import c2cciutils.prettier
import c2cciutils.security
Expand Down Expand Up @@ -141,6 +142,82 @@ def black_config(
return True


def _check_properties(
check: str, file: str, path: str, properties: CommentedMap, reference: Dict[str, Any]
) -> bool:
if path:
path += "."

success = True

for key, value in reference.items():
if key not in properties:
c2cciutils.error(
check,
f"The property '{path}{key}' should be defined",
file,
properties.lc.line + 1,
properties.lc.col + 1,
)
success = False
if isinstance(value, dict):
if not isinstance(properties[key], dict):
c2cciutils.error(
check,
f"The property '{path}{key}' should be a dictionary",
file,
properties.lc.line + 1,
properties.lc.col + 1,
)
success = False
else:
success |= _check_properties(check, file, path + key, properties[key], value)
else:
if properties[key] != value:
c2cciutils.error(
check,
f"The property '{path}{key}' should have the value, '{value}', "
f"but is '{properties[key]}'",
file,
properties.lc.line + 1,
properties.lc.col + 1,
)
success = False
return success


def prospector_config(
config: c2cciutils.configuration.ChecksBlackConfigurationConfig,
full_config: c2cciutils.configuration.Configuration,
args: Namespace,
) -> bool:
"""
Check the prospector configuration.

config is like:
properties: # dictionary of properties to check

Arguments:
config: The check section config
full_config: All the CI config
args: The parsed command arguments
"""
del full_config, args
success = True

# If there is no python file the check is disabled
for filename in (
subprocess.check_output(["git", "ls-files", ".prospector.yaml"]).decode().strip().split("\n")
):
with open(filename, encoding="utf-8") as dependabot_file:
properties: CommentedMap = ruamel.yaml.round_trip_load(dependabot_file) # type: ignore
success |= _check_properties(
"prospector_config", filename, "", properties, config.get("properties", {})
)

return success


def editorconfig(
config: c2cciutils.configuration.ChecksEditorconfigConfig,
full_config: c2cciutils.configuration.Configuration,
Expand Down Expand Up @@ -246,7 +323,7 @@ def eof(config: None, full_config: c2cciutils.configuration.Configuration, args:
if (
subprocess.call(
f"git check-attr -a '{filename}' | grep ' text: set'",
shell=True,
shell=True, # nosec
stdout=FNULL,
)
== 0
Expand Down Expand Up @@ -300,7 +377,7 @@ def workflows(
files += glob.glob(".github/workflows/*.yml")
for filename in files:
with open(filename, encoding="utf-8") as open_file:
workflow = yaml.load(open_file, yaml.SafeLoader)
workflow = yaml.load(open_file, Loader=yaml.SafeLoader)

for name, job in workflow.get("jobs").items():
if job.get("runs-on") in config.get("images_blacklist", []):
Expand Down Expand Up @@ -367,7 +444,7 @@ def required_workflows(
continue

with open(filename, encoding="utf-8") as open_file:
workflow = yaml.load(open_file, yaml.SafeLoader)
workflow = yaml.load(open_file, Loader=yaml.SafeLoader)

for name, job in workflow.get("jobs").items():
if "if" in conf:
Expand Down Expand Up @@ -557,7 +634,7 @@ def _versions_audit(all_versions: Set[str], full_config: c2cciutils.configuratio
success = False
else:
with open(filename, encoding="utf-8") as open_file:
workflow = yaml.load(open_file, yaml.SafeLoader)
workflow = yaml.load(open_file, Loader=yaml.SafeLoader)

branch_to_version_re = c2cciutils.compile_re(full_config["version"].get("branch_to_version_re", []))

Expand Down Expand Up @@ -603,7 +680,7 @@ def _versions_rebuild(
success = False
else:
with open(filename, encoding="utf-8") as open_file:
workflow = yaml.load(open_file, yaml.SafeLoader)
workflow = yaml.load(open_file, Loader=yaml.SafeLoader)

for _, job in workflow.get("jobs").items():
rebuild_versions += _get_branch_matrix(job, branch_to_version_re)
Expand Down
33 changes: 27 additions & 6 deletions c2cciutils/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"""


from typing import Dict, Literal, TypedDict, Any, Union, List

from typing import Any, Dict, List, Literal, TypedDict, Union

# Audit
#
Expand Down Expand Up @@ -129,6 +128,7 @@
{
"black": "ChecksBlack",
"black_config": "ChecksBlackConfiguration",
"prospector_config": "ChecksProspectorConfiguration",
"codespell": "ChecksCodespell",
"dependabot_config": "ChecksDependabotConfiguration",
"editorconfig": "ChecksEditorconfig",
Expand Down Expand Up @@ -185,7 +185,7 @@
ChecksBlackConfigurationConfig = TypedDict(
"ChecksBlackConfigurationConfig",
{
# The properties key = value thet should be present
# The properties key = value that should be present
"properties": Dict[str, Union[Union[int, float], str]],
},
total=False,
Expand All @@ -206,7 +206,7 @@
ChecksCodespellConfig = TypedDict(
"ChecksCodespellConfig",
{
# List of argument that will be added to the codspell command
# List of argument that will be added to the codespell command
"arguments": List[str],
# List of regular expression that should be ignored
"ignore_re": List[str],
Expand Down Expand Up @@ -316,10 +316,31 @@

# Checks print config
#
# The print the autogenerated configguration
# The print the auto-generated configuration
ChecksPrintConfig = bool


# Checks Prospector configuration
#
# The Black configuration check configuration
#
# oneOf
ChecksProspectorConfiguration = Union["ChecksProspectorConfigurationConfig", Literal[False]]


# Checks prospector configuration config
#
# The Prospector configuration check configuration
ChecksProspectorConfigurationConfig = TypedDict(
"ChecksProspectorConfigurationConfig",
{
# The properties key = value that should be present
"properties": Dict[str, Any],
},
total=False,
)


# checks required workflows
#
# The required workflow check configuration
Expand Down Expand Up @@ -378,7 +399,7 @@
"backport_labels": bool,
# Check the versions of the protected branches
"branches": bool,
# Versions that are not in the `SECURITY.md` but should still be consided
# Versions that are not in the `SECURITY.md` but should still be considered
"extra_versions": List[str],
# Check the versions in the rebuild workflows
#
Expand Down
6 changes: 3 additions & 3 deletions c2cciutils/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import datetime
import glob
import os
import pickle
import subprocess
import pickle # nosec
import subprocess # nosec
import sys
import uuid
from typing import Optional
Expand Down Expand Up @@ -68,7 +68,7 @@ def init_calendar_service(self) -> Credentials:
# time.
if os.path.exists(self.credentials_pickle_file):
with open(self.credentials_pickle_file, "rb") as token:
creds = pickle.load(token)
creds = pickle.load(token) # nosec
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
Expand Down
Loading