forked from ticketfrei/ticketfrei
removed a lot of unnecessary clutter
This commit is contained in:
parent
17d044ec20
commit
a8efcd7825
2
appkeys/.gitignore
vendored
2
appkeys/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!.gitignore
|
2
appkeys/nbg_ticketfrei@chaos.social
Normal file
2
appkeys/nbg_ticketfrei@chaos.social
Normal file
|
@ -0,0 +1,2 @@
|
|||
63c8d9ad74e688ad1160c7b91a69d2bc91bf56ecb9dee13377a5cdf9320ad332
|
||||
7b4f452ef07ba0f045bea0420eac034a539236fa5bf994a6718b9bed06993722
|
|
@ -1,13 +0,0 @@
|
|||
bastard
|
||||
bitch
|
||||
whore
|
||||
hitler
|
||||
slut
|
||||
hure
|
||||
jude
|
||||
schwuchtel
|
||||
fag
|
||||
faggot
|
||||
nigger
|
||||
neger
|
||||
schlitz
|
0
frontend.py
Normal file → Executable file
0
frontend.py
Normal file → Executable file
|
@ -1,366 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import base64
|
||||
import bottle
|
||||
import sqlite3
|
||||
import sendmail
|
||||
import backend
|
||||
import jwt
|
||||
import pylibscrypt
|
||||
import smtplib
|
||||
import tweepy
|
||||
from mastodon import Mastodon
|
||||
# from bottle_auth import AuthPlugin
|
||||
|
||||
|
||||
class Datagetter(object):
|
||||
def __init__(self):
|
||||
self.db = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "ticketfrei.sqlite")
|
||||
self.conn = self.create_connection(self.db)
|
||||
self.cur = self.conn.cursor()
|
||||
|
||||
def create_connection(self, db_file):
|
||||
""" create a database connection to the SQLite database
|
||||
specified by the db_file
|
||||
:param db_file: database file
|
||||
:return: Connection object or None
|
||||
"""
|
||||
try:
|
||||
conn = sqlite3.connect(db_file)
|
||||
return conn
|
||||
except sqlite3.Error as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
|
||||
app = application = bottle.Bottle()
|
||||
|
||||
|
||||
@app.route('/login', method="POST")
|
||||
def login():
|
||||
"""
|
||||
Login to the ticketfrei account with credentials from the user table.
|
||||
|
||||
:return: bot.py Session Cookie
|
||||
"""
|
||||
email = bottle.request.forms.get('uname')
|
||||
psw = bottle.request.forms.get('psw')
|
||||
psw = psw.encode("utf-8")
|
||||
db.cur.execute("SELECT pass_hashed FROM user WHERE email=?;", (email, ))
|
||||
try:
|
||||
pass_hashed = db.cur.fetchone()[0]
|
||||
except TypeError:
|
||||
return "Wrong Credentials." # no user with this email
|
||||
if pylibscrypt.scrypt_mcf_check(pass_hashed, psw):
|
||||
bottle.response.set_cookie("account", email, secret)
|
||||
return bottle.redirect("/settings")
|
||||
else:
|
||||
return "Wrong Credentials." # passphrase is wrong
|
||||
|
||||
|
||||
@app.route('/register', method="POST")
|
||||
def register():
|
||||
"""
|
||||
Login to the ticketfrei account with credentials from the user table.
|
||||
|
||||
:return: bot.py Session Cookie
|
||||
"""
|
||||
email = bottle.request.forms.get('email')
|
||||
psw = bottle.request.forms.get('psw')
|
||||
pswrepeat = bottle.request.forms.get('psw-repeat')
|
||||
if pswrepeat != psw:
|
||||
return "ERROR: Passwords don't match. Try again."
|
||||
|
||||
# check if email is already in use
|
||||
db.cur.execute("SELECT id FROM user WHERE email=?;", (email,))
|
||||
if db.cur.fetchone() is not None:
|
||||
return "E-Mail is already in use." # account already exists
|
||||
|
||||
# hash and format for being encoded in the confirmation mail
|
||||
psw = psw.encode("utf-8")
|
||||
pass_hashed = pylibscrypt.scrypt_mcf(psw) # hash password
|
||||
pass_hashed = base64.encodebytes(pass_hashed)
|
||||
pass_hashed = pass_hashed.decode("ascii")
|
||||
payload = {"email": email, "pass_hashed": pass_hashed}
|
||||
|
||||
# create confirm_link
|
||||
encoded_jwt = jwt.encode(payload, secret).decode('utf-8')
|
||||
confirm_link = "http://" + bottle.request.get_header('host') + "/confirm/" + str(encoded_jwt) # :todo http -> https
|
||||
|
||||
# send the mail
|
||||
m = sendmail.Mailer(config)
|
||||
try:
|
||||
m.send("Complete your registration here: " + confirm_link, email, "[Ticketfrei] Confirm your account")
|
||||
except smtplib.SMTPRecipientsRefused:
|
||||
return "Please enter a valid E-Mail address."
|
||||
return "We sent you an E-Mail. Please click on the confirmation link."
|
||||
|
||||
|
||||
@app.route('/confirm/<encoded_jwt>', method="GET")
|
||||
def confirm_account(encoded_jwt):
|
||||
"""
|
||||
Confirm the account creation and create a database entry.
|
||||
:return: Redirection to bot.html
|
||||
"""
|
||||
# get values from URL
|
||||
payload = jwt.decode(encoded_jwt, secret)
|
||||
email = payload["email"]
|
||||
pass_hashed = base64.b64decode(payload["pass_hashed"])
|
||||
|
||||
# create db entry
|
||||
db.cur.execute("INSERT INTO user(email, pass_hashed, enabled) VALUES(?, ?, ?);", (email, pass_hashed, 1))
|
||||
# insert default good- & blacklist into db
|
||||
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "goodlists", "nbg_goodlist"),
|
||||
"r") as f:
|
||||
default_goodlist = f.read()
|
||||
db.cur.execute("INSERT INTO trigger_good(user_id, words) VALUES(?, ?);", (get_user_id(email), default_goodlist))
|
||||
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "blacklists", "nbg_blacklist"),
|
||||
"r") as f:
|
||||
default_blacklist = f.read()
|
||||
db.cur.execute("INSERT INTO trigger_bad(user_id, words) VALUES(?, ?);", (get_user_id(email), default_blacklist))
|
||||
db.conn.commit()
|
||||
bottle.response.set_cookie("account", email, secret, path="/")
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/settings')
|
||||
def manage_bot():
|
||||
"""
|
||||
Restricted area. Deliver the bot settings page.
|
||||
Deliver user settings with Cookies.
|
||||
:return: If it returns something, it just refreshes the page.
|
||||
"""
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
if email is not None:
|
||||
user_id = get_user_id(email)
|
||||
# get Enable Status from db
|
||||
db.cur.execute("SELECT enabled FROM user WHERE email = ?;", (email,))
|
||||
enabled = db.cur.fetchone()[0]
|
||||
# Set Enable Status with a Cookie
|
||||
resp = bottle.static_file("../static/bot.html", root='../static')
|
||||
if enabled:
|
||||
resp.set_cookie("enabled", "True")
|
||||
else:
|
||||
resp.set_cookie("enabled", "False")
|
||||
|
||||
# Get goodlist from db
|
||||
db.cur.execute("SELECT words FROM trigger_good WHERE user_id=?;", (user_id,))
|
||||
words = db.cur.fetchone()[0]
|
||||
# Deliver goodlist with a Cookie
|
||||
resp.set_cookie("goodlist", words, path="/settings")
|
||||
|
||||
# Get blacklist from db
|
||||
db.cur.execute("SELECT words FROM trigger_bad WHERE user_id=?;", (user_id,))
|
||||
words = db.cur.fetchone()[0]
|
||||
# Deliver badlist with a Cookie
|
||||
resp.set_cookie("blacklist", words, path="/settings")
|
||||
|
||||
return resp
|
||||
else:
|
||||
bottle.abort(401, "Wrong username or passphrase. Try again!")
|
||||
|
||||
|
||||
def get_user_id(email):
|
||||
# get user_id from email
|
||||
db.cur.execute("SELECT id FROM user WHERE email = ?", (email, ))
|
||||
return db.cur.fetchone()[0]
|
||||
|
||||
|
||||
@app.route('/settings/goodlist', method="POST")
|
||||
def update_goodlist():
|
||||
"""
|
||||
Writes the goodlist textarea on /settings to the database.
|
||||
This function expects a multi-line string, transmitted over the textarea form.
|
||||
:return: redirect to settings page
|
||||
"""
|
||||
# get new goodlist
|
||||
words = bottle.request.forms.get("goodlist")
|
||||
user_id = get_user_id(bottle.request.get_cookie("account", secret=secret))
|
||||
# write new goodlist to db
|
||||
db.cur.execute("UPDATE trigger_good SET words = ? WHERE user_id = ?;", (words, user_id, ))
|
||||
db.conn.commit()
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/settings/blacklist', method="POST")
|
||||
def update_blacklist():
|
||||
"""
|
||||
Writes the blacklist textarea on /settings to the database.
|
||||
This function expects a multi-line string, transmitted over the textarea form.
|
||||
:return: redirect to settings page
|
||||
"""
|
||||
# get new blacklist
|
||||
words = bottle.request.forms.get("blacklist")
|
||||
# get user_id
|
||||
user_id = get_user_id(bottle.request.get_cookie("account", secret=secret))
|
||||
# write new goodlist to db
|
||||
db.cur.execute("UPDATE trigger_bad SET words = ? WHERE user_id = ?;", (words, user_id, ))
|
||||
db.conn.commit()
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/enable', method="POST")
|
||||
def enable():
|
||||
"""
|
||||
Enable the bot. Called by the Enable button in bot.html
|
||||
:return: redirect to settings page
|
||||
"""
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
db.cur.execute("UPDATE user SET enabled = 1 WHERE email=?;", (email,))
|
||||
db.conn.commit()
|
||||
bottle.response.set_cookie("enabled", "True")
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/disable', method="POST")
|
||||
def disable():
|
||||
"""
|
||||
Disable the bot. Called by the Disable button in bot.html
|
||||
:return: redirect to settings page
|
||||
"""
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
db.cur.execute("UPDATE user SET enabled = 0 WHERE email=?;", (email,))
|
||||
db.conn.commit()
|
||||
bottle.response.set_cookie("enabled", "False")
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/login/twitter')
|
||||
def login_twitter():
|
||||
"""
|
||||
Starts the twitter OAuth authentication process.
|
||||
:return: redirect to twitter.
|
||||
"""
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
consumer_key = config["tapp"]["consumer_key"]
|
||||
consumer_secret = config["tapp"]["consumer_secret"]
|
||||
callback_url = host + "/login/twitter/callback"
|
||||
auth = tweepy.OAuthHandler(consumer_key, consumer_secret, callback_url)
|
||||
try:
|
||||
redirect_url = auth.get_authorization_url()
|
||||
except tweepy.TweepError:
|
||||
return 'Error! Failed to get request token.'
|
||||
db.cur.execute("INSERT INTO twitter_request_tokens(user_id, request_token) VALUES(?, ?);", (get_user_id(email), auth.request_token))
|
||||
db.conn.commit()
|
||||
return bottle.redirect(redirect_url)
|
||||
|
||||
|
||||
@app.route('/login/twitter/callback')
|
||||
def twitter_callback():
|
||||
"""
|
||||
Gets the callback
|
||||
:return:
|
||||
"""
|
||||
# twitter passes the verifier/oauth token secret in a GET request.
|
||||
verifier = bottle.request.query('oauth_verifier')
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
consumer_key = config["tapp"]["consumer_key"]
|
||||
consumer_secret = config["tapp"]["consumer_secret"]
|
||||
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
|
||||
db.cur.execute("SELECT request_token FROM twitter_request_tokens WHERE user_id = ?;", (get_user_id(email)))
|
||||
try:
|
||||
request_token = db.cur.fetchone()[0]
|
||||
except ValueError:
|
||||
return "Could not get request token from db."
|
||||
db.cur.execute("DELETE FROM twitter_request_tokens WHERE user_id = ?;", (get_user_id(email)))
|
||||
db.conn.commit()
|
||||
auth.request_token = { "oauth_token" : request_token,
|
||||
"oauth_token_secret" : verifier}
|
||||
try:
|
||||
auth.get_access_token(verifier)
|
||||
except tweepy.TweepError:
|
||||
print('Error! Failed to get access token.')
|
||||
db.cur.execute("INSERT INTO twitter_accounts(user_id, access_token_key, access_token_secret) VALUES(?, ?, ?);",
|
||||
(get_user_id(email), auth.access_token, auth.access_token_secret))
|
||||
db.conn.commit()
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
|
||||
@app.route('/login/mastodon', method="POST")
|
||||
def login_mastodon():
|
||||
"""
|
||||
Starts the mastodon OAuth authentication process.
|
||||
:return: redirect to twitter.
|
||||
"""
|
||||
email = bottle.request.get_cookie("account", secret=secret)
|
||||
|
||||
# get app tokens
|
||||
instance_url = bottle.request.forms.get('instance_url')
|
||||
db.cur.execute("SELECT client_id, client_secret FROM mastodon_instances WHERE instance = ?;", (instance_url))
|
||||
try:
|
||||
client_id, client_secret = db.cur.fetchone()[0]
|
||||
except TypeError:
|
||||
id = "ticketfrei" + str(secret)[0:4]
|
||||
client_id, client_secret = Mastodon.create_app(id, api_base_url=instance_url)
|
||||
db.cur.execute("INSERT INTO mastodon_instances(instance, client_id, client_secret) VALUES(?, ?, ?);",
|
||||
(instance_url, client_id, client_secret))
|
||||
db.conn.commit()
|
||||
|
||||
# get access token and write it to db
|
||||
uname = bottle.request.forms.get('uname')
|
||||
psw = bottle.request.forms.get('psw')
|
||||
mastodon = Mastodon(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
api_base_url=instance_url
|
||||
)
|
||||
access_token = mastodon.log_in(uname, psw)
|
||||
db.cur.execute("SELECT id FROM mastodon_instances WHERE instance = ?;", (instance_url))
|
||||
instance_id = db.cur.fetchone()[0]
|
||||
db.cur.execute("INSERT INTO mastodon_accounts(user_id, access_token, instance_id, active) VALUES(?, ?, ?, ?);",
|
||||
(get_user_id(email), access_token, instance_id, 1))
|
||||
return bottle.redirect("/settings")
|
||||
|
||||
@app.route('/static/<filename:path>')
|
||||
def static(filename):
|
||||
"""
|
||||
Serve static files
|
||||
"""
|
||||
if filename == "bot.html":
|
||||
bottle.abort(401, "Sorry, access denied.")
|
||||
return bottle.static_file(filename, root='../static')
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def show_index():
|
||||
"""
|
||||
The front "index" page
|
||||
:return: /static/index.html
|
||||
"""
|
||||
return bottle.static_file("../static/index.html", root='../static')
|
||||
|
||||
|
||||
class StripPathMiddleware(object):
|
||||
"""
|
||||
Get that slash out of the request
|
||||
"""
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
def __call__(self, e, h):
|
||||
e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')
|
||||
return self.a(e, h)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
global config
|
||||
config = backend.get_config()
|
||||
|
||||
global db
|
||||
global secret
|
||||
global twitter
|
||||
|
||||
secret = os.urandom(32)
|
||||
db = Datagetter()
|
||||
host = '0.0.0.0'
|
||||
|
||||
# from bottle_auth.social import twitter as twitterplugin
|
||||
# callback_url = host + '/login/twitter/callback'
|
||||
# twitter = twitterplugin.Twitter(config['tapp']['consumer_key'], config['tapp']['consumer_secret'], callback_url)
|
||||
# bottle.install(AuthPlugin(twitter))
|
||||
|
||||
try:
|
||||
bottle.run(app=StripPathMiddleware(app), host=host, port=8080)
|
||||
finally:
|
||||
db.conn.close()
|
|
@ -1,17 +0,0 @@
|
|||
kontroll?e
|
||||
konti
|
||||
db
|
||||
vgn
|
||||
vag
|
||||
zivil
|
||||
sicherheit
|
||||
uniform
|
||||
station
|
||||
bus
|
||||
bahn
|
||||
tram
|
||||
linie
|
||||
nuernberg
|
||||
nürnberg
|
||||
s\d
|
||||
u\d\d?
|
Loading…
Reference in a new issue