aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclarkzjw <[email protected]>2023-02-23 15:38:38 -0800
committerclarkzjw <[email protected]>2023-02-23 15:38:38 -0800
commit20b8220a12fc92f95ecae267ce4eb5a80584f564 (patch)
tree1090256b48a76aae7afe2e10b860a02b43790807
parent31a2d111d1c0ceb2ebfd5bb5daf4ee0ab2de4eb4 (diff)
parent4cee8500a51aff6d0a445a3a6259cafed92d4845 (diff)
downloadswarm2fediverse-20b8220a12fc92f95ecae267ce4eb5a80584f564.tar.gz
Merge branch 'feature/encryption'
- bot: encrypt access_key with cryptography.fernet library
-rw-r--r--README.md1
-rw-r--r--bot.py5
-rw-r--r--callback.py22
-rw-r--r--config.ini.example1
-rw-r--r--config.py2
-rw-r--r--dbstore/peewee_store.py6
-rw-r--r--util.py18
7 files changed, 36 insertions, 19 deletions
diff --git a/README.md b/README.md
index 4d71069..4881eb8 100644
--- a/README.md
+++ b/README.md
@@ -24,4 +24,3 @@ Foursquare Swarm like Telegram bot to check in at places and post to Fediverse (
24- [ ] add Telegram payment option to enable raw GPS checkins 24- [ ] add Telegram payment option to enable raw GPS checkins
25- [ ] i18n 25- [ ] i18n
26- [ ] Anonymized usage analysis, monitoring (Grafana/Prometheus) 26- [ ] Anonymized usage analysis, monitoring (Grafana/Prometheus)
27
diff --git a/bot.py b/bot.py
index 45b2af7..7d10ddd 100644
--- a/bot.py
+++ b/bot.py
@@ -4,7 +4,7 @@ import asyncio
4import logging 4import logging
5from dataclasses import dataclass 5from dataclasses import dataclass
6from http import HTTPStatus 6from http import HTTPStatus
7from config import BOT_TOKEN, TELEGRAM_WEBHOOK_URL, HEALTHCHECK_URL, FEDI_LOGIN_CALLBACK_URL, BOT_DOMAIN, BOT_PORT 7from config import BOT_TOKEN, TELEGRAM_WEBHOOK_URL, HEALTHCHECK_URL, FEDI_LOGIN_CALLBACK_URL, BOT_DOMAIN, BOT_PORT, ENCRYPT_KEY
8import uvicorn 8import uvicorn
9from starlette.applications import Starlette 9from starlette.applications import Starlette
10from starlette.requests import Request 10from starlette.requests import Request
@@ -61,6 +61,7 @@ from config import (
61from prompt.string import PROMPT_CHOOSE_ACTION 61from prompt.string import PROMPT_CHOOSE_ACTION
62from mastodon import Mastodon 62from mastodon import Mastodon
63from dbstore.peewee_store import db, User, get_user_by_state 63from dbstore.peewee_store import db, User, get_user_by_state
64from util import encrypt, decrypt
64 65
65logging.basicConfig( 66logging.basicConfig(
66 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO 67 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
@@ -104,7 +105,7 @@ async def process_oauth_login_callback(update: FediLoginCallbackUpdate, context:
104 redirect_uri="{}{}".format(BOT_DOMAIN, FEDI_LOGIN_CALLBACK_URL), 105 redirect_uri="{}{}".format(BOT_DOMAIN, FEDI_LOGIN_CALLBACK_URL),
105 scopes=BOT_SCOPE 106 scopes=BOT_SCOPE
106 ) 107 )
107 user.access_key = access_token 108 user.access_key = encrypt(access_token, ENCRYPT_KEY)
108 user.save() 109 user.save()
109 110
110 text = "You have successfully logged in to your Mastodon account!" 111 text = "You have successfully logged in to your Mastodon account!"
diff --git a/callback.py b/callback.py
index d968523..a1b4b2d 100644
--- a/callback.py
+++ b/callback.py
@@ -9,10 +9,11 @@ from command import *
9from dbstore.peewee_store import get_poi_by_fsq_id 9from dbstore.peewee_store import get_poi_by_fsq_id
10from foursquare.poi import OSM_ENDPOINT 10from foursquare.poi import OSM_ENDPOINT
11from foursquare.poi import query_poi 11from foursquare.poi import query_poi
12from config import BOT_SCOPE 12from config import BOT_SCOPE, ENCRYPT_KEY
13from dbstore.peewee_store import User, db, TOOT_VISIBILITY_PRIVATE, TOOT_VISIBILITY_PUBLIC, TOOT_VISIBILITY_UNLISTED 13from dbstore.peewee_store import User, db, TOOT_VISIBILITY_PRIVATE, TOOT_VISIBILITY_PUBLIC, TOOT_VISIBILITY_UNLISTED
14import uuid 14import uuid
15from mastodon import Mastodon 15from mastodon import Mastodon
16from util import decrypt
16 17
17 18
18def generate_uuid(): 19def generate_uuid():
@@ -23,7 +24,7 @@ def get_mastodon_client(user_id: int):
23 with db.connection_context(): 24 with db.connection_context():
24 user = User.get(User.telegram_user_id == user_id) 25 user = User.get(User.telegram_user_id == user_id)
25 if user.home_instance and user.access_key: 26 if user.home_instance and user.access_key:
26 return Mastodon(access_token=user.access_key, api_base_url=user.home_instance) 27 return Mastodon(access_token=decrypt(user.access_key, ENCRYPT_KEY), api_base_url=user.home_instance)
27 28
28 29
29def generate_toot_text(poi_name, poi_locality, poi_region, poi_lat, poi_lon): 30def generate_toot_text(poi_name, poi_locality, poi_region, poi_lat, poi_lon):
@@ -85,21 +86,20 @@ async def callback_generate_fedi_login_url(update: Update, context: ContextTypes
85 user_id = update.effective_user.id 86 user_id = update.effective_user.id
86 state = generate_uuid() 87 state = generate_uuid()
87 88
88 db.connect() 89 with db.connection_context():
89 u = User.get_or_none(telegram_user_id=user_id) 90 u = User.get_or_none(telegram_user_id=user_id)
90 if u is None: 91 if u is None:
91 u = User.create(telegram_user_id=user_id, access_key="", home_instance=home_instance, 92 u = User.create(telegram_user_id=user_id, access_key="", home_instance=home_instance,
92 client_id=client_id, client_secret=client_secret, state=state) 93 client_id=client_id, client_secret=client_secret, state=state)
93 u.save() 94 u.save()
94 db.close()
95 95
96 oauth_url = m.auth_request_url(redirect_uris="{}{}".format(BOT_DOMAIN, FEDI_LOGIN_CALLBACK_URL), 96 oauth_url = m.auth_request_url(redirect_uris="{}{}".format(BOT_DOMAIN, FEDI_LOGIN_CALLBACK_URL),
97 scopes=BOT_SCOPE, 97 scopes=BOT_SCOPE,
98 state=state) 98 state=state)
99 99
100 msg = await update.message.reply_text(PROMPT_FEDI_LOGIN, 100 msg = await update.message.reply_text(PROMPT_FEDI_LOGIN,
101 reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Login", url=oauth_url)]]), 101 reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Login", url=oauth_url)]]),
102 parse_mode=ParseMode.MARKDOWN) 102 parse_mode=ParseMode.MARKDOWN)
103 103
104 context.user_data[PROMPT_FEDI_LOGIN] = msg.message_id 104 context.user_data[PROMPT_FEDI_LOGIN] = msg.message_id
105 return FEDI_LOGIN 105 return FEDI_LOGIN
diff --git a/config.ini.example b/config.ini.example
index 2efd6d5..e3a9121 100644
--- a/config.ini.example
+++ b/config.ini.example
@@ -1,3 +1,4 @@
1[DEFAULT] 1[DEFAULT]
2BOT_TOKEN = 2BOT_TOKEN =
3FOURSQUARE_API_KEY = 3FOURSQUARE_API_KEY =
4ENCRYPT_KEY =
diff --git a/config.py b/config.py
index b2025ca..83ee37a 100644
--- a/config.py
+++ b/config.py
@@ -8,7 +8,7 @@ config.read("config.ini")
8 8
9BOT_TOKEN = config["DEFAULT"]["BOT_TOKEN"] 9BOT_TOKEN = config["DEFAULT"]["BOT_TOKEN"]
10FSQ_API_KEY = config["DEFAULT"]["FOURSQUARE_API_KEY"] 10FSQ_API_KEY = config["DEFAULT"]["FOURSQUARE_API_KEY"]
11 11ENCRYPT_KEY = config["DEFAULT"]["ENCRYPT_KEY"]
12 12
13MEDIA_GROUP_TIMEOUT = 3 13MEDIA_GROUP_TIMEOUT = 3
14 14
diff --git a/dbstore/peewee_store.py b/dbstore/peewee_store.py
index d124de2..445816e 100644
--- a/dbstore/peewee_store.py
+++ b/dbstore/peewee_store.py
@@ -16,10 +16,8 @@ class BaseModel(Model):
16 16
17class User(BaseModel): 17class User(BaseModel):
18 telegram_user_id = CharField(unique=True, primary_key=True) 18 telegram_user_id = CharField(unique=True, primary_key=True)
19 # TODO: 19 access_key = CharField(max_length=256)
20 # add AES encryption to access_key 20 home_instance = CharField(max_length=256)
21 access_key = CharField(max_length=64)
22 home_instance = CharField(max_length=128)
23 state = CharField(max_length=128) 21 state = CharField(max_length=128)
24 client_id = CharField(max_length=128) 22 client_id = CharField(max_length=128)
25 client_secret = CharField(max_length=128) 23 client_secret = CharField(max_length=128)
diff --git a/util.py b/util.py
new file mode 100644
index 0000000..61efa0b
--- /dev/null
+++ b/util.py
@@ -0,0 +1,18 @@
1from cryptography.fernet import Fernet
2
3
4def encrypt(input: str, key: str) -> str:
5 f = Fernet(key)
6 return f.encrypt(bytes(input, 'utf-8')).decode('utf-8')
7
8
9def decrypt(input: str, key: str) -> str:
10 f = Fernet(key)
11 return f.decrypt(input).decode('utf-8')
12
13
14# if __name__ == "__main__":
15# key = Fernet.generate_key().decode('utf-8')
16# print(key)
17# print(encrypt("Hello World!", key))
18# print(decrypt(encrypt("Hello World!", key), key))
Powered by cgit v1.2.3 (git 2.41.0)