Skip to content

Commit

Permalink
Add ProofRequiredError Exception and submit-challenge command
Browse files Browse the repository at this point in the history
  • Loading branch information
maltee1 committed Apr 24, 2023
1 parent 4e53aea commit 86fd9b9
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
13 changes: 13 additions & 0 deletions mausignald/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ class GroupPatchNotAcceptedError(ResponseError):
pass


class ProofRequiredError(ResponseError):
def __init__(self, data: dict[str, Any]) -> None:
self.options = data.get("options")
self.retry_after = data.get("retry_after")
self.token = data.get("token")
message = (
f"You have been rate-limited by Signal. Try again in {self.retry_after}"
"seconds or complete a captcha challenge using the `submit-challenge` command."
)
super().__init__(data, message_override=message)


response_error_types = {
"invalid_request": RequestValidationFailure,
"TimeoutException": TimeoutException,
Expand All @@ -134,6 +146,7 @@ class GroupPatchNotAcceptedError(ResponseError):
"ProfileUnavailableError": ProfileUnavailableError,
"NoSuchAccountError": NoSuchAccountError,
"GroupPatchNotAcceptedError": GroupPatchNotAcceptedError,
"ProofRequiredError": ProofRequiredError,
# TODO add rest from https://gitlab.com/signald/signald/-/tree/main/src/main/java/io/finn/signald/clientprotocol/v1/exceptions
}

Expand Down
7 changes: 7 additions & 0 deletions mausignald/signald.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,10 @@ async def find_uuid(self, username: str, number: str) -> UUID | None:
"resolve_address", partial=Address(number=number).serialize(), account=username
)
return Address.deserialize(resp).uuid

async def submit_challenge(
self, username: str, captcha_token: str | None, challenge: str | None
) -> None:
await self.request_v1(
"submit_challenge", account=username, captcha_token=captcha_token, challenge=challenge
)
28 changes: 28 additions & 0 deletions mautrix_signal/commands/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,34 @@ async def confirm_bridge(evt: CommandEvent) -> EventID | None:
)


@command_handler(
needs_auth=True,
management_only=False,
help_section=SECTION_SIGNAL,
help_text="Submit a captcha challenge for the last occuring token",
help_args="<captcha token>",
)
async def submit_challenge(evt: CommandEvent) -> None:
challenge_token = evt.sender.challenge_token
captcha_token = evt.args[0]
if not challenge_token:
return await evt.reply(
"No open challenge found. If the bridge was restarted, try"
"triggering another ProofRequiredError"
)
if not captcha_token:
return await evt.reply("**Usage:** `$cmdprefix+sp captcha-challenge <captcha-token>`")
try:
await evt.bridge.signal.submit_challenge(
evt.sender.username, captcha_token=evt.args[0], challenge=challenge_token
)
except Exception as e:
await evt.reply(f"failed to submit captcha challenge: {e}")
return
await evt.reply("Captcha challenge submitted successfully")
return


async def _locked_confirm_bridge(
evt: CommandEvent, portal: po.Portal, room_id: RoomID, is_logged_in: bool
) -> EventID | None:
Expand Down
3 changes: 3 additions & 0 deletions mautrix_signal/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
GroupPatchNotAcceptedError,
NotConnected,
ProfileUnavailableError,
ProofRequiredError,
RPCError,
)
from mausignald.types import (
Expand Down Expand Up @@ -328,6 +329,8 @@ async def handle_matrix_message(
status, event_id, self.mxid, EventType.ROOM_MESSAGE, message.msgtype, error=e
)
await sender.handle_auth_failure(e)
if isinstance(e, ProofRequiredError):
sender.challenge_token = e.token
await self._send_error_notice("message", e)
background_task.create(self._send_message_status(event_id, e))

Expand Down
2 changes: 2 additions & 0 deletions mautrix_signal/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class User(DBUser, BaseUser):
_websocket_connection_state: BridgeStateEvent | None
_latest_non_transient_bridge_state: datetime | None

challenge_token: str | None

def __init__(
self,
mxid: UserID,
Expand Down

0 comments on commit 86fd9b9

Please sign in to comment.