added twitter & masto OAuth to new web.py - untested, take care!
This commit is contained in:
parent
235b8524f8
commit
b9613a60de
49
db.py
49
db.py
|
@ -6,15 +6,13 @@ from os import path, urandom
|
||||||
from pylibscrypt import scrypt_mcf, scrypt_mcf_check
|
from pylibscrypt import scrypt_mcf, scrypt_mcf_check
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import pytoml as toml
|
import pytoml as toml
|
||||||
import sendmail
|
from mastodon import Mastodon
|
||||||
import smtplib
|
|
||||||
|
|
||||||
|
|
||||||
class DB(object):
|
class DB(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
dbfile = path.join(path.dirname(path.abspath(__file__)),
|
dbfile = path.join(path.dirname(path.abspath(__file__)),
|
||||||
'ticketfrei.sqlite')
|
'ticketfrei.sqlite')
|
||||||
#dbfile = ':memory:'
|
|
||||||
self.conn = sqlite3.connect(dbfile)
|
self.conn = sqlite3.connect(dbfile)
|
||||||
self.cur = self.conn.cursor()
|
self.cur = self.conn.cursor()
|
||||||
self.cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='user';")
|
self.cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='user';")
|
||||||
|
@ -132,13 +130,6 @@ class DB(object):
|
||||||
return None
|
return None
|
||||||
return User(self, row[0])
|
return User(self, row[0])
|
||||||
|
|
||||||
def send_confirmation_mail(self, confirm_link, email):
|
|
||||||
m = sendmail.Mailer(self.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."
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
|
|
||||||
|
@ -153,6 +144,44 @@ class User(object):
|
||||||
def state(self):
|
def state(self):
|
||||||
return dict(foo='bar')
|
return dict(foo='bar')
|
||||||
|
|
||||||
|
def save_request_token(self, token):
|
||||||
|
self.db.cur.execute("INSERT INTO twitter_request_tokens(user_id, request_token) VALUES(?, ?);",
|
||||||
|
(self.uid, token))
|
||||||
|
self.db.conn.commit()
|
||||||
|
|
||||||
|
def get_request_token(self):
|
||||||
|
self.db.cur.execute("SELECT request_token FROM twitter_request_tokens WHERE user_id = ?;", (id,))
|
||||||
|
request_token = self.db.cur.fetchone()[0]
|
||||||
|
self.db.cur.execute("DELETE FROM twitter_request_tokens WHERE user_id = ?;", (id,))
|
||||||
|
self.db.conn.commit()
|
||||||
|
return request_token
|
||||||
|
|
||||||
|
def save_twitter_token(self, access_token, access_token_secret):
|
||||||
|
self.db.cur.execute(
|
||||||
|
"INSERT INTO twitter_accounts(user_id, access_token_key, access_token_secret) VALUES(?, ?, ?);",
|
||||||
|
(id, access_token, access_token_secret))
|
||||||
|
self.db.conn.commit()
|
||||||
|
|
||||||
|
def get_mastodon_app_keys(self, instance):
|
||||||
|
self.db.cur.execute("SELECT client_id, client_secret FROM mastodon_instances WHERE instance = ?;", (instance, ))
|
||||||
|
try:
|
||||||
|
client_id, client_secret = self.db.cur.fetchone()[0]
|
||||||
|
return client_id, client_secret
|
||||||
|
except TypeError:
|
||||||
|
app_name = "ticketfrei" + str(self.db.secret)[0:4]
|
||||||
|
client_id, client_secret = Mastodon.create_app(app_name, api_base_url=instance)
|
||||||
|
self.db.cur.execute("INSERT INTO mastodon_instances(instance, client_id, client_secret) VALUES(?, ?, ?);",
|
||||||
|
(instance, client_id, client_secret))
|
||||||
|
self.db.conn.commit()
|
||||||
|
return client_id, client_secret
|
||||||
|
|
||||||
|
def save_masto_token(self, access_token, instance):
|
||||||
|
self.db.cur.execute("SELECT id FROM mastodon_instances WHERE instance = ?;", (instance, ))
|
||||||
|
instance_id = self.db.cur.fetchone()[0]
|
||||||
|
self.db.cur.execute("INSERT INTO mastodon_accounts(user_id, access_token, mastodon_instances_id, active) "
|
||||||
|
"VALUES(?, ?, ?, ?);", (self.uid, access_token, instance_id, 1))
|
||||||
|
self.db.commit()
|
||||||
|
|
||||||
|
|
||||||
class DBPlugin(object):
|
class DBPlugin(object):
|
||||||
name = 'DBPlugin'
|
name = 'DBPlugin'
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
<h2>Log in with Mastodon</h2>
|
<h2>Log in with Mastodon</h2>
|
||||||
<p>
|
<p>
|
||||||
<form action="/login/mastodon" method='post'>
|
<form action="/login/mastodon" method='post'>
|
||||||
|
<label for="email">E-Mail of your Mastodon-Account</label>
|
||||||
|
<input type="text" placeholder="Enter Email" name="email" id="email" required>
|
||||||
|
|
||||||
|
<label for="pass">Mastodon Password</label>
|
||||||
|
<input type="password" placeholder="Enter Password" name="pass" id="pass" required>
|
||||||
|
|
||||||
<label>Mastodon instance:
|
<label>Mastodon instance:
|
||||||
<input type='text' name='instance_url' list='instances' placeholder='social.example.net'/>
|
<input type='text' name='instance_url' list='instances' placeholder='social.example.net'/>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import bottle
|
import bottle
|
||||||
from bottle import get, post, redirect, request, response, view
|
from bottle import get, post, redirect, request, response, view
|
||||||
from db import DBPlugin
|
from db import DBPlugin
|
||||||
|
import tweepy
|
||||||
|
import sendmail
|
||||||
|
import smtplib
|
||||||
|
from mastodon import Mastodon
|
||||||
|
|
||||||
|
|
||||||
@get('/')
|
@get('/')
|
||||||
|
@ -8,6 +12,7 @@ from db import DBPlugin
|
||||||
def propaganda():
|
def propaganda():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@post('/register', db='db')
|
@post('/register', db='db')
|
||||||
@view('template/register.tpl')
|
@view('template/register.tpl')
|
||||||
def register_post(db):
|
def register_post(db):
|
||||||
|
@ -24,6 +29,14 @@ def register_post(db):
|
||||||
return dict(info='Confirmation mail sent.')
|
return dict(info='Confirmation mail sent.')
|
||||||
|
|
||||||
|
|
||||||
|
def send_confirmation_mail(self, confirm_link, email):
|
||||||
|
m = sendmail.Mailer(self.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."
|
||||||
|
|
||||||
|
|
||||||
@get('/confirm/<token>', db='db')
|
@get('/confirm/<token>', db='db')
|
||||||
@view('template/propaganda.tpl')
|
@view('template/propaganda.tpl')
|
||||||
def confirm(db, token):
|
def confirm(db, token):
|
||||||
|
@ -59,6 +72,7 @@ def api_enable(user):
|
||||||
def static(filename):
|
def static(filename):
|
||||||
return bottle.static_file(filename, root='static')
|
return bottle.static_file(filename, root='static')
|
||||||
|
|
||||||
|
|
||||||
@get('/logout/')
|
@get('/logout/')
|
||||||
def logout():
|
def logout():
|
||||||
# clear auth cookie
|
# clear auth cookie
|
||||||
|
@ -67,5 +81,62 @@ def logout():
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
|
|
||||||
|
@get('/login/twitter', user='user')
|
||||||
|
def login_twitter(user):
|
||||||
|
"""
|
||||||
|
Starts the twitter OAuth authentication process.
|
||||||
|
:return: redirect to twitter.
|
||||||
|
"""
|
||||||
|
consumer_key = user.db.config["tapp"]["consumer_key"]
|
||||||
|
consumer_secret = user.db.config["tapp"]["consumer_secret"]
|
||||||
|
callback_url = bottle.request.get_header('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.'
|
||||||
|
user.save_request_token(auth.request_token)
|
||||||
|
return bottle.redirect(redirect_url)
|
||||||
|
|
||||||
|
|
||||||
|
@get('/login/twitter/callback', user="user")
|
||||||
|
def twitter_callback(user):
|
||||||
|
"""
|
||||||
|
Gets the callback
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
# twitter passes the verifier/oauth token secret in a GET request.
|
||||||
|
verifier = bottle.request.query('oauth_verifier')
|
||||||
|
consumer_key = user.db.config["tapp"]["consumer_key"]
|
||||||
|
consumer_secret = user.db.config["tapp"]["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)
|
||||||
|
return bottle.redirect("/settings")
|
||||||
|
|
||||||
|
|
||||||
|
@post('/login/mastodon', user="user")
|
||||||
|
def login_mastodon(user):
|
||||||
|
"""
|
||||||
|
Starts the mastodon OAuth authentication process.
|
||||||
|
:return: redirect to twitter.
|
||||||
|
"""
|
||||||
|
# get app tokens
|
||||||
|
instance_url = bottle.request.forms.get('instance_url')
|
||||||
|
masto_email = bottle.request.forms.get('email')
|
||||||
|
masto_pass = bottle.request.forms.get('password')
|
||||||
|
client_id, client_secret = user.get_mastodon_app_keys(instance_url)
|
||||||
|
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)
|
||||||
|
return dict(info='Thanks for supporting decentralized social networks!')
|
||||||
|
except:
|
||||||
|
return dict(error='Login to Mastodon failed.')
|
||||||
|
|
||||||
|
|
||||||
bottle.install(DBPlugin('/'))
|
bottle.install(DBPlugin('/'))
|
||||||
bottle.run(host='localhost', port=8080)
|
bottle.run(host='localhost', port=8080)
|
||||||
|
|
Loading…
Reference in a new issue