mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 09:10:00 +00:00
[Config change] Require recaptcha of new uploaders (#376)
* Reorganize config.example.py, add ACCOUNT_RECAPTCHA_AGE * Require new accounts to pass recaptcha on upload Based on ACCOUNT_RECAPTCHA_AGE in config.
This commit is contained in:
parent
214952e7b6
commit
1e5f61ddf7
|
@ -1,20 +1,47 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
|
######################
|
||||||
|
## Maintenance mode ##
|
||||||
|
######################
|
||||||
|
|
||||||
# A read-only maintenance mode, in which the database is not modified
|
# A read-only maintenance mode, in which the database is not modified
|
||||||
MAINTENANCE_MODE = True
|
MAINTENANCE_MODE = False
|
||||||
# A maintenance message (used in layout.html template)
|
# A maintenance message (used in layout.html template)
|
||||||
MAINTENANCE_MODE_MESSAGE = 'Site is currently in read-only maintenance mode.'
|
MAINTENANCE_MODE_MESSAGE = 'Site is currently in read-only maintenance mode.'
|
||||||
# Allow logging in during maintenance (without updating last login date)
|
# Allow logging in during maintenance (without updating last login date)
|
||||||
MAINTENANCE_MODE_LOGINS = True
|
MAINTENANCE_MODE_LOGINS = True
|
||||||
|
|
||||||
USE_RECAPTCHA = False
|
#############
|
||||||
USE_EMAIL_VERIFICATION = False
|
## General ##
|
||||||
USE_MYSQL = True
|
#############
|
||||||
|
|
||||||
# Enable this once stat integration is done
|
# What the site identifies itself as. This affects templates, not database stuff.
|
||||||
|
SITE_NAME = 'Nyaa'
|
||||||
|
|
||||||
|
# General prefix for running multiple sites, eg. most database tables are site-prefixed
|
||||||
|
SITE_FLAVOR = 'nyaa' # 'nyaa' or 'sukebei'
|
||||||
|
# Full external urls to both sites, used for site-change links
|
||||||
|
EXTERNAL_URLS = {'fap':'***', 'main':'***'}
|
||||||
|
|
||||||
|
# Secret keys for Flask
|
||||||
|
CSRF_SESSION_KEY = '***'
|
||||||
|
SECRET_KEY = '***'
|
||||||
|
|
||||||
|
# Present a recaptcha for anonymous uploaders
|
||||||
|
USE_RECAPTCHA = False
|
||||||
|
# Require email validation
|
||||||
|
USE_EMAIL_VERIFICATION = False
|
||||||
|
# Use MySQL or Sqlite3 (mostly deprecated)
|
||||||
|
USE_MYSQL = True
|
||||||
|
# Show seeds/peers/completions in torrent list/page
|
||||||
ENABLE_SHOW_STATS = True
|
ENABLE_SHOW_STATS = True
|
||||||
|
|
||||||
|
# Recaptcha keys (https://www.google.com/recaptcha)
|
||||||
|
RECAPTCHA_PUBLIC_KEY = '***'
|
||||||
|
RECAPTCHA_PRIVATE_KEY = '***'
|
||||||
|
|
||||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
if USE_MYSQL:
|
if USE_MYSQL:
|
||||||
SQLALCHEMY_DATABASE_URI = ('mysql://test:test123@localhost/nyaav2?charset=utf8mb4')
|
SQLALCHEMY_DATABASE_URI = ('mysql://test:test123@localhost/nyaav2?charset=utf8mb4')
|
||||||
|
@ -22,50 +49,54 @@ else:
|
||||||
SQLALCHEMY_DATABASE_URI = (
|
SQLALCHEMY_DATABASE_URI = (
|
||||||
'sqlite:///' + os.path.join(BASE_DIR, 'test.db') + '?check_same_thread=False')
|
'sqlite:///' + os.path.join(BASE_DIR, 'test.db') + '?check_same_thread=False')
|
||||||
|
|
||||||
CSRF_SESSION_KEY = '***'
|
# Email server settings
|
||||||
SECRET_KEY = '***'
|
|
||||||
|
|
||||||
# Prefix for running multiple sites, user table will not be prefixed.
|
|
||||||
SITE_FLAVOR = 'nyaa' # 'nyaa' or 'sukebei'
|
|
||||||
EXTERNAL_URLS = {'fap':'***', 'main':'***'}
|
|
||||||
# for recaptcha and email verification:
|
|
||||||
# keys for localhost. Change as appropriate when actual domain is registered.
|
|
||||||
RECAPTCHA_PUBLIC_KEY = '***'
|
|
||||||
RECAPTCHA_PRIVATE_KEY = '***'
|
|
||||||
SMTP_SERVER = '***'
|
SMTP_SERVER = '***'
|
||||||
SMTP_PORT = 587
|
SMTP_PORT = 587
|
||||||
MAIL_FROM_ADDRESS = '***'
|
MAIL_FROM_ADDRESS = '***'
|
||||||
SMTP_USERNAME = '***'
|
SMTP_USERNAME = '***'
|
||||||
SMTP_PASSWORD = '***'
|
SMTP_PASSWORD = '***'
|
||||||
|
|
||||||
# What the site identifies itself as. This affects templates, not database stuff.
|
|
||||||
SITE_NAME = 'Nyaa'
|
|
||||||
|
|
||||||
# The maximum number of files a torrent can contain
|
# The maximum number of files a torrent can contain
|
||||||
# until the site says "Too many files to display."
|
# until the site says "Too many files to display."
|
||||||
MAX_FILES_VIEW = 1000
|
MAX_FILES_VIEW = 1000
|
||||||
|
|
||||||
#
|
# Verify uploaded torrents have the given tracker in them?
|
||||||
# Setting to make sure main announce url is present in torrent
|
|
||||||
#
|
|
||||||
ENFORCE_MAIN_ANNOUNCE_URL = False
|
ENFORCE_MAIN_ANNOUNCE_URL = False
|
||||||
MAIN_ANNOUNCE_URL = 'http://127.0.0.1:6881/announce'
|
MAIN_ANNOUNCE_URL = 'http://127.0.0.1:6881/announce'
|
||||||
|
|
||||||
|
# Tracker API integration - don't mind this
|
||||||
TRACKER_API_URL = 'http://127.0.0.1:6881/api'
|
TRACKER_API_URL = 'http://127.0.0.1:6881/api'
|
||||||
TRACKER_API_AUTH = 'topsecret'
|
TRACKER_API_AUTH = 'topsecret'
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Account ##
|
||||||
|
#############
|
||||||
|
|
||||||
# Torrents uploaded without an account must be at least this big in total (bytes)
|
# Torrents uploaded without an account must be at least this big in total (bytes)
|
||||||
# Set to 0 to disable
|
# Set to 0 to disable
|
||||||
MINIMUM_ANONYMOUS_TORRENT_SIZE = 1 * 1024 * 1024
|
MINIMUM_ANONYMOUS_TORRENT_SIZE = 1 * 1024 * 1024
|
||||||
|
|
||||||
|
# Minimum age for an account not to be served a captcha (seconds)
|
||||||
|
# Relies on USE_RECAPTCHA. Set to 0 to disable.
|
||||||
|
ACCOUNT_RECAPTCHA_AGE = 7 * 24 * 3600 # A week
|
||||||
|
|
||||||
|
# Backup original .torrent uploads
|
||||||
BACKUP_TORRENT_FOLDER = 'torrents'
|
BACKUP_TORRENT_FOLDER = 'torrents'
|
||||||
|
|
||||||
#
|
############
|
||||||
# Search Options
|
## Search ##
|
||||||
#
|
############
|
||||||
|
|
||||||
|
# How many results should a page contain. Applies to RSS as well.
|
||||||
RESULTS_PER_PAGE = 75
|
RESULTS_PER_PAGE = 75
|
||||||
|
|
||||||
# See README.MD on Elasticsearch setup
|
# Use better searching with ElasticSearch
|
||||||
|
# See README.MD on setup!
|
||||||
USE_ELASTIC_SEARCH = False
|
USE_ELASTIC_SEARCH = False
|
||||||
|
# Highlight matches (for debugging)
|
||||||
ENABLE_ELASTIC_SEARCH_HIGHLIGHT = False
|
ENABLE_ELASTIC_SEARCH_HIGHLIGHT = False
|
||||||
|
|
||||||
# Max ES search results, do not set over 10000
|
# Max ES search results, do not set over 10000
|
||||||
ES_MAX_SEARCH_RESULT = 1000
|
ES_MAX_SEARCH_RESULT = 1000
|
||||||
ES_INDEX_NAME = SITE_FLAVOR # we create indicies named nyaa or sukebei
|
# ES index name generally (nyaa or sukebei)
|
||||||
|
ES_INDEX_NAME = SITE_FLAVOR
|
||||||
|
|
|
@ -239,6 +239,17 @@ class BanForm(FlaskForm):
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def recaptcha_validator_shim(form, field):
|
||||||
|
''' Selectively does a recaptcha validation '''
|
||||||
|
if app.config['USE_RECAPTCHA']:
|
||||||
|
# Recaptcha anonymous and new users
|
||||||
|
if not flask.g.user or flask.g.user.age < app.config['ACCOUNT_RECAPTCHA_AGE']:
|
||||||
|
return RecaptchaValidator()(form, field)
|
||||||
|
else:
|
||||||
|
# Always pass validating the recaptcha field if disabled
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class UploadForm(FlaskForm):
|
class UploadForm(FlaskForm):
|
||||||
torrent_file = FileField('Torrent file', [
|
torrent_file = FileField('Torrent file', [
|
||||||
FileRequired()
|
FileRequired()
|
||||||
|
@ -251,17 +262,8 @@ class UploadForm(FlaskForm):
|
||||||
'%(max)d at most.')
|
'%(max)d at most.')
|
||||||
])
|
])
|
||||||
|
|
||||||
if config['USE_RECAPTCHA']:
|
recaptcha = RecaptchaField(validators=[recaptcha_validator_shim])
|
||||||
# Captcha only for not logged in users
|
|
||||||
_recaptcha_validator = RecaptchaValidator()
|
|
||||||
|
|
||||||
def _validate_recaptcha(form, field):
|
|
||||||
if not flask.g.user:
|
|
||||||
return UploadForm._recaptcha_validator(form, field)
|
|
||||||
|
|
||||||
recaptcha = RecaptchaField(validators=[_validate_recaptcha])
|
|
||||||
|
|
||||||
# category = SelectField('Category')
|
|
||||||
category = DisabledSelectField('Category')
|
category = DisabledSelectField('Category')
|
||||||
|
|
||||||
def validate_category(form, field):
|
def validate_category(form, field):
|
||||||
|
|
|
@ -601,6 +601,11 @@ class User(db.Model):
|
||||||
def is_banned(self):
|
def is_banned(self):
|
||||||
return self.status == UserStatusType.BANNED
|
return self.status == UserStatusType.BANNED
|
||||||
|
|
||||||
|
@property
|
||||||
|
def age(self):
|
||||||
|
'''Account age in seconds'''
|
||||||
|
return (datetime.utcnow() - self.created_time).total_seconds()
|
||||||
|
|
||||||
|
|
||||||
class AdminLogBase(DeclarativeHelperBase):
|
class AdminLogBase(DeclarativeHelperBase):
|
||||||
__tablename_base__ = 'adminlog'
|
__tablename_base__ = 'adminlog'
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if config.USE_RECAPTCHA and not g.user %}
|
{% if config.USE_RECAPTCHA and (not g.user or g.user.age < config['ACCOUNT_RECAPTCHA_AGE']) %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
{% for error in upload_form.recaptcha.errors %}
|
{% for error in upload_form.recaptcha.errors %}
|
||||||
|
|
Loading…
Reference in a new issue