1
0
Fork 0
mirror of https://github.com/Lynnesbian/FediBooks/ synced 2024-11-25 16:48:58 +00:00

Compare commits

...

2 commits

4 changed files with 73 additions and 38 deletions

View file

@ -17,14 +17,14 @@ def bot_accounts_add(mysql, cfg):
error = "Incorrectly formatted handle." error = "Incorrectly formatted handle."
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
username = handle_list[1] session['username'] = handle_list[1]
instance = handle_list[2] session['instance'] = handle_list[2]
session['handle'] = request.form['account']
# gab check
try: try:
r = requests.get("https://{}/api/v1/instance".format(instance), timeout=10) r = requests.get("https://{}/api/v1/instance".format(session['instance']), timeout=10)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
error = "Couldn't connect to {}.".format(instance) error = "Couldn't connect to {}.".format(session['instance'])
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
except: except:
error = "An unknown error occurred." error = "An unknown error occurred."
@ -32,13 +32,56 @@ def bot_accounts_add(mysql, cfg):
if r.status_code == 200: if r.status_code == 200:
j = r.json() j = r.json()
if 'contact_account' in j and 'is_pro' in j['contact_account']: if "Pleroma" in j['version']:
# gab instance session['instance_type'] = "Pleroma"
error = "Gab instances are not supported." session['step'] += 1
return render_template("bot/accounts_add.html", error = error) else:
if 'contact_account' in j and 'is_pro' in j['contact_account']:
# gab instance
session['error'] = "Gab instances are not supported."
return render_template("bot/accounts_add.html", error = error)
else:
session['instance_type'] = "Mastodon"
session['step'] += 1
else:
error = "Unsupported instance type. Misskey support is planned."
return render_template("bot/accounts_add.html", error = error)
session['client_id'], session['client_secret'] = Mastodon.create_app(
"FediBooks User Authenticator",
api_base_url="https://{}".format(session['instance']),
scopes=["read:statuses"] if session['instance_type'] == 'Mastodon' else ["read"],
website=cfg['base_uri']
)
client = Mastodon(
client_id=session['client_id'],
client_secret=session['client_secret'],
api_base_url="https://{}".format(session['instance'])
)
session['url'] = client.auth_request_url(
client_id=session['client_id'],
scopes=["read:statuses"] if session['instance_type'] == 'Mastodon' else ["read"]
)
elif session['step'] == 2:
# test authentication
try:
client = Mastodon(client_id=session['client_id'], client_secret=session['client_secret'], api_base_url=session['instance'])
session['secret'] = client.log_in(
code = request.form['code'],
scopes=["read:statuses"] if session['instance_type'] == 'Mastodon' else ["read"],
)
client.account_verify_credentials()
except:
session['step'] = 1
error = "Authentication failed."
return render_template("bot/accounts_add.html", error = error)
# 1. download host-meta to find webfinger URL # 1. download host-meta to find webfinger URL
r = requests.get("https://{}/.well-known/host-meta".format(instance), timeout=10) r = requests.get("https://{}/.well-known/host-meta".format(session['instance']), timeout=10)
if r.status_code != 200: if r.status_code != 200:
error = "Couldn't get host-meta." error = "Couldn't get host-meta."
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
@ -47,7 +90,7 @@ def bot_accounts_add(mysql, cfg):
#TODO: use more reliable method #TODO: use more reliable method
try: try:
uri = re.search(r'template="([^"]+)"', r.text).group(1) uri = re.search(r'template="([^"]+)"', r.text).group(1)
uri = uri.format(uri = "{}@{}".format(username, instance)) uri = uri.format(uri = "{}@{}".format(session['username'], session['instance']))
except: except:
error = "Couldn't find WebFinger URL." error = "Couldn't find WebFinger URL."
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
@ -72,38 +115,18 @@ def bot_accounts_add(mysql, cfg):
# 3. format as outbox URL and check to make sure it works # 3. format as outbox URL and check to make sure it works
outbox = "{}/outbox?page=true".format(uri) outbox = "{}/outbox?page=true".format(uri)
r = requests.get(uri, headers={"Accept": "application/json"}, timeout=10) r = requests.get(outbox, headers={"Accept": "application/json,application/activity+json"}, timeout=10)
if r.status_code == 200: if r.status_code == 200:
# success!! # success!!
c = mysql.connection.cursor() c = mysql.connection.cursor()
c.execute("REPLACE INTO `fedi_accounts` (`handle`, `outbox`) VALUES (%s, %s)", (request.form['account'], outbox)) c.execute("REPLACE INTO `fedi_accounts` (`handle`, `outbox`) VALUES (%s, %s)", (session['handle'], outbox))
c.execute("INSERT INTO `bot_learned_accounts` (`bot_id`, `fedi_id`) VALUES (%s, %s)", (session['bot'], request.form['account'])) c.execute("INSERT INTO `bot_learned_accounts` (`bot_id`, `fedi_id`) VALUES (%s, %s)", (session['bot'], session['handle']))
c.close() c.close()
mysql.connection.commit() mysql.connection.commit()
if 'account' in cfg:
client = Mastodon(
cfg['account']['client_id'],
cfg['account']['client_secret'],
cfg['account']['secret'],
"https://{}".format(cfg['account']['instance'])
)
status = """
Hi, {user}. Someone has created a FediBooks bot that learns from your posts. The bot's username is {bot}. Your public posts are now being downloaded and stored for use by this bot.
If you do not want {bot} to learn from your posts, click here: {overview}
If you want to ensure that nobody can use {home} to create bots that use your post history, click here: {blacklist}
""".format(
user = request.form['account'],
bot = session['bot'].replace("@", "@\u200B"),
overview = "{}/overview/{}".format(cfg['base_uri'], request.form['account']),
blacklist = "{}/blacklist".format(cfg['base_uri']),
home = cfg['base_uri']
)
client.status_post(status)
return redirect("/bot/accounts/{}".format(session['bot']), 303) return redirect("/bot/accounts/{}".format(session['bot']), 303)
else: else:
error = "Couldn't access ActivityPub outbox. {} may require authenticated fetches, which FediBooks doesn't support yet.".format(instance) error = "Couldn't access ActivityPub outbox. {} may require authenticated fetches, which FediBooks doesn't support yet.".format(session['instance'])
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
else: else:
# new account add request # new account add request

View file

@ -100,8 +100,15 @@ def bot_create(mysql, cfg, scopes, scopes_pleroma):
session['step'] = 3 session['step'] = 3
return render_template("bot/create.html", error = error) return render_template("bot/create.html", error = error)
# authentication success!!
c = mysql.connection.cursor() c = mysql.connection.cursor()
c.execute("SELECT COUNT(*) FROM bots WHERE handle = %s", (handle,))
count = c.fetchone()
if count != None and count[0] == 1:
session['error'] = "{} is currently in use by another FediBooks bot.".format(handle)
session['step'] = 1
return redirect(url_for("render_bot_create"), 303)
# authentication success!!
c.execute("INSERT INTO `credentials` (client_id, client_secret, secret) VALUES (%s, %s, %s)", (session['client_id'], session['client_secret'], session['secret'])) c.execute("INSERT INTO `credentials` (client_id, client_secret, secret) VALUES (%s, %s, %s)", (session['client_id'], session['client_secret'], session['secret']))
credentials_id = c.lastrowid credentials_id = c.lastrowid
mysql.connection.commit() mysql.connection.commit()
@ -123,6 +130,7 @@ def bot_create(mysql, cfg, scopes, scopes_pleroma):
del session['instance_type'] del session['instance_type']
del session['client_id'] del session['client_id']
del session['client_secret'] del session['client_secret']
else: else:
# user is starting a new bot create request # user is starting a new bot create request
session['step'] = 1 session['step'] = 1

View file

@ -160,6 +160,7 @@ label.important {
margin: 10px 0; margin: 10px 0;
font-weight: 300; font-weight: 300;
display: block; display: block;
text-align: center;
} }
input, select, textarea { input, select, textarea {
font-size: 1.2em; font-size: 1.2em;

View file

@ -22,7 +22,10 @@
{% elif session['step'] == 2 %} {% elif session['step'] == 2 %}
<h2 class="thin centred">Authentication required</h2> <h2 class="thin centred">Authentication required</h2>
<p>{{ session['instance'] }} requires authentication to view public posts. Ensure you're signed in as {{ session['account'] }}, and click Next. You will be prompted to give FediBooks access to read your posts, which is required for your bot.</p> <p>You now need to authenticate with {{ session['instance'] }}. If {{ session['handle'] }} is your account, click "Open". If it's someone else's account, copy the URL in the box below and send it to them, and ask them to send you the code they receive.</p>
<input readonly value="{{ session['url'] }}"> <a href="{{ session['url'] }}" target="_blank" class="button btn-primary"><i class="fas fa-external-link-alt"></i>Open</a>
<p>After you've authenticated, paste the code returned by {{ session['instance'] }} into the textbox below.</p>
<input name="code" placeholder="OAuth code">
{% elif session['step'] == 3 %} {% elif session['step'] == 3 %}
@ -37,7 +40,7 @@
{% endif %} {% endif %}
<div class="container centred"> <div class="container centred">
<a href="/" class="button btn-secondary"><i class="fas fa-times"></i> Cancel</a> <a href="/bot/accounts/{{ session['bot'] }}" class="button btn-secondary"><i class="fas fa-times"></i> Cancel</a>
{% if session['step'] != 1 %} {% if session['step'] != 1 %}
<a href="/bot/accounts/add/back" class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</a> <a href="/bot/accounts/add/back" class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</a>
{% endif %} {% endif %}