--- /dev/null
+<?php
+
+namespace BookStack\Console\Commands;
+
+use BookStack\User;
+use BookStack\Repos\UserRepo;
+use Illuminate\Console\Command;
+
+class DeleteUsers extends Command{
+
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'bookstack:delete-users';
+
+ protected $user;
+
+ protected $userRepo;
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Delete users that are not "admin" or system users.';
+
+ public function __construct(User $user, UserRepo $userRepo)
+ {
+ $this->user = $user;
+ $this->userRepo = $userRepo;
+ parent::__construct();
+ }
+
+ public function handle()
+ {
+ $confirm = $this->ask('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)');
+ $numDeleted = 0;
+ if (strtolower(trim($confirm)) === 'yes')
+ {
+ $totalUsers = $this->user->count();
+ $users = $this->user->where('system_name', '=', null)->with('roles')->get();
+ foreach ($users as $user)
+ {
+ if ($user->hasSystemRole('admin'))
+ {
+ // don't delete users with "admin" role
+ continue;
+ }
+ $this->userRepo->destroy($user);
+ ++$numDeleted;
+ }
+ $this->info("Deleted $numDeleted of $totalUsers total users.");
+ }
+ else
+ {
+ $this->info('Exiting...');
+ }
+ }
+
+}
use Exception;
use Illuminate\Auth\AuthenticationException;
+use Illuminate\Http\Request;
+use Illuminate\Pipeline\Pipeline;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Auth\Access\AuthorizationException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class Handler extends ExceptionHandler
{
return response()->view('errors/' . $code, ['message' => $message], $code);
}
+ // Handle 404 errors with a loaded session to enable showing user-specific information
+ if ($this->isExceptionType($e, NotFoundHttpException::class)) {
+ return $this->loadErrorMiddleware($request, function ($request) use ($e) {
+ $message = $e->getMessage() ?: trans('errors.404_page_not_found');
+ return response()->view('errors/404', ['message' => $message], 404);
+ });
+ }
+
return parent::render($request, $e);
}
+ /**
+ * Load the middleware required to show state/session-enabled error pages.
+ * @param Request $request
+ * @param $callback
+ * @return mixed
+ */
+ protected function loadErrorMiddleware(Request $request, $callback)
+ {
+ $middleware = (\Route::getMiddlewareGroups()['web_errors']);
+ return (new Pipeline($this->container))
+ ->send($request)
+ ->through($middleware)
+ ->then($callback);
+ }
+
/**
* Check the exception chain to compare against the original exception type.
* @param Exception $e
* @param string $bookSlug
* @param string $pageSlug
* @return Response
+ * @throws NotFoundException
*/
public function show($bookSlug, $pageSlug)
{
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
} catch (NotFoundException $e) {
$page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug);
- if ($page === null) abort(404);
+ if ($page === null) throw $e;
return redirect($page->getUrl());
}
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\BookStack\Http\Middleware\Localization::class
],
+ 'web_errors' => [
+ \BookStack\Http\Middleware\EncryptCookies::class,
+ \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
+ \Illuminate\Session\Middleware\StartSession::class,
+ \Illuminate\View\Middleware\ShareErrorsFromSession::class,
+ \BookStack\Http\Middleware\VerifyCsrfToken::class,
+ \BookStack\Http\Middleware\Localization::class
+ ],
'api' => [
'throttle:60,1',
'bindings',
*/
public function isOnlyAdmin(User $user)
{
- if (!$user->roles->pluck('name')->contains('admin')) return false;
+ if (!$user->hasSystemRole('admin')) return false;
- $adminRole = $this->role->getRole('admin');
+ $adminRole = $this->role->getSystemRole('admin');
if ($adminRole->users->count() > 1) return false;
return true;
}
*/
public function hasSystemRole($role)
{
- return $this->roles->pluck('system_name')->contains('admin');
+ return $this->roles->pluck('system_name')->contains($role);
}
/**
Feel free to create issues to request new features or to report bugs and problems. Just please follow the template given when creating the issue.
-Pull requests are very welcome. If the scope of your pull request is very large it may be best to open the pull request early or create an issue for it to discuss how it will fit in to the project and plan out the merge.
+### Pull Request
+
+Pull requests are very welcome. If the scope of your pull request is large it may be best to open the pull request early or create an issue for it to discuss how it will fit in to the project and plan out the merge.
+
+Pull requests should be created from the `master` branch and should be merged back into `master` once done. Please do not build from or request a merge into the `release` branch as this is only for publishing releases.
+
+If you are looking to alter CSS or JavaScript content please edit the source files found in `resources/assets`. Any CSS or JS files within `public` are built from these source files and therefore should not be edited directly.
## Website, Docs & Blog
@extends('simple-layout')
@section('content')
-
-
<div class="container">
<p> </p>
</div>
@if (setting('app-public') || !user()->isDefault())
-
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card">
<h3 class="text-muted">{{ trans('errors.error_occurred') }}</h3>
<div class="body">
- <h5>{{ $message }}</h5>
+ <h5>{{ $message or 'An unknown error occurred' }}</h5>
<p><a href="{{ baseUrl('/') }}" class="button outline">{{ trans('errors.return_home') }}</a></p>
</div>
</div>
--- /dev/null
+<?php namespace Tests;
+
+class ErrorTest extends TestCase
+{
+
+ public function test_404_page_does_not_show_login()
+ {
+ // Due to middleware being handled differently this will not fail
+ // if our custom, middleware-loaded handler fails but this is here
+ // as a reminder and as a general check in the event of other issues.
+ $editor = $this->getEditor();
+ $this->actingAs($editor);
+ $notFound = $this->get('/fgfdngldfnotfound');
+ $notFound->assertStatus(404);
+ $notFound->assertDontSeeText('Log in');
+ $notFound->assertSeeText($editor->getShortName(9));
+ }
+}
\ No newline at end of file