In Laravel 5.8, the `Container::tagged()` method was changed to return
an iterator [1].
We only use the result for iteration, or, in this case, to pass a bunch
of "reporters" to the error handler middleware, therefore we need to
accept an iterable here.
[1]: https://laravel.com/docs/5.8/upgrade#container-generators
- Stop trying to implement Laravel's Application contract, which
has no value for us.
- Stop inheriting from the Container, injecting one works equally
well and does not clutter up the interfaces.
- Inject the Paths collection instead of unwrapping it again, for
better encapsulation.
This brings us one step closer toward upgrading our Laravel
components (#2055), because we no longer need to adopt the changes
to the Application contract.
This extends our boot exception handling block to also catch and format
all exceptions that could be thrown while building our request handler,
i.e. the middleware stack handling requests.
The only exceptions that would now not be handled in this way could be
raised by Zend's `RequestHandlerRunner` and its delegates, which we
should be able to rely on.
Exceptions on request execution will be handled by the error handler in
the middleware stack.
Fixes#1607.
...not based on status code.
To simplify this logic, we now use the same error "type" both when
routes are not found and specific models are not found. One exception is
ours, one is from Laravel, but for the purposes of error handling they
should be treated the same.
Fixesflarum/core#1641.
The error handling middleware now expects an array of reporters.
Extensions can register new reporters in the container like this:
use Flarum\Foundation\ErrorHandling\Reporter;
$container->tag(NewReporter::class, Reporter::class);
Note that this is just an implementation detail and will be hidden
behind an extender.
This separates the error registry (mapping exception types to status
codes) from actual handling (the middleware) as well as error formatting
(Whoops, pretty error pages or JSON-API?) and reporting (log? Sentry?).
The components can be reused in different places (e.g. the API client
and the error handler middleware both need the registry to understand
all the exceptions Flarum knows how to handle), while still allowing to
change only the parts that need to change (the API stack always uses the
JSON-API formatter, and the forum stack switches between Whoops and
pretty error pages based on debug mode).
Finally, this paves the way for some planned features and extensibility:
- A console error handler can build on top of the registry.
- Extensions can register new exceptions and how to handle them.
- Extensions can change how we report exceptions (e.g. Sentry).
- We can build more pretty error pages, even different ones for
exceptions having the same status code.
* Integration tests: Memoize request handler as well
This is useful to send HTTP requests (or their PSR-7 equivalents)
through the entire application's middleware stack (instead of
talking to specific controllers, which should be considered
implementation detail).
* Add tests for CSRF token check
* Integration tests: Configure vendor path
Now that this is possible, make the easy change...
* Implement middleware for CSRF token verification
This fixes a rather large oversight in Flarum's codebase, which was that
we had no explicit CSRF protection using the traditional token approach.
The JS frontend was actually sending these tokens, but the backend did
not require them.
* Accept CSRF token in request body as well
* Refactor tests to shorten HTTP requests
Multiple tests now provide JSON request bodies, and others copy cookies
from previous responses, so let's provide convenient helpers for these.
* Fixed issue with tmp/storage/views not existing, this caused tmpname to notice.
Fixed csrf test that assumed an access token allows application access, which is actually api token.
Improved return type hinting in the StartSession middleware
* Using a different setting key now, so that it won't break tests whenever you re-run them once smtp is set.
Fixed, badly, the test to create users etc caused by the prepareDatabase flushing all settings by default.
* added custom view, now needs translation
- Simpler class naming:
Frontend\CompilerFactory → Frontend\Assets
Frontend\HtmlDocumentFactory → Frontend\Frontend
Frontend\HtmlDocument → Frontend\Document
- Remove AssetInterface and simply collect callbacks in Frontend\Assets
instead
- Remove ContentInterface because it serves no purpose (never type-
hinted or type-checked)
- Commit and add asset URLs to the Document via a content callback
instead of in the Document factory class itself
- Add translations and locale assets to Assets separate to the assets
factory, as non-forum/admin asset bundles probably won't want them
- Update Frontend Extender to allow the creation of new asset bundles
- Make custom LESS validation listener a standalone class instead of
extending RecompileFrontendAssets
Having a custom view implies that a friendly message is displayed to
the user, in which case we can bet that the exception won't need to be
"debugged" per se.
* fixed not being able to use master token because id column no longer holds key
* added flexibility of user_id column
* added tests to confirm the api keys actually work as intended
Seems the created_at column has no default value. This was always the case, at least that's what I can tell from a clean install and no migrations changing that default value.
```
$table->timestamp('created_at');
```
* Remove AbstractOAuth2Controller
There is no reason to provide an implementation for a specific oAuth2
library in core; it's not generic enough (eg. auth-twitter can't use it).
This code could be moved into another package which auth extensions
depend on, but it's a negligible amount of relatively simple code that
I don't think it's worth the trouble.
* Introduce login providers
Users can have many login providers (a combination of a provider name
and an identifier for that user, eg. their Facebook ID).
After retrieving user data from a provider (eg. Facebook), you pass the
login provider details into the Auth\ResponseFactory. If an associated
user is found, a response that logs them in will be returned. If not, a
registration token will be created so the user can proceed to sign up.
Once the token is fulfilled, the login provider will be associated with
the user.
By not letting PHP render the stack trace, we prevent displaying
sensitive information (such as the database credentials). Instead,
we display a simple line with the exception message.
In the console, the full exception can still be shown, as that is
a tool only for forum admins anyway.
Fixes#1421.
This is in preparation for fixing #1421 - it allows us to
encapsulate the exception handling in the server classes, so that
we can keep the skeleton (flarum/flarum) lean.
By passing in just the frontend identifier, we can hide some of the
implementation details, in this case the identifier of the Frontend
instance in the IoC container.
Depending on the state of the Flarum installation (installed, not
installed, currently upgrading, maintenance mode), we should enable
different sets of service providers.
For example, during installation we should not resolve a setting
repository from the container. This new architecture lets us do so,
but we can easily (and cleanly) register a different implementation
during installation.
This should prevent problems such as #1370 in the future.
These are completely distinct functionalities, toggled through the
system-wide debug flag. By moving the selection of the middleware
to use to the place where the middleware pipe is built, we make
the middleware itself be unaware of these flags. The two classes
are more focused on what they are doing, with the constructor
dependencies clearly representing their requirements.
In addition, this means we can just use the HandleErrorsWithWhoops
middleware in the installer, which means we do not need to worry
about how to inject a SettingsRepositoryInterface implementation
when flarum is not yet set up.
Refactor Frontend + Asset code
- Use Laravel's Filesystem component for asset IO, meaning theoretically
assets should be storable on S3 etc.
- More reliable checking for asset recompilation when debug mode is on,
so you don't have to constantly delete the compiled assets to force
a recompile. Should also fix issues with locale JS files being
recompiled with the same name and cached.
- Remove JavaScript minification, because it will be done by Webpack
(exception is for the TextFormatter JS).
- Add support for JS sourcemaps.
- Separate frontend view and assets completely. This is an important
distinction because frontend assets are compiled independent of a
request, whereas putting together a view depends on a request.
- Bind frontend view/asset factory instances to the container (in
service providers) rather than subclassing. Asset and content
populators can be added to these factories – these are simply objects
that populate the asset compilers or the view with information.
- Add RouteHandlerFactory functions that make it easy to hook up a
frontend controller with a frontend instance ± some content.
- Remove the need for "nojs"
- Fix cache:clear command
- Recompile assets when settings/enabled extensions change
This finally adopts the new standardized interfaces instead of the
work-in-progress ones with the `Interop\` prefix.
Since we have now updated to PHP 7.1, we can also use Stratigility
3.0 as the middleware dispatcher.