Browse Source

Merge pull request #50 from nafiesl/49_system_admins

Admin for Managing All Users and DB Backup Manager
pull/60/head
Nafies Luthfi 6 years ago
committed by GitHub
parent
commit
06da5646bc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .env.example
  2. 12
      app/Helpers/functions.php
  3. 1
      app/Http/Kernel.php
  4. 24
      app/Http/Middleware/AdminOnly.php
  5. 2
      app/Policies/CouplePolicy.php
  6. 4
      app/Policies/UserPolicy.php
  7. 12
      config/app.php
  8. 3
      resources/lang/en/birthday.php
  9. 1
      resources/lang/id/birthday.php
  10. 2
      resources/views/birthdays/index.blade.php
  11. 2
      resources/views/layouts/partials/nav.blade.php
  12. 5
      routes/web.php
  13. 44
      tests/Unit/Helpers/IsSystemAdminHelperTest.php
  14. 30
      tests/Unit/Policies/CouplePolicyTest.php
  15. 47
      tests/Unit/Policies/UserPolicyTest.php

1
.env.example

@ -3,6 +3,7 @@ APP_KEY=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost
SYSTEM_ADMIN_EMAILS=
LOG_CHANNEL=stack

12
app/Helpers/functions.php

@ -58,3 +58,15 @@ function userPhotoPath($photoPath, $genderId)
return asset('images/icon_user_'.$genderId.'.png');
}
function is_system_admin(User $user)
{
if ($user->email) {
if (config('app.system_admin_emails')) {
$adminEmails = explode(';', config('app.system_admin_emails'));
return in_array($user->email, $adminEmails);
}
}
return false;
}

1
app/Http/Kernel.php

@ -53,6 +53,7 @@ class Kernel extends HttpKernel
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'admin' => \App\Http\Middleware\AdminOnly::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

24
app/Http/Middleware/AdminOnly.php

@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Closure;
class AdminOnly
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!is_system_admin($request->user())) {
abort(403);
}
return $next($request);
}
}

2
app/Policies/CouplePolicy.php

@ -19,6 +19,6 @@ class CouplePolicy
*/
public function edit(User $user, Couple $couple)
{
return $couple->manager_id == $user->id;
return $couple->manager_id == $user->id || is_system_admin($user);
}
}

4
app/Policies/UserPolicy.php

@ -18,7 +18,7 @@ class UserPolicy
*/
public function edit(User $user, User $editableUser)
{
return $editableUser->id == $user->id || $editableUser->manager_id == $user->id;
return $editableUser->id == $user->id || $editableUser->manager_id == $user->id || is_system_admin($user);
}
/**
@ -30,6 +30,6 @@ class UserPolicy
*/
public function delete(User $user, User $editableUser)
{
return $editableUser->manager_id == $user->id && $editableUser->id != $user->id;
return ($editableUser->manager_id == $user->id || is_system_admin($user)) && $editableUser->id != $user->id;
}
}

12
config/app.php

@ -29,6 +29,18 @@ return [
/*
|--------------------------------------------------------------------------
| System Administrator Emails
|--------------------------------------------------------------------------
|
| This is config stores emails of users who have role of administrators.
| The user can edit and delete any users and marriages int he system.
|
*/
'system_admin_emails' => env('SYSTEM_ADMIN_EMAILS'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|

3
resources/lang/en/birthday.php

@ -1,8 +1,9 @@
<?php
return [
'birthday' => 'Birhtday',
'birthday' => 'Birthday',
'upcoming' => 'Upcoming birthdays',
'no_upcoming' => 'No upcoming birthdays in the next :days days.',
'remaining' => ':count days',
'age_years' => ':age years',
'days' => 'days',

1
resources/lang/id/birthday.php

@ -3,6 +3,7 @@
return [
'birthday' => 'Ulang Tahun',
'upcoming' => 'Ulang tahun akan datang',
'no_upcoming' => 'Belum ada ulang tahun dalam :days hari kedepan.',
'remaining' => ':count hari',
'age_years' => ':age tahun',
'days' => 'Hari',

2
resources/views/birthdays/index.blade.php

@ -35,7 +35,7 @@
</tr>
@empty
<tr>
<td colspan="4">{{ __('user.no_upcoming_birthday', ['days' => 60]) }}</td>
<td colspan="4">{{ __('birthday.no_upcoming', ['days' => 60]) }}</td>
</tr>
@endforelse
</tbody>

2
resources/views/layouts/partials/nav.blade.php

@ -39,7 +39,9 @@
</a>
<ul class="dropdown-menu" role="menu">
@if (is_system_admin(auth()->user()))
<li><a href="{{ route('backups.index') }}">{{ __('backup.list') }}</a></li>
@endif
<li><a href="{{ route('profile') }}">{{ __('app.my_profile') }}</a></li>
<li><a href="{{ route('password.change') }}">{{ __('auth.change_password') }}</a></li>
<li>

5
routes/web.php

@ -50,9 +50,14 @@ Route::get('couples/{couple}/edit', ['as' => 'couples.edit', 'uses' => 'CouplesC
Route::patch('couples/{couple}', ['as' => 'couples.update', 'uses' => 'CouplesController@update']);
/**
* Admin only routes
*/
Route::group(['middleware' => 'admin'], function () {
/**
* Backup Restore Database Routes
*/
Route::post('backups/upload', ['as' => 'backups.upload', 'uses' => 'BackupsController@upload']);
Route::post('backups/{fileName}/restore', ['as' => 'backups.restore', 'uses' => 'BackupsController@restore']);
Route::get('backups/{fileName}/dl', ['as' => 'backups.download', 'uses' => 'BackupsController@download']);
Route::resource('backups', 'BackupsController');
});

44
tests/Unit/Helpers/IsSystemAdminHelperTest.php

@ -0,0 +1,44 @@
<?php
namespace Tests\Unit\Helpers;
use App\User;
use Tests\TestCase;
class IsSystemAdminHelperTest extends TestCase
{
/** @test */
public function user_is_an_admin()
{
$adminEmail1 = 'admin1@example.net';
$adminEmail2 = 'admin2@example.net';
config(['app.system_admin_emails' => $adminEmail1.';'.$adminEmail2]);
$admin1 = factory(User::class)->make(['email' => $adminEmail1]);
$admin2 = factory(User::class)->make(['email' => $adminEmail2]);
$userWithEmail = factory(User::class)->make(['email' => 'user@example.net']);
$userWithNoEmail = factory(User::class)->make(['email' => null]);
$this->assertTrue(is_system_admin($admin1));
$this->assertTrue(is_system_admin($admin2));
$this->assertFalse(is_system_admin($userWithEmail));
$this->assertFalse(is_system_admin($userWithNoEmail));
}
/** @test */
public function if_config_is_null()
{
$adminEmail1 = 'admin1@example.net';
$adminEmail2 = 'admin2@example.net';
$admin1 = factory(User::class)->make(['email' => $adminEmail1]);
$admin2 = factory(User::class)->make(['email' => $adminEmail2]);
$userWithEmail = factory(User::class)->make(['email' => 'user@example.net']);
$userWithNoEmail = factory(User::class)->make(['email' => null]);
$this->assertFalse(is_system_admin($admin1));
$this->assertFalse(is_system_admin($admin2));
$this->assertFalse(is_system_admin($userWithEmail));
$this->assertFalse(is_system_admin($userWithNoEmail));
}
}

30
tests/Unit/Policies/CouplePolicyTest.php

@ -3,7 +3,9 @@
namespace Tests\Unit\Policies;
use App\Couple;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Tests\TestCase;
class CouplePolicyTest extends TestCase
@ -11,11 +13,33 @@ class CouplePolicyTest extends TestCase
use RefreshDatabase;
/** @test */
public function admin_can_edit_couple_data()
public function manager_can_edit_couples()
{
$couple = factory(Couple::class)->create();
$manager = $couple->manager;
$otherCoupleManagerId = Str::random();
$manager = factory(User::class)->create();
$couple = factory(Couple::class)->create(['manager_id' => $manager->id]);
$otherCouple = factory(Couple::class)->create(['manager_id' => $otherCoupleManagerId]);
$this->assertTrue($manager->can('edit', $couple));
$this->assertFalse($manager->can('edit', $otherCouple));
}
/** @test */
public function admins_can_edit_any_couple_data()
{
$adminEmail = 'admin@example.net';
$otherCoupleManagerId = Str::random();
config(['app.system_admin_emails' => $adminEmail]);
$manager = factory(User::class)->create();
$admin = factory(User::class)->create(['email' => $adminEmail]);
$couple = factory(Couple::class)->create(['manager_id' => $manager->id]);
$otherCouple = factory(Couple::class)->create(['manager_id' => $otherCoupleManagerId]);
$this->assertTrue($admin->can('edit', $couple));
$this->assertTrue($admin->can('edit', $otherCouple));
$this->assertTrue($manager->can('edit', $couple));
$this->assertFalse($manager->can('edit', $otherCouple));
}
}

47
tests/Unit/Policies/UserPolicyTest.php

@ -3,8 +3,9 @@
namespace Tests\Unit\Policies;
use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Tests\TestCase;
class UserPolicyTest extends TestCase
{
@ -13,10 +14,32 @@ class UserPolicyTest extends TestCase
/** @test */
public function manager_can_edit_users_profile()
{
$otherUserManagerId = Str::random();
$manager = factory(User::class)->create();
$user = factory(User::class)->create(['manager_id' => $manager->id]);
$otherUser = factory(User::class)->create(['manager_id' => $otherUserManagerId]);
$this->assertTrue($manager->can('edit', $user));
$this->assertFalse($manager->can('edit', $otherUser));
}
/** @test */
public function admins_can_edit_any_user_profile()
{
$adminEmail = 'admin@example.net';
$otherUserManagerId = Str::random();
config(['app.system_admin_emails' => $adminEmail]);
$manager = factory(User::class)->create();
$admin = factory(User::class)->create(['email' => $adminEmail]);
$user = factory(User::class)->create(['manager_id' => $manager->id]);
$otherUser = factory(User::class)->create(['manager_id' => $otherUserManagerId]);
$this->assertTrue($admin->can('edit', $user));
$this->assertTrue($admin->can('edit', $otherUser));
$this->assertTrue($manager->can('edit', $user));
$this->assertFalse($manager->can('edit', $otherUser));
}
/** @test */
@ -30,10 +53,32 @@ class UserPolicyTest extends TestCase
/** @test */
public function manager_can_delete_a_user()
{
$otherUserManagerId = Str::random();
$manager = factory(User::class)->create();
$user = factory(User::class)->create(['manager_id' => $manager->id]);
$otherUser = factory(User::class)->create(['manager_id' => $otherUserManagerId]);
$this->assertTrue($manager->can('delete', $user));
$this->assertFalse($manager->can('delete', $otherUser));
}
/** @test */
public function admins_can_delete_any_user()
{
$adminEmail = 'admin@example.net';
$otherUserManagerId = Str::random();
config(['app.system_admin_emails' => $adminEmail]);
$manager = factory(User::class)->create();
$admin = factory(User::class)->create(['email' => $adminEmail]);
$user = factory(User::class)->create(['manager_id' => $manager->id]);
$otherUser = factory(User::class)->create(['manager_id' => $otherUserManagerId]);
$this->assertTrue($admin->can('delete', $user));
$this->assertTrue($admin->can('delete', $otherUser));
$this->assertTrue($manager->can('delete', $user));
$this->assertFalse($manager->can('delete', $otherUser));
}
/** @test */

Loading…
Cancel
Save