Enhance Pantalaimon integration and config

Integrated Pantalaimon support with updated configuration instructions and examples, facilitating secure communication when using the Matrix homeserver. The .gitignore is now extended to exclude a Pantalaimon configuration file, preventing sensitive information from accidental commits. Removed encryption callbacks and related functions as the application leverages Pantalaimon for E2EE, simplifying the codebase and shifting encryption responsibilities externally. Streamlined dependency management by removing the requirements.txt in favor of pyproject.toml, aligning with modern Python practices. This change overall improves security handling and eases future maintenance.
This commit is contained in:
Kumi 2023-12-05 10:09:14 +01:00
parent 4eb33a3c0a
commit 57b68ef3e3
Signed by: kumi
GPG key ID: ECBCC9082395383F
11 changed files with 50 additions and 157 deletions

3
.gitignore vendored
View file

@ -6,4 +6,5 @@ venv/
*.pyc
__pycache__/
*.bak
dist/
dist/
pantalaimon.conf

View file

@ -129,6 +129,9 @@ APIKey = sk-yoursecretkey
# The URL to your Matrix homeserver
#
# If you are using Pantalaimon, this should be the URL of your Pantalaimon
# instance, not the Matrix homeserver itself.
#
Homeserver = https://matrix.local
# An Access Token for the user your bot runs as

5
pantalaimon.example.conf Normal file
View file

@ -0,0 +1,5 @@
[Homeserver]
Homeserver = https://example.com
ListenAddress = localhost
ListenPort = 8010
IgnoreVerification = True

View file

@ -0,0 +1,22 @@
from nio import AsyncClient
from configparser import ConfigParser
async def main():
config = ConfigParser()
config.read("config.ini")
user_id = input("User ID: ")
password = input("Password: ")
client = AsyncClient(config["Matrix"]["Homeserver"])
client.user = user_id
await client.login(password)
print("Access token: " + client.access_token)
await client.close()
if __name__ == "__main__":
import asyncio
asyncio.get_event_loop().run_until_complete(main())

View file

@ -50,8 +50,12 @@ trackingmore = [
"trackingmore @ git+https://kumig.it/kumitterer/trackingmore-api-tool.git",
]
e2ee = [
"pantalaimon",
]
all = [
"matrix-gptbot[openai,wolframalpha,trackingmore]",
"matrix-gptbot[openai,wolframalpha,trackingmore,e2ee]",
"geopy",
"beautifulsoup4",
]

View file

@ -1,11 +0,0 @@
openai>=1.2
matrix-nio[e2e]
markdown2[all]
tiktoken
duckdb
python-magic
pillow
wolframalpha
pydub
git+https://kumig.it/kumitterer/trackingmore-api-tool.git

View file

@ -16,15 +16,12 @@ from .invite import room_invite_callback
from .join import join_callback
from .message import message_callback
from .roommember import roommember_callback
from .encrypted import encrypted_message_callback
from .keys import keys_query_callback
from .test_response import test_response_callback
RESPONSE_CALLBACKS = {
#Response: test_response_callback,
SyncResponse: sync_callback,
JoinResponse: join_callback,
#KeysQueryResponse: keys_query_callback,
}
EVENT_CALLBACKS = {
@ -32,5 +29,4 @@ EVENT_CALLBACKS = {
InviteEvent: room_invite_callback,
RoomMessageText: message_callback,
RoomMemberEvent: roommember_callback,
#MegolmEvent: encrypted_message_callback,
}

View file

@ -1,21 +0,0 @@
from nio import RoomMessage
async def encrypted_message_callback(room, event, bot):
try:
# Request room key from server
room_key = await bot.matrix_client.request_room_key(room.room_id)
# Attempt to decrypt the event
decrypted_event = await bot.matrix_client.decrypt_event(event)
# Check if decryption was successful and the decrypted event has a new type
if isinstance(decrypted_event, RoomMessage):
# Send the decrypted event back to _event_callback for further processing
await bot._event_callback(room, decrypted_event)
else:
# Handle other decrypted event types or log a message
bot.logger.log(f"Decrypted event of type {type(decrypted_event)}", "info")
except Exception as e:
bot.logger.log(f"Error decrypting event: {e}", "error")
await bot.send_message(room.room_id, "Sorry, I was unable to decrypt your message. Please try again, or use an unencrypted room.", True)

View file

@ -1,14 +0,0 @@
from nio.crypto.device import OlmDevice
async def keys_query_callback(response, bot):
bot.matrix_client.receive_response(response)
try:
for user_id, device_dict in response.device_keys.items():
for device_id, keys in device_dict.items():
bot.logger.log(f"New keys for {device_id} from {user_id}: {keys}", "info")
device = OlmDevice(user_id, device_id, keys)
await bot.matrix_client.verify_device(device)
except Exception as e:
bot.logger.log(f"Error handling KeysQueryResponse: {e}", "error")
raise

View file

@ -15,7 +15,6 @@ from nio import (
MatrixRoom,
Api,
RoomMessagesError,
MegolmEvent,
GroupEncryptionError,
EncryptionError,
RoomMessageText,
@ -33,12 +32,9 @@ from nio import (
RoomMessageAudio,
DownloadError,
DownloadResponse,
RoomKeyRequest,
RoomKeyRequestError,
ToDeviceEvent,
ToDeviceError,
)
from nio.crypto import Olm
from nio.store import SqliteStore
@ -71,7 +67,7 @@ from .trackingmore import TrackingMore
class GPTBot:
# Default values
database: Optional[sqlite3.Connection] = None
crypto_store_path: Optional[str | Path] = None
database_path: Optional[str | Path] = None
matrix_client: Optional[AsyncClient] = None
sync_token: Optional[str] = None
logger: Optional[Logger] = Logger()
@ -207,15 +203,14 @@ class GPTBot:
bot.config = config
# Set the database connection
bot.database = (
sqlite3.connect(config["Database"]["Path"])
bot.database_path = (
config["Database"]["Path"]
if "Database" in config and "Path" in config["Database"]
else None
)
bot.crypto_store_path = (
config["Database"]["CryptoStore"]
if "Database" in config and "CryptoStore" in config["Database"]
bot.database = (
sqlite3.connect(bot.database_path)
if bot.database_path
else None
)
@ -316,26 +311,6 @@ class GPTBot:
if len(messages) >= n:
break
if isinstance(event, ToDeviceEvent):
try:
event = await self.matrix_client.decrypt_to_device_event(event)
except ToDeviceError:
self.logger.log(
f"Could not decrypt message {event.event_id} in room {room_id}",
"error",
)
continue
if isinstance(event, MegolmEvent):
try:
event = await self.matrix_client.decrypt_event(event)
except (GroupEncryptionError, EncryptionError):
self.logger.log(
f"Could not decrypt message {event.event_id} in room {room_id}",
"error",
)
continue
if isinstance(event, RoomMessageText):
if event.body.startswith("!gptbot ignoreolder"):
break
@ -753,36 +728,6 @@ class GPTBot:
content = None
if self.matrix_client.olm and room.encrypted:
try:
if not room.members_synced:
responses = []
responses.append(
await self.matrix_client.joined_members(room.room_id)
)
if self.matrix_client.olm.should_share_group_session(room.room_id):
try:
event = self.matrix_client.sharing_session[room.room_id]
await event.wait()
except KeyError:
await self.matrix_client.share_group_session(
room.room_id,
ignore_unverified_devices=True,
)
if msgtype != "m.reaction":
response = self.matrix_client.encrypt(
room.room_id, "m.room.message", msgcontent
)
msgtype, content = response
except Exception as e:
self.logger.log(
f"Error encrypting message: {e} - sending unencrypted", "warning"
)
raise
if not content:
msgtype = "m.room.message"
content = msgcontent
@ -843,16 +788,8 @@ class GPTBot:
if not self.matrix_client.device_id:
self.matrix_client.device_id = await self._get_device_id()
# Set up database
IN_MEMORY = False
if not self.database:
self.logger.log(
"No database connection set up, using in-memory database. Data will be lost on bot shutdown.",
"warning",
)
IN_MEMORY = True
self.database = sqlite3.connect(":memory:")
self.database = sqlite3.connect(Path(__file__).parent.parent / "database.db")
self.logger.log("Running migrations...")
@ -872,34 +809,13 @@ class GPTBot:
else:
self.logger.log(f"Already at latest version {after}.")
if IN_MEMORY:
client_config = AsyncClientConfig(
store_sync_tokens=True, encryption_enabled=False
)
else:
matrix_store = SqliteStore
client_config = AsyncClientConfig(
store_sync_tokens=True, encryption_enabled=True, store=matrix_store
)
self.matrix_client.config = client_config
self.matrix_client.store = matrix_store(
self.matrix_client.user_id,
self.matrix_client.device_id,
'.', #store path
database_name=self.crypto_store_path or "",
)
matrix_store = SqliteStore
client_config = AsyncClientConfig(
store_sync_tokens=True, encryption_enabled=False, store=matrix_store
)
self.matrix_client.config = client_config
self.matrix_client.olm = Olm(
self.matrix_client.user_id,
self.matrix_client.device_id,
self.matrix_client.store,
)
self.matrix_client.encrypted_rooms = (
self.matrix_client.store.load_encrypted_rooms()
)
# Run initial sync (now includes joining rooms)
# Run initial sync (includes joining rooms)
sync = await self.matrix_client.sync(timeout=30000, full_state=True)
if isinstance(sync, SyncResponse):
await self.response_callback(sync)
@ -944,14 +860,6 @@ class GPTBot:
self.logger.log("Syncing one last time...", "warning")
await self.matrix_client.sync(timeout=30000, full_state=True)
async def request_keys(session_id, room_id):
request = RoomKeyRequest(session_id, room_id)
response = await client.send(request)
if isinstance(response, RoomKeyRequestError):
print(f"Failed to request keys for session {session_id}: {response.message}")
else:
print(f"Requested keys for session {session_id}")
async def create_space(self, name, visibility=RoomVisibility.private) -> str:
"""Create a space.