#3 Album permissions can now be allocated to groups

This commit is contained in:
Andy Heathershaw 2017-02-16 17:32:01 +00:00
parent 29e62715c0
commit 78e5d0e3c0
9 changed files with 205 additions and 21 deletions

View File

@ -30,6 +30,14 @@ class Album extends Model
protected $hidden = [ protected $hidden = [
]; ];
public function doesGroupHavePermission(Group $group, Permission $permission)
{
return $this->groupPermissions()->where([
'group_id' => $group->id,
'permission_id' => $permission->id
])->count() > 0;
}
public function generateAlias() public function generateAlias()
{ {
$this->url_alias = ucfirst(preg_replace('/[^a-z0-9\-]/', '-', strtolower($this->name))); $this->url_alias = ucfirst(preg_replace('/[^a-z0-9\-]/', '-', strtolower($this->name)));
@ -50,6 +58,11 @@ class Album extends Model
return $source; return $source;
} }
public function groupPermissions()
{
return $this->belongsToMany(Permission::class, 'album_group_permissions');
}
public function photos() public function photos()
{ {
return $this->hasMany(Photo::class); return $this->hasMany(Photo::class);

View File

@ -3,12 +3,15 @@
namespace app\Http\Controllers\Admin; namespace app\Http\Controllers\Admin;
use App\Album; use App\Album;
use App\AlbumGroupPermission;
use App\Facade\Theme; use App\Facade\Theme;
use App\Facade\UserConfig; use App\Facade\UserConfig;
use App\Group;
use App\Helpers\FileHelper; use App\Helpers\FileHelper;
use App\Helpers\MiscHelper; use App\Helpers\MiscHelper;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Permission;
use App\Photo; use App\Photo;
use App\Services\PhotoService; use App\Services\PhotoService;
use App\Storage; use App\Storage;
@ -142,6 +145,58 @@ class AlbumController extends Controller
]); ]);
} }
public function setGroupPermissions(Request $request, $id)
{
$this->authorize('admin-access');
/** @var Album $album */
$album = $this->loadAlbum($id);
if ($request->get('action') == 'add_group' && $request->has('group_id'))
{
/* Add a new group to the permission list for this album */
/** @var Group $group */
$group = Group::where('id', $request->get('group_id'))->first();
if (is_null($group))
{
App::abort(404);
}
// Link all default permissions to the group
/** @var Permission $permission */
foreach (Permission::where(['section' => 'album', 'is_default' => true])->get() as $permission)
{
$album->groupPermissions()->attach($permission->id, ['group_id' => $group->id]);
}
$album->save();
}
else if ($request->get('action') == 'update_permissions')
{
/* Update existing permissions for this album */
$album->groupPermissions()->detach();
$permissions = $request->get('permissions');
if (is_array($permissions))
{
foreach ($permissions as $groupID => $permissionIDs)
{
foreach ($permissionIDs as $permissionID)
{
$album->groupPermissions()->attach($permissionID, [
'group_id' => $groupID,
'created_at' => new \DateTime(),
'updated_at' => new \DateTime()
]);
}
}
}
}
return redirect(route('albums.show', [$album->id, 'tab' => 'permissions']));
}
/** /**
* Display the specified resource. * Display the specified resource.
* *
@ -169,8 +224,27 @@ class AlbumController extends Controller
$allowedAlbumViews[$view] = trans(sprintf('gallery.album_views.%s', $view)); $allowedAlbumViews[$view] = trans(sprintf('gallery.album_views.%s', $view));
} }
$addNewGroups = [];
$existingGroups = [];
foreach (Group::orderBy('name')->get() as $group)
{
if ($album->groupPermissions()->where('group_id', $group->id)->count() == 0)
{
$addNewGroups[] = $group;
}
else
{
$existingGroups[] = $group;
}
}
$activeTab = $request->get('tab');
return Theme::render('admin.show_album', [ return Theme::render('admin.show_album', [
'active_tab' => (strlen($activeTab) == 0) ? 'photos' : $activeTab,
'album' => $album, 'album' => $album,
'add_new_groups' => $addNewGroups,
'all_permissions' => Permission::where('section', 'album')->get(),
'allowed_views' => $allowedAlbumViews, 'allowed_views' => $allowedAlbumViews,
'bulk_actions' => [ 'bulk_actions' => [
'rotate_left' => trans('admin.photo_actions.rotate_left'), 'rotate_left' => trans('admin.photo_actions.rotate_left'),
@ -185,6 +259,7 @@ class AlbumController extends Controller
'delete' => trans('admin.photo_actions.delete') 'delete' => trans('admin.photo_actions.delete')
], ],
'error' => $request->session()->get('error'), 'error' => $request->session()->get('error'),
'existing_groups' => $existingGroups,
'file_upload_limit' => $fileUploadLimit, 'file_upload_limit' => $fileUploadLimit,
'is_upload_enabled' => $isUploadEnabled, 'is_upload_enabled' => $isUploadEnabled,
'max_post_limit' => $postLimit, 'max_post_limit' => $postLimit,

15
app/Permission.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['section', 'description'];
}

View File

@ -4,6 +4,29 @@ use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
{ {
public static function createOrUpdate($tableName, array $values = [], $includeTimestamps = true)
{
$record = DB::table($tableName)->where($values)->first();
if (is_null($record))
{
// Add timestamps if we're creating a record
if ($includeTimestamps && !isset($values['created_at']))
{
$values['created_at'] = new \DateTime();
}
if ($includeTimestamps && !isset($values['updated_at']))
{
$values['updated_at'] = new \DateTime();
}
DB::table($tableName)->insert($values);
$record = DB::table($tableName)->where($values)->first();
}
return $record;
}
/** /**
* Run the database seeds. * Run the database seeds.
* *
@ -11,6 +34,6 @@ class DatabaseSeeder extends Seeder
*/ */
public function run() public function run()
{ {
// $this->call(UsersTableSeeder::class); $this->call(PermissionsSeeder::class);
} }
} }

View File

@ -13,8 +13,7 @@ return [
'album_no_photos_button' => 'Upload photos', 'album_no_photos_button' => 'Upload photos',
'album_photos_tab' => 'Photos', 'album_photos_tab' => 'Photos',
'album_saved_successfully' => 'The ":name" album was updated successfully.', 'album_saved_successfully' => 'The ":name" album was updated successfully.',
'album_security_heading' => 'Security', 'album_security_tab' => 'Permissions',
'album_security_intro' => 'The settings below affect the visibility of this album to other users.',
'album_settings_tab' => 'Settings', 'album_settings_tab' => 'Settings',
'album_upload_tab' => 'Upload', 'album_upload_tab' => 'Upload',
'analyse_and_more' => [ 'analyse_and_more' => [
@ -114,6 +113,10 @@ return [
], ],
'save_changes_heading' => 'Save changes', 'save_changes_heading' => 'Save changes',
'save_changes_intro' => 'If you have made any changes to the above fields, you\'ll need to hit the Save Changes button below.', 'save_changes_intro' => 'If you have made any changes to the above fields, you\'ll need to hit the Save Changes button below.',
'security_groups_heading' => 'Group Permissions',
'security_heading' => 'Permissions',
'security_text' => 'You can assign permissions on this album to either groups (recommended) or directly to users.',
'security_users_heading' => 'User Permissions',
'select_all_action' => 'Select all', 'select_all_action' => 'Select all',
'select_all_album_active' => 'Any action you select in the list below will apply to all photos in this album.', 'select_all_album_active' => 'Any action you select in the list below will apply to all photos in this album.',
'select_all_choice' => [ 'select_all_choice' => [

View File

@ -24,6 +24,7 @@ return [
'realname_label' => 'Your name:', 'realname_label' => 'Your name:',
'register_action' => 'Create account', 'register_action' => 'Create account',
'remember_me_label' => 'Remember me', 'remember_me_label' => 'Remember me',
'remove_action' => 'Remove',
'select' => 'Select', 'select' => 'Select',
'settings_hotlink_protection' => 'Prevent hot-linking to images', 'settings_hotlink_protection' => 'Prevent hot-linking to images',
'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.', 'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.',

View File

@ -0,0 +1,7 @@
<?php
return [
'album' => [
'list-gallery' => 'See this album in the gallery index',
'view' => 'Access this gallery'
]
];

View File

@ -26,14 +26,15 @@
<div> <div>
<ul class="nav nav-tabs" role="tablist"> <ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#photos-tab" aria-controls="photos-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-photo"></i> @lang('admin.album_photos_tab')</a></li> <li role="presentation" class="{{ $active_tab == 'photos' ? 'active' : '' }}"><a href="#photos-tab" aria-controls="photos-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-photo"></i> @lang('admin.album_photos_tab')</a></li>
<li role="presentation"><a href="#upload-tab" aria-controls="upload-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-upload"></i> @lang('admin.album_upload_tab')</a></li> <li role="presentation" class="{{ $active_tab == 'upload' ? 'active' : '' }}"><a href="#upload-tab" aria-controls="upload-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-upload"></i> @lang('admin.album_upload_tab')</a></li>
<li role="presentation"><a href="#settings-tab" aria-controls="settings-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-cog"></i> @lang('admin.album_settings_tab')</a></li> <li role="presentation" class="{{ $active_tab == 'permissions' ? 'active' : '' }}"><a href="#permissions-tab" aria-controls="permissions-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-lock"></i> @lang('admin.album_security_tab')</a></li>
<li role="presentation" class="{{ $active_tab == 'settings' ? 'active' : '' }}"><a href="#settings-tab" aria-controls="settings-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-cog"></i> @lang('admin.album_settings_tab')</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
{{-- Photos --}} {{-- Photos --}}
<div role="tabpanel" class="tab-pane active" id="photos-tab"> <div role="tabpanel" class="tab-pane{{ $active_tab == 'photos' ? ' active' : '' }}" id="photos-tab">
@if (count($photos) == 0) @if (count($photos) == 0)
<div class="text-center" style="margin-top: 30px;"> <div class="text-center" style="margin-top: 30px;">
<h4 class="text-danger"><b>@lang('admin.album_no_photos_p1')</b></h4> <h4 class="text-danger"><b>@lang('admin.album_no_photos_p1')</b></h4>
@ -77,7 +78,7 @@
</div> </div>
{{-- Upload --}} {{-- Upload --}}
<div role="tabpanel" class="tab-pane" id="upload-tab"> <div role="tabpanel" class="tab-pane{{ $active_tab == 'upload' ? ' active' : '' }}" id="upload-tab">
@if (!$is_upload_enabled) @if (!$is_upload_enabled)
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
@ -165,8 +166,65 @@
@endif @endif
</div> </div>
{{-- Permissions --}}
<div role="tabpanel" class="tab-pane{{ $active_tab == 'permissions' ? ' active' : '' }}" id="permissions-tab">
<h4>@lang('admin.security_heading')</h4>
<p>@lang('admin.security_text')</p>
<hr/>
<h5 style="font-weight: bold;">@lang('admin.security_groups_heading')</h5>
<form action="{{ route('albums.set_group_permissions', ['id' => $album->id]) }}" method="post">
{{ csrf_field() }}
@if (count($existing_groups) > 0)
<div class="panel-group" id="groups-accordion" role="tablist" aria-multiselectable="true">
@foreach ($existing_groups as $group)
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="heading-{{ $group->id }}">
<h4 class="panel-title">
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-{{ $group->id }}" aria-expanded="true" aria-controls="collapse-{{ $group->id }}">
{{ $group->name }}
</a>
</h4>
</div>
<div id="collapse-{{ $group->id }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-{{ $group->id }}">
<div class="panel-body">
<p style="margin-bottom: 20px;"><a href="">Select All</a> &middot; <a href="">Select None</a></p>
@foreach ($all_permissions as $permission)
<div class="checkbox">
<label for="permission|{{ $group->id }}|{{ $permission->id }}">
<input id="permission|{{ $group->id }}|{{ $permission->id }}" name="permissions[{{ $group->id }}][]" value="{{ $permission->id }}" type="checkbox"{{ $album->doesGroupHavePermission($group, $permission) ? ' checked="checked"' : '' }} /> {{ trans(sprintf('permissions.%s.%s', $permission->section, $permission->description)) }}
</label>
</div>
@endforeach
</div>
</div>
</div>
@endforeach
</div>
@endif
<div class="form-group">
<select class="form-control" name="group_id" style="width: auto; display: inline;"@if (count($add_new_groups) == 0) disabled="disabled"@endif>
@foreach ($add_new_groups as $group)
<option value="{{ $group->id }}">{{ $group->name }}</option>
@endforeach
</select>
<button type="submit" name="action" value="add_group" class="btn btn-primary"@if (count($add_new_groups) == 0) disabled="disabled"@endif>Assign Permissions</button>
<button type="submit" name="action" value="update_permissions" class="btn btn-success pull-right">
<i class="fa fa-fw fa-check"></i> @lang('forms.save_action')
</button>
</div>
</form>
<hr/>
<h5 style="font-weight: bold;">@lang('admin.security_users_heading')</h5>
</div>
{{-- Settings --}} {{-- Settings --}}
<div role="tabpanel" class="tab-pane" id="settings-tab"> <div role="tabpanel" class="tab-pane{{ $active_tab == 'settings' ? ' active' : '' }}" id="settings-tab">
{!! Form::model($album, ['route' => ['albums.update', $album->id], 'method' => 'PUT']) !!} {!! Form::model($album, ['route' => ['albums.update', $album->id], 'method' => 'PUT']) !!}
<h4><i class="fa fa-fw fa-info"></i> @lang('admin.album_basic_info_heading')</h4> <h4><i class="fa fa-fw fa-info"></i> @lang('admin.album_basic_info_heading')</h4>
<p>@lang('admin.album_basic_info_intro')</p> <p>@lang('admin.album_basic_info_intro')</p>
@ -199,18 +257,6 @@
<hr/> <hr/>
<h4><i class="fa fa-fw fa-lock"></i> @lang('admin.album_security_heading')</h4>
<p>@lang('admin.album_security_intro')</p>
<div class="checkbox" style="margin-top: 20px;">
<label>
<input type="checkbox" name="is_private"@if ($album->is_private) checked="checked"@endif>
<strong>@lang('forms.private_album_label')</strong>
</label>
</div>
<hr/>
<div class="row"> <div class="row">
<div class="col-sm-6 col-sm-push-6"> <div class="col-sm-6 col-sm-push-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -41,6 +41,7 @@ Route::group(['prefix' => 'admin'], function () {
// Album management // Album management
Route::get('albums/{id}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse'); Route::get('albums/{id}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse');
Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete'); Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
Route::post('albums/{id}/set-group-permissions', 'Admin\AlbumController@setGroupPermissions')->name('albums.set_group_permissions');
Route::resource('albums', 'Admin\AlbumController'); Route::resource('albums', 'Admin\AlbumController');
// Photo management // Photo management