Laravel 10 + Cachet Core

This commit is contained in:
James Brooks
2024-01-19 20:03:17 +00:00
parent 8b565ab7f0
commit cf674850dd
1271 changed files with 8105 additions and 123368 deletions
@@ -1,198 +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\Http\Controllers\Api;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Response;
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
abstract class AbstractApiController extends Controller
{
/**
* The HTTP response headers.
*
* @var array
*/
protected $headers = [];
/**
* The HTTP response meta data.
*
* @var array
*/
protected $meta = [];
/**
* The HTTP response data.
*
* @var mixed
*/
protected $data = null;
/**
* The HTTP response status code.
*
* @var int
*/
protected $statusCode = 200;
/**
* Set the response headers.
*
* @param array $headers
*
* @return $this
*/
protected function setHeaders(array $headers)
{
$this->headers = $headers;
return $this;
}
/**
* Set the response meta data.
*
* @param array $meta
*
* @return $this
*/
protected function setMetaData(array $meta)
{
$this->meta = $meta;
return $this;
}
/**
* Set the response meta data.
*
* @param array $data
*
* @return $this
*/
protected function setData($data)
{
$this->data = $data;
return $this;
}
/**
* Set the response status code.
*
* @param int $statusCode
*
* @return $this
*/
protected function setStatusCode($statusCode)
{
$this->statusCode = $statusCode;
return $this;
}
/**
* Respond with an item response.
*
* @param mixed
*
* @return \Illuminate\Http\JsonResponse
*/
public function item($item)
{
return $this->setData(AutoPresenter::decorate($item))->respond();
}
/**
* Respond with a collection response.
*
* @param \Illuminate\Support\Collection $collection
*
* @return \Illuminate\Http\JsonResponse
*/
public function collection(Collection $collection)
{
return $this->setData(AutoPresenter::decorate($collection))->respond();
}
/**
* Respond with a pagination response.
*
* @param \Illuminate\Pagination\Paginator $paginator
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
protected function paginator(Paginator $paginator, Request $request)
{
foreach ($request->query as $key => $value) {
if ($key != 'page') {
$paginator->appends($key, $value);
}
}
$pagination = [
'pagination' => [
'total' => (int) $paginator->total(),
'count' => count($paginator->items()),
'per_page' => (int) $paginator->perPage(),
'current_page' => (int) $paginator->currentPage(),
'total_pages' => (int) $paginator->lastPage(),
'links' => [
'next_page' => $paginator->nextPageUrl(),
'previous_page' => $paginator->previousPageUrl(),
],
],
];
$items = $paginator->getCollection();
return $this->setMetaData($pagination)->setData(AutoPresenter::decorate($items->values()))->respond();
}
/**
* Respond with a no content response.
*
* @return \Illuminate\Http\JsonResponse
*/
protected function noContent()
{
return $this->setStatusCode(204)->respond();
}
/**
* Build the response.
*
* @return \Illuminate\Http\Response
*/
protected function respond()
{
$response = [];
if (!empty($this->meta)) {
$response['meta'] = $this->meta;
}
$response['data'] = $this->data;
if ($this->data instanceof Arrayable) {
$response['data'] = $this->data->toArray();
}
return Response::json($response, $this->statusCode, $this->headers);
}
}
@@ -1,137 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Models\Component;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ComponentController extends AbstractApiController
{
/**
* Get all components.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
if (app(Guard::class)->check()) {
$components = Component::query();
} else {
$components = Component::enabled();
}
if ($tags = Binput::get('tags')) {
$components->withAnyTags($tags);
}
$components->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$components->sort($sortBy, $direction);
}
$components = $components->paginate(Binput::get('per_page', 20));
return $this->paginator($components, Request::instance());
}
/**
* Get a single component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Component $component)
{
return $this->item($component);
}
/**
* Create a new component.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
try {
$component = execute(new CreateComponentCommand(
Binput::get('name'),
Binput::get('description'),
Binput::get('status'),
Binput::get('link'),
Binput::get('order'),
Binput::get('group_id'),
(bool) Binput::get('enabled', true),
Binput::get('meta'),
Binput::get('tags')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($component);
}
/**
* Update an existing component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Component $component)
{
try {
execute(new UpdateComponentCommand(
$component,
Binput::get('name'),
Binput::get('description'),
Binput::get('status'),
Binput::get('link'),
Binput::get('order'),
Binput::get('group_id'),
Binput::get('enabled', $component->enabled),
Binput::get('meta'),
Binput::get('tags'),
(bool) Binput::get('silent', false)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($component);
}
/**
* Delete an existing component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Component $component)
{
execute(new RemoveComponentCommand($component));
return $this->noContent();
}
}
@@ -1,145 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\CreateComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\RemoveComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Models\ComponentGroup;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the component group controller.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
*/
class ComponentGroupController extends AbstractApiController
{
/**
* The user session object.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $guard;
/**
* Creates a new component group controller instance.
*
* @param \Illuminate\Contracts\Auth\Guard $guard
*/
public function __construct(Guard $guard)
{
$this->guard = $guard;
}
/**
* Get all groups.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$groups = ComponentGroup::query();
if (!$this->guard->check()) {
$groups = ComponentGroup::visible();
}
$groups->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::get('order', 'asc');
$groups->sort($sortBy, $direction);
}
$groups = $groups->paginate(Binput::get('per_page', 20));
return $this->paginator($groups, Request::instance());
}
/**
* Get a single group.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(ComponentGroup $group)
{
return $this->item($group);
}
/**
* Create a new component group.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
try {
$group = execute(new CreateComponentGroupCommand(
Binput::get('name'),
Binput::get('order', 0),
Binput::get('collapsed', 0),
Binput::get('visible', ComponentGroup::VISIBLE_AUTHENTICATED)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($group);
}
/**
* Update an existing group.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(ComponentGroup $group)
{
try {
$group = execute(new UpdateComponentGroupCommand(
$group,
Binput::get('name'),
Binput::get('order'),
Binput::get('collapsed'),
Binput::get('visible')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($group);
}
/**
* Delete an existing group.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(ComponentGroup $group)
{
execute(new RemoveComponentGroupCommand($group));
return $this->noContent();
}
}
@@ -1,63 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Integrations\Contracts\Releases;
use CachetHQ\Cachet\Integrations\Contracts\System;
/**
* This is the general api controller.
*
* @author James Brooks <james@alt-three.com>
*/
class GeneralController extends AbstractApiController
{
/**
* Ping endpoint allows API consumers to check the version.
*
* @return \Illuminate\Http\JsonResponse
*/
public function ping()
{
return $this->item('Pong!');
}
/**
* Endpoint to show the Cachet version.
*
* @return \Illuminate\Http\JsonResponse
*/
public function version()
{
$latest = app()->make(Releases::class)->latest();
return $this->setMetaData([
'on_latest' => version_compare(CACHET_VERSION, $latest['tag_name']) === 1,
'latest' => $latest,
])->item(CACHET_VERSION);
}
/**
* Get the system status message.
*
* @return \Illuminate\Http\JsonResponse
*/
public function status()
{
$system = app()->make(System::class)->getStatus();
return $this->item([
'status' => $system['system_status'],
'message' => $system['system_message'],
]);
}
}
@@ -1,135 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\RemoveIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand;
use CachetHQ\Cachet\Models\Incident;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class IncidentController extends AbstractApiController
{
/**
* Get all incidents.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$incidentVisibility = app(Guard::class)->check() ? 0 : 1;
$incidents = Incident::where('visible', '>=', $incidentVisibility);
$incidents->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$incidents->sort($sortBy, $direction);
}
$incidents = $incidents->paginate(Binput::get('per_page', 20));
return $this->paginator($incidents, Request::instance());
}
/**
* Get a single incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Incident $incident)
{
return $this->item($incident);
}
/**
* Create a new incident.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
try {
$incident = execute(new CreateIncidentCommand(
Binput::get('name'),
Binput::get('status'),
Binput::get('message', null, false, false),
(bool) Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
(bool) Binput::get('notify', true),
(bool) Binput::get('stickied', false),
Binput::get('occurred_at'),
Binput::get('template'),
Binput::get('vars', []),
Binput::get('meta', [])
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($incident);
}
/**
* Update an existing incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Incident $incident)
{
try {
$incident = execute(new UpdateIncidentCommand(
$incident,
Binput::get('name'),
Binput::get('status'),
Binput::get('message'),
(bool) Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
(bool) Binput::get('notify', true),
(bool) Binput::get('stickied', false),
Binput::get('occurred_at'),
Binput::get('template'),
Binput::get('vars', [])
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($incident);
}
/**
* Delete an existing incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Incident $incident)
{
execute(new RemoveIncidentCommand($incident));
return $this->noContent();
}
}
@@ -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\Http\Controllers\Api;
use CachetHQ\Cachet\Models\IncidentTemplate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Support\Facades\Request;
class IncidentTemplateController extends AbstractApiController
{
/**
* Get all incident templates.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$templates = IncidentTemplate::query();
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$templates->sort($sortBy, $direction);
}
$templates = $templates->paginate(Binput::get('per_page', 20));
return $this->paginator($templates, Request::instance());
}
/**
* Get a single incident templates.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $incidentTemplate
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(IncidentTemplate $incidentTemplate)
{
return $this->item($incidentTemplate);
}
}
@@ -1,134 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\IncidentUpdate\CreateIncidentUpdateCommand;
use CachetHQ\Cachet\Bus\Commands\IncidentUpdate\RemoveIncidentUpdateCommand;
use CachetHQ\Cachet\Bus\Commands\IncidentUpdate\UpdateIncidentUpdateCommand;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentUpdate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the incident update controller.
*
* @author James Brooks <james@alt-three.com>
*/
class IncidentUpdateController extends AbstractApiController
{
/**
* Return all updates on the incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\JsonResponse
*/
public function index(Incident $incident)
{
$updates = $incident->updates()->orderBy('created_at', 'desc');
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$updates->sort($sortBy, $direction);
}
$updates = $updates->paginate(Binput::get('per_page', 20));
return $this->paginator($updates, Request::instance());
}
/**
* Return a single incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
* @param \CachetHQ\Cachet\Models\IncidentUpdate $update
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Incident $incident, IncidentUpdate $update)
{
return $this->item($update);
}
/**
* Create a new incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\JsonResponse
*/
public function store(Incident $incident)
{
try {
$update = execute(new CreateIncidentUpdateCommand(
$incident,
Binput::get('status'),
Binput::get('message'),
Binput::get('component_id'),
Binput::get('component_status'),
Auth::user()
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($update);
}
/**
* Update an incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
* @param \CachetHQ\Cachet\Models\IncidentUpdate $update
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Incident $incident, IncidentUpdate $update)
{
try {
$update = execute(new UpdateIncidentUpdateCommand(
$update,
Binput::get('status'),
Binput::get('message'),
Auth::user()
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($update);
}
/**
* Create a new incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
* @param \CachetHQ\Cachet\Models\IncidentUpdate $update
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Incident $incident, IncidentUpdate $update)
{
try {
execute(new RemoveIncidentUpdateCommand($update));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->noContent();
}
}
@@ -1,129 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricCommand;
use CachetHQ\Cachet\Models\Metric;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class MetricController extends AbstractApiController
{
/**
* Get all metrics.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function index()
{
$metrics = Metric::query();
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$metrics->sort($sortBy, $direction);
}
$metrics = $metrics->paginate(Binput::get('per_page', 20));
return $this->paginator($metrics, Request::instance());
}
/**
* Get a single metric.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Metric $metric)
{
return $this->item($metric);
}
/**
* Create a new metric.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
try {
$metric = execute(new CreateMetricCommand(
Binput::get('name'),
Binput::get('suffix'),
Binput::get('description'),
Binput::get('default_value'),
Binput::get('calc_type', 0),
Binput::get('display_chart', true),
Binput::get('places', 2),
Binput::get('default_view', Binput::get('view', 1)),
Binput::get('threshold', 5),
Binput::get('order', 0),
Binput::get('visible', 1)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($metric);
}
/**
* Update an existing metric.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Metric $metric)
{
try {
$metric = execute(new UpdateMetricCommand(
$metric,
Binput::get('name'),
Binput::get('suffix'),
Binput::get('description'),
Binput::get('default_value'),
Binput::get('calc_type'),
Binput::get('display_chart'),
Binput::get('places'),
Binput::get('default_view', Binput::get('view')),
Binput::get('threshold'),
Binput::get('order'),
Binput::get('visible')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($metric);
}
/**
* Delete an existing metric.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Metric $metric)
{
execute(new RemoveMetricCommand($metric));
return $this->noContent();
}
}
@@ -1,97 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricPointCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricPointCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricPointCommand;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class MetricPointController extends AbstractApiController
{
/**
* Get a single metric point.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
*
* @return \Illuminate\Http\JsonResponse
*/
public function index(Metric $metric, MetricPoint $metricPoint)
{
$points = $metric->points()->paginate(Binput::get('per_page', 20));
return $this->paginator($points, Request::instance());
}
/**
* Create a new metric point.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function store(Metric $metric)
{
try {
$metricPoint = execute(new CreateMetricPointCommand(
$metric,
Binput::get('value'),
Binput::get('timestamp')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($metricPoint);
}
/**
* Updates a metric point.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Metric $metric, MetricPoint $metricPoint)
{
$metricPoint = execute(new UpdateMetricPointCommand(
$metricPoint,
$metric,
Binput::get('value'),
Binput::get('timestamp')
));
return $this->item($metricPoint);
}
/**
* Destroys a metric point.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Metric $metric, MetricPoint $metricPoint)
{
execute(new RemoveMetricPointCommand($metricPoint));
return $this->noContent();
}
}
@@ -1,129 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
use CachetHQ\Cachet\Models\Schedule;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the schedule controller.
*
* @author James Brooks <james@alt-three.com>
*/
class ScheduleController extends AbstractApiController
{
/**
* Return all schedules.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$schedule = Schedule::query();
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$schedule->sort($sortBy, $direction);
}
$schedule = $schedule->paginate(Binput::get('per_page', 20));
return $this->paginator($schedule, Request::instance());
}
/**
* Return a single schedule.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Schedule $schedule)
{
return $this->item($schedule);
}
/**
* Create a new schedule.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
try {
$schedule = execute(new CreateScheduleCommand(
Binput::get('name'),
Binput::get('message', null, false, false),
Binput::get('status'),
Binput::get('scheduled_at'),
Binput::get('completed_at'),
Binput::get('components', []),
Binput::get('notify', false)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($schedule);
}
/**
* Update a schedule.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(Schedule $schedule)
{
try {
$schedule = execute(new UpdateScheduleCommand(
$schedule,
Binput::get('name'),
Binput::get('message'),
Binput::get('status'),
Binput::get('scheduled_at'),
Binput::get('completed_at'),
Binput::get('components', [])
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($schedule);
}
/**
* Delete a schedule.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Schedule $schedule)
{
try {
execute(new DeleteScheduleCommand($schedule));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->noContent();
}
}
@@ -1,74 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Models\Subscriber;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the subscriber controller class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SubscriberController extends AbstractApiController
{
/**
* Get all subscribers.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$subscribers = Subscriber::paginate(Binput::get('per_page', 20));
return $this->paginator($subscribers, Request::instance());
}
/**
* Create a new subscriber.
*
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
$verified = Binput::get('verify', app(Repository::class)->get('setting.skip_subscriber_verification'));
try {
$subscriber = execute(new SubscribeSubscriberCommand(Binput::get('email'), $verified, Binput::get('components', null)));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($subscriber);
}
/**
* Delete a subscriber.
*
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Subscriber $subscriber)
{
execute(new UnsubscribeSubscriberCommand($subscriber));
return $this->noContent();
}
}
@@ -1,37 +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\Http\Controllers\Api;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriptionCommand;
use CachetHQ\Cachet\Models\Subscription;
/**
* This is the subscription controller class.
*
* @author James Brooks <james@alt-three.com>
*/
class SubscriptionController extends AbstractApiController
{
/**
* Delete a subscription.
*
* @param \CachetHQ\Cachet\Models\Subscription $subscription
*
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Subscription $subscription)
{
execute(new UnsubscribeSubscriptionCommand($subscription));
return $this->noContent();
}
}
-144
View File
@@ -1,144 +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\Http\Controllers;
use CachetHQ\Cachet\Bus\Events\User\UserFailedTwoAuthEvent;
use CachetHQ\Cachet\Bus\Events\User\UserLoggedInEvent;
use CachetHQ\Cachet\Bus\Events\User\UserLoggedOutEvent;
use CachetHQ\Cachet\Bus\Events\User\UserPassedTwoAuthEvent;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use PragmaRX\Google2FA\Google2FA;
class AuthController extends Controller
{
/**
* Shows the login view.
*
* @return \Illuminate\View\View
*/
public function showLogin()
{
return View::make('auth.login')
->withPageTitle(trans('dashboard.login.login'));
}
/**
* Logs the user in.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postLogin()
{
$loginData = Binput::only(['username', 'password', 'remember_me']);
// Login with username or email.
$loginKey = filter_var($loginData['username'], FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
$loginData[$loginKey] = Arr::pull($loginData, 'username');
$rememberUser = Arr::pull($loginData, 'remember_me') === '1';
// Validate login credentials.
if (Auth::validate($loginData)) {
Auth::once($loginData);
if (Auth::user()->hasTwoFactor) {
Session::put('2fa_id', Auth::user()->id);
return cachet_redirect('auth.two-factor');
}
Auth::attempt($loginData, $rememberUser);
event(new UserLoggedInEvent(Auth::user()));
return Redirect::intended(cachet_route('dashboard'));
}
return cachet_redirect('auth.login')
->withInput(Binput::except('password'))
->withError(trans('forms.login.invalid'));
}
/**
* Shows the two-factor-auth view.
*
* @return \Illuminate\View\View
*/
public function showTwoFactorAuth()
{
return View::make('auth.two-factor-auth');
}
/**
* Validates the Two Factor token.
*
* This feels very hacky, but we have to juggle authentication and codes.
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postTwoFactor()
{
// Check that we have a session.
if ($userId = Session::pull('2fa_id')) {
$code = str_replace(' ', '', Binput::get('code'));
// Maybe a temp login here.
Auth::loginUsingId($userId);
$user = Auth::user();
$google2fa = new Google2FA();
$valid = $google2fa->verifyKey($user->google_2fa_secret, $code);
if ($valid) {
event(new UserPassedTwoAuthEvent($user));
event(new UserLoggedInEvent($user));
return Redirect::intended('dashboard');
} else {
event(new UserFailedTwoAuthEvent($user));
// Failed login, log back out.
Auth::logout();
return cachet_redirect('auth.login')->withError(trans('forms.login.invalid-token'));
}
}
return cachet_redirect('auth.login')->withError(trans('forms.login.invalid-token'));
}
/**
* Logs the user out, deleting their session etc.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function logoutAction()
{
event(new UserLoggedOutEvent(Auth::user()));
Auth::logout();
return cachet_redirect('status-page');
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
}
@@ -1,132 +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\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\IncidentTemplate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\QueryException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ApiController extends AbstractApiController
{
/**
* Updates a component with the entered info.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*
* @return \CachetHQ\Cachet\Models\Component
*/
public function postUpdateComponent(Component $component)
{
try {
execute(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
Binput::get('status'),
$component->link,
$component->order,
$component->group_id,
$component->enabled,
$component->meta,
false
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $this->item($component);
}
/**
* Updates a components ordering.
*
* @return array
*/
public function postUpdateComponentOrder()
{
$componentData = Binput::get('ids');
foreach ($componentData as $order => $componentId) {
try {
$component = Component::find($componentId);
execute(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
$component->status,
$component->link,
$order + 1,
$component->group_id,
$component->enabled,
$component->meta,
true
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
}
return $this->collection(Component::query()->orderBy('order')->get());
}
/**
* Updates the order of component groups.
*
* @return array
*/
public function postUpdateComponentGroupOrder()
{
$groupData = Binput::get('ids');
foreach ($groupData as $order => $groupId) {
$group = ComponentGroup::find($groupId);
execute(new UpdateComponentGroupCommand(
$group,
$group->name,
$order + 1,
$group->collapsed,
$group->visible
));
}
return $this->collection(ComponentGroup::query()->orderBy('order')->get());
}
/**
* Returns a template by slug.
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*
* @return \CachetHQ\Cachet\Models\IncidentTemplate
*/
public function getIncidentTemplate()
{
$templateSlug = Binput::get('slug');
if ($template = IncidentTemplate::where('slug', '=', $templateSlug)->first()) {
return $template;
}
throw new ModelNotFoundException("Incident template for $templateSlug could not be found.");
}
}
@@ -1,196 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the component controller class.
*
* @author James Brooks <james@alt-three.com>
*/
class ComponentController extends Controller
{
/**
* Array of sub-menu items.
*
* @var array
*/
protected $subMenu = [];
/**
* Creates a new component controller instance.
*
* @return void
*/
public function __construct()
{
$this->subMenu = [
'components' => [
'title' => trans('dashboard.components.components'),
'url' => cachet_route('dashboard.components'),
'icon' => 'ion-ios-browsers',
'active' => false,
],
'groups' => [
'title' => trans_choice('dashboard.components.groups.groups', 2),
'url' => cachet_route('dashboard.components.groups'),
'icon' => 'ion-folder',
'active' => false,
],
];
View::share([
'subMenu' => $this->subMenu,
'subTitle' => trans_choice('dashboard.components.components', 2),
]);
}
/**
* Shows the components view.
*
* @return \Illuminate\View\View
*/
public function showComponents()
{
$components = Component::with('group')->orderBy('order')->orderBy('created_at')->get();
$this->subMenu['components']['active'] = true;
return View::make('dashboard.components.index')
->withPageTitle(trans_choice('dashboard.components.components', 2).' - '.trans('dashboard.dashboard'))
->withComponents($components)
->withSubMenu($this->subMenu);
}
/**
* Shows the edit component view.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\View\View
*/
public function showEditComponent(Component $component)
{
$groups = ComponentGroup::all();
$pageTitle = sprintf('"%s" - %s - %s', $component->name, trans('dashboard.components.edit.title'), trans('dashboard.dashboard'));
return View::make('dashboard.components.edit')
->withPageTitle($pageTitle)
->withComponent($component)
->withGroups($groups);
}
/**
* Updates a component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\RedirectResponse
*/
public function updateComponentAction(Component $component)
{
$componentData = Binput::get('component');
try {
$component = execute(new UpdateComponentCommand(
$component,
$componentData['name'],
$componentData['description'],
$componentData['status'],
$componentData['link'],
$componentData['order'],
$componentData['group_id'],
$componentData['enabled'],
null, // Meta data cannot be supplied through the dashboard yet.
$componentData['tags'], // Meta data cannot be supplied through the dashboard yet.
true // Silent since we're not really making changes to the component (this should be optional)
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.components.edit', [$component->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.components.edit', [$component->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.edit.success')));
}
/**
* Shows the add component view.
*
* @return \Illuminate\View\View
*/
public function showAddComponent()
{
return View::make('dashboard.components.add')
->withPageTitle(trans('dashboard.components.add.title').' - '.trans('dashboard.dashboard'))
->withGroups(ComponentGroup::all());
}
/**
* Creates a new component.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createComponentAction()
{
$componentData = Binput::get('component');
try {
$component = execute(new CreateComponentCommand(
$componentData['name'],
$componentData['description'],
$componentData['status'],
$componentData['link'],
$componentData['order'],
$componentData['group_id'],
$componentData['enabled'],
null, // Meta data cannot be supplied through the dashboard yet.
$componentData['tags']
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.components.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.components')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.add.success')));
}
/**
* Deletes a given component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteComponentAction(Component $component)
{
execute(new RemoveComponentCommand($component));
return cachet_redirect('dashboard.components')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.delete.success')));
}
}
@@ -1,173 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\CreateComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\RemoveComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the component group controller class.
*
* @author James Brooks <james@alt-three.com>
*/
class ComponentGroupController extends Controller
{
/**
* Array of sub-menu items.
*
* @var array
*/
protected $subMenu = [];
/**
* Creates a new component controller instance.
*
* @return void
*/
public function __construct()
{
$this->subMenu = [
'components' => [
'title' => trans('dashboard.components.components'),
'url' => cachet_route('dashboard.components'),
'icon' => 'ion-ios-browsers',
'active' => false,
],
'groups' => [
'title' => trans_choice('dashboard.components.groups.groups', 2),
'url' => cachet_route('dashboard.components.groups'),
'icon' => 'ion-folder',
'active' => false,
],
];
View::share([
'sub_menu' => $this->subMenu,
'subTitle' => trans_choice('dashboard.components.components', 2),
]);
}
/**
* Shows the component groups view.
*
* @return \Illuminate\View\View
*/
public function showComponentGroups()
{
$this->subMenu['groups']['active'] = true;
return View::make('dashboard.components.groups.index')
->withPageTitle(trans_choice('dashboard.components.groups.groups', 2).' - '.trans('dashboard.dashboard'))
->withGroups(ComponentGroup::orderBy('order')->get())
->withSubMenu($this->subMenu);
}
/**
* Deletes a given component group.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteComponentGroupAction(ComponentGroup $group)
{
execute(new RemoveComponentGroupCommand($group));
return cachet_redirect('dashboard.components.groups')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.delete.success')));
}
/**
* Shows the add component group view.
*
* @return \Illuminate\View\View
*/
public function showAddComponentGroup()
{
return View::make('dashboard.components.groups.add')
->withPageTitle(trans('dashboard.components.groups.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Shows the edit component group view.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\View\View
*/
public function showEditComponentGroup(ComponentGroup $group)
{
return View::make('dashboard.components.groups.edit')
->withPageTitle(trans('dashboard.components.groups.edit.title').' - '.trans('dashboard.dashboard'))
->withGroup($group);
}
/**
* Creates a new component.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postAddComponentGroup()
{
try {
$group = execute(new CreateComponentGroupCommand(
Binput::get('name'),
Binput::get('order', 0),
Binput::get('collapsed'),
Binput::get('visible')
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.components.groups.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.components.groups')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.add.success')));
}
/**
* Updates a component group.
*
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return \Illuminate\Http\RedirectResponse
*/
public function updateComponentGroupAction(ComponentGroup $group)
{
try {
$group = execute(new UpdateComponentGroupCommand(
$group,
Binput::get('name'),
$group->order,
Binput::get('collapsed'),
Binput::get('visible')
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.components.groups.edit', [$group->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.components.groups.edit', [$group->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.edit.success')));
}
}
@@ -1,206 +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\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Bus\Commands\User\WelcomeUserCommand;
use CachetHQ\Cachet\Integrations\Contracts\Feed;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\View;
use Jenssegers\Date\Date;
/**
* This is the dashboard controller class.
*
* @author James Brooks <james@alt-three.com>
*/
class DashboardController extends Controller
{
/**
* Start date.
*
* @var \Jenssegers\Date\Date
*/
protected $startDate;
/**
* The timezone the status page is running in.
*
* @var string
*/
protected $timeZone;
/**
* The feed integration.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\Feed
*/
protected $feed;
/**
* The user session object.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $guard;
/**
* Creates a new dashboard controller instance.
*
* @param \CachetHQ\Cachet\Integrations\Contracts\Feed $feed
* @param \Illuminate\Contracts\Auth\Guard $guard
*
* @return void
*/
public function __construct(Feed $feed, Guard $guard)
{
$this->feed = $feed;
$this->guard = $guard;
$this->startDate = new Date();
$this->dateTimeZone = Config::get('cachet.timezone');
}
/**
* Redirect /admin to /dashboard.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function redirectAdmin()
{
return cachet_redirect('dashboard');
}
/**
* Shows the dashboard view.
*
* @return \Illuminate\View\View
*/
public function showDashboard()
{
$components = Component::orderBy('order')->get();
$incidents = $this->getIncidents();
$subscribers = $this->getSubscribers();
$componentGroups = $this->getVisibleGroupedComponents();
$ungroupedComponents = Component::ungrouped()->get();
$welcomeUser = !Auth::user()->welcomed;
if ($welcomeUser) {
execute(new WelcomeUserCommand(Auth::user()));
}
$entries = null;
if ($feed = $this->feed->latest() !== 1) {
if (is_object($feed)) {
$entries = array_slice($feed->channel->item, 0, 5);
}
}
return View::make('dashboard.index')
->withPageTitle(trans('dashboard.dashboard'))
->withComponents($components)
->withIncidents($incidents)
->withSubscribers($subscribers)
->withEntries($entries)
->withComponentGroups($componentGroups)
->withUngroupedComponents($ungroupedComponents)
->withWelcomeUser($welcomeUser);
}
/**
* Fetches all of the incidents over the last 30 days.
*
* @return \Illuminate\Support\Collection
*/
protected function getIncidents()
{
$allIncidents = Incident::whereBetween('occurred_at', [
$this->startDate->copy()->subDays(30)->format('Y-m-d').' 00:00:00',
$this->startDate->format('Y-m-d').' 23:59:59',
])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
return (new Date($incident->occurred_at))
->setTimezone($this->dateTimeZone)->toDateString();
});
// Add in days that have no incidents
foreach (range(0, 30) as $i) {
$date = (new Date($this->startDate))->setTimezone($this->dateTimeZone)->subDays($i);
if (!isset($allIncidents[$date->toDateString()])) {
$allIncidents[$date->toDateString()] = [];
}
}
// Sort the array so it takes into account the added days
$allIncidents = $allIncidents->sortBy(function ($value, $key) {
return strtotime($key);
}, SORT_REGULAR, false);
return $allIncidents;
}
/**
* Fetches all of the subscribers over the last 30 days.
*
* @return \Illuminate\Support\Collection
*/
protected function getSubscribers()
{
$allSubscribers = Subscriber::whereBetween('created_at', [
$this->startDate->copy()->subDays(30)->format('Y-m-d').' 00:00:00',
$this->startDate->format('Y-m-d').' 23:59:59',
])->orderBy('created_at', 'desc')->get()->groupBy(function (Subscriber $incident) {
return (new Date($incident->created_at))
->setTimezone($this->dateTimeZone)->toDateString();
});
// Add in days that have no incidents
foreach (range(0, 30) as $i) {
$date = (new Date($this->startDate))->setTimezone($this->dateTimeZone)->subDays($i);
if (!isset($allSubscribers[$date->toDateString()])) {
$allSubscribers[$date->toDateString()] = [];
}
}
// Sort the array so it takes into account the added days
$allSubscribers = $allSubscribers->sortBy(function ($value, $key) {
return strtotime($key);
}, SORT_REGULAR, false);
return $allSubscribers;
}
/**
* Get visible grouped components.
*
* @return \Illuminate\Support\Collection
*/
protected function getVisibleGroupedComponents()
{
$componentGroupsBuilder = ComponentGroup::query();
if (!$this->guard->check()) {
$componentGroupsBuilder = ComponentGroup::visible();
}
$usedComponentGroups = Component::grouped()->pluck('group_id');
return $componentGroupsBuilder->used($usedComponentGroups)
->get();
}
}
@@ -1,300 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\RemoveIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand;
use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the incident controller.
*
* @author James Brooks <james@alt-three.com>
*/
class IncidentController extends Controller
{
/**
* Stores the sub-sidebar tree list.
*
* @var array
*/
protected $subMenu = [];
/**
* The guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* The system instance.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
protected $system;
/**
* Creates a new incident controller instance.
*
* @param \Illuminate\Contracts\Auth\Guard $auth
*
* @return void
*/
public function __construct(Guard $auth, System $system)
{
$this->auth = $auth;
$this->system = $system;
View::share('subTitle', trans('dashboard.incidents.title'));
}
/**
* Shows the incidents view.
*
* @return \Illuminate\View\View
*/
public function showIncidents()
{
$incidents = Incident::with('user')->orderBy('created_at', 'desc')->get();
return View::make('dashboard.incidents.index')
->withPageTitle(trans('dashboard.incidents.incidents').' - '.trans('dashboard.dashboard'))
->withIncidents($incidents);
}
/**
* Shows the add incident view.
*
* @return \Illuminate\View\View
*/
public function showAddIncident()
{
return View::make('dashboard.incidents.add')
->withPageTitle(trans('dashboard.incidents.add.title').' - '.trans('dashboard.dashboard'))
->withComponentsInGroups(ComponentGroup::with('components')->get())
->withComponentsOutGroups(Component::where('group_id', '=', 0)->get())
->withNotificationsEnabled($this->system->canNotifySubscribers())
->withIncidentTemplates(IncidentTemplate::all());
}
/**
* Shows the incident templates.
*
* @return \Illuminate\View\View
*/
public function showTemplates()
{
return View::make('dashboard.templates.index')
->withPageTitle(trans('dashboard.incidents.templates.title').' - '.trans('dashboard.dashboard'))
->withIncidentTemplates(IncidentTemplate::all());
}
/**
* Creates a new incident.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createIncidentAction()
{
try {
$incident = execute(new CreateIncidentCommand(
Binput::get('name'),
Binput::get('status'),
Binput::get('message', null, false, false),
Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
Binput::get('notify', false),
Binput::get('stickied', false),
Binput::get('occurred_at'),
null,
[],
['seo' => Binput::get('seo', [])]
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.incidents.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.incidents')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.add.success')));
}
/**
* Shows the add incident template view.
*
* @return \Illuminate\View\View
*/
public function showAddIncidentTemplate()
{
return View::make('dashboard.templates.add')
->withPageTitle(trans('dashboard.incidents.templates.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Shows the edit incident template view.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\View\View
*/
public function showEditTemplateAction(IncidentTemplate $template)
{
return View::make('dashboard.templates.edit')
->withPageTitle(trans('dashboard.incidents.templates.edit.title').' - '.trans('dashboard.dashboard'))
->withTemplate($template);
}
/**
* Deletes an incident template.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteTemplateAction(IncidentTemplate $template)
{
$template->delete();
return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.delete.success')));
}
/**
* Creates a new incident template.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createIncidentTemplateAction()
{
try {
IncidentTemplate::create([
'name' => Binput::get('name'),
'template' => Binput::get('template', null, false, false),
]);
} catch (ValidationException $e) {
return cachet_redirect('dashboard.templates.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.add.success')));
}
/**
* Deletes a given incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteIncidentAction(Incident $incident)
{
execute(new RemoveIncidentCommand($incident));
return cachet_redirect('dashboard.incidents')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.delete.success')));
}
/**
* Shows the edit incident view.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\View\View
*/
public function showEditIncidentAction(Incident $incident)
{
return View::make('dashboard.incidents.edit')
->withPageTitle(trans('dashboard.incidents.edit.title').' - '.trans('dashboard.dashboard'))
->withIncident($incident)
->withComponentsInGroups(ComponentGroup::with('components')->get())
->withComponentsOutGroups(Component::where('group_id', '=', 0)->get())
->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
* Edit an incident.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editIncidentAction(Incident $incident)
{
try {
$incident = execute(new UpdateIncidentCommand(
$incident,
Binput::get('name'),
Binput::get('status'),
Binput::get('message'),
Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
Binput::get('notify', true),
Binput::get('stickied', false),
Binput::get('occurred_at'),
null,
[],
['seo' => Binput::get('seo', [])]
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.incidents.edit', ['id' => $incident->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.edit.failure')))
->withErrors($e->getMessageBag());
}
if ($incident->component) {
$incident->component->update(['status' => Binput::get('component_status')]);
}
return cachet_redirect('dashboard.incidents.edit', ['id' => $incident->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.edit.success')));
}
/**
* Edit an incident template.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editTemplateAction(IncidentTemplate $template)
{
try {
$template->update(Binput::get('template'));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template)
->withTemplateErrors($e->getMessageBag()->getErrors());
}
return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template);
}
}
@@ -1,161 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the incident template controller.
*
* @author James Brooks <james@alt-three.com>
*/
class IncidentTemplateController extends Controller
{
/**
* Stores the sub-sidebar tree list.
*
* @var array
*/
protected $subMenu = [];
/**
* The guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* The system instance.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
protected $system;
/**
* Creates a new incident controller instance.
*
* @param \Illuminate\Contracts\Auth\Guard $auth
*
* @return void
*/
public function __construct(Guard $auth, System $system)
{
$this->auth = $auth;
$this->system = $system;
View::share('sub_title', trans('dashboard.incidents.title'));
}
/**
* Shows the incident templates.
*
* @return \Illuminate\View\View
*/
public function showTemplates()
{
return View::make('dashboard.templates.index')
->withPageTitle(trans('dashboard.incidents.templates.title').' - '.trans('dashboard.dashboard'))
->withIncidentTemplates(IncidentTemplate::all());
}
/**
* Shows the add incident template view.
*
* @return \Illuminate\View\View
*/
public function showAddIncidentTemplate()
{
return View::make('dashboard.templates.add')
->withPageTitle(trans('dashboard.incidents.templates.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Shows the edit incident template view.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\View\View
*/
public function showEditTemplateAction(IncidentTemplate $template)
{
return View::make('dashboard.templates.edit')
->withPageTitle(trans('dashboard.incidents.templates.edit.title').' - '.trans('dashboard.dashboard'))
->withTemplate($template);
}
/**
* Deletes an incident template.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteTemplateAction(IncidentTemplate $template)
{
$template->delete();
return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.delete.success')));
}
/**
* Creates a new incident template.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createIncidentTemplateAction()
{
try {
IncidentTemplate::create([
'name' => Binput::get('name'),
'template' => Binput::get('template', null, false, false),
]);
} catch (ValidationException $e) {
return cachet_redirect('dashboard.templates.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.add.success')));
}
/**
* Edit an incident template.
*
* @param \CachetHQ\Cachet\Models\IncidentTemplate $template
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editTemplateAction(IncidentTemplate $template)
{
try {
$template->update(Binput::get('template'));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template)
->withTemplateErrors($e->getMessageBag()->getErrors());
}
return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template);
}
}
@@ -1,172 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\IncidentUpdate\CreateIncidentUpdateCommand;
use CachetHQ\Cachet\Bus\Commands\IncidentUpdate\UpdateIncidentUpdateCommand;
use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use CachetHQ\Cachet\Models\IncidentUpdate;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the incident update controller.
*
* @author James Brooks <james@alt-three.com>
*/
class IncidentUpdateController extends Controller
{
/**
* Stores the sub-sidebar tree list.
*
* @var array
*/
protected $subMenu = [];
/**
* The guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* The system instance.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
protected $system;
/**
* Creates a new incident controller instance.
*
* @param \Illuminate\Contracts\Auth\Guard $auth
*
* @return void
*/
public function __construct(Guard $auth, System $system)
{
$this->auth = $auth;
$this->system = $system;
View::share('sub_title', trans('dashboard.incidents.title'));
}
/**
* Shows the incident update form.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\View\View
*/
public function showIncidentUpdates(Incident $incident)
{
return View::make('dashboard.incidents.updates.index')->withIncident($incident);
}
/**
* Shows the incident update form.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\View\View
*/
public function showCreateIncidentUpdateAction(Incident $incident)
{
return View::make('dashboard.incidents.updates.add')
->withIncident($incident)
->withIncidentTemplates(IncidentTemplate::all())
->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
* Creates a new incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createIncidentUpdateAction(Incident $incident)
{
try {
$incidentUpdate = execute(new CreateIncidentUpdateCommand(
$incident,
Binput::get('status'),
Binput::get('message'),
Binput::get('component_id'),
Binput::get('component_status'),
$this->auth->user()
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.incidents.updates.create', ['id' => $incident->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.updates.add.failure')))
->withErrors($e->getMessageBag());
}
if ($incident->component) {
$incident->component->update(['status' => Binput::get('component_status')]);
}
return cachet_redirect('dashboard.incidents')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.updates.success')));
}
/**
* Shows the edit incident view.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
* @param \CachetHQ\Cachet\Models\IncidentUpdate $incidentUpdate
*
* @return \Illuminate\View\View
*/
public function showEditIncidentUpdateAction(Incident $incident, IncidentUpdate $incidentUpdate)
{
return View::make('dashboard.incidents.updates.edit')
->withIncident($incident)
->withUpdate($incidentUpdate)
->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
* Edit an incident update.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
* @param \CachetHQ\Cachet\Models\IncidentUpdate $incidentUpdate
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editIncidentUpdateAction(Incident $incident, IncidentUpdate $incidentUpdate)
{
try {
$incidentUpdate = execute(new UpdateIncidentUpdateCommand(
$incidentUpdate,
Binput::get('status'),
Binput::get('message'),
$this->auth->user()
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.incidents.updates.edit', ['incident' => $incident->id, 'incident_update' => $incidentUpdate->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.updates.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.incidents.updates', ['incident' => $incident->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.updates.edit.success')));
}
}
@@ -1,171 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricCommand;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
class MetricController extends Controller
{
/**
* Shows the metrics view.
*
* @return \Illuminate\View\View
*/
public function showMetrics()
{
$metrics = Metric::orderBy('order')->orderBy('id')->get();
return View::make('dashboard.metrics.index')
->withPageTitle(trans('dashboard.metrics.metrics').' - '.trans('dashboard.dashboard'))
->withMetrics($metrics);
}
/**
* Shows the add metric view.
*
* @return \Illuminate\View\View
*/
public function showAddMetric()
{
return View::make('dashboard.metrics.add')
->withPageTitle(trans('dashboard.metrics.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Shows the metric points.
*
* @return \Illuminate\View\View
*/
public function showMetricPoints()
{
return View::make('dashboard.metrics.points.index')
->withPageTitle(trans('dashboard.metrics.points.title').' - '.trans('dashboard.dashboard'))
->withMetrics(MetricPoint::all());
}
/**
* Creates a new metric.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createMetricAction()
{
$metricData = Binput::get('metric');
try {
execute(new CreateMetricCommand(
$metricData['name'],
$metricData['suffix'],
$metricData['description'],
$metricData['default_value'],
$metricData['calc_type'],
$metricData['display_chart'],
$metricData['places'],
$metricData['default_view'],
$metricData['threshold'],
0, // Default order
$metricData['visible']
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.metrics.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.metrics.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.metrics')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.add.success')));
}
/**
* Shows the add metric point view.
*
* @return \Illuminate\View\View
*/
public function showAddMetricPoint()
{
return View::make('dashboard.metrics.points.add')
->withPageTitle(trans('dashboard.metrics.points.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Deletes a given metric.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteMetricAction(Metric $metric)
{
execute(new RemoveMetricCommand($metric));
return cachet_redirect('dashboard.metrics')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.delete.success')));
}
/**
* Shows the edit metric view.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\View\View
*/
public function showEditMetricAction(Metric $metric)
{
return View::make('dashboard.metrics.edit')
->withPageTitle(trans('dashboard.metrics.edit.title').' - '.trans('dashboard.dashboard'))
->withMetric($metric);
}
/**
* Edit an metric.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editMetricAction(Metric $metric)
{
try {
execute(new UpdateMetricCommand(
$metric,
Binput::get('name', null, false),
Binput::get('suffix', null, false),
Binput::get('description', null, false),
Binput::get('default_value', null, false),
Binput::get('calc_type', null, false),
Binput::get('display_chart', null, false),
Binput::get('places', null, false),
Binput::get('default_view', null, false),
Binput::get('threshold', null, false),
null,
Binput::get('visible', null, false)
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.metrics.edit', [$metric->id])
->withInput(Binput::all())
->withTitle(sprintf('<strong>%s</strong>', trans('dashboard.notifications.whoops')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.metrics.edit', [$metric->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.edit.success')));
}
}
@@ -1,175 +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\Http\Controllers\Dashboard;
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;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
/**
* This is the schedule controller class.
*
* @author James Brooks <james@alt-three.com>
*/
class ScheduleController extends Controller
{
/**
* Stores the sub-sidebar tree list.
*
* @var array
*/
protected $subMenu = [];
/**
* The system instance.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
protected $system;
/**
* Creates a new schedule controller instance.
*
* @return void
*/
public function __construct(System $system)
{
$this->system = $system;
View::share('subTitle', trans('dashboard.schedule.title'));
}
/**
* Lists all scheduled maintenance.
*
* @return \Illuminate\View\View
*/
public function showIndex()
{
$schedule = Schedule::orderBy('created_at')->get();
return View::make('dashboard.maintenance.index')
->withPageTitle(trans('dashboard.schedule.schedule').' - '.trans('dashboard.dashboard'))
->withSchedule($schedule);
}
/**
* Shows the add schedule maintenance form.
*
* @return \Illuminate\View\View
*/
public function showAddSchedule()
{
$incidentTemplates = IncidentTemplate::all();
return View::make('dashboard.maintenance.add')
->withPageTitle(trans('dashboard.schedule.add.title').' - '.trans('dashboard.dashboard'))
->withIncidentTemplates($incidentTemplates)
->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
* Creates a new scheduled maintenance.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function addScheduleAction()
{
try {
execute(new CreateScheduleCommand(
Binput::get('name'),
Binput::get('message', null, false, false),
Binput::get('status', Schedule::UPCOMING),
Binput::get('scheduled_at'),
Binput::get('completed_at'),
Binput::get('components', []),
Binput::get('notify', false)
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.schedule.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.schedule.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.schedule')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.add.success')));
}
/**
* Shows the edit schedule maintenance form.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\View\View
*/
public function showEditSchedule(Schedule $schedule)
{
$incidentTemplates = IncidentTemplate::all();
return View::make('dashboard.maintenance.edit')
->withPageTitle(trans('dashboard.schedule.edit.title').' - '.trans('dashboard.dashboard'))
->withIncidentTemplates($incidentTemplates)
->withSchedule($schedule);
}
/**
* Updates the given incident.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\RedirectResponse
*/
public function editScheduleAction(Schedule $schedule)
{
try {
$schedule = execute(new UpdateScheduleCommand(
$schedule,
Binput::get('name', null),
Binput::get('message', null),
Binput::get('status', null),
Binput::get('scheduled_at', null),
Binput::get('completed_at', null),
Binput::get('components', [])
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.schedule.edit', [$schedule->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.schedule.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.schedule.edit', [$schedule->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.edit.success')));
}
/**
* Deletes a given schedule.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteScheduleAction(Schedule $schedule)
{
execute(new DeleteScheduleCommand($schedule));
return cachet_redirect('dashboard.schedule')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.delete.success')));
}
}
@@ -1,438 +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\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Integrations\Contracts\Credits;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Notifications\System\SystemTestNotification;
use CachetHQ\Cachet\Settings\Repository;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
use Monolog\Handler\SyslogHandler;
class SettingsController extends Controller
{
/**
* Array of sub-menu items.
*
* @var array
*/
protected $subMenu = [];
/**
* Creates a new settings controller instance.
*
* @return void
*/
public function __construct()
{
$this->subMenu = [
'setup' => [
'title' => trans('dashboard.settings.app-setup.app-setup'),
'url' => cachet_route('dashboard.settings.setup'),
'icon' => 'ion-gear-b',
'active' => false,
],
'theme' => [
'title' => trans('dashboard.settings.theme.theme'),
'url' => cachet_route('dashboard.settings.theme'),
'icon' => 'ion-paintbrush',
'active' => false,
],
'stylesheet' => [
'title' => trans('dashboard.settings.stylesheet.stylesheet'),
'url' => cachet_route('dashboard.settings.stylesheet'),
'icon' => 'ion-paintbucket',
'active' => false,
],
'customization' => [
'title' => trans('dashboard.settings.customization.customization'),
'url' => cachet_route('dashboard.settings.customization'),
'icon' => 'ion-wand',
'active' => false,
],
'localization' => [
'title' => trans('dashboard.settings.localization.localization'),
'url' => cachet_route('dashboard.settings.localization'),
'icon' => 'ion-earth',
'active' => false,
],
'security' => [
'title' => trans('dashboard.settings.security.security'),
'url' => cachet_route('dashboard.settings.security'),
'icon' => 'ion-lock-combination',
'active' => false,
],
'analytics' => [
'title' => trans('dashboard.settings.analytics.analytics'),
'url' => cachet_route('dashboard.settings.analytics'),
'icon' => 'ion-stats-bars',
'active' => false,
],
'log' => [
'title' => trans('dashboard.settings.log.log'),
'url' => cachet_route('dashboard.settings.log'),
'icon' => 'ion-document-text',
'active' => false,
],
'credits' => [
'title' => trans('dashboard.settings.credits.credits'),
'url' => cachet_route('dashboard.settings.credits'),
'icon' => 'ion-ios-list',
'active' => false,
],
'mail' => [
'title' => trans('dashboard.settings.mail.mail'),
'url' => cachet_route('dashboard.settings.mail'),
'icon' => 'ion-paper-airplane',
'active' => false,
],
'about' => [
'title' => CACHET_VERSION,
'url' => 'javascript: void(0);',
'icon' => 'ion-flag',
'active' => false,
],
];
View::share([
'subTitle' => trans('dashboard.settings.settings'),
'subMenu' => $this->subMenu,
]);
}
/**
* Shows the settings setup view.
*
* @return \Illuminate\View\View
*/
public function showSetupView()
{
$this->subMenu['setup']['active'] = true;
Session::flash('redirect_to', $this->subMenu['setup']['url']);
return View::make('dashboard.settings.app-setup')
->withPageTitle(trans('dashboard.settings.app-setup.app-setup').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu)
->withRawAppAbout(Config::get('setting.app_about'));
}
/**
* Shows the settings analytics view.
*
* @return \Illuminate\View\View
*/
public function showAnalyticsView()
{
$this->subMenu['analytics']['active'] = true;
Session::flash('redirect_to', $this->subMenu['analytics']['url']);
return View::make('dashboard.settings.analytics')
->withPageTitle(trans('dashboard.settings.analytics.analytics').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Shows the settings localization view.
*
* @return \Illuminate\View\View
*/
public function showLocalizationView()
{
$this->subMenu['localization']['active'] = true;
Session::flash('redirect_to', $this->subMenu['localization']['url']);
return View::make('dashboard.settings.localization')
->withPageTitle(trans('dashboard.settings.localization.localization').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Shows the settings customization view.
*
* @return \Illuminate\View\View
*/
public function showCustomizationView()
{
$this->subMenu['customization']['active'] = true;
Session::flash('redirect_to', $this->subMenu['customization']['url']);
return View::make('dashboard.settings.customization')
->withPageTitle(trans('dashboard.settings.customization.customization').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Shows the settings theme view.
*
* @return \Illuminate\View\View
*/
public function showThemeView()
{
$this->subMenu['theme']['active'] = true;
Session::flash('redirect_to', $this->subMenu['theme']['url']);
return View::make('dashboard.settings.theme')
->withPageTitle(trans('dashboard.settings.theme.theme').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Shows the settings security view.
*
* @return \Illuminate\View\View
*/
public function showSecurityView()
{
$this->subMenu['security']['active'] = true;
$unsecureUsers = User::whereNull('google_2fa_secret')->orWhere('google_2fa_secret', '=', '')->get();
Session::flash('redirect_to', $this->subMenu['security']['url']);
return View::make('dashboard.settings.security')
->withPageTitle(trans('dashboard.settings.security.security').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu)
->withUnsecureUsers($unsecureUsers);
}
/**
* Shows the settings stylesheet view.
*
* @return \Illuminate\View\View
*/
public function showStylesheetView()
{
$this->subMenu['stylesheet']['active'] = true;
Session::flash('redirect_to', $this->subMenu['stylesheet']['url']);
return View::make('dashboard.settings.stylesheet')
->withPageTitle(trans('dashboard.settings.stylesheet.stylesheet').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Show the credits view.
*
* @return \Illuminate\View\View
*/
public function showCreditsView()
{
$this->subMenu['credits']['active'] = true;
$credits = app(Credits::class)->latest();
$backers = $credits['backers'];
$contributors = $credits['contributors'];
shuffle($backers);
shuffle($contributors);
return View::make('dashboard.settings.credits')
->withPageTitle(trans('dashboard.settings.credits.credits').' - '.trans('dashboard.dashboard'))
->withBackers($backers)
->withContributors($contributors)
->withSubMenu($this->subMenu);
}
/**
* Show the most recent log.
*
* @return \Illuminate\View\View
*/
public function showLogView()
{
$this->subMenu['log']['active'] = true;
$log = Log::getLogger();
$logContents = '';
collect($log->getHandlers())->reject(function ($handler) {
return $handler instanceof SyslogHandler;
})->each(function ($handler) use (&$logContents, $log) {
if (file_exists($path = $log->getHandlers()[0]->getUrl())) {
$logContents = file_get_contents($path);
}
});
return View::make('dashboard.settings.log')->withLog($logContents)->withSubMenu($this->subMenu);
}
/**
* Show the mail settings view.
*
* @return \Illuminate\View\View
*/
public function showMailView()
{
$this->subMenu['mail']['active'] = true;
return View::make('dashboard.settings.mail')->withConfig(Config::get('mail'));
}
/**
* Test the mail config.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function testMail()
{
Auth::user()->notify(new SystemTestNotification());
return cachet_redirect('dashboard.settings.mail')
->withSuccess(trans('dashboard.notifications.awesome'));
}
/**
* Handle updating of the settings.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postMail()
{
$config = Binput::get('config');
execute(new UpdateConfigCommand($config));
return cachet_redirect('dashboard.settings.mail')
->withInput(Binput::all())
->withSuccess(trans('dashboard.notifications.awesome'));
}
/**
* Updates the status page settings.
*
* @return \Illuminate\View\View
*/
public function postSettings()
{
$setting = app(Repository::class);
if (Binput::get('remove_banner') === '1') {
$setting->set('app_banner', null);
}
$parameters = Binput::all();
if (isset($parameters['header'])) {
if ($header = Binput::get('header', null, false, false)) {
$setting->set('header', $header);
} else {
$setting->delete('header');
}
}
if (isset($parameters['footer'])) {
if ($footer = Binput::get('footer', null, false, false)) {
$setting->set('footer', $footer);
} else {
$setting->delete('footer');
}
}
if (isset($parameters['stylesheet'])) {
if ($stylesheet = Binput::get('stylesheet', null, false, false)) {
$setting->set('stylesheet', $stylesheet);
} else {
$setting->delete('stylesheet');
}
}
if (Binput::hasFile('app_banner')) {
$this->handleUpdateBanner($setting);
}
$excludedParams = [
'_token',
'app_banner',
'remove_banner',
'header',
'footer',
'stylesheet',
];
try {
foreach (Binput::except($excludedParams) as $settingName => $settingValue) {
if ($settingName === 'app_analytics_pi_url') {
$settingValue = rtrim($settingValue, '/');
}
$setting->set($settingName, $settingValue);
}
} catch (Exception $e) {
return Redirect::back()->withErrors(trans('dashboard.settings.edit.failure'));
}
if (Binput::has('app_locale')) {
Lang::setLocale(Binput::get('app_locale'));
}
if (Binput::has('always_authenticate')) {
Artisan::call('route:clear');
}
return Redirect::back()->withSuccess(trans('dashboard.settings.edit.success'));
}
/**
* Handle updating of the banner image.
*
* @param \CachetHQ\Cachet\Settings\Repository $setting
*
* @return void
*/
protected function handleUpdateBanner(Repository $setting)
{
$file = Binput::file('app_banner');
$redirectUrl = $this->subMenu['theme']['url'];
// Image Validation.
// Image size in bytes.
$maxSize = $file->getMaxFilesize();
if ($file->getSize() > $maxSize) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.too-big', ['size' => $maxSize]));
}
if (!$file->isValid() || $file->getError()) {
return Redirect::to($redirectUrl)->withErrors($file->getErrorMessage());
}
if (!Str::startsWith($file->getMimeType(), 'image/')) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.images-only'));
}
// Store the banner.
$setting->set('app_banner', base64_encode(file_get_contents($file->getRealPath())));
// Store the banner type.
$setting->set('app_banner_type', $file->getMimeType());
}
}
@@ -1,89 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Models\Subscriber;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
class SubscriberController extends Controller
{
/**
* Shows the subscribers view.
*
* @return \Illuminate\View\View
*/
public function showSubscribers()
{
return View::make('dashboard.subscribers.index')
->withPageTitle(trans('dashboard.subscribers.subscribers').' - '.trans('dashboard.dashboard'))
->withSubscribers(Subscriber::with('subscriptions.component')->get());
}
/**
* Shows the add subscriber view.
*
* @return \Illuminate\View\View
*/
public function showAddSubscriber()
{
return View::make('dashboard.subscribers.add')
->withPageTitle(trans('dashboard.subscribers.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Creates a new subscriber.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function createSubscriberAction()
{
$verified = app(Repository::class)->get('setting.skip_subscriber_verification');
try {
$subscribers = preg_split("/\r\n|\n|\r/", Binput::get('email'));
foreach ($subscribers as $subscriber) {
execute(new SubscribeSubscriberCommand($subscriber, $verified));
}
} catch (ValidationException $e) {
return cachet_redirect('dashboard.subscribers.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.subscribers.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.subscribers.create')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.subscribers.add.success')));
}
/**
* Deletes a subscriber.
*
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @throws \Exception
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteSubscriberAction(Subscriber $subscriber)
{
execute(new UnsubscribeSubscriberCommand($subscriber));
return cachet_redirect('dashboard.subscribers');
}
}
@@ -1,160 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\User\CreateUserCommand;
use CachetHQ\Cachet\Bus\Commands\User\InviteUserCommand;
use CachetHQ\Cachet\Bus\Commands\User\RemoveUserCommand;
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
class TeamController extends Controller
{
/**
* Shows the team members view.
*
* @return \Illuminate\View\View
*/
public function showTeamView()
{
$team = User::all();
return View::make('dashboard.team.index')
->withPageTitle(trans('dashboard.team.team').' - '.trans('dashboard.dashboard'))
->withTeamMembers($team);
}
/**
* Shows the edit team member view.
*
* @param \CachetHQ\Cachet\Models\User $user
*
* @return \Illuminate\View\View
*/
public function showTeamMemberView(User $user)
{
return View::make('dashboard.team.edit')
->withPageTitle(trans('dashboard.team.edit.title').' - '.trans('dashboard.dashboard'))
->withUser($user);
}
/**
* Shows the add team member view.
*
* @return \Illuminate\View\View
*/
public function showAddTeamMemberView()
{
return View::make('dashboard.team.add')
->withPageTitle(trans('dashboard.team.add.title').' - '.trans('dashboard.dashboard'));
}
/**
* Shows the invite team member view.
*
* @return \Illuminate\View\View
*/
public function showInviteTeamMemberView()
{
return View::make('dashboard.team.invite')
->withPageTitle(trans('dashboard.team.invite.title').' - '.trans('dashboard.dashboard'));
}
/**
* Creates a new team member.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postAddUser()
{
try {
execute(new CreateUserCommand(
Binput::get('username'),
Binput::get('password'),
Binput::get('email'),
Binput::get('level')
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.team.create')
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.add.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.team.create')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.add.success')));
}
/**
* Updates a user.
*
* @param \CachetHQ\Cachet\Models\User $user
*
* @return \Illuminate\View\View
*/
public function postUpdateUser(User $user)
{
$userData = array_filter(Binput::only(['username', 'email', 'password', 'level']));
try {
$user->update($userData);
} catch (ValidationException $e) {
return cachet_redirect('dashboard.team.edit', [$user->id])
->withInput($userData)
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.team.edit', [$user->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')));
}
/**
* Creates a new team member.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postInviteUser()
{
try {
execute(new InviteUserCommand(
array_unique(array_filter((array) Binput::get('emails')))
));
} catch (ValidationException $e) {
return cachet_redirect('dashboard.team.invite')
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.invite.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.team.invite')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.invite.success')));
}
/**
* Delete a user.
*
* @param \CachetHQ\Cachet\Models\User $user
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteUser(User $user)
{
execute(new RemoveUserCommand($user));
return cachet_redirect('dashboard.team')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.delete.success')));
}
}
@@ -1,92 +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\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Events\User\UserDisabledTwoAuthEvent;
use CachetHQ\Cachet\Bus\Events\User\UserEnabledTwoAuthEvent;
use CachetHQ\Cachet\Bus\Events\User\UserRegeneratedApiTokenEvent;
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use PragmaRX\Google2FA\Google2FA;
class UserController extends Controller
{
/**
* Shows the user view.
*
* @return \Illuminate\View\View
*/
public function showUser()
{
return View::make('dashboard.user.index')
->withPageTitle(trans('dashboard.team.profile').' - '.trans('dashboard.dashboard'));
}
/**
* Updates the current user.
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
*
* @return \Illuminate\View\View
*/
public function postUser()
{
$userData = array_filter(Binput::only(['username', 'email', 'password', 'google2fa']));
$enable2FA = (bool) Arr::pull($userData, 'google2fa');
// Let's enable/disable auth
if ($enable2FA && !Auth::user()->hasTwoFactor) {
event(new UserEnabledTwoAuthEvent(Auth::user()));
$google2fa = new Google2FA();
$userData['google_2fa_secret'] = $google2fa->generateSecretKey();
} elseif (!$enable2FA) {
event(new UserDisabledTwoAuthEvent(Auth::user()));
$userData['google_2fa_secret'] = '';
}
try {
Auth::user()->update($userData);
} catch (ValidationException $e) {
return cachet_redirect('dashboard.user')
->withInput($userData)
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')))
->withErrors($e->getMessageBag());
}
return cachet_redirect('dashboard.user')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')));
}
/**
* Regenerates the users API key.
*
* @param \CachetHQ\Cachet\Models\User $user
*
* @return \Illuminate\View\View
*/
public function regenerateApiKey(User $user)
{
$user->api_key = User::generateApiKey();
$user->save();
event(new UserRegeneratedApiTokenEvent($user));
return cachet_redirect('dashboard.user');
}
}
-284
View File
@@ -1,284 +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\Http\Controllers;
use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\View;
/**
* This is the setup controller.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
*/
class SetupController extends Controller
{
/**
* Array of cache drivers.
*
* @var string[]
*/
protected $cacheDrivers = [
'apc' => 'APC(u)',
'array' => 'Array',
'file' => 'File',
'database' => 'Database',
'memcached' => 'Memcached',
'redis' => 'Redis',
];
/**
* Array of cache drivers.
*
* @var string[]
*/
protected $mailDrivers = [
'smtp' => 'SMTP',
'mail' => 'Mail',
'sendmail' => 'Sendmail',
'mailgun' => 'Mailgun',
'mandrill' => 'Mandrill',
'ses' => 'Amazon SES',
'sparkpost' => 'SparkPost',
'log' => 'Log (Testing)',
];
/**
* Array of queue drivers.
*
* @var string[]
*/
protected $queueDrivers = [
'null' => 'None',
'sync' => 'Synchronous',
'database' => 'Database',
'beanstalkd' => 'Beanstalk',
'sqs' => 'Amazon SQS',
'redis' => 'Redis',
];
/**
* Array of step1 rules.
*
* @var string[]
*/
protected $rulesStep1;
/**
* Array of step2 rules.
*
* @var string[]
*/
protected $rulesStep2;
/**
* Array of step3 rules.
*
* @var string[]
*/
protected $rulesStep3;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->rulesStep1 = [
'env.cache_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
'env.session_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
'env.queue_driver' => 'required|in:'.implode(',', array_keys($this->queueDrivers)),
'env.mail_driver' => 'required|in:'.implode(',', array_keys($this->mailDrivers)),
];
$this->rulesStep2 = [
'settings.app_name' => 'required',
'settings.app_domain' => 'required',
'settings.app_timezone' => 'required',
'settings.app_locale' => 'required',
'settings.show_support' => 'bool',
];
$this->rulesStep3 = [
'user.username' => ['required', 'regex:/\A(?!.*[:;]-\))[ -~]+\z/'],
'user.email' => 'email|required',
'user.password' => 'required',
];
}
/**
* Returns the setup page.
*
* @return \Illuminate\View\View
*/
public function getIndex()
{
$requestedLanguages = Request::getLanguages();
$userLanguage = Config::get('app.locale');
$langs = Config::get('langs');
foreach ($requestedLanguages as $language) {
$language = str_replace('_', '-', $language);
if (isset($langs[$language])) {
$userLanguage = $language;
break;
}
}
app('translator')->setLocale($userLanguage);
// Since .env may already be configured, we should show that data!
$cacheConfig = [
'driver' => Config::get('cache.default'),
];
$sessionConfig = [
'driver' => Config::get('session.driver'),
];
$queueConfig = [
'driver' => Config::get('queue.default'),
];
$mailConfig = [
'driver' => Config::get('mail.driver'),
'host' => Config::get('mail.host'),
'from' => Config::get('mail.from'),
'username' => Config::get('mail.username'),
'password' => Config::get('mail.password'),
];
return View::make('setup.index')
->withPageTitle(trans('setup.setup'))
->withCacheDrivers($this->cacheDrivers)
->withQueueDrivers($this->queueDrivers)
->withMailDrivers($this->mailDrivers)
->withUserLanguage($userLanguage)
->withAppUrl(Request::root())
->withCacheConfig($cacheConfig)
->withSessionConfig($sessionConfig)
->withQueueConfig($queueConfig)
->withMailConfig($mailConfig);
}
/**
* Handles validation on step one of the setup form.
*
* @return \Illuminate\Http\Response
*/
public function postStep1()
{
$postData = Binput::all();
$v = Validator::make($postData, $this->rulesStep1);
$v->sometimes('env.mail_host', 'required', function ($input) {
return $input->env['mail_driver'] === 'smtp';
});
$v->sometimes(['env.mail_address', 'env.mail_password'], 'required', function ($input) {
return !in_array($input->env['mail_driver'], ['log', 'smtp']);
});
$v->sometimes(['env.mail_username'], 'required', function ($input) {
return !in_array($input->env['mail_driver'], ['sendmail', 'log']);
});
if ($v->passes()) {
return Response::json(['status' => 1]);
}
return Response::json(['errors' => $v->getMessageBag()], 400);
}
/**
* Handles validation on step two of the setup form.
*
* @return \Illuminate\Http\Response
*/
public function postStep2()
{
$postData = Binput::all();
$v = Validator::make($postData, $this->rulesStep1 + $this->rulesStep2);
if ($v->passes()) {
return Response::json(['status' => 1]);
}
return Response::json(['errors' => $v->getMessageBag()], 400);
}
/**
* Handles the actual app setup, including user, settings and env.
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
*/
public function postStep3()
{
$postData = Binput::all();
$v = Validator::make($postData, $this->rulesStep1 + $this->rulesStep2 + $this->rulesStep3);
if ($v->passes()) {
// Pull the user details out.
$userDetails = Arr::pull($postData, 'user');
$user = User::create([
'username' => $userDetails['username'],
'email' => $userDetails['email'],
'password' => $userDetails['password'],
'level' => User::LEVEL_ADMIN,
]);
Auth::login($user);
$setting = app(Repository::class);
$settings = Arr::pull($postData, 'settings');
foreach ($settings as $settingName => $settingValue) {
$setting->set($settingName, $settingValue);
}
$envData = Arr::pull($postData, 'env');
// Write the env to the .env file.
execute(new UpdateConfigCommand($envData));
if (Request::ajax()) {
return Response::json(['status' => 1]);
}
return cachet_redirect('dashboard');
}
if (Request::ajax()) {
return Response::json(['errors' => $v->getMessageBag()], 400);
}
return cachet_redirect('setup')->withInput()->withErrors($v->getMessageBag());
}
}
-90
View File
@@ -1,90 +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\Http\Controllers;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Invite\ClaimInviteCommand;
use CachetHQ\Cachet\Bus\Commands\User\SignupUserCommand;
use CachetHQ\Cachet\Models\Invite;
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SignupController extends Controller
{
/**
* Handle the signup with invite.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function getSignup($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$invite = Invite::where('code', '=', $code)->first();
if (!$invite || $invite->is_claimed) {
throw new BadRequestHttpException();
}
return View::make('signup')
->withCode($invite->code)
->withUsername(Binput::old('username'))
->withEmail(Binput::old('email', $invite->email));
}
/**
* Handle a signup request.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function postSignup($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$invite = Invite::where('code', '=', $code)->first();
if (!$invite || $invite->is_claimed) {
throw new BadRequestHttpException();
}
try {
execute(new SignupUserCommand(
Binput::get('username'),
Binput::get('password'),
Binput::get('email'),
User::LEVEL_USER
));
} catch (ValidationException $e) {
return cachet_redirect('signup.invite', [$invite->code])
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.signup.failure')))
->withErrors($e->getMessageBag());
}
execute(new ClaimInviteCommand($invite));
return cachet_redirect('status-page')
->withSuccess(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.awesome'), trans('cachet.signup.success')));
}
}
@@ -1,220 +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\Http\Controllers;
use CachetHQ\Badger\Facades\Badger;
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\Schedule;
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
use CachetHQ\Cachet\Services\Dates\DateFactory;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use Jenssegers\Date\Date;
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
/**
* This is the status page controller class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
*/
class StatusPageController extends AbstractApiController
{
/**
* Displays the status page.
*
* @return \Illuminate\View\View
*/
public function showIndex()
{
$onlyDisruptedDays = Config::get('setting.only_disrupted_days');
$appIncidentDays = (int) Config::get('setting.app_incident_days', 1);
$startDate = Date::createFromFormat('Y-m-d', Binput::get('start_date', Date::now()->toDateString()));
$endDate = $startDate->copy()->subDays($appIncidentDays);
$canPageForward = false;
$canPageBackward = false;
$previousDate = null;
$nextDate = null;
if ($onlyDisruptedDays) {
// In this case, start_date GET parameter means the page
$page = (int) Binput::get('start_date', 0);
$allIncidentDays = Incident::where('visible', '>=', (int) !Auth::check())
->select('occurred_at')
->whereBetween('occurred_at', [
$endDate->format('Y-m-d').' 00:00:00',
$startDate->format('Y-m-d').' 23:59:59',
])
->distinct()
->orderBy('occurred_at', 'desc')
->get()
->map(function (Incident $incident) {
return app(DateFactory::class)->make($incident->occurred_at)->toDateString();
})->unique()
->values();
$numIncidentDays = count($allIncidentDays);
$numPages = round($numIncidentDays / max($appIncidentDays, 1));
$selectedDays = $allIncidentDays->slice($page * $appIncidentDays, $appIncidentDays)->all();
if (count($selectedDays) > 0) {
$startDate = Date::createFromFormat('Y-m-d', array_values($selectedDays)[0]);
$endDate = Date::createFromFormat('Y-m-d', array_values(array_slice($selectedDays, -1))[0]);
}
$canPageForward = $page > 0;
$canPageBackward = ($page + 1) < $numPages;
$previousDate = $page + 1;
$nextDate = $page - 1;
} else {
$date = Date::now();
$canPageForward = (bool) $startDate->lt($date->sub('1 day'));
$canPageBackward = Incident::where('occurred_at', '<', $date->format('Y-m-d'))->count() > 0;
$previousDate = $startDate->copy()->subDays($appIncidentDays)->toDateString();
$nextDate = $startDate->copy()->addDays($appIncidentDays)->toDateString();
}
$allIncidents = Incident::with('component', 'updates.incident')
->where('visible', '>=', (int) !Auth::check())->whereBetween('occurred_at', [
$endDate->format('Y-m-d').' 00:00:00',
$startDate->format('Y-m-d').' 23:59:59',
])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
return app(DateFactory::class)->make($incident->occurred_at)->toDateString();
});
if (!$onlyDisruptedDays) {
$incidentDays = array_pad([], $appIncidentDays, null);
// Add in days that have no incidents
foreach ($incidentDays as $i => $day) {
$date = app(DateFactory::class)->make($startDate)->subDays($i);
if (!isset($allIncidents[$date->toDateString()])) {
$allIncidents[$date->toDateString()] = [];
}
}
}
// Sort the array so it takes into account the added days
$allIncidents = $allIncidents->sortBy(function ($value, $key) {
return strtotime($key);
}, SORT_REGULAR, true);
return View::make('index')
->withDaysToShow($appIncidentDays)
->withAllIncidents($allIncidents)
->withCanPageForward($canPageForward)
->withCanPageBackward($canPageBackward)
->withPreviousDate($previousDate)
->withNextDate($nextDate);
}
/**
* Shows an incident in more detail.
*
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return \Illuminate\View\View
*/
public function showIncident(Incident $incident)
{
return View::make('single-incident')->withIncident($incident);
}
/**
* Show a single schedule.
*
* @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\View\View
*/
public function showSchedule(Schedule $schedule)
{
return View::make('single-schedule')->withSchedule($schedule);
}
/**
* Returns metrics in a readily formatted way.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function getMetrics(Metric $metric)
{
$type = Binput::get('filter', AutoPresenter::decorate($metric)->view_name);
$metrics = app(MetricRepository::class);
switch ($type) {
case 'last_hour': $metricData = $metrics->listPointsLastHour($metric);
break;
case 'today': $metricData = $metrics->listPointsToday($metric);
break;
case 'week': $metricData = $metrics->listPointsForWeek($metric);
break;
case 'month': $metricData = $metrics->listPointsForMonth($metric);
break;
default: $metricData = [];
}
return $this->item([
'metric' => $metric->toArray(),
'items' => $metricData,
]);
}
/**
* Generates a Shield (badge) for the component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\Response
*/
public function showComponentBadge(Component $component)
{
$component = AutoPresenter::decorate($component);
switch ($component->status_color) {
case 'reds': $color = Config::get('setting.style_reds', '#FF6F6F');
break;
case 'blues': $color = Config::get('setting.style_blues', '#3498DB');
break;
case 'greens': $color = Config::get('setting.style_greens', '#7ED321');
break;
case 'yellows': $color = Config::get('setting.style_yellows', '#F7CA18');
break;
default: $color = null;
}
$badge = Badger::generate(
$component->name,
$component->human_status,
substr($color, 1),
Binput::get('style', 'flat-square')
);
return Response::make($badge, 200, ['Content-Type' => 'image/svg+xml']);
}
}
@@ -1,224 +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\Http\Controllers;
use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriptionCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UpdateSubscriberSubscriptionCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\VerifySubscriberCommand;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
use CachetHQ\Cachet\Notifications\Subscriber\ManageSubscriptionNotification;
use GrahamCampbell\Binput\Facades\Binput;
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* This is the subscribe controller.
*
* @author James Brooks <james@alt-three.com>
*/
class SubscribeController extends Controller
{
/**
* The illuminate guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* Create a new subscribe controller instance.
*
* @param \Illuminate\Contracts\Auth\Guard $auth
*
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Show the subscribe by email page.
*
* @return \Illuminate\View\View
*/
public function showSubscribe()
{
return View::make('subscribe.subscribe')
->withAboutApp(Markdown::convertToHtml(Config::get('setting.app_about')));
}
/**
* Handle the subscribe user.
*
* @return \Illuminate\View\View
*/
public function postSubscribe()
{
$email = Binput::get('email');
$subscriptions = Binput::get('subscriptions');
$verified = app(Repository::class)->get('setting.skip_subscriber_verification');
try {
$subscription = execute(new SubscribeSubscriberCommand($email, $verified));
} catch (ValidationException $e) {
return cachet_redirect('status-page')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
// Send the subscriber a link to manage their subscription.
$subscription->notify(new ManageSubscriptionNotification());
return redirect()->back()->withSuccess(
sprintf(
'%s %s',
trans('dashboard.notifications.awesome'),
trans('cachet.subscriber.email.manage_subscription')
)
);
}
/**
* Handle the verify subscriber email.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function getVerify($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber) {
throw new BadRequestHttpException();
}
if (!$subscriber->is_verified) {
execute(new VerifySubscriberCommand($subscriber));
}
return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $code]))
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
}
/**
* Handle the unsubscribe.
*
* @param string|null $code
* @param int|null $subscription
*
* @return \Illuminate\View\View
*/
public function getUnsubscribe($code = null, $subscription = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber || !$subscriber->is_verified) {
throw new BadRequestHttpException();
}
if ($subscription) {
execute(new UnsubscribeSubscriptionCommand(Subscription::forSubscriber($subscriber->id)->firstOrFail()));
} else {
execute(new UnsubscribeSubscriberCommand($subscriber));
}
return cachet_redirect('status-page')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed')));
}
/**
* Shows the subscription manager page.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function showManage($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$includePrivate = $this->auth->check();
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
$usedComponentGroups = Component::enabled()->authenticated($includePrivate)->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
$componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
$ungroupedComponents = Component::enabled()->authenticated($includePrivate)->where('group_id', '=', 0)->orderBy('order')->orderBy('created_at')->get();
if (!$subscriber) {
throw new BadRequestHttpException();
}
return View::make('subscribe.manage')
->withUngroupedComponents($ungroupedComponents)
->withSubscriber($subscriber)
->withSubscriptions($subscriber->subscriptions->pluck('component_id')->all())
->withComponentGroups($componentGroups);
}
/**
* Updates the subscription manager for a subscriber.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function postManage($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber) {
throw new BadRequestHttpException();
}
try {
execute(new UpdateSubscriberSubscriptionCommand($subscriber, Binput::get('subscriptions')));
} catch (ValidationException $e) {
return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $subscriber->verify_code]))
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $subscriber->verify_code]))
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.updated-subscribe')));
}
}
+49 -46
View File
@@ -1,65 +1,68 @@
<?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 App\Http;
namespace CachetHQ\Cachet\Http;
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;
use CachetHQ\Cachet\Http\Middleware\TrustProxies;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Routing\Middleware\ValidateSignature;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* @var array
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
TrustProxies::class,
CheckForMaintenanceMode::class,
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware.
* The application's route middleware groups.
*
* @var array
* @var array<string, array<int, class-string|string>>
*/
protected $routeMiddleware = [
'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,
'signed' => ValidateSignature::class,
'subscribers' => SubscribersConfigured::class,
'throttle' => Throttler::class,
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's middleware aliases.
*
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
*
* @var array<string, class-string|string>
*/
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
-43
View File
@@ -1,43 +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\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
/**
* This is the acceptable middleware class.
*
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class Acceptable
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $type
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $type = null)
{
if (!$request->accepts($type ?: 'application/json')) {
throw new NotAcceptableHttpException();
}
return $next($request);
}
}
-63
View File
@@ -1,63 +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\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* This is the admin middleware class.
*
* @author Joseph Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class Admin
{
/**
* The authentication guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* Create a new admin middleware 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 (!$this->auth->check() || ($this->auth->check() && !$this->auth->user()->isAdmin)) {
throw new HttpException(401);
}
return $next($request);
}
}
-76
View File
@@ -1,76 +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\Http\Middleware;
use CachetHQ\Cachet\Models\User;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* This is the api authentication middleware class.
*
* @author Joseph Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class ApiAuthentication
{
/**
* The authentication guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* Create a new api authentication middleware 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
* @param bool $required
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $required = false)
{
if ($this->auth->guest()) {
if ($apiToken = $request->header('X-Cachet-Token')) {
try {
$this->auth->onceUsingId(User::findByApiToken($apiToken)->id);
} catch (ModelNotFoundException $e) {
if ($required) {
throw new HttpException(401);
}
}
} elseif ($required) {
throw new HttpException(401);
}
}
return $next($request);
}
}
+6 -52
View File
@@ -1,63 +1,17 @@
<?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 App\Http\Middleware;
namespace CachetHQ\Cachet\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* This is the authenticate middleware class.
*
* @author Joseph Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class Authenticate
class Authenticate extends Middleware
{
/**
* The authentication guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
* Get the path the user should be redirected to when they are not authenticated.
*/
protected $auth;
/**
* Create a new authenticate middleware instance.
*
* @param \Illuminate\Contracts\Auth\Guard $auth
*
* @return void
*/
public function __construct(Guard $auth)
protected function redirectTo(Request $request): ?string
{
$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 ($this->auth->guest()) {
throw new HttpException(401);
}
return $next($request);
return $request->expectsJson() ? null : route('login');
}
}
-37
View File
@@ -1,37 +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\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;
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array<int, string>
*/
protected $except = [
//
];
}
-89
View File
@@ -1,89 +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\Http\Middleware;
use CachetHQ\Cachet\Settings\Repository as SettingsRepository;
use Closure;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Illuminate\Http\Request;
use Jenssegers\Date\Date;
/**
* This is the localize middleware class.
*
* @author James Brooks <james@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class Localize
{
/**
* The config repository instance.
*
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* The settings repository instance.
*
* @var \CachetHQ\Cachet\Settings\Repository
*/
protected $settings;
/**
* Constructs a new localize middleware instance.
*
* @param \Illuminate\Contracts\Config\Repository $config
* @param \CachetHQ\Cachet\Settings\Repository $settings
*
* @return void
*/
public function __construct(ConfigRepository $config, SettingsRepository $settings)
{
$this->config = $config;
$this->settings = $settings;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (!(bool) $this->settings->get('automatic_localization')) {
return $next($request);
}
$requestedLanguages = $request->getLanguages();
$userLanguage = $this->config->get('app.locale');
$langs = $this->config->get('langs');
foreach ($requestedLanguages as $language) {
$language = str_replace('_', '-', $language);
if (isset($langs[$language])) {
$userLanguage = $language;
break;
}
}
app('translator')->setLocale($userLanguage);
Date::setLocale($userLanguage);
return $next($request);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array<int, string>
*/
protected $except = [
//
];
}
-62
View File
@@ -1,62 +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\Http\Middleware;
use CachetHQ\Cachet\Settings\Repository;
use Closure;
use Illuminate\Http\Request;
/**
* This is the ready for use middleware class.
*
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
*/
class ReadyForUse
{
/**
* The settings repository instance.
*
* @var \CachetHQ\Cachet\Settings\Repository
*/
protected $settings;
/**
* Creates a new setup already completed middleware instance.
*
* @param \CachetHQ\Cachet\Settings\Repository $settings
*
* @return void
*/
public function __construct(Repository $settings)
{
$this->settings = $settings;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (!$request->is('setup*') && !$this->settings->get('app_name')) {
return cachet_redirect('setup');
}
return $next($request);
}
}
+12 -44
View File
@@ -1,60 +1,28 @@
<?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;
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
/**
* This is the redirect if authenticated middleware class.
*
* @author Graham Campbell <graham@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class RedirectIfAuthenticated
{
/**
* The authentication guard instance.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* Create a new redirect if authenticated middleware 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
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, Closure $next, string ...$guards): Response
{
if ($this->auth->check()) {
return cachet_redirect('dashboard');
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
@@ -1,53 +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\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);
}
}
@@ -1,67 +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\Http\Middleware;
use CachetHQ\Cachet\Settings\ReadException;
use CachetHQ\Cachet\Settings\Repository;
use Closure;
use Illuminate\Http\Request;
/**
* This is the setup already completed middelware class.
*
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
* @author Joseph Cohen <joe@alt-three.com>
*/
class SetupAlreadyCompleted
{
/**
* The settings repository instance.
*
* @var \CachetHQ\Cachet\Settings\Repository
*/
protected $settings;
/**
* Creates a new setup already completed middleware instance.
*
* @param \CachetHQ\Cachet\Settings\Repository $settings
*
* @return void
*/
public function __construct(Repository $settings)
{
$this->settings = $settings;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
try {
if ($this->settings->get('app_name')) {
return cachet_redirect('dashboard');
}
} catch (ReadException $e) {
// not setup then!
}
return $next($request);
}
}
@@ -1,57 +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\Http\Middleware;
use Closure;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Http\Request;
/**
* This is the subscribers configured middleware class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SubscribersConfigured
{
/**
* The config repository instance.
*
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* Creates a subscribers configured middleware instance.
*
* @param \Illuminate\Contracts\Config\Repository $config
*
* @return void
*/
public function __construct(Repository $config)
{
$this->config = $config;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
return $next($request);
}
}
-125
View File
@@ -1,125 +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\Http\Middleware;
use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
/**
* This is the throttler middleware class.
*
* @author Graham Campbell <graham@alt-three.com>
*/
class Throttler
{
/**
* The rate limiter instance.
*
* @var \Illuminate\Cache\RateLimiter
*/
protected $limiter;
/**
* Create a new throttler middleware instance.
*
* @param \Illuminate\Cache\RateLimiter $limiter
*
* @return void
*/
public function __construct(RateLimiter $limiter)
{
$this->limiter = $limiter;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param int|string $limit
* @param int|string $decay
*
* @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $limit = 60, $decay = 1)
{
return $this->safeHandle($request, $next, (int) $limit, (int) $decay);
}
/**
* Handle an incoming request, with correct types.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param int $limit
* @param int $decay
*
* @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
*
* @return mixed
*/
protected function safeHandle(Request $request, Closure $next, int $limit, int $decay)
{
$key = $request->fingerprint();
if ($this->limiter->tooManyAttempts($key, $limit, $decay)) {
throw $this->buildException($key, $limit);
}
$this->limiter->hit($key, $decay);
$response = $next($request);
$response->headers->add($this->getHeaders($key, $limit));
return $response;
}
/**
* Create a too many requests http exception.
*
* @param string $key
* @param int $limit
*
* @return \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
*/
protected function buildException(string $key, int $limit)
{
$after = $this->limiter->availableIn($key);
$exception = new TooManyRequestsHttpException($after, 'Rate limit exceeded.');
$exception->setHeaders($this->getHeaders($key, $limit, $after, $exception->getHeaders()));
return $exception;
}
/**
* Get the limit header information.
*
* @param string $key
* @param int $limit
* @param int|null $after
* @param array $merge
*
* @return array
*/
protected function getHeaders(string $key, int $limit, int $after = null, array $merge = [])
{
$remaining = $after === null ? $this->limiter->retriesLeft($key, $limit) : 0;
$headers = ['X-RateLimit-Limit' => $limit, 'X-RateLimit-Remaining' => $remaining];
return array_merge($headers, $merge);
}
}
-61
View File
@@ -1,61 +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\Http\Middleware;
use Closure;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Http\Request;
/**
* This is the timezone middleware class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class Timezone
{
/**
* The config repository instance.
*
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* Creates a new timezone middleware instance.
*
* @param \Illuminate\Contracts\Config\Repository $config
*
* @return void
*/
public function __construct(Repository $config)
{
$this->config = $config;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if ($tz = $request->header('Time-Zone')) {
$this->config->set('cachet.timezone', $tz);
}
return $next($request);
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
/**
* Get the host patterns that should be trusted.
*
* @return array<int, string|null>
*/
public function hosts(): array
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}
+9 -31
View File
@@ -1,31 +1,16 @@
<?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 App\Http\Middleware;
namespace CachetHQ\Cachet\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
/**
* This is the trust proxies middleware class.
*
* @author James Brooks <james@alt-three.com>
*/
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
* @var array<int, string>|string|null
*/
protected $proxies;
@@ -34,17 +19,10 @@ class TrustProxies extends Middleware
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
/**
* Create new trust proxies instance.
*
* @return void
*/
public function __construct()
{
$proxies = Config::get('trustedproxies.proxies');
$this->proxies = empty($proxies) ? '*' : explode(',', trim($proxies));
}
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
class ValidateSignature extends Middleware
{
/**
* The names of the query string parameters that should be ignored.
*
* @var array<int, string>
*/
protected $except = [
// 'fbclid',
// 'utm_campaign',
// 'utm_content',
// 'utm_medium',
// 'utm_source',
// 'utm_term',
];
}
+3 -24
View File
@@ -1,38 +1,17 @@
<?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;
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
/**
* This is the verify csrf token middleware class.
*
* @author James Brooks <james@alt-three.com>
*/
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
* @var array<int, string>
*/
protected $except = [
'/api/*',
//
];
}
-98
View File
@@ -1,98 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the api routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class ApiRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = false;
/**
* Define the api routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'namespace' => 'Api',
'prefix' => 'api/v1',
], function (Registrar $router) {
$router->group(['middleware' => ['auth.api', 'cors']], function (Registrar $router) {
$router->get('components', 'ComponentController@index');
$router->get('components/groups', 'ComponentGroupController@index');
$router->get('components/groups/{component_group}', 'ComponentGroupController@show');
$router->get('components/{component}', 'ComponentController@show');
$router->get('incidents', 'IncidentController@index');
$router->get('incidents/templates', 'IncidentTemplateController@index');
$router->get('incidents/templates/{incident_template}', 'IncidentTemplateController@show');
$router->get('incidents/{incident}', 'IncidentController@show');
$router->get('incidents/{incident}/updates', 'IncidentUpdateController@index');
$router->get('incidents/{incident}/updates/{update}', 'IncidentUpdateController@show');
$router->get('metrics', 'MetricController@index');
$router->get('metrics/{metric}', 'MetricController@show');
$router->get('metrics/{metric}/points', 'MetricPointController@index');
$router->get('schedules', 'ScheduleController@index');
$router->get('schedules/{schedule}', 'ScheduleController@show');
});
$router->group(['middleware' => ['auth.api:true']], function (Registrar $router) {
$router->get('subscribers', 'SubscriberController@index');
$router->post('components', 'ComponentController@store');
$router->post('components/groups', 'ComponentGroupController@store');
$router->post('incidents', 'IncidentController@store');
$router->post('incidents/{incident}/updates', 'IncidentUpdateController@store');
$router->post('metrics', 'MetricController@store');
$router->post('metrics/{metric}/points', 'MetricPointController@store');
$router->post('schedules', 'ScheduleController@store');
$router->post('subscribers', 'SubscriberController@store');
$router->put('components/groups/{component_group}', 'ComponentGroupController@update');
$router->put('components/{component}', 'ComponentController@update');
$router->put('incidents/{incident}', 'IncidentController@update');
$router->put('incidents/{incident}/updates/{update}', 'IncidentUpdateController@update');
$router->put('metrics/{metric}', 'MetricController@update');
$router->put('metrics/{metric}/points/{metric_point}', 'MetricPointController@update');
$router->put('schedules/{schedule}', 'ScheduleController@update');
$router->delete('components/groups/{component_group}', 'ComponentGroupController@destroy');
$router->delete('components/{component}', 'ComponentController@destroy');
$router->delete('incidents/{incident}', 'IncidentController@destroy');
$router->delete('incidents/{incident}/updates/{update}', 'IncidentUpdateController@destroy');
$router->delete('metrics/{metric}', 'MetricController@destroy');
$router->delete('metrics/{metric}/points/{metric_point}', 'MetricPointController@destroy');
$router->delete('schedules/{schedule}', 'ScheduleController@destroy');
$router->delete('subscribers/{subscriber}', 'SubscriberController@destroy');
$router->delete('subscriptions/{subscription}', 'SubscriptionController@destroy');
});
});
}
}
-50
View File
@@ -1,50 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the api routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class ApiSystemRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = false;
/**
* Define the api routes for the system status, ping and version.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'namespace' => 'Api',
'prefix' => 'api/v1',
], function (Registrar $router) {
$router->group(['middleware' => ['auth.api']], function (Registrar $router) {
$router->get('ping', 'GeneralController@ping');
$router->get('version', 'GeneralController@version');
$router->get('status', ['uses' => 'GeneralController@status', 'middleware' => ['cache']]);
});
});
}
}
-73
View File
@@ -1,73 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the auth routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class AuthRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the auth routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['ready'],
'prefix' => 'auth',
], function (Registrar $router) {
$router->get('login', [
'as' => 'get:auth.login',
'middleware' => 'guest',
'uses' => 'AuthController@showLogin',
]);
$router->post('login', [
'as' => 'post:auth.login',
'middleware' => ['guest', 'throttle:10,10'],
'uses' => 'AuthController@postLogin',
]);
$router->get('2fa', [
'as' => 'get:auth.two-factor',
'uses' => 'AuthController@showTwoFactorAuth',
]);
$router->post('2fa', [
'as' => 'post:auth.two-factor',
'middleware' => ['throttle:10,10'],
'uses' => 'AuthController@postTwoFactor',
]);
$router->get('logout', [
'as' => 'get:auth.logout',
'uses' => 'AuthController@logoutAction',
'middleware' => 'auth',
]);
});
}
}
-51
View File
@@ -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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard api routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class ApiRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard api routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/api',
], function (Registrar $router) {
$router->get('incidents/templates', 'ApiController@getIncidentTemplate');
$router->post('components/groups/order', 'ApiController@postUpdateComponentGroupOrder');
$router->post('components/order', 'ApiController@postUpdateComponentOrder');
$router->any('components/{component}', 'ApiController@postUpdateComponent');
});
}
}
-54
View File
@@ -1,54 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard base routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class BaseRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard base routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
], function (Registrar $router) {
$router->get('admin', 'DashboardController@redirectAdmin');
$router->group(['prefix' => 'dashboard'], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard',
'uses' => 'DashboardController@showDashboard',
]);
});
});
}
}
@@ -1,100 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard component routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class ComponentRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard component routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/components',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.components',
'uses' => 'ComponentController@showComponents',
]);
$router->get('create', [
'as' => 'get:dashboard.components.create',
'uses' => 'ComponentController@showAddComponent',
]);
$router->post('create', [
'as' => 'post:dashboard.components.create',
'uses' => 'ComponentController@createComponentAction',
]);
$router->get('groups', [
'as' => 'get:dashboard.components.groups',
'uses' => 'ComponentGroupController@showComponentGroups',
]);
$router->get('groups/create', [
'as' => 'get:dashboard.components.groups.create',
'uses' => 'ComponentGroupController@showAddComponentGroup',
]);
$router->post('groups/create', [
'as' => 'post:dashboard.components.groups.create',
'uses' => 'ComponentGroupController@postAddComponentGroup',
]);
$router->get('groups/{component_group}', [
'as' => 'get:dashboard.components.groups.edit',
'uses' => 'ComponentGroupController@showEditComponentGroup',
]);
$router->post('groups/{component_group}', [
'as' => 'post:dashboard.components.groups.edit',
'uses' => 'ComponentGroupController@updateComponentGroupAction',
]);
$router->delete('groups/{component_group}', [
'as' => 'delete:dashboard.components.groups.delete',
'uses' => 'ComponentGroupController@deleteComponentGroupAction',
]);
$router->get('{component}', [
'as' => 'get:dashboard.components.edit',
'uses' => 'ComponentController@showEditComponent',
]);
$router->post('{component}', [
'as' => 'post:dashboard.components.edit',
'uses' => 'ComponentController@updateComponentAction',
]);
$router->delete('{component}', [
'as' => 'delete:dashboard.components.delete',
'uses' => 'ComponentController@deleteComponentAction',
]);
});
}
}
@@ -1,94 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard incident routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class IncidentRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard incident routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/incidents',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.incidents',
'uses' => 'IncidentController@showIncidents',
]);
$router->get('create', [
'as' => 'get:dashboard.incidents.create',
'uses' => 'IncidentController@showAddIncident',
]);
$router->post('create', [
'as' => 'post:dashboard.incidents.create',
'uses' => 'IncidentController@createIncidentAction',
]);
$router->get('{incident}', [
'as' => 'get:dashboard.incidents.edit',
'uses' => 'IncidentController@showEditIncidentAction',
]);
$router->post('{incident}', [
'as' => 'post:dashboard.incidents.edit',
'uses' => 'IncidentController@editIncidentAction',
]);
$router->delete('{incident}', [
'as' => 'delete:dashboard.incidents.delete',
'uses' => 'IncidentController@deleteIncidentAction',
]);
$router->get('{incident}/updates', [
'as' => 'get:dashboard.incidents.updates',
'uses' => 'IncidentUpdateController@showIncidentUpdates',
]);
$router->get('{incident}/updates/create', [
'as' => 'get:dashboard.incidents.updates.create',
'uses' => 'IncidentUpdateController@showCreateIncidentUpdateAction',
]);
$router->post('{incident}/updates/create', [
'as' => 'post:dashboard.incidents.updates.create',
'uses' => 'IncidentUpdateController@createIncidentUpdateAction',
]);
$router->get('{incident}/updates/{incident_update}', [
'as' => 'get:dashboard.incidents.updates.edit',
'uses' => 'IncidentUpdateController@showEditIncidentUpdateAction',
]);
$router->post('{incident}/updates/{incident_update}', [
'as' => 'post:dashboard.incidents.updates.edit',
'uses' => 'IncidentUpdateController@editIncidentUpdateAction',
]);
});
}
}
@@ -1,73 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard metric routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class MetricRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard metric routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/metrics',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.metrics',
'uses' => 'MetricController@showMetrics',
]);
$router->get('create', [
'as' => 'get:dashboard.metrics.create',
'uses' => 'MetricController@showAddMetric',
]);
$router->post('create', [
'as' => 'post:dashboard.metrics.create',
'uses' => 'MetricController@createMetricAction',
]);
$router->get('{metric}', [
'as' => 'get:dashboard.metrics.edit',
'uses' => 'MetricController@showEditMetricAction',
]);
$router->post('{metric}', [
'as' => 'post:dashboard.metrics.edit',
'uses' => 'MetricController@editMetricAction',
]);
$router->delete('{metric}', [
'as' => 'delete:dashboard.metrics.delete',
'uses' => 'MetricController@deleteMetricAction',
]);
});
}
}
@@ -1,73 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard schedule routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class ScheduleRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard schedule routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/schedule',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.schedule',
'uses' => 'ScheduleController@showIndex',
]);
$router->get('create', [
'as' => 'get:dashboard.schedule.create',
'uses' => 'ScheduleController@showAddSchedule',
]);
$router->post('create', [
'as' => 'post:dashboard.schedule.create',
'uses' => 'ScheduleController@addScheduleAction',
]);
$router->get('{schedule}', [
'as' => 'get:dashboard.schedule.edit',
'uses' => 'ScheduleController@showEditSchedule',
]);
$router->post('{schedule}', [
'as' => 'post:dashboard.schedule.edit',
'uses' => 'ScheduleController@editScheduleAction',
]);
$router->delete('{schedule}', [
'as' => 'delete:dashboard.schedule.delete',
'uses' => 'ScheduleController@deleteScheduleAction',
]);
});
}
}
-100
View File
@@ -1,100 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard setting routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class SettingRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard setting routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/settings',
], function (Registrar $router) {
$router->get('setup', [
'as' => 'get:dashboard.settings.setup',
'uses' => 'SettingsController@showSetupView',
]);
$router->get('analytics', [
'as' => 'get:dashboard.settings.analytics',
'uses' => 'SettingsController@showAnalyticsView',
]);
$router->get('localization', [
'as' => 'get:dashboard.settings.localization',
'uses' => 'SettingsController@showLocalizationView',
]);
$router->get('security', [
'as' => 'get:dashboard.settings.security',
'uses' => 'SettingsController@showSecurityView',
]);
$router->get('theme', [
'as' => 'get:dashboard.settings.theme',
'uses' => 'SettingsController@showThemeView',
]);
$router->get('stylesheet', [
'as' => 'get:dashboard.settings.stylesheet',
'uses' => 'SettingsController@showStylesheetView',
]);
$router->get('customization', [
'as' => 'get:dashboard.settings.customization',
'uses' => 'SettingsController@showCustomizationView',
]);
$router->get('credits', [
'as' => 'get:dashboard.settings.credits',
'uses' => 'SettingsController@showCreditsView',
]);
$router->get('log', [
'as' => 'get:dashboard.settings.log',
'uses' => 'SettingsController@showLogView',
]);
$router->get('mail', [
'as' => 'get:dashboard.settings.mail',
'uses' => 'SettingsController@showMailView',
]);
$router->post('mail', [
'as' => 'post:dashboard.settings.mail',
'uses' => 'SettingsController@postMail',
]);
$router->post('mail/test', [
'as' => 'post:dashboard.settings.mail.test',
'uses' => 'SettingsController@testMail',
]);
$router->post('/', [
'as' => 'post:dashboard.settings',
'uses' => 'SettingsController@postSettings',
]);
});
}
}
@@ -1,65 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard subscriber routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class SubscriberRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard subscriber routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/subscribers',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.subscribers',
'uses' => 'SubscriberController@showSubscribers',
]);
$router->get('create', [
'as' => 'get:dashboard.subscribers.create',
'uses' => 'SubscriberController@showAddSubscriber',
]);
$router->post('create', [
'as' => 'post:dashboard.subscribers.create',
'uses' => 'SubscriberController@createSubscriberAction',
]);
$router->delete('{subscriber}/delete', [
'as' => 'delete:dashboard.subscribers.delete',
'uses' => 'SubscriberController@deleteSubscriberAction',
]);
});
}
}
-84
View File
@@ -1,84 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard team routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class TeamRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard team routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/team',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.team',
'uses' => 'TeamController@showTeamView',
]);
$router->group(['middleware' => 'admin'], function (Registrar $router) {
$router->get('create', [
'as' => 'get:dashboard.team.create',
'uses' => 'TeamController@showAddTeamMemberView',
]);
$router->post('create', [
'as' => 'post:dashboard.team.create',
'uses' => 'TeamController@postAddUser',
]);
$router->get('invite', [
'as' => 'get:dashboard.team.invite',
'uses' => 'TeamController@showInviteTeamMemberView',
]);
$router->post('invite', [
'as' => 'post:dashboard.team.invite',
'uses' => 'TeamController@postInviteUser',
]);
$router->get('{user}', [
'as' => 'get:dashboard.team.edit',
'uses' => 'TeamController@showTeamMemberView',
]);
$router->post('{user}', [
'as' => 'post::dashboard.team.edit',
'uses' => 'TeamController@postUpdateUser',
]);
$router->delete('{user}', [
'as' => 'delete:dashboard.team.delete',
'uses' => 'TeamController@deleteUser',
]);
});
});
}
}
@@ -1,73 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard template routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class TemplateRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard template routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/templates',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.templates',
'uses' => 'IncidentTemplateController@showTemplates',
]);
$router->get('create', [
'as' => 'get:dashboard.templates.create',
'uses' => 'IncidentTemplateController@showAddIncidentTemplate',
]);
$router->post('create', [
'as' => 'post:dashboard.templates.create',
'uses' => 'IncidentTemplateController@createIncidentTemplateAction',
]);
$router->get('{incident_template}', [
'as' => 'get:dashboard.templates.edit',
'uses' => 'IncidentTemplateController@showEditTemplateAction',
]);
$router->post('{incident_template}', [
'as' => 'post:dashboard.templates.edit',
'uses' => 'IncidentTemplateController@editTemplateAction',
]);
$router->delete('{incident_template}', [
'as' => 'delete:dashboard.templates.delete',
'uses' => 'IncidentTemplateController@deleteTemplateAction',
]);
});
}
}
-60
View File
@@ -1,60 +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\Http\Routes\Dashboard;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the dashboard user routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Connor S. Parks <connor@connorvg.tv>
*/
class UserRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the dashboard user routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['auth'],
'namespace' => 'Dashboard',
'prefix' => 'dashboard/user',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:dashboard.user',
'uses' => 'UserController@showUser',
]);
$router->post('/', [
'as' => 'post:dashboard.user',
'uses' => 'UserController@postUser',
]);
$router->get('{user}/api/regen', [
'as' => 'get:dashboard.user.api.regen',
'uses' => 'UserController@regenerateApiKey',
]);
});
}
}
-59
View File
@@ -1,59 +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\Http\Routes\Setup;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the setup api routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class ApiRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = false;
/**
* Define the setup routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['setup'],
'prefix' => 'setup',
], function (Registrar $router) {
$router->post('step1', [
'as' => 'post:setup.step1',
'uses' => 'SetupController@postStep1',
]);
$router->post('step2', [
'as' => 'post:setup.step2',
'uses' => 'SetupController@postStep2',
]);
$router->post('step3', [
'as' => 'post:setup.step3',
'uses' => 'SetupController@postStep3',
]);
});
}
}
-50
View File
@@ -1,50 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the setup routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SetupRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the setup routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['setup'],
'prefix' => 'setup',
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:setup',
'uses' => 'SetupController@getIndex',
]);
});
}
}
-54
View File
@@ -1,54 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the signup routes class.
*
* @author Joseph Cohen <joe@alt-three.com>
*/
class SignupRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the signup routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['ready', 'guest'],
'prefix' => 'signup',
], function (Registrar $router) {
$router->get('invite/{code}', [
'as' => 'get:signup.invite',
'uses' => 'SignupController@getSignup',
]);
$router->post('invite/{code}', [
'as' => 'post:signup.invite',
'uses' => 'SignupController@postSignup',
]);
});
}
}
-68
View File
@@ -1,68 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the status page routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class StatusPageRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the status page routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['ready', 'localize'],
], function (Registrar $router) {
$router->get('/', [
'as' => 'get:status-page',
'uses' => 'StatusPageController@showIndex',
]);
$router->get('incidents/{incident}', [
'as' => 'get:incident',
'uses' => 'StatusPageController@showIncident',
]);
$router->get('schedules/{schedule}', [
'as' => 'get:schedule',
'uses' => 'StatusPageController@showSchedule',
]);
$router->get('metrics/{metric}', [
'as' => 'get:metric',
'uses' => 'StatusPageController@getMetrics',
]);
$router->get('component/{component}/shield', [
'as' => 'get:component_shield',
'uses' => 'StatusPageController@showComponentBadge',
]);
});
}
}
-73
View File
@@ -1,73 +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\Http\Routes;
use Illuminate\Contracts\Routing\Registrar;
/**
* This is the subscriber routes class.
*
* @author James Brooks <james@alt-three.com>
*/
class SubscribeRoutes
{
/**
* Defines if these routes are for the browser.
*
* @var bool
*/
public static $browser = true;
/**
* Define the subscribe routes.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
*
* @return void
*/
public function map(Registrar $router)
{
$router->group([
'middleware' => ['ready', 'localize', 'subscribers'],
], function (Registrar $router) {
$router->get('subscribe', [
'as' => 'get:subscribe',
'uses' => 'SubscribeController@showSubscribe',
]);
$router->post('subscribe', [
'as' => 'post:subscribe',
'uses' => 'SubscribeController@postSubscribe',
]);
$router->get('subscribe/manage/{code}', [
'as' => 'get:subscribe.manage',
'middleware' => ['signed'],
'uses' => 'SubscribeController@showManage',
]);
$router->post('subscribe/manage/{code}', [
'as' => 'post:subscribe.manage',
'uses' => 'SubscribeController@postManage',
]);
$router->get('subscribe/verify/{code}', [
'as' => 'get:subscribe.verify',
'middleware' => ['signed'],
'uses' => 'SubscribeController@getVerify',
]);
$router->get('unsubscribe/{code}/{subscription?}', [
'as' => 'get:subscribe.unsubscribe',
'uses' => 'SubscribeController@getUnsubscribe',
]);
});
}
}