ticketfrei/frontend.py

181 lines
5.1 KiB
Python
Raw Normal View History

2018-03-28 22:12:19 +00:00
#!/usr/bin/env python3
2018-03-22 01:23:31 +00:00
import bottle
from bottle import get, post, redirect, request, response, view
2018-03-24 15:26:35 +00:00
from config import config
2018-03-28 15:36:35 +00:00
from db import db
2018-03-24 15:26:35 +00:00
import logging
import tweepy
from sendmail import sendmail
2018-03-28 15:36:35 +00:00
from session import SessionPlugin
from mastodon import Mastodon
2018-03-24 15:26:35 +00:00
2018-03-29 00:40:22 +00:00
def url(route):
2018-03-29 19:58:55 +00:00
return '%s://%s/%s' % (
request.urlparts.scheme,
request.urlparts.netloc,
route)
2018-03-29 00:40:22 +00:00
2018-03-22 01:23:31 +00:00
@get('/')
@view('template/propaganda.tpl')
def propaganda():
pass
2018-03-22 01:23:31 +00:00
2018-03-28 15:36:35 +00:00
@post('/register')
2018-03-22 01:23:31 +00:00
@view('template/register.tpl')
2018-03-28 15:36:35 +00:00
def register_post():
2018-04-14 15:53:08 +00:00
try:
email = request.forms['email']
password = request.forms['pass']
password_repeat = request.forms['pass-repeat']
except KeyError:
return dict(error='Please, fill the form.')
2018-03-22 01:23:31 +00:00
if password != password_repeat:
return dict(error='Passwords do not match.')
if db.by_email(email):
return dict(error='Email address already in use.')
# send confirmation mail
2018-03-28 23:13:53 +00:00
try:
sendmail(
email,
2018-03-29 00:40:22 +00:00
"Confirm your account",
"Complete your registration here: %s" % (
url('confirm/%s' % db.user_token(email, password))
2018-03-28 23:13:53 +00:00
)
)
return dict(info='Confirmation mail sent.')
except Exception:
2018-04-14 14:31:45 +00:00
logger.error("Could not send confirmation mail.", exc_info=True)
2018-03-28 23:13:53 +00:00
return dict(error='Could not send confirmation mail.')
2018-03-22 01:23:31 +00:00
2018-03-28 15:36:35 +00:00
@get('/confirm/<token>')
2018-03-22 01:23:31 +00:00
@view('template/propaganda.tpl')
2018-03-28 15:36:35 +00:00
def confirm(token):
2018-03-22 01:23:31 +00:00
# create db-entry
2018-03-28 15:36:35 +00:00
if db.confirm(token):
# :todo show info "Account creation successful."
2018-04-14 15:34:43 +00:00
redirect('/settings')
2018-03-28 15:36:35 +00:00
return dict(error='Email confirmation failed.')
2018-03-22 01:23:31 +00:00
2018-03-28 15:36:35 +00:00
@post('/login')
2018-03-22 01:23:31 +00:00
@view('template/login.tpl')
2018-03-28 15:36:35 +00:00
def login_post():
2018-03-22 01:23:31 +00:00
# check login
2018-03-28 23:13:53 +00:00
try:
2018-04-14 15:53:08 +00:00
if db.by_email(request.forms['email']) \
.check_password(request.forms['pass']):
2018-04-14 15:34:43 +00:00
redirect('/settings')
2018-04-14 15:53:08 +00:00
except KeyError:
return dict(error='Please, fill the form.')
2018-03-28 23:13:53 +00:00
except AttributeError:
pass
2018-03-29 19:58:55 +00:00
return dict(error='Authentication failed.')
2018-03-22 01:23:31 +00:00
2018-03-28 15:36:35 +00:00
@get('/settings')
2018-03-22 01:23:31 +00:00
@view('template/settings.tpl')
def settings(user):
return user.state()
2018-03-28 15:36:35 +00:00
@get('/api/state')
2018-03-22 01:23:31 +00:00
def api_enable(user):
return user.state()
@get('/static/<filename:path>')
def static(filename):
return bottle.static_file(filename, root='static')
@get('/logout/')
def logout():
# clear auth cookie
response.set_cookie('uid', '', expires=0, path="/")
# :todo show info "Logout successful."
2018-04-14 15:34:43 +00:00
redirect('/')
2018-03-22 01:23:31 +00:00
2018-03-28 15:36:35 +00:00
@get('/login/twitter')
def login_twitter(user):
"""
Starts the twitter OAuth authentication process.
:return: redirect to twitter.
"""
consumer_key = config["twitter"]["consumer_key"]
consumer_secret = config["twitter"]["consumer_secret"]
callback_url = url("login/twitter/callback")
auth = tweepy.OAuthHandler(consumer_key, consumer_secret, callback_url)
try:
redirect_url = auth.get_authorization_url()
except tweepy.TweepError:
logger.error('Twitter OAuth Error: Failed to get request token.',
exc_info=True)
return dict(error="Failed to get request token.")
user.save_request_token(auth.request_token)
2018-04-14 15:34:43 +00:00
redirect(redirect_url)
2018-03-28 15:36:35 +00:00
@get('/login/twitter/callback')
def twitter_callback(user):
"""
Gets the callback
:return:
"""
# twitter passes the verifier/oauth token secret in a GET request.
2018-03-24 15:26:35 +00:00
verifier = request.query('oauth_verifier')
2018-03-25 15:50:28 +00:00
consumer_key = config["twitter"]["consumer_key"]
consumer_secret = config["twitter"]["consumer_secret"]
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
request_token = user.get_request_token
auth.request_token = {"oauth_token": request_token,
"oauth_token_secret": verifier}
auth.get_access_token(verifier)
user.save_twitter_token(auth.access_token, auth.access_token_secret)
2018-04-14 15:34:43 +00:00
redirect("/settings")
2018-03-28 15:36:35 +00:00
@post('/login/mastodon')
def login_mastodon(user):
"""
Starts the mastodon OAuth authentication process.
:return: redirect to twitter.
"""
# get app tokens
2018-03-24 15:26:35 +00:00
instance_url = request.forms.get('instance_url')
masto_email = request.forms.get('email')
print(masto_email)
2018-03-24 15:26:35 +00:00
masto_pass = request.forms.get('pass')
print(masto_pass)
client_id, client_secret = user.get_mastodon_app_keys(instance_url)
2018-03-24 15:26:35 +00:00
m = Mastodon(client_id=client_id, client_secret=client_secret,
api_base_url=instance_url)
try:
access_token = m.log_in(masto_email, masto_pass)
user.save_masto_token(access_token, instance_url)
2018-03-24 15:26:35 +00:00
return dict(
info='Thanks for supporting decentralized social networks!'
)
2018-03-28 23:25:17 +00:00
except Exception:
2018-03-24 15:26:35 +00:00
logger.error('Login to Mastodon failed.', exc_info=True)
return dict(error='Login to Mastodon failed.')
logger = logging.getLogger()
2018-03-28 22:24:56 +00:00
fh = logging.StreamHandler()
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
2018-03-28 15:36:35 +00:00
application = bottle.default_app()
bottle.install(SessionPlugin('/'))
if __name__ == '__main__':
# testing only
bottle.run(host='localhost', port=8080)
else:
application.catchall = False