2
0
mirror of https://github.com/codl/forget synced 2025-01-19 10:31:10 +01:00

add rate limits

This commit is contained in:
codl 2017-08-10 17:07:39 +02:00
parent 279cb21f95
commit ca2798a428
No known key found for this signature in database
GPG Key ID: 6CD7C8891ED1233A
5 changed files with 45 additions and 14 deletions

17
app.py
View File

@ -1,9 +1,12 @@
from flask import Flask from flask import Flask, g, request
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData from sqlalchemy import MetaData
from flask_migrate import Migrate from flask_migrate import Migrate
import version import version
from lib import cachebust from lib import cachebust
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from lib import get_viewer
app = Flask(__name__) app = Flask(__name__)
@ -44,3 +47,15 @@ def inject_static():
def static(filename, **kwargs): def static(filename, **kwargs):
return url_for('static', filename=filename, **kwargs) return url_for('static', filename=filename, **kwargs)
return {'st': static} return {'st': static}
def rate_limit_key():
viewer = get_viewer()
if viewer:
return viewer.id
for address in request.access_route:
if address != '127.0.0.1':
print(address)
return address
return request.remote_addr
limiter = Limiter(app, key_func=rate_limit_key)

View File

@ -2,4 +2,4 @@ from .auth import require_auth
from .interval import decompose_interval from .interval import decompose_interval
from .interval import SCALES as interval_scales from .interval import SCALES as interval_scales
from .cachebust import cachebust from .cachebust import cachebust
from .session import set_session_cookie from .session import set_session_cookie, get_viewer_session, get_viewer

View File

@ -1,5 +1,18 @@
from flask import request
def set_session_cookie(session, response, secure=True): def set_session_cookie(session, response, secure=True):
response.set_cookie('forget_sid', session.id, response.set_cookie('forget_sid', session.id,
max_age=60*60*48, max_age=60*60*48,
httponly=True, httponly=True,
secure=secure) secure=secure)
def get_viewer_session():
from model import Session
sid = request.cookies.get('forget_sid', None)
if sid:
return Session.query.get(sid)
def get_viewer():
session = get_viewer_session()
if session:
return session.account

View File

@ -6,6 +6,7 @@ celery==4.1.0
click==6.7 click==6.7
contextlib2==0.5.5 contextlib2==0.5.5
Flask==0.12.2 Flask==0.12.2
Flask-Limiter==0.9.5
Flask-Migrate==2.0.4 Flask-Migrate==2.0.4
Flask-Script==2.0.5 Flask-Script==2.0.5
Flask-SQLAlchemy==2.2 Flask-SQLAlchemy==2.2
@ -14,6 +15,7 @@ honcho==1.0.1
itsdangerous==0.24 itsdangerous==0.24
Jinja2==2.9.6 Jinja2==2.9.6
kombu==4.1.0 kombu==4.1.0
limits==1.2.1
Mako==1.0.6 Mako==1.0.6
MarkupSafe==1.0 MarkupSafe==1.0
psycopg2==2.7.1 psycopg2==2.7.1

View File

@ -4,8 +4,9 @@ import lib.twitter
import lib import lib
from lib import require_auth from lib import require_auth
from lib import set_session_cookie from lib import set_session_cookie
from lib import get_viewer_session
from model import Account, Session, Post, TwitterArchive from model import Account, Session, Post, TwitterArchive
from app import app, db, sentry from app import app, db, sentry, limiter
import tasks import tasks
from zipfile import BadZipFile from zipfile import BadZipFile
from twitter import TwitterError from twitter import TwitterError
@ -14,16 +15,13 @@ import version
@app.before_request @app.before_request
def load_viewer(): def load_viewer():
g.viewer = None g.viewer = get_viewer_session()
sid = request.cookies.get('forget_sid', None) if g.viewer and sentry:
if sid: sentry.user_context({
g.viewer = Session.query.get(sid) 'id': g.viewer.account.id,
if g.viewer and sentry: 'username': g.viewer.account.screen_name,
sentry.user_context({ 'service': g.viewer.account.service
'id': g.viewer.account.id, })
'username': g.viewer.account.screen_name,
'service': g.viewer.account.service
})
@app.context_processor @app.context_processor
def inject_version(): def inject_version():
@ -31,7 +29,7 @@ def inject_version():
@app.after_request @app.after_request
def touch_viewer(resp): def touch_viewer(resp):
if g.viewer: if 'viewer' in g and g.viewer:
set_session_cookie(g.viewer, resp, app.config.get('HTTPS')) set_session_cookie(g.viewer, resp, app.config.get('HTTPS'))
g.viewer.touch() g.viewer.touch()
db.session.commit() db.session.commit()
@ -49,6 +47,7 @@ def index():
twitter_login_error = 'twitter_login_error' in request.args) twitter_login_error = 'twitter_login_error' in request.args)
@app.route('/login/twitter') @app.route('/login/twitter')
@limiter.limit('3/minute')
def twitter_login_step1(): def twitter_login_step1():
try: try:
return redirect(lib.twitter.get_login_url( return redirect(lib.twitter.get_login_url(
@ -59,6 +58,7 @@ def twitter_login_step1():
return redirect(url_for('index', twitter_login_error='', _anchor='log_in')) return redirect(url_for('index', twitter_login_error='', _anchor='log_in'))
@app.route('/login/twitter/callback') @app.route('/login/twitter/callback')
@limiter.limit('3/minute')
def twitter_login_step2(): def twitter_login_step2():
try: try:
oauth_token = request.args['oauth_token'] oauth_token = request.args['oauth_token']
@ -78,6 +78,7 @@ def twitter_login_step2():
return redirect(url_for('index', twitter_login_error='', _anchor='log_in')) return redirect(url_for('index', twitter_login_error='', _anchor='log_in'))
@app.route('/upload_tweet_archive', methods=('POST',)) @app.route('/upload_tweet_archive', methods=('POST',))
@limiter.limit('10/10 minutes')
@require_auth @require_auth
def upload_tweet_archive(): def upload_tweet_archive():
ta = TwitterArchive(account = g.viewer.account, ta = TwitterArchive(account = g.viewer.account,