curious-greg/web.py
2018-11-10 22:56:45 +10:00

100 lines
4 KiB
Python
Executable file

#!/usr/bin/env python3
#Curious Greg - Curious Cat to Mastodon crossposter
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import requests, json, hashlib, urllib
from mastodon import Mastodon
from flask import Flask, render_template, request, session, redirect, url_for
import mysql.connector
import bcrypt
cfg = json.load(open("meta.json"))
scopes = ["read:accounts", "write:statuses"]
db = mysql.connector.connect(user=cfg['dbuser'], password=cfg['dbpass'], database=cfg['dbname'])
c = db.cursor()
c.execute("CREATE TABLE IF NOT EXISTS `data` (username TINYTEXT NOT NULL, instance TINYTEXT NOT NULL, password TINYTEXT NOT NULL, avi TEXT NOT NULL, secret TINYTEXT NOT NULL, client_id TINYTEXT NOT NULL, client_secret TINYTEXT NOT NULL, cc TINYTEXT, latest_post TINYTEXT, latest_timestamp TIMESTAMP, time_between_checks INT)")
app = Flask(cfg['name'])
app.secret_key = cfg['flask_key']
@app.route('/')
def main():
if 'acct' not in session:
return render_template("landing_page.html")
else:
return redirect(url_for('home'))
@app.route('/home')
def home():
if 'acct' in session:
acct = session['acct']
return render_template("home.html", acct=acct)
else:
return redirect(url_for('main'))
@app.route('/debug') #TODO: remove this before making the site live ;p
def print_debug_info():
return json.dumps(session._get_current_object())
@app.route('/login')
def log_in():
if 'acct' in session:
#user is probably already logged in. if they aren't, home() will handle things and redirect them back here
return redirect(url_for('home'))
return render_template("login.html")
# return(json.dumps(client_info))
#internal stuff
@app.route('/internal/auth_a')
def internal_auth_a(): #TODO: prevent these endpoints from being spammed somehow
session['instance_url'] = request.args.get('instance', default='mastodon.social', type=str)
if not session['instance_url'].startswith("https://"):
session['instance_url'] = "https://{}".format(session['instance_url'])
session['client_id'], session['client_secret'] = Mastodon.create_app(cfg['name'],
api_base_url=session['instance_url'],
scopes=scopes,
website=cfg['website'],
redirect_uris=['https://cg.lynnesbian.space/internal/auth_b', 'http://localhost:5000/internal/auth_b']
)
client = Mastodon(client_id=session['client_id'], client_secret=session['client_secret'], api_base_url=session['instance_url'])
url = client.auth_request_url(client_id=session['client_id'], redirect_uris='http://localhost:5000/internal/auth_b', scopes=scopes)
return redirect(url, code=307)
@app.route('/internal/auth_b')
def internal_auth_b():
#write details to DB
client = Mastodon(client_id=session['client_id'], client_secret=session['client_secret'], api_base_url=session['instance_url'])
session['secret'] = client.log_in(code = request.args.get('code'), scopes=scopes, redirect_uri='http://localhost:5000/internal/auth_b')
acct_info = client.account_verify_credentials()
session['username'] = acct_info['username']
session['avi'] = acct_info['avatar']
session['acct'] = "@{}@{}".format(session['username'], session['instance_url'].replace("https://", ""))
if c.execute("SELECT COUNT(*) FROM data WHERE username LIKE ? AND instance LIKE ?", (session['username'], session['instance_url'])).fetchone()[0] > 0:
#user already has an account with CG
return redirect(url_for('log_in'))
else:
return redirect(url_for('home'))
@app.route('/internal/do_login')
def do_login():
pass
@app.route('/create_password')
def create_password():
return render_template("create_password.html")
@app.route('/internal/create_account', methods=['POST'])
def create_account():
pw = bcrypt.hashpw(request.form['pw'], bcrypt.gensalt(15))
c.execute("INSERT INTO data (username, instance, avi, password, secret, client_id, client_secret) VALUES (?, ?, ?, ?, ?)", (session['username'], pw, session['instance_url'], session['secret'], session['client_id'], session['client_secret']))
db.commit()