132 lines
4.5 KiB
Python
132 lines
4.5 KiB
Python
import urllib
|
|
import requests
|
|
import functools
|
|
import oauth2 as oauth
|
|
from flask import Flask, request, abort, jsonify, render_template, make_response, json
|
|
|
|
app = Flask('socialist')
|
|
app.config.from_pyfile('socialist.cfg')
|
|
|
|
consumer_secret = app.config['CONSUMER_SECRET']
|
|
consumer_key = app.config['CONSUMER_KEY']
|
|
|
|
oauth_token = app.config['OAUTH_TOKEN']
|
|
oauth_token_secret = app.config['OAUTH_TOKEN_SECRET']
|
|
|
|
auth_url = app.config['AUTH_URL']
|
|
cap_url = app.config['CAP_URL']
|
|
|
|
api_allowed = app.config['API_AUTHORIZED']
|
|
twitter_role = app.config['TWITTER_ROLE']
|
|
|
|
def api_access(f):
|
|
@functools.wraps(f)
|
|
def func(*a, **kw):
|
|
dn = request.environ.get('PEER_DN')
|
|
if dn not in api_allowed:
|
|
return abort(403)
|
|
return f(*a, **kw)
|
|
return func
|
|
|
|
def get_login():
|
|
return request.login
|
|
|
|
def plain_error(text='Unauthorized', code=401):
|
|
return make_response(text, code, { 'Content-Type': 'text/plain' })
|
|
|
|
def json_error(errors=[{'message': 'Unauthorized', 'code':401}], status_code=401):
|
|
res = jsonify(errors = errors)
|
|
res.status_code = status_code
|
|
return res
|
|
|
|
def require_role(role, login_source = get_login, error_func = plain_error):
|
|
def decorator(f):
|
|
@functools.wraps(f)
|
|
def func(*a, **kw):
|
|
res = requests.get('/'.join((cap_url, role, get_login())), verify = False) # T_T
|
|
if res.status_code == 200:
|
|
return f(*a, **kw)
|
|
else:
|
|
return error_func()
|
|
return func
|
|
return decorator
|
|
|
|
def irc_dereference(from_parameter = 'nick', to_attribute = 'login', error_func = plain_error):
|
|
def decorator(f):
|
|
@functools.wraps(f)
|
|
def func(*a, **kw):
|
|
res = requests.post(auth_url + '/irc', verify = False, # T_T
|
|
data = { 'nick': request.form[from_parameter] })
|
|
if res.status_code == 200:
|
|
request.login = res.text
|
|
return f(*a, **kw)
|
|
else:
|
|
return error_func()
|
|
return func
|
|
return decorator
|
|
|
|
def oauth_req(url, http_method = 'GET', data = {}, headers = None):
|
|
# za https://dev.twitter.com/docs/auth/oauth/single-user-with-examples#python
|
|
from urllib import urlencode
|
|
consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
|
|
token = oauth.Token(key=oauth_token, secret=oauth_token_secret)
|
|
client = oauth.Client(consumer, token)
|
|
return client.request(
|
|
url,
|
|
method = http_method,
|
|
body = urlencode(data),
|
|
headers = headers)
|
|
|
|
def post_update(entry, format_str, title_shortener, max_title_length):
|
|
title = title_shortener(get_text(entry, 'title'), max_title_length)
|
|
try:
|
|
author = get_text(get_first_child(entry, 'author'), 'name')
|
|
except IndexError:
|
|
author = 'Somebody'
|
|
url = get_first_child(entry, 'link').attributes['href'].value
|
|
text = format_str % dict(title=title, author=author, url=url)
|
|
logger.info('posting update (text: "%s")' % text)
|
|
oauth_req('https://api.twitter.com/1/statuses/update.json', 'POST',
|
|
{ 'status': text })
|
|
|
|
@app.route('/')
|
|
def motd():
|
|
return render_template('motd.html')
|
|
|
|
@app.route('/socialist/tweet', methods=['GET'])
|
|
def test_form():
|
|
return render_template('tweet_form.html')
|
|
|
|
def irc_authorize(role, role_error):
|
|
def decorator(f):
|
|
mkerr = lambda ermsg: [{'messages': ermsg, 'code': 401}]
|
|
return api_access(
|
|
irc_dereference(error_func = lambda: json_error(mkerr('Unknown nick')))(
|
|
require_role(role, error_func = lambda: json_error(mkerr(role_error)))(
|
|
f)))
|
|
return decorator
|
|
|
|
@app.route('/socialist/tweet', methods=['POST'])
|
|
@irc_authorize(twitter_role, 'Unauthorized to tweet')
|
|
def irc_tweet():
|
|
tw_res = oauth_req('https://api.twitter.com/1.1/statuses/update.json', 'POST',
|
|
{ 'status': request.form['text'] })
|
|
print tw_res
|
|
return make_response(tw_res[1], tw_res[0].status, { 'Content-Type': 'application/json'})
|
|
|
|
@app.route('/socialist/detweet/<tid>', methods=['POST'])
|
|
@irc_authorize(twitter_role, 'Unauthorized to remove tweets')
|
|
def irc_detweet(tid):
|
|
tw_res = oauth_req('https://api.twitter.com/1.1/statuses/destroy/%s.json' % tid, 'POST')
|
|
return make_response(tw_res[1], tw_res[0].status, { 'Content-Type': 'application/json'})
|
|
|
|
@app.route('/socialist/test', methods=['POST'])
|
|
@irc_authorize(twitter_role, "test error")
|
|
def irc_test():
|
|
return json_error()
|
|
|
|
app.debug = True
|
|
|
|
if __name__ == '__main__':
|
|
app.run('0.0.0.0', port=8083, debug=True)
|