Skip to content

Commit

Permalink
squashme move tests and try mypy stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
half-duplex committed Nov 12, 2023
1 parent 746e614 commit ca33e00
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 212 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ lint-style:
flake8

lint-type:
mypy --check-untyped-defs sopel
mypy sopel

.PHONY: test test_norecord test_novcr vcr_rerecord
test:
Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ sopel-plugins = "sopel.cli.plugins:main"
[project.entry-points.pytest11]
pytest-sopel = "sopel.tests.pytest_plugin"

[tool.mypy]
check_untyped_defs = true

[[tool.mypy.overrides]]
module = 'scramp.*'
ignore_missing_imports = true

[tool.pytest.ini_options]
# NOTE: sopel/ is included here to include dynamically-generated tests
testpaths = ["test", "sopel"]
Expand Down
1 change: 0 additions & 1 deletion sopel/coretasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ def _handle_sasl_capability(
auth_target = bot.settings.core.auth_target
is_required = 'sasl' in (auth_method, server_auth_method)

LOGGER.critical("FOO. BAR!")
if not is_required:
# not required: we are fine, available or not
return plugin.CapabilityNegotiation.DONE
Expand Down
200 changes: 200 additions & 0 deletions test/coretasks/test_coretasks_sasl.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""Test behavior of SASL by ``sopel.coretasks``"""
from __future__ import annotations

from base64 import b64decode, b64encode
from typing import TYPE_CHECKING

import pytest
from scramp import ScramMechanism

from sopel import coretasks
from sopel.tests import rawlist

if TYPE_CHECKING:
from sopel.bot import Sopel
from sopel.config import Config
from sopel.tests.factories import BotFactory, ConfigFactory

Expand Down Expand Up @@ -344,3 +347,200 @@ def test_sasl_nak(botfactory: BotFactory, tmpconfig) -> None:
'CAP END',
'QUIT :Error negotiating capabilities.',
)


def test_sasl_bad_method(mockbot: Sopel):
"""Verify the bot behaves when configured with an unsupported SASL method."""
mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-MD4"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
assert mockbot.backend.message_sent == rawlist(
"CAP REQ :sasl",
"CAP END",
)
# with pytest.raises(Exception): # ASDF TODO
mockbot.on_message("AUTHENTICATE +")


def test_sasl_plain_auth(mockbot: Sopel):
"""Verify the bot performs SASL PLAIN auth correctly."""
mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "PLAIN"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
assert mockbot.backend.message_sent == rawlist(
"CAP REQ :sasl",
"AUTHENTICATE PLAIN",
)
mockbot.on_message("AUTHENTICATE +")
assert (
len(mockbot.backend.message_sent) == 3
and mockbot.backend.message_sent[-1]
== rawlist("AUTHENTICATE VGVzdEJvdABUZXN0Qm90AGh1bnRlcjI=")[0]
)
mockbot.on_message(
"900 TestBot test!test@test TestBot :You are now logged in as TestBot"
)
mockbot.on_message("903 TestBot :SASL authentication succeeded")
assert (
len(mockbot.backend.message_sent) == 4
and mockbot.backend.message_sent[-1] == rawlist("CAP END")[0]
)


def test_sasl_scram_sha_256_auth(mockbot: Sopel):
"""Verify the bot performs SASL SCRAM-SHA-256 auth correctly."""
mech = ScramMechanism()
salt, stored_key, server_key, iter_count = mech.make_auth_info(
"hunter2", iteration_count=5000
)
scram_server = mech.make_server(
lambda x: (salt, stored_key, server_key, iter_count)
)

mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-SHA-256"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
assert mockbot.backend.message_sent == rawlist(
"CAP REQ :sasl",
"AUTHENTICATE SCRAM-SHA-256",
)
mockbot.on_message("AUTHENTICATE +")

scram_server.set_client_first(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message(
"AUTHENTICATE "
+ b64encode(scram_server.get_server_first().encode("utf-8")).decode("utf-8")
)
scram_server.set_client_final(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message(
"AUTHENTICATE "
+ b64encode(scram_server.get_server_final().encode("utf-8")).decode("utf-8")
)
assert (
len(mockbot.backend.message_sent) == 5
and mockbot.backend.message_sent[-1] == rawlist("AUTHENTICATE +")[0]
)

mockbot.on_message(
"900 TestBot test!test@test TestBot :You are now logged in as TestBot"
)
mockbot.on_message("903 TestBot :SASL authentication succeeded")
assert (
len(mockbot.backend.message_sent) == 6
and mockbot.backend.message_sent[-1] == rawlist("CAP END")[0]
)


def test_sasl_scram_sha_256_nonsense_server_first(mockbot: Sopel):
"""Verify the bot handles a nonsense SCRAM-SHA-256 server_first correctly."""
mech = ScramMechanism()
salt, stored_key, server_key, iter_count = mech.make_auth_info(
"hunter2", iteration_count=5000
)
scram_server = mech.make_server(
lambda x: (salt, stored_key, server_key, iter_count)
)

mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-SHA-256"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
mockbot.on_message("AUTHENTICATE +")

scram_server.set_client_first(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message("AUTHENTICATE " + b64encode(b"junk").decode("utf-8"))
assert (
len(mockbot.backend.message_sent) == 4
and mockbot.backend.message_sent[-1] == rawlist("AUTHENTICATE *")[0]
)


def test_sasl_scram_sha_256_nonsense_server_final(mockbot: Sopel):
"""Verify the bot handles a nonsense SCRAM-SHA-256 server_final correctly."""
mech = ScramMechanism()
salt, stored_key, server_key, iter_count = mech.make_auth_info(
"hunter2", iteration_count=5000
)
scram_server = mech.make_server(
lambda x: (salt, stored_key, server_key, iter_count)
)

mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-SHA-256"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
mockbot.on_message("AUTHENTICATE +")

scram_server.set_client_first(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message(
"AUTHENTICATE "
+ b64encode(scram_server.get_server_first().encode("utf-8")).decode("utf-8")
)
scram_server.set_client_final(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message("AUTHENTICATE " + b64encode(b"junk").decode("utf-8"))
assert (
len(mockbot.backend.message_sent) == 5
and mockbot.backend.message_sent[-1] == rawlist("AUTHENTICATE *")[0]
)


def test_sasl_scram_sha_256_error_server_first(mockbot: Sopel):
"""Verify the bot handles an error SCRAM-SHA-256 server_first correctly."""

mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-SHA-256"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
mockbot.on_message("AUTHENTICATE +")

mockbot.on_message("AUTHENTICATE " + b64encode(b"e=some-error").decode("utf-8"))
assert (
len(mockbot.backend.message_sent) == 4
and mockbot.backend.message_sent[-1] == rawlist("AUTHENTICATE *")[0]
)


def test_sasl_scram_sha_256_error_server_final(mockbot: Sopel):
"""Verify the bot handles an error SCRAM-SHA-256 server_final correctly."""
mech = ScramMechanism()
salt, stored_key, server_key, iter_count = mech.make_auth_info(
"hunter2", iteration_count=5000
)
scram_server = mech.make_server(
lambda x: (salt, stored_key, server_key, iter_count)
)

mockbot.settings.core.auth_method = "sasl"
mockbot.settings.core.auth_target = "SCRAM-SHA-256"
mockbot.on_message("CAP * LS :sasl")
mockbot.on_message("CAP TestBot ACK :sasl")
mockbot.on_message("AUTHENTICATE +")

scram_server.set_client_first(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message(
"AUTHENTICATE "
+ b64encode(scram_server.get_server_first().encode("utf-8")).decode("utf-8")
)
scram_server.set_client_final(
b64decode(mockbot.backend.message_sent[-1].split(b" ")[-1]).decode("utf-8")
)
mockbot.on_message("AUTHENTICATE " + b64encode(b"e=some-error").decode("utf-8"))
assert (
len(mockbot.backend.message_sent) == 5
and mockbot.backend.message_sent[-1] == rawlist("AUTHENTICATE *")[0]
)
Loading

0 comments on commit ca33e00

Please sign in to comment.