Require login by default & fast-fail if login is required but user isn't - #1645
Conversation
edede69 to
bcff86f
Compare
chrismiceli
left a comment
There was a problem hiding this comment.
Seems logical to fail safely and avoid unnecessary db connections. Can you elaborate on where those db connections were setup for authenticated pages that were hit while unauthenticated? Just curious.
Sure. Since we store sessions in the database, all pages need a DB connection and we've written the code in If the user does have a session cookie, we need to connect to the database and load the session to see if they're actually logged in, but we don't need to do other things like try to load the user's record, configure gettext, etc if they aren't actually logged in. Letting |
bpfoley
left a comment
There was a problem hiding this comment.
Just an overall comment about this, that something feels slightly odd about the design to me, but it's largely because my mental model (and PHPStan's way of analyzing the entire repo) doesn't quite align with what the codebase actually is: namely a large group of disjoint scripts, one per .php file that happen to include_once()/require_once() some common files.
This is what caused me to have to rename some functions that had the same function name across different scripts, but different numbers of arguments: PHPStan assumed that the first definition of the function it saw (in one .php file) was the correct one, and the second one was a mismatch.
Imagine
acounts/activate.php
<?php
namespace Accounts\Activate;
$require_login = false;
include_once($relPath.'base.inc');project.php
<?php
namespace Project;
include_once($relPath.'base.inc');Now, when in base.inc we say
if (!@isset($require_login)) {
$require_login = true;
}
...
if ($require_login) {
require_login();
}we're actually referring to different 'instances' of $require_login depending on which include_once the interpreter ran. One instance is 'really' the $require_login from acounts/activate.php and the other instance is defined 'on behalf of' project.php. Since PHP variables aren't namespaced, we can't call these \Accounts\Activate\$require_login and \Project\$require_login, but that's effectively what they are.
I guess what I'm describing in a round-about way is the caveat about global variables in PHP: they're really what programming language people call 'dynamically scoped' rather than 'lexically scoped'. And that's the reason they aren't namespaced, because namespacing is a lexical thing.
Just to be clear, I'm not objecting to this PR at all. These ramblings are just me internalising what it means.
|
Numbers are fun, let's show some numbers. This is testing done using
|
Right. The DP codebase is not a "PHP application" it's a bunch of scripts in a trench coat pretending to be an application. Given that as a constraint, is there a better mechanism to achieve this than a global variable? Would PHPStan appreciate a constant better? We should be able to achieve the same thing that way. |
bcff86f to
68429b8
Compare
So... I don't think this is a constraint as such, just something I was trying to internalise. From PHPStan's point of view, all the different So this is just my very roundabout way of saying LGTM! |
Make all pages require login by default and opt-out the few pages that don't require it.
We can bypass many expensive checks like connecting to the database and setting up gettext if it's impossible for the user to be logged in because they haven't sent us a session cookie.
68429b8 to
c3800a2
Compare
|
I've made the assumption that everything that has had the Some, I can understand (the front page,
Some, like As I said -- not objecting so much as just curious. |
https://github.com/DistributedProofreaders/dproofreaders/blob/master/SETUP/ci/check_require_login.php has some additional comments on why. I think the idea was that we wanted the |
Thanks -- that's about what I figured. Though without a proofing interface, I'm not sure prooffacehelp is any use, nor the snapshot legend without the snapshot. 😁 |
Note: this is intended for merging after this month's release.
Shift the logic such that login is required on all pages and make the few that don't require login to explicitly state that. This lets us do a few wise & performant things:
The interesting changes in this PR are in:
pinc/base.incpinc/bootstrap.incpinc/dpsession.incThis will require matching changes in noncvs that currently call
require_login()now that the function is deprecated and a no-op.Sandbox: https://www.pgdp.org/~cpeel/c.branch/require-login-by-default/