Merge remote-tracking branch 'forked/2.4' into upgrade-google2fa
# Conflicts: # composer.lock
This commit is contained in:
@@ -60,6 +60,13 @@ final class CreateScheduleCommand
|
||||
*/
|
||||
public $components;
|
||||
|
||||
/**
|
||||
* Whether to notify that the incident was reported.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $notify;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
@@ -72,6 +79,7 @@ final class CreateScheduleCommand
|
||||
'scheduled_at' => 'required|string',
|
||||
'completed_at' => 'nullable|string',
|
||||
'components' => 'nullable|array',
|
||||
'notify' => 'nullable|bool',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -83,10 +91,11 @@ final class CreateScheduleCommand
|
||||
* @param string $scheduled_at
|
||||
* @param string $completed_at
|
||||
* @param array $components
|
||||
* @param bool $notify
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name, $message, $status, $scheduled_at, $completed_at, array $components = [])
|
||||
public function __construct($name, $message, $status, $scheduled_at, $completed_at, $components, $notify)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->message = $message;
|
||||
@@ -94,5 +103,6 @@ final class CreateScheduleCommand
|
||||
$this->scheduled_at = $scheduled_at;
|
||||
$this->completed_at = $completed_at;
|
||||
$this->components = $components;
|
||||
$this->notify = $notify;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,18 +36,27 @@ final class ScheduleWasCreatedEvent implements ActionInterface, ScheduleEventInt
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* Whether to notify that the incident was reported.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $notify;
|
||||
|
||||
/**
|
||||
* Create a new schedule was created event instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\User $user
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
* @param bool notify
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, Schedule $schedule)
|
||||
public function __construct(User $user, Schedule $schedule, $notify = false)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->schedule = $schedule;
|
||||
$this->notify = $notify;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,8 +66,7 @@ class CreateScheduleCommandHandler
|
||||
{
|
||||
try {
|
||||
$schedule = Schedule::create($this->filter($command));
|
||||
|
||||
event(new ScheduleWasCreatedEvent($this->auth->user(), $schedule));
|
||||
event(new ScheduleWasCreatedEvent($this->auth->user(), $schedule, (bool) $command->notify));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new ValidationException(new MessageBag([$e->getMessage()]));
|
||||
}
|
||||
@@ -96,6 +95,7 @@ class CreateScheduleCommandHandler
|
||||
'status' => $command->status,
|
||||
'scheduled_at' => $scheduledAt,
|
||||
'completed_at' => $completedAt,
|
||||
'notify' => $command->notify,
|
||||
];
|
||||
|
||||
$availableParams = array_filter($params, function ($val) {
|
||||
|
||||
@@ -51,6 +51,9 @@ class SendScheduleEmailNotificationHandler
|
||||
public function handle(ScheduleEventInterface $event)
|
||||
{
|
||||
$schedule = $event->schedule;
|
||||
if (!$event->notify) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First notify all global subscribers.
|
||||
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get()->each(function ($subscriber) use ($schedule) {
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace CachetHQ\Cachet\Foundation\Providers;
|
||||
|
||||
use CachetHQ\Cachet\Http\Middleware\Acceptable;
|
||||
use CachetHQ\Cachet\Http\Middleware\Authenticate;
|
||||
use CachetHQ\Cachet\Http\Middleware\RemoteUserAuthenticate;
|
||||
use CachetHQ\Cachet\Http\Middleware\Timezone;
|
||||
use CachetHQ\Cachet\Http\Middleware\VerifyCsrfToken;
|
||||
use CachetHQ\Cachet\Http\Routes\ApiSystemRoutes;
|
||||
@@ -151,6 +152,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||
|
||||
if ($applyAlwaysAuthenticate && !$this->isWhiteListedAuthRoute($routes)) {
|
||||
$middleware[] = Authenticate::class;
|
||||
$middleware[] = RemoteUserAuthenticate::class;
|
||||
}
|
||||
|
||||
$router->group(['middleware' => $middleware], function (Router $router) use ($routes) {
|
||||
|
||||
@@ -73,7 +73,8 @@ class ScheduleController extends AbstractApiController
|
||||
Binput::get('status'),
|
||||
Binput::get('scheduled_at'),
|
||||
Binput::get('completed_at'),
|
||||
Binput::get('components', [])
|
||||
Binput::get('components', []),
|
||||
Binput::get('notify', false)
|
||||
));
|
||||
} catch (QueryException $e) {
|
||||
throw new BadRequestHttpException();
|
||||
|
||||
@@ -45,8 +45,7 @@ class MetricController extends Controller
|
||||
public function showAddMetric()
|
||||
{
|
||||
return View::make('dashboard.metrics.add')
|
||||
->withPageTitle(trans('dashboard.metrics.add.title').' - '.trans('dashboard.dashboard'))
|
||||
->withAcceptableThresholds(Metric::ACCEPTABLE_THRESHOLDS);
|
||||
->withPageTitle(trans('dashboard.metrics.add.title').' - '.trans('dashboard.dashboard'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,8 +131,7 @@ class MetricController extends Controller
|
||||
{
|
||||
return View::make('dashboard.metrics.edit')
|
||||
->withPageTitle(trans('dashboard.metrics.edit.title').' - '.trans('dashboard.dashboard'))
|
||||
->withMetric($metric)
|
||||
->withAcceptableThresholds(Metric::ACCEPTABLE_THRESHOLDS);
|
||||
->withMetric($metric);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@ use AltThree\Validator\ValidationException;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
|
||||
use CachetHQ\Cachet\Integrations\Contracts\System;
|
||||
use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
@@ -35,13 +36,21 @@ class ScheduleController extends Controller
|
||||
*/
|
||||
protected $subMenu = [];
|
||||
|
||||
/**
|
||||
* The system instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Integrations\Contracts\System
|
||||
*/
|
||||
protected $system;
|
||||
|
||||
/**
|
||||
* Creates a new schedule controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(System $system)
|
||||
{
|
||||
$this->system = $system;
|
||||
View::share('subTitle', trans('dashboard.schedule.title'));
|
||||
}
|
||||
|
||||
@@ -70,7 +79,8 @@ class ScheduleController extends Controller
|
||||
|
||||
return View::make('dashboard.maintenance.add')
|
||||
->withPageTitle(trans('dashboard.schedule.add.title').' - '.trans('dashboard.dashboard'))
|
||||
->withIncidentTemplates($incidentTemplates);
|
||||
->withIncidentTemplates($incidentTemplates)
|
||||
->withNotificationsEnabled($this->system->canNotifySubscribers());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +97,8 @@ class ScheduleController extends Controller
|
||||
Binput::get('status', Schedule::UPCOMING),
|
||||
Binput::get('scheduled_at'),
|
||||
Binput::get('completed_at'),
|
||||
Binput::get('components', [])
|
||||
Binput::get('components', []),
|
||||
Binput::get('notify', false)
|
||||
));
|
||||
} catch (ValidationException $e) {
|
||||
return cachet_redirect('dashboard.schedule.create')
|
||||
|
||||
@@ -31,7 +31,7 @@ class SubscriberController extends Controller
|
||||
{
|
||||
return View::make('dashboard.subscribers.index')
|
||||
->withPageTitle(trans('dashboard.subscribers.subscribers').' - '.trans('dashboard.dashboard'))
|
||||
->withSubscribers(Subscriber::all());
|
||||
->withSubscribers(Subscriber::with('subscriptions.component')->get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,9 +15,11 @@ use Barryvdh\Cors\HandleCors;
|
||||
use CachetHQ\Cachet\Http\Middleware\Admin;
|
||||
use CachetHQ\Cachet\Http\Middleware\ApiAuthentication;
|
||||
use CachetHQ\Cachet\Http\Middleware\Authenticate;
|
||||
use CachetHQ\Cachet\Http\Middleware\CacheControl;
|
||||
use CachetHQ\Cachet\Http\Middleware\Localize;
|
||||
use CachetHQ\Cachet\Http\Middleware\ReadyForUse;
|
||||
use CachetHQ\Cachet\Http\Middleware\RedirectIfAuthenticated;
|
||||
use CachetHQ\Cachet\Http\Middleware\RemoteUserAuthenticate;
|
||||
use CachetHQ\Cachet\Http\Middleware\SetupAlreadyCompleted;
|
||||
use CachetHQ\Cachet\Http\Middleware\SubscribersConfigured;
|
||||
use CachetHQ\Cachet\Http\Middleware\Throttler;
|
||||
@@ -44,16 +46,18 @@ class Kernel extends HttpKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'admin' => Admin::class,
|
||||
'can' => Authorize::class,
|
||||
'cors' => HandleCors::class,
|
||||
'auth' => Authenticate::class,
|
||||
'auth.api' => ApiAuthentication::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'localize' => Localize::class,
|
||||
'ready' => ReadyForUse::class,
|
||||
'setup' => SetupAlreadyCompleted::class,
|
||||
'subscribers' => SubscribersConfigured::class,
|
||||
'throttle' => Throttler::class,
|
||||
'admin' => Admin::class,
|
||||
'auth.api' => ApiAuthentication::class,
|
||||
'auth.remoteuser' => RemoteUserAuthenticate::class,
|
||||
'auth' => Authenticate::class,
|
||||
'cache' => CacheControl::class,
|
||||
'can' => Authorize::class,
|
||||
'cors' => HandleCors::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'localize' => Localize::class,
|
||||
'ready' => ReadyForUse::class,
|
||||
'setup' => SetupAlreadyCompleted::class,
|
||||
'subscribers' => SubscribersConfigured::class,
|
||||
'throttle' => Throttler::class,
|
||||
];
|
||||
}
|
||||
|
||||
37
app/Http/Middleware/CacheControl.php
Normal file
37
app/Http/Middleware/CacheControl.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CacheControl
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
$maxAge = time() + 30;
|
||||
|
||||
$response->header('Cache-Control', 'public,max-age='.$maxAge);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
53
app/Http/Middleware/RemoteUserAuthenticate.php
Normal file
53
app/Http/Middleware/RemoteUserAuthenticate.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use CachetHQ\Cachet\Models\User;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RemoteUserAuthenticate
|
||||
{
|
||||
/**
|
||||
* Create a new remote user authenticate instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Guard $auth
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($remoteUser = $request->server('REMOTE_USER')) {
|
||||
$user = User::where('email', '=', $remoteUser)->first();
|
||||
|
||||
if ($user instanceof User && $this->auth->guest()) {
|
||||
$this->auth->login($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -52,10 +52,6 @@ class SubscribersConfigured
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (!$this->config->get('setting.enable_subscribers')) {
|
||||
return cachet_redirect('status-page');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
/**
|
||||
* This is the trust proxies middleware class.
|
||||
@@ -42,6 +43,8 @@ class TrustProxies extends Middleware
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->proxies = empty(env('TRUSTED_PROXIES')) ? '*' : explode(',', trim(env('TRUSTED_PROXIES')));
|
||||
$proxies = Config::get('trustedproxies.proxies');
|
||||
|
||||
$this->proxies = empty($proxies) ? '*' : explode(',', trim($proxies));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ApiSystemRoutes
|
||||
$router->group(['middleware' => ['auth.api']], function (Registrar $router) {
|
||||
$router->get('ping', 'GeneralController@ping');
|
||||
$router->get('version', 'GeneralController@version');
|
||||
$router->get('status', 'GeneralController@status');
|
||||
$router->get('status', ['uses' => 'GeneralController@status', 'middleware' => ['cache']]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,13 +62,6 @@ class Metric extends Model implements HasPresenter
|
||||
*/
|
||||
const VISIBLE_HIDDEN = 2;
|
||||
|
||||
/**
|
||||
* Array of acceptable threshold minutes.
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
const ACCEPTABLE_THRESHOLDS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60];
|
||||
|
||||
/**
|
||||
* The model's attributes.
|
||||
*
|
||||
@@ -134,7 +127,6 @@ class Metric extends Model implements HasPresenter
|
||||
'default_value' => 'required|numeric',
|
||||
'places' => 'required|numeric|between:0,4',
|
||||
'default_view' => 'required|numeric|between:0,3',
|
||||
'threshold' => 'required|numeric|between:0,10',
|
||||
'visible' => 'required|numeric|between:0,2',
|
||||
];
|
||||
|
||||
|
||||
@@ -12,21 +12,19 @@
|
||||
namespace CachetHQ\Cachet\Models;
|
||||
|
||||
use AltThree\Validator\ValidatingTrait;
|
||||
use CachetHQ\Cachet\Presenters\UserPresenter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use McCool\LaravelAutoPresenter\HasPresenter;
|
||||
|
||||
/**
|
||||
* This is the user model.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class User extends Authenticatable implements HasPresenter
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use Notifiable, ValidatingTrait;
|
||||
|
||||
@@ -211,14 +209,4 @@ class User extends Authenticatable implements HasPresenter
|
||||
{
|
||||
return trim($this->google_2fa_secret) !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the presenter class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPresenterClass()
|
||||
{
|
||||
return UserPresenter::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ class ComponentStatusChangedNotification extends Notification
|
||||
|
||||
return (new SlackMessage())
|
||||
->$status()
|
||||
->content(trans('notifications.component.status_update.slack.subject'))
|
||||
->content(trans('notifications.component.status_update.slack.title'))
|
||||
->attachment(function ($attachment) use ($content, $notifiable) {
|
||||
$attachment->title($content, cachet_route('status-page'))
|
||||
->fields(array_filter([
|
||||
|
||||
@@ -133,8 +133,7 @@ class NewIncidentNotification extends Notification
|
||||
->fields(array_filter([
|
||||
'ID' => "#{$this->incident->id}",
|
||||
'Link' => $this->incident->permalink,
|
||||
]))
|
||||
->footer(trans('cachet.subscriber.unsubscribe', ['link' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code)]));
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +124,7 @@ class NewScheduleNotification extends Notification implements ShouldQueue
|
||||
->fields(array_filter([
|
||||
'ID' => "#{$this->schedule->id}",
|
||||
'Status' => $this->schedule->human_status,
|
||||
]))
|
||||
->footer(trans('cachet.subscriber.unsubscribe', ['link' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code)]));
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Presenters;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Laravolt\Avatar\Facade as Avatar;
|
||||
use McCool\LaravelAutoPresenter\BasePresenter;
|
||||
|
||||
/**
|
||||
* This is the user presenter class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class UserPresenter extends BasePresenter implements Arrayable
|
||||
{
|
||||
/**
|
||||
* Returns the users avatar.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function avatar()
|
||||
{
|
||||
if (Config::get('setting.enable_external_dependencies')) {
|
||||
return sprintf('https://www.gravatar.com/avatar/%s?size=%d', md5(strtolower($this->email)), 200);
|
||||
}
|
||||
|
||||
return Avatar::create($this->username)->toBase64();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the presenter instance to an array.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_merge($this->wrappedObject->toArray(), [
|
||||
'avatar' => $this->avatar(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user