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

Change: enable running with no config if no plugin needs a config #726

Closed
wants to merge 12 commits into from
Closed
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
2 changes: 1 addition & 1 deletion poetry.lock

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

10 changes: 4 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ repository = "https://github.com/greenbone/troubadix"
homepage = "https://github.com/greenbone/troubadix"

# Full list: https://pypi.org/pypi?%3Aaction=list_classifiers
classifiers=[
classifiers = [
"Development Status :: 4 - Beta",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", # pylint: disable=line-too-long
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", # pylint: disable=line-too-long
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.9",
Expand All @@ -21,10 +21,7 @@ classifiers=[
"Topic :: Software Development :: Libraries :: Python Modules",
]

packages = [
{ include = "troubadix"},
{ include = "tests", format = "sdist" },
]
packages = [{ include = "troubadix" }, { include = "tests", format = "sdist" }]

[tool.poetry.dependencies]
python = "^3.9"
Expand All @@ -35,6 +32,7 @@ chardet = ">=4,<6"
validators = "0.20.0"
gitpython = "^3.1.31"
charset-normalizer = "^3.2.0"
tomli = { version = "^2.0.1", python = "<3.11" }

[tool.poetry.dev-dependencies]
autohooks = ">=21.7.0"
Expand Down
117 changes: 48 additions & 69 deletions tests/plugins/test_http_links_in_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,48 @@

from pathlib import Path

from troubadix.plugin import LinterError
from troubadix.plugin import ConfigurationError, LinterError
from troubadix.plugins.http_links_in_tags import CheckHttpLinksInTags

from . import PluginTestCase

BASE_CONFIG = {CheckHttpLinksInTags.name: {"exclusions": []}}


class CheckHttpLinksInTagsTestCase(PluginTestCase):

def test_validate_config(self):
fake_context = self.create_file_plugin_context()

valid_plugin_config = {
"exclusions": ["Foo Bar. https://www.website.de/demo"]
}
valid_config = {"check_http_links_in_tags": valid_plugin_config}

# config extraction and validation is done when the init method
# is called with the optional key config.
plugin = CheckHttpLinksInTags(fake_context, config=valid_config)

self.assertEqual(plugin.config, valid_plugin_config)

invalid_config_missing_plugin_key = {}
with self.assertRaises(ConfigurationError) as context:
plugin.extract_plugin_config(invalid_config_missing_plugin_key)
self.assertEqual(
str(context.exception),
"Configuration for plugin 'check_http_links_in_tags' is missing.",
)
invalid_plugin_config_missing_required_key = {}
with self.assertRaises(ConfigurationError) as context:
plugin.validate_plugin_config(
invalid_plugin_config_missing_required_key
)
self.assertEqual(
str(context.exception),
"Configuration for plugin 'check_http_links_in_tags' "
"is missing required key: 'exclusions'",
)

def test_ok(self):
path = Path("some/file.nasl")
content = (
Expand All @@ -33,11 +68,18 @@ def test_ok(self):
' script_tag(name:"solution_type", value:"VendorFix");\n'
' script_tag(name:"solution", value:"meh");\n'
'port = get_app_port_from_cpe_prefix("cpe:/o:foo:bar");\n'
' script_tag(name:"summary", value:"Foo Bar. '
'https://www.website.de/demo");\n'
)
fake_plugin_config = {
"exclusions": ["Foo Bar. https://www.website.de/demo"]
}
fake_context = self.create_file_plugin_context(
nasl_file=path, file_content=content
nasl_file=path,
file_content=content,
)
plugin = CheckHttpLinksInTags(fake_context)
plugin = CheckHttpLinksInTags(fake_context, config=BASE_CONFIG)
plugin.config = fake_plugin_config

results = list(plugin.run())

Expand All @@ -46,7 +88,7 @@ def test_ok(self):
def test_exclude_inc_file(self):
path = Path("some/file.inc")
fake_context = self.create_file_plugin_context(nasl_file=path)
plugin = CheckHttpLinksInTags(fake_context)
plugin = CheckHttpLinksInTags(fake_context, config=BASE_CONFIG)

results = list(plugin.run())

Expand All @@ -64,7 +106,7 @@ def test_not_ok(self):
fake_context = self.create_file_plugin_context(
nasl_file=path, file_content=content
)
plugin = CheckHttpLinksInTags(fake_context)
plugin = CheckHttpLinksInTags(fake_context, config=BASE_CONFIG)

results = list(plugin.run())

Expand Down Expand Up @@ -92,7 +134,7 @@ def test_not_ok2(self):
fake_context = self.create_file_plugin_context(
nasl_file=path, file_content=content
)
plugin = CheckHttpLinksInTags(fake_context)
plugin = CheckHttpLinksInTags(fake_context, config=BASE_CONFIG)

results = list(plugin.run())

Expand All @@ -106,66 +148,3 @@ def test_not_ok2(self):
'value:"https://nvd.nist.gov/vuln/detail/CVE-1234");',
results[0].message,
)

def test_http_link_in_tags_ok(self):
testcases = [
"01. The payloads try to open a connection to www.google.com",
"02. The script attempts to connect to www.google.com",
"03. to retrieve a web page from www.google.com",
"04. Subject: commonName=www.paypal.com",
"05. Terms of use at https://www.verisign.com/rpa",
"06. example.com",
"07. example.org",
"08. www.exam",
"09. sampling the resolution of a name (www.google.com)",
"10. once with 'www.' and once without",
"11. wget http://www.javaop.com/~ron/tmp/nc",
"12. as www.windowsupdate.com. (BZ#506016)",
"13. located at http://sambarserver/session/pagecount.",
"14. http://rest.modx.com",
"15. ftp:// ",
"16. ftp://'",
"17. ftp://)",
"18. ftp.c",
"19. ftp.exe",
"20. using special ftp://",
"21. running ftp.",
"22. ftp. The vulnerability",
"23. 'http://' protocol",
"24. handle <a href='http://...'> properly",
"25. Switch to git+https://",
"26. wget https://compromised-domain.com/important-file",
"27. the https:// scheme",
"28. https://[email protected]",
"29. 'http://'",
"30. 'https://'",
"31. distributions on ftp.proftpd.org have all been",
"32. information from www.mutt.org:",
"33. According to www.tcpdump.org:",
"34. According to www.kde.org:",
"35. From the www.info-zip.org site:",
# pylint: disable=line-too-long
"36. (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and",
"37. Sorry about having to reissue this one -- I pulled it from ftp.gnu.org not",
"38. http://internal-host$1 is still insecure",
"39. from online sources (ftp://, http:// etc.).",
"40. this and https:// and that.",
"41. such as 'http://:80'",
"42. <http://localhost/moodle/admin/>",
]

for testcase in testcases:
self.assertTrue(CheckHttpLinksInTags.check_to_continue(testcase))

def test_http_link_in_tags_not_ok(self):
testcases = [
"The payloads try to open a connection to www.bing.com",
"examplephishing.org",
"located at http://sambdadancinglessions/session/pagecount.",
"fdp:// ",
"Switch to svn+https://",
"greenbone.net",
]

for testcase in testcases:
self.assertFalse(CheckHttpLinksInTags.check_to_continue(testcase))
112 changes: 57 additions & 55 deletions tests/standalone_plugins/test_deprecate_vts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,88 +4,90 @@
# pylint: disable=protected-access
import unittest
from pathlib import Path
from tests.plugins import TemporaryDirectory

from tests.plugins import TemporaryDirectory
from troubadix.standalone_plugins.deprecate_vts import (
deprecate,
parse_args,
DeprecatedFile,
_get_summary,
_finalize_content,
update_summary,
get_files_from_path,
_get_summary,
deprecate,
filter_files,
get_files_from_path,
parse_args,
update_summary,
)


class ParseArgsTestCase(unittest.TestCase):
def test_parse_args(self):
testfile = "testfile.nasl"
output_path = "attic/"
reason = "NOTUS"

args = parse_args(
[
"--files",
testfile,
"--output-path",
output_path,
"--deprecation-reason",
reason,
]
)
self.assertEqual(args.files, [Path(testfile)])
self.assertEqual(args.output_path, Path(output_path))
self.assertEqual(args.deprecation_reason, reason)

def test_mandatory_arg_group_both(self):
testfile = "testfile.nasl"
output_path = "attic/"
input_path = "nasl/common"
reason = "NOTUS"

with self.assertRaises(SystemExit):
parse_args(
with TemporaryDirectory() as out_dir:
args = parse_args(
[
"--files",
testfile,
"--output-path",
output_path,
"--input-path",
input_path,
str(out_dir),
"--deprecation-reason",
reason,
]
)
self.assertEqual(args.files, [Path(testfile)])
self.assertEqual(args.output_path, out_dir)
self.assertEqual(args.deprecation_reason, reason)

def test_mandatory_arg_group_both(self):
testfile = "testfile.nasl"
reason = "NOTUS"

with (
TemporaryDirectory() as out_dir,
TemporaryDirectory() as in_dir,
):
with self.assertRaises(SystemExit):
parse_args(
[
"--files",
testfile,
"--input-path",
str(in_dir),
"--deprecation-reason",
reason,
"--output-path",
str(out_dir),
]
)

def test_invalid_reason(self):
output_path = "attic/"
input_path = "nasl/common"
reason = "foo"
with self.assertRaises(SystemExit):
parse_args(
[
"--output-path",
output_path,
"--input-path",
input_path,
"--deprecation-reason",
reason,
]
)

with TemporaryDirectory() as out_dir, TemporaryDirectory() as in_dir:
with self.assertRaises(SystemExit):
parse_args(
[
"--output-path",
str(out_dir),
"--input-path",
str(in_dir),
"--deprecation-reason",
reason,
]
)

def test_mandatory_arg_group_neither(self):
output_path = "attic/"
reason = "NOTUS"
with self.assertRaises(SystemExit):
parse_args(
[
"--output-path",
output_path,
"--deprecation-reason",
reason,
]
)
with TemporaryDirectory() as out_dir:
with self.assertRaises(SystemExit):
parse_args(
[
"--output-path",
str(out_dir),
"--deprecation-reason",
reason,
]
)


NASL_CONTENT = (
Expand Down
15 changes: 9 additions & 6 deletions tests/test_argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import tempfile
import unittest
from multiprocessing import cpu_count
from pathlib import Path
Expand Down Expand Up @@ -134,9 +135,9 @@ def test_parse_min_cpu(self):
self.assertEqual(parsed_args.n_jobs, cpu_count() // 2)

def test_parse_root(self):
parsed_args = parse_args(self.terminal, ["--root", "foo"])

self.assertEqual(parsed_args.root, Path("foo"))
with tempfile.TemporaryDirectory() as tmpdir:
parsed_args = parse_args(self.terminal, ["--root", tmpdir])
self.assertEqual(parsed_args.root, Path(tmpdir))

def test_parse_fix(self):
parsed_args = parse_args(self.terminal, ["--fix"])
Expand All @@ -149,6 +150,8 @@ def test_parse_ignore_warnings(self):
self.assertTrue(parsed_args.ignore_warnings)

def test_parse_log_file_statistic(self):
parsed_args = parse_args(self.terminal, ["--log-file-statistic", "foo"])

self.assertEqual(parsed_args.log_file_statistic, Path("foo"))
with tempfile.NamedTemporaryFile() as tmpfile:
parsed_args = parse_args(
self.terminal, ["--log-file-statistic", str(tmpfile.name)]
)
self.assertEqual(parsed_args.log_file_statistic, Path(tmpfile.name))
Loading
Loading