Store user agent with files

Needed for moderation.
This commit is contained in:
Mia Herkt 2023-03-29 07:21:36 +02:00
parent e00866f5e4
commit 3d1facaec3
Signed by: mia
SSH key fingerprint: SHA256:wqxNmz1v3S4rHhF0I3z/ogVueFRUac93swSgNGfr8No
3 changed files with 47 additions and 7 deletions

View file

@ -135,6 +135,7 @@ class File(db.Model):
ext = db.Column(db.UnicodeText)
mime = db.Column(db.UnicodeText)
addr = db.Column(db.UnicodeText)
ua = db.Column(db.UnicodeText)
removed = db.Column(db.Boolean, default=False)
nsfw_score = db.Column(db.Float)
expiration = db.Column(db.BigInteger)
@ -143,11 +144,12 @@ class File(db.Model):
last_vscan = db.Column(db.DateTime)
size = db.Column(db.BigInteger)
def __init__(self, sha256, ext, mime, addr, expiration, mgmt_token):
def __init__(self, sha256, ext, mime, addr, ua, expiration, mgmt_token):
self.sha256 = sha256
self.ext = ext
self.mime = mime
self.addr = addr
self.ua = ua
self.expiration = expiration
self.mgmt_token = mgmt_token
@ -212,7 +214,7 @@ class File(db.Model):
Any value greater that the longest allowed file lifespan will be rounded down to that
value.
"""
def store(file_, requested_expiration: typing.Optional[int], addr, secret: bool):
def store(file_, requested_expiration: typing.Optional[int], addr, ua, secret: bool):
data = file_.read()
digest = sha256(data).hexdigest()
@ -278,9 +280,10 @@ class File(db.Model):
mime = get_mime()
ext = get_ext(mime)
mgmt_token = secrets.token_urlsafe()
f = File(digest, ext, mime, addr, expiration, mgmt_token)
f = File(digest, ext, mime, addr, ua, expiration, mgmt_token)
f.addr = addr
f.ua = ua
if isnew:
f.secret = None
@ -368,11 +371,11 @@ requested_expiration can be:
Any value greater that the longest allowed file lifespan will be rounded down to that
value.
"""
def store_file(f, requested_expiration: typing.Optional[int], addr, secret: bool):
def store_file(f, requested_expiration: typing.Optional[int], addr, ua, secret: bool):
if in_upload_bl(addr):
return "Your host is blocked from uploading files.\n", 451
sf, isnew = File.store(f, requested_expiration, addr, secret)
sf, isnew = File.store(f, requested_expiration, addr, ua, secret)
response = make_response(sf.geturl())
response.headers["X-Expires"] = sf.expiration
@ -382,7 +385,7 @@ def store_file(f, requested_expiration: typing.Optional[int], addr, secret: boo
return response
def store_url(url, addr, secret: bool):
def store_url(url, addr, ua, secret: bool):
if is_fhost_url(url):
abort(400)
@ -403,7 +406,7 @@ def store_url(url, addr, secret: bool):
f = urlfile(read=r.raw.read, content_type=r.headers["content-type"], filename="")
return store_file(f, None, addr, secret)
return store_file(f, None, addr, ua, secret)
else:
abort(413)
else:
@ -498,6 +501,7 @@ def fhost():
request.files["file"],
int(request.form["expires"]),
request.remote_addr,
request.user_agent.string,
secret
)
except ValueError:
@ -509,12 +513,14 @@ def fhost():
request.files["file"],
None,
request.remote_addr,
request.user_agent.string,
secret
)
elif "url" in request.form:
return store_url(
request.form["url"],
request.remote_addr,
request.user_agent.string,
secret
)
elif "shorten" in request.form:

View file

@ -0,0 +1,30 @@
"""Store user agent string with files
Revision ID: dd0766afb7d2
Revises: 30bfe33aa328
Create Date: 2023-03-29 07:18:49.113200
"""
# revision identifiers, used by Alembic.
revision = 'dd0766afb7d2'
down_revision = '30bfe33aa328'
from alembic import op
import sqlalchemy as sa
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('file', schema=None) as batch_op:
batch_op.add_column(sa.Column('ua', sa.UnicodeText(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('file', schema=None) as batch_op:
batch_op.drop_column('ua')
# ### end Alembic commands ###

4
mod.py
View file

@ -26,6 +26,7 @@ class NullptrMod(Screen):
("f4", "filter(4, 'Filter extension:')", "Filter Ext."),
("f5", "refresh", "Refresh"),
("f6", "filter_clear", "Clear filter"),
("f7", "filter(5, 'Filter user agent:')", "Filter UA"),
("r", "remove_file(False)", "Remove file"),
("ctrl+r", "remove_file(True)", "Ban file"),
("p", "ban_ip(False)", "Ban IP"),
@ -60,6 +61,7 @@ class NullptrMod(Screen):
case 2: finput.value = self.current_file.addr
case 3: finput.value = self.current_file.mime
case 4: finput.value = self.current_file.ext
case 5: finput.value = self.current_file.ua
def on_input_submitted(self, message: Input.Submitted) -> None:
self.query_one("#filter_container").display = False
@ -74,6 +76,7 @@ class NullptrMod(Screen):
case 2: ftable.query = ftable.base_query.filter(File.addr == message.value)
case 3: ftable.query = ftable.base_query.filter(File.mime.like(message.value))
case 4: ftable.query = ftable.base_query.filter(File.ext.like(message.value))
case 5: ftable.query = ftable.base_query.filter(File.ua.like(message.value))
else:
ftable.query = ftable.base_query
@ -249,6 +252,7 @@ class NullptrMod(Screen):
("MIME type:", f.mime),
("SHA256 checksum:", f.sha256),
("Uploaded by:", Text(f.addr)),
("User agent:", Text(f.ua or "")),
("Management token:", f.mgmt_token),
("Secret:", f.secret),
("Is NSFW:", ("Yes" if f.is_nsfw else "No") + (f" (Score: {f.nsfw_score:0.4f})" if f.nsfw_score else " (Not scanned)")),