Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
Previously the website was connected to the database with a "database
owner" user, which has far too many permissions. Now there's a special
vndb_site user with only the necessary permissions. The primary
reason to do this is to decrease the impact if the site process is
compromised. E.g. it's now no longer possible to delete or modify old
entry revisions. An attacker can still do a lot of damage, however.
Additionally (and this was the main reason to implement this change in
the first place), the user sessions, passwords and email data is now not
easily accessible anymore. Hopefully, the new user management
abstractions will prevent email and password dumps in case of an SQL
injection or RCE vulnerability in the site code. Of course, this only
works if my implementation is fully correct and there's no privilige
escalation vulnerability somewhere.
Furthermore, changing your password now invalidates any existing
sessions, and the password reset function is disabled for 'usermods'
(because usermods can list email addresses from the database, and the
password reset function could still allow an attacker to gain access to
anyone's account).
I also changed the format of the password reset tokens, as they totally
don't need to be salted.
|
|
|
|
VNDB tends to get unresponsive for a few minutes when the daily cron is
run. This should help somewhat.
|
|
|
|
This is a generalization of the search improvements made in
7da2edeaa0f6cf7794f4f8f68960497dc1be893c and
92235222dba4e5d0c7713d53ef12e0f10e371b83
And has been applied to the dropdown searches for producers, staff, tags
and traits.
For all those searches, exact matches are listed first, followed by
prefix matches, and then substring matches. Relevance is currently only
based on the primary name/title and ignores aliases (except for staff).
This is fixable, but not trivial, and I'm not sure it's all that useful.
|
|
|
|
- Merged polls table into threads table. Not much of a
storage/performance difference, and it's a bit simpler this way.
- Merged DB::Polls into DB::Discussions. Mainly because of the above
change in DB structure.
- Add option to remove an existing poll.
- Allow preview and recast to be changed without deleting the votes
- Set preview option by default. Because personal preferences. :)
- Minor form validation differences
|
|
|
|
They had to be deleted from the database at some point, otherwise we
still have thousands of easily-cracked password hashes in the database.
Note that I could have opted to use scrypt on top of the sha256 hashes
so the passwords would remain secure without needing to reset
everything, but doing that after one year of switching to scrypt is
likely not worth it. Everyone who still actively uses his account has
already been converted to scrypt, everyone else should just reset their
password whevener they decide to come back.
|
|
The new database schema doesn't allow an alias to be removed when it is
still linked to a VN.
|
|
These indices provide a significant speed-up of /v+ and /u+ pages, and
improve some other stuff as well.
|
|
An index on threads_posts.date was necessary to speed up some very
common "recent posts" queries on both the homepage and the thread index.
Postgres thought that the same index could be used to speed up the
full-text search (because it's ordered by date, after all), but that
completely killed performance. That was solved with a bb_tsvector()
wrapper to tell the query planner that not using the full-text index is
incredibly show, which in turn improved the search performance beyond
what it was.
Many thread-related queries are still somewhat slow, but that seems to
be a limitation in the schema. I'll just keep monitoring to see if
that's worth fixing in the future.
Interestingly, dbThreadCount() needs to use a sequential scan, but it's
still remarkably fast.
|
|
This changes quite a bit to the way the editing functions work. Because
these functions are very repetitive and it's easy to keep things out of
sync, I created a script to generate them automatically. I had to rename
a few function and table names for consistency to make this work.
Since database entries don't have a 'latest' column anymore, and since
the order in which tables are updated doesn't have to be fixed, I
dropped many of the SQL triggers and replaced them with a
edit_committed() function which is called from edit_*_commit() and
checks for stuff to be done.
Don't forget to run 'make' before importing the update script.
|
|
|
|
This basically makes VNDB browsable again, but editing entries is still
broken.
I split off the get-old-revision functionality from the db*Get() methods
into db*GetRev(). This split makes sense even with the old SQL schema:
db*Get() had to special-case some joins/filters when fetching an older
revision, and none of the other filters would work in that case. This
split does cause some code duplication in that all db*GetRev() methods
look very much alike, and that the columns they fetch is almost
identical to the db*Get() methods. Not sure yet how to avoid the
duplication elegantly.
I didn't do a whole lot of query optimization yet (most issues require
extra indices, I'll investigate later which indices will make a big
difference), but I did fix some low hanging fruit whenever I encountered
something.
I don't think I've worsened anything, performance-wise.
|
|
This commit breaks pretty much everything. Lots of code will have to be
fixed to work with this new schema.
The basic idea is to separate live data from archived data, which allows
for smaller and more effective indices on the live data, and the
archived data doesn't need such indices and have to be accessed at all
for most operations. Another goal is to eliminate table joins to fetch
some necessary information, e.g. it's not necessary anymore to join the
main item tables in order to fetch only the latest revision of some item
data.
This is very much work in progress. I might stumble upon some weird
issue while fixing the code, and might have to redesign everything
from scratch again. Let's just see how things go.
|
|
Turns out that fetching whether or not you have unread notifications
(done on every pageview if you're logged in) was pretty slow. The index
speeds up both that query and the "my notifications" view.
The extra purge for old notifications for users with more than 500
notifications ensures that the index stays effective for the unread
notifications count. Otherwise it'll have to read half of the
notifications table anyway to check the 'unread' filter.
|
|
Turning the foreign key references into idempotent statements required
adding the name for each reference in the query. I used the names of the
production database, but since the names are autogenerated at creation
time, it's possible that they have other names if the database has been
created slightly differently.
Using explicit names for everything and having idempotent SQL statements
is rather useful when making nontrivial modifications to the database
schema. Which is something I consider doing.
|
|
Same reasoning as 19ce5fcf536ed478ad34b6b1014bf6f44841d25d
|
|
And also fix strip_bb_tags() to be case-insensitive and fix a bug in
converting the query into a tsquery.
|
|
Inspired by wakaranai's implementation at
https://github.com/morkt/vndb/commit/b852c87ad145fdaaa09c79b6378dd819b46f7e87
This version is different in a number of aspects:
- Separate search functions for title search and fulltext post search.
Perhaps not the most convenient option, but the downside of a combined
search is that if the query matches the threads' title, then all of
the posts in that thread will show up in the results. This didn't seem
very useful.
- Sorting is based purely on post date. Rank-based sort is slow without
a separate caching column, and in my opinion not all that useful.
Implementation differences:
- Integrated in the existing DB::Discussions functions, so less code to
maintain and more code reuse.
- No separate caching column for the tsvector, a functional index is
used instead. This is a bit slower (index results need to be
re-checked against the actual messages, hence the slowdown), but has
the advantage of smaller database dumps and less complexity in
updating the cache.
Things to fix or look at:
- Highlighting of the search query in message contents.
- Allow or-style query matching
|
|
The char(2) solution is both inefficient and ugly. Also needed to be
careful with handling the extra space that Postgres would automatically
add to single-character types.
|
|
|
|
This fixes the unexpected behaviour that changing the spoiler setting on
one page will change it for all pages. All manual spoiler changing
options are temporary now.
|
|
The name of the profile setting isn't very clear. Not sure what to do
with it.
|
|
|
|
|
|
https://vndb.org/t6138.226 - https://vndb.org/t6048.132
|
|
|
|
|
|
|
|
So that the /util/sql/ files are in sync with the actual DB again.
|
|
Conflicts:
lib/VNDB/DB/VN.pm
lib/VNDB/Handler/VNPage.pm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Moves staff<->vn linking form to the main VN edit form
- Fixes a bug with linking staff aliases to VNs
- Adds staff changes to the VN revisions
- And some misc. improvements
|
|
|
|
Used to link to a visual-novels.net review or something. Links have been
hidden and dead since ages. No need to keep the column around.
|
|
I increased the N parameter to approximate about 500ms to generate the
hash. This is quite a paranoid setting for a website, but login attempts
are throttled so there's not much of a DoS factor. (Alright, password
changing feature isn't throttled so the DoS factor still exists. But
really, there's some pages with longer page generation times anyway.)
I did lower the size of the salt a bit (Crypt::ScryptKDF uses 256 bits
by default), because 64 bits of randomness should have low enough chance
of collision with only ~100k users (even with a million users,
seriously).
|
|
It doesn't make a whole lot to separate the hashed password and the salt
from each other, you need both to do anything with them, and from the
database perspective they're both completely opaque strings only usable
for direct comparison with other hashed strings.
This change is mostly as preparation for switching to a proper key
derivation function (sha256 isn't...) and to add support for longer
and/or binary salt.
Because the passwd field now needs to be interpreted in Perl, it's being
passed around as a binary string rather than a hex-encoded value.
API login is broken in this commit. I'll get to that.
|
|
I believe I didn't do this conversion earlier (back when I converted the
language types) because PostgreSQL didn't support dynamically adding new
values to an existing enum back then, and modifying an enum was a huge
pain. Recent versions do support this, so there's no reason to keep it
as a string.
...I just felt like adding some churn to the code base.
|
|
Easier to work with in custom queries.
|
|
Suggested by Hinoe, quoting his reasoning:
In popularity rankings, change the normalization from
"sqrt(LowerVoteCount)" == "LowerVoteCount^0.5" to something that grows
somewhat more slowly.
Details: Natural logarithm itself (ln(LowerVoteCount+1)) is too slow;
at the current VN count (15403), it returns 9.64; however, sqrt(15402)
is just above 124.1, which I feel is already too high. After
experimenting with the exponents a bit, I decided that the best point
likely lies between 0.3, which returns a bit above 18.0, and 0.4,
which returns a bit above 47.3. Thus, I suggest that the new function
be LowerVoteCount^0.36788; the exponent is a 5-digit approximation of
e^-1, just because it's a nice number in the specified area and works
well, returning circa 34.7.
|
|
|