Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions laravel/app/Http/Controllers/DepartmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function __construct()
{
$this->middleware('auth');
$this->middleware('bindings');
$this->middleware('published:department');
}

// Display list of departments in an event
Expand Down
27 changes: 27 additions & 0 deletions laravel/app/Http/Controllers/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function __construct()
{
$this->middleware('auth');
$this->middleware('bindings');
$this->middleware('published:event');
}

// Private function to manage file uploads
Expand Down Expand Up @@ -281,4 +282,30 @@ public function cloneEvent(Request $request, Event $event)
$request->session()->flash('success', 'Event has been cloned.');
return redirect('/event/' . $newEvent->id);
}

/**
* Publish/Unpublish an event
*
* @param Request $request
* @param Event $event targeted event in the query string
* @return Response redirect to the targeted event
*/
public function publish(Request $request, Event $event)
{
$publish = $request->input('publish');

// toggle if publish does not exist
if($publish === null) {
$publish = ($event->published_at === null);
}

if($publish) { // publish
$event->published_at = Carbon::now();
} else { // unpublish
$event->published_at = null;
}
$event->save();

return redirect("/event/{$event->id}");
}
}
1 change: 1 addition & 0 deletions laravel/app/Http/Controllers/ScheduleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function __construct()
{
$this->middleware('auth');
$this->middleware('bindings');
$this->middleware('published:schedule');
}

// Helper function to convert form input into database-friendly information
Expand Down
1 change: 1 addition & 0 deletions laravel/app/Http/Controllers/ShiftController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function __construct()
{
$this->middleware('auth');
$this->middleware('bindings');
$this->middleware('published:shift');
}

// Display list of shifts in an event
Expand Down
1 change: 1 addition & 0 deletions laravel/app/Http/Controllers/SlotController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function __construct()
{
$this->middleware('auth');
$this->middleware('bindings');
$this->middleware('published:slot');
}

// Helper function to determine if an event has passed
Expand Down
1 change: 1 addition & 0 deletions laravel/app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ class Kernel extends HttpKernel
'admin' => \App\Http\Middleware\IsAdmin::class,
'lead' => \App\Http\Middleware\IsLead::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'published' => \App\Http\Middleware\CheckPublished::class,
];
}
82 changes: 82 additions & 0 deletions laravel/app/Http/Middleware/CheckPublished.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;
use App\Models\Slot;
use App\Models\Department;
use App\Models\Schedule;
use App\Models\Shift;

class CheckPublished
{
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;

/**
* Create a new filter instance.
*
* @param 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, Closure $next, $model_name)
{
if($request->{$model_name})
{
$event = $this->childModelToEvent($request->{$model_name});

$is_published = ($event->published_at !== null);
$is_admin= $this->auth->user()->hasRole('admin');
$is_department_lead = $this->auth->user()->hasRole('department-lead');
if(!$is_published && !$is_admin && !$is_department_lead)
{
return response('Unauthorized.', 401);
}
}

return $next($request);
}

/**
* Get parent event of shift, slot, schedule, or department
*
* @param Model $model descendent model of Event
* @return Event Event or parent Event
*/
public static function childModelToEvent($model)
{

$model_class = get_class($model);
$event = $model;
if($model_class === Department::class) {
$event = $model->event;
}
if($model_class === Shift::class) {
$event = $model->event;
}
if($model_class === Schedule::class) {
$event = $model->shift->event;
}
if($model_class === Slot::class) {
$event = $model->schedule->shift->event;
}
return $event;
}
}
3 changes: 2 additions & 1 deletion laravel/app/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@
Route::post('/event/{event}/edit', 'EventController@edit');

Route::get('/event/{event}/delete', 'EventController@deleteForm');
Route::post('/event/{event}/delete', 'EventController@delete');
Route::post('/event{event}/delete', 'EventController@delete');

Route::get('/event/{event}/clone', 'EventController@cloneForm');
Route::post('/event/{event}/clone', 'EventController@cloneEvent');

Route::get('/event/{event}', 'EventController@view');

Route::post('/event/{event}/publish', 'EventController@publish');

// Department routes
Route::get('/event/{event}/departments', 'DepartmentController@listDepartments');
Expand Down
2 changes: 2 additions & 0 deletions laravel/app/Providers/AuthServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class AuthServiceProvider extends ServiceProvider
'create-event',
'edit-event',
'delete-event',
'publish-event',
'read-department',
'create-department',
'edit-department',
Expand All @@ -52,6 +53,7 @@ class AuthServiceProvider extends ServiceProvider

'department-lead' =>
[
'publish-event',
'create-schedule',
'edit-schedule',
'delete-schedule',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddPublishedAtToEventsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('events', function (Blueprint $table) {
$table->timestamp('published_at')->nullable();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->drop('published_at');
});
}
}
21 changes: 14 additions & 7 deletions laravel/resources/views/pages/dashboard.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,21 @@
<hr>

@foreach($future as $event)
<p>
@if($event->featured)
<span class="burn glyphicon glyphicon-fire"></span>
@endif
<?php
$user_roles = Auth::user()->getRoleNames();
$is_lead = in_array('department-lead', $user_roles);
$is_admin = in_array('admin', $user_roles);
?>
@if($event->published_at !== null || $is_lead || $is_admin)
<p>
@if($event->featured)
<span class="burn glyphicon glyphicon-fire"></span>
@endif

<b><a href='/event/{{ $event->id }}'>{{ $event->name }}</a></b>
<i>from {{ $event->start_date }} until {{ $event->end_date }}</i>
</p>
<b><a href='/event/{{ $event->id }}'>{{ $event->name }}</a></b>
<i>from {{ $event->start_date }} until {{ $event->end_date }}</i>
</p>
@endif
@endforeach

<br>
Expand Down
13 changes: 13 additions & 0 deletions laravel/resources/views/pages/event/view.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
@section('content')
<section class="event" data-id="{{ $event->id }}">
<div class="pull-right relative" style="z-index: 1">
@can('publish-event')
<span style="display:inline-block">
{!! Form::open(['url' => "/event/{$event->id}/publish", 'method' => 'post']) !!}
<?php
$unpublished = ($event->published_at === null);
$publish_text = ($unpublished) ? 'Publish Event' : 'Unpublish Event';
?>
Comment thread
Meleeman01 marked this conversation as resolved.
<input type="hidden" name="publish" value="{{ $unpublished }}">
<button type="submit" class="btn btn-success">{{ $publish_text }}</button>
{!! Form::close() !!}
</span>
@endcan

@can('create-event')
<a href="/event/{{ $event->id }}/clone" class="btn btn-primary">Clone Event</a>
@endcan
Expand Down
54 changes: 54 additions & 0 deletions laravel/tests/Feature/CheckPublishedTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

use App\Models\User;
use App\Models\UserData;
use App\Models\Slot;

class CheckPublishedTest extends TestCase
{
use RefreshDatabase;

/**
* @test
*
* @return void
*/
public function unpublished_event_viewable_by_admin()
{
// Given
$admin = factory(User::class)->states('admin')->create();

$admin->data()->save(factory(UserData::class)->make());
$slot = factory(Slot::class)->create();

// When
$response = $this->actingAs($admin)->get("/slot/{$slot->id}/view");

// Then
$response->assertStatus(200);
}

/**
* @test
*
* @return void
*/
public function unpublished_event_not_viewable_by_volunteer()
{
// Given
$volunteer = factory(User::class)->create();
$slot = factory(Slot::class)->create();

// When
$response = $this->actingAs($volunteer)->get("/slot/{$slot->id}/view");

// Then
$response->assertStatus(401);
}
}
2 changes: 2 additions & 0 deletions laravel/tests/Feature/SlotControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

class SlotControllerTest extends TestCase
{
use RefreshDatabase;

/**
* @test
* @return void
Expand Down
33 changes: 33 additions & 0 deletions laravel/tests/Unit/CheckPublishedTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

use App\Http\Middleware\CheckPublished;
use App\Models\Slot;
use App\Models\Event;

class CheckPublishedTest extends TestCase
{
use RefreshDatabase;

/**
* @test
*
* @return void
*/
public function handle_parses_model_name()
{
// Given
$slot = factory(Slot::class)->create();

// When
$event = CheckPublished::childModelToEvent($slot);

// Then
$this->assertEquals(Event::class, get_class($event));
}
}