blue-twilight/app/Http/Controllers/Admin/DefaultController.php

447 lines
15 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Album;
use App\ExternalService;
use App\Facade\Theme;
use App\Facade\UserConfig;
use App\Group;
use App\Helpers\AnalysisQueueHelper;
use App\Helpers\DbHelper;
use App\Helpers\MiscHelper;
use App\Helpers\PermissionsHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\SaveSettingsRequest;
use App\Label;
use App\Mail\TestMailConfig;
use App\Photo;
use App\PhotoComment;
use App\Services\GiteaService;
use App\Services\PhotoService;
use App\Storage;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\View;
class DefaultController extends Controller
{
private $passwordSettingKeys;
public function __construct()
{
$this->middleware('auth');
View::share('is_admin', true);
$this->passwordSettingKeys = [
'rabbitmq_password',
'smtp_password',
'facebook_app_secret',
'google_app_secret',
'twitter_app_secret'
];
}
public function about()
{
return Theme::render('admin.about', [
'current_version' => config('app.version'),
'licence_text' => file_get_contents(sprintf('%s/LICENSE', dirname(dirname(dirname(dirname(__DIR__))))))
]);
}
public function aboutLatestRelease()
{
try
{
$giteaService = new GiteaService();
$releaseInfo = $giteaService->checkForLatestRelease();
// Convert the publish date so we can re-format it with the user's settings
$publishDate = \DateTime::createFromFormat('Y-m-d\TH:i:sP', $releaseInfo->published_at);
// HTML-ify the body text
$body = nl2br($releaseInfo->body);
$body = preg_replace('/\*\*(.+)\*\*/', '<b>$1</b>', $body);
// Remove the "v" from the release name
$version = substr($releaseInfo->tag_name, 1);
// Determine if we can upgrade
$canUpgrade = version_compare($version, config('app.version')) > 0;
return response()->json([
'can_upgrade' => $canUpgrade,
'body' => $body,
'name' => $version,
'publish_date' => $publishDate->format(UserConfig::get('date_format')),
'url' => $releaseInfo->html_url
]);
}
catch (\Exception $ex)
{
return response()->json(['error' => $ex->getMessage()]);
}
}
public function metadataUpgrade()
{
$albumIDs = DbHelper::getAlbumIDsForCurrentUser();
$photoMetadata = DB::table('photos')
->whereIn('album_id', $albumIDs)
->select([
'album_id',
DB::raw('MIN(metadata_version) AS min_metadata_version')
])
->groupBy('album_id')
->get();
$resultingAlbumIDs = [];
foreach ($photoMetadata as $metadata)
{
if (isset($metadata->min_metadata_version) && $metadata->min_metadata_version > 0)
{
$resultingAlbumIDs[$metadata->album_id] = $metadata->min_metadata_version;
}
}
// Now load the full album definitions
$albumsQuery = DbHelper::getAlbumsForCurrentUser_NonPaged();
$albumsQuery->whereIn('id', array_keys($resultingAlbumIDs));
$albums = $albumsQuery->paginate(UserConfig::get('items_per_page'));
/** @var Album $album */
foreach ($resultingAlbumIDs as $albumID => $metadataMinVersion)
{
foreach ($albums as $album)
{
if ($album->id == $albumID)
{
$album->min_metadata_version = $metadataMinVersion;
}
}
}
return Theme::render('admin.metadata_upgrade', [
'albums' => $albums,
'current_metadata_version' => PhotoService::METADATA_VERSION
]);
}
public function index()
{
$this->authorizeAccessToAdminPanel();
$albumCount = count(DbHelper::getAlbumIDsForCurrentUser());
$photoCount = Photo::all()->count();
$groupCount = Group::all()->count();
$labelCount = Label::all()->count();
$commentCount = PhotoComment::whereNotNull('approved_at')->count();
$userCount = User::where('is_activated', true)->count();
$minMetadataVersion = Photo::min('metadata_version');
$metadataUpgradeNeeded = $minMetadataVersion > 0 && $minMetadataVersion < PhotoService::METADATA_VERSION;
// Default to a supported function call to get the OS version
$osVersion = sprintf('%s %s', php_uname('s'), php_uname('r'));
// If the exec() function is enabled, we can do a bit better
if (MiscHelper::isExecEnabled())
{
$osVersion = exec('lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om');
}
return Theme::render('admin.index', [
'album_count' => $albumCount,
'app_version' => config('app.version'),
'comment_count' => $commentCount,
'group_count' => $groupCount,
'label_count' => $labelCount,
'memory_limit' => ini_get('memory_limit'),
'metadata_upgrade_needed' => $metadataUpgradeNeeded,
'photo_count' => $photoCount,
'php_version' => phpversion(),
'os_version' => $osVersion,
'server_name' => gethostname(),
'upload_file_size' => ini_get('upload_max_filesize'),
'upload_max_limit' => ini_get('post_max_size'),
'user_count' => $userCount
]);
}
public function quickUpload(Request $request)
{
$this->authorizeAccessToAdminPanel('admin:manage-albums');
$returnUrl = $request->headers->get('referer');
if (!MiscHelper::isSafeUrl($returnUrl))
{
$returnUrl = route('home');
}
// Pre-validate the upload before passing to the Photos controller
$files = $request->files->get('photo');
if (!is_array($files) || count($files) == 0)
{
$request->session()->flash('error', trans('admin.quick_upload.no_image_provided'));
return redirect($returnUrl);
}
$albumID = $request->get('album_id');
if (intval($albumID) == 0)
{
$albumName = trim($request->get('album_name'));
if (strlen($albumName) == 0)
{
$request->session()->flash('error', trans('admin.quick_upload.no_album_selected'));
return redirect($returnUrl);
}
$album = new Album();
$album->storage_id = Storage::where('is_default', true)->first()->id;
$album->user_id = Auth::user()->id;
$album->default_view = UserConfig::get('default_album_view');
$album->name = $albumName;
$album->description = '';
$album->is_permissions_inherited = true;
$album->save();
// Rebuild the permissions cache
$helper = new PermissionsHelper();
$helper->rebuildCache();
$request->request->set('album_id', $album->id);
}
/** @var PhotoController $photoController */
$photoController = app(PhotoController::class);
return $photoController->store($request);
}
public function rebuildPermissionsCache()
{
$helper = new PermissionsHelper();
$helper->rebuildCache();
return response()->json(true);
}
public function saveSettings(SaveSettingsRequest $request)
{
$this->authorizeAccessToAdminPanel('admin:configure');
$checkboxKeys = [
'albums_menu_parents_only',
'allow_photo_comments',
'allow_photo_comments_anonymous',
'allow_self_registration',
'enable_visitor_hits',
'hotlink_protection',
'moderate_anonymous_users',
'moderate_known_users',
'queue_emails',
'rabbitmq_enabled',
'recaptcha_enabled_registration',
'remove_copyright',
'require_email_verification',
'restrict_original_download',
'smtp_encryption',
'social_facebook_login',
'social_google_login',
'social_twitter_login',
'social_user_feeds',
'social_user_profiles'
];
$updateKeys = [
'albums_menu_number_items',
'analysis_queue_storage_location',
'app_name',
'date_format',
'facebook_external_service_id',
'google_external_service_id',
'photo_comments_allowed_html',
'photo_comments_thread_depth',
'rabbitmq_server',
'rabbitmq_port',
'rabbitmq_username',
'rabbitmq_password',
'rabbitmq_queue',
'rabbitmq_vhost',
'sender_address',
'sender_name',
'smtp_server',
'smtp_port',
'smtp_username',
'smtp_password',
'theme',
'twitter_external_service_id',
'recaptcha_site_key',
'recaptcha_secret_key',
'analytics_code'
];
$defaults = UserConfig::defaults();
foreach ($updateKeys as $key)
{
$config = UserConfig::getOrCreateModel($key);
// Bit of a hack when the browser returns an empty password field - meaning the user didn't change it
// - don't touch it!
if (
(
$key == 'smtp_password' &&
strlen($config->value) > 0 &&
strlen($request->request->get($key)) == 0 &&
strlen($request->request->get('smtp_username')) > 0
) || (
$key == 'rabbitmq_password' &&
strlen($config->value) > 0 &&
strlen($request->request->get($key)) == 0 &&
strlen($request->request->get('rabbitmq_username')) > 0
)
)
{
continue;
}
$config->value = $request->request->get($key);
if (in_array($key, $this->passwordSettingKeys) && strlen($config->value) > 0)
{
$config->value = encrypt($config->value);
}
if (isset($defaults[$key]) && $defaults[$key] == $config->value)
{
$config->delete();
}
else
{
$config->save();
}
}
foreach ($checkboxKeys as $key)
{
$config = UserConfig::getOrCreateModel($key);
$config->value = ($request->request->get($key) == 'on' ? 1 : 0);
if (isset($defaults[$key]) && $defaults[$key] == $config->value)
{
$config->delete();
}
else
{
$config->save();
}
}
$request->session()->flash('success', trans('admin.settings_saved_message'));
return redirect(route('admin.settings'));
}
public function settings(Request $request)
{
$this->authorizeAccessToAdminPanel('admin:configure');
// Load the current configuration
$config = array_merge(UserConfig::defaults(), UserConfig::getAll());
$dateFormats = UserConfig::allowedDateFormats();
$dateFormatsLookup = [];
foreach ($dateFormats as $dateFormat)
{
$dateFormatsLookup[$dateFormat] = date($dateFormat);
}
foreach ($this->passwordSettingKeys as $passwordSettingKey)
{
if (isset($config[$passwordSettingKey]) && !empty($config[$passwordSettingKey]))
{
$config[$passwordSettingKey] = decrypt($config[$passwordSettingKey]);
}
}
$themeNamesLookup = UserConfig::allowedThemeNames();
// Storage sources for the Image Processing tab
$storageSources = AnalysisQueueHelper::getCompatibleStorages();
// External services
$externalServices = ExternalService::all();
$facebookServices = $externalServices->filter(function (ExternalService $item)
{
return $item->service_type == ExternalService::FACEBOOK;
});
$googleServices = $externalServices->filter(function (ExternalService $item)
{
return $item->service_type == ExternalService::GOOGLE;
});
$twitterServices = $externalServices->filter(function (ExternalService $item)
{
return $item->service_type == ExternalService::TWITTER;
});
return Theme::render('admin.settings', [
'config' => $config,
'date_formats' => $dateFormatsLookup,
'facebookServices' => $facebookServices,
'googleServices' => $googleServices,
'storage_sources' => $storageSources,
'success' => $request->session()->get('success'),
'theme_names' => $themeNamesLookup,
'twitterServices' => $twitterServices
]);
}
public function testMailSettings(SaveSettingsRequest $request)
{
$this->authorizeAccessToAdminPanel('admin:configure');
try
{
$validKeys = [
'sender_address',
'sender_name',
'smtp_server',
'smtp_port',
'smtp_username',
'smtp_password',
'smtp_encryption'
];
$config = $request->only($validKeys);
/** @var \Swift_Mailer $swiftMailer */
$swiftMailer = resolve('mailer')->getSwiftMailer();
/** @var \Swift_SmtpTransport $transport */
$transport = $swiftMailer->getTransport();
$transport->setHost($config['smtp_server']);
$transport->setPort(intval($config['smtp_port']));
$transport->setUsername($config['smtp_username']);
$transport->setPassword($config['smtp_password']);
if (isset($config['smtp_encryption']) && strtolower($config['smtp_encryption']) == 'on')
{
$transport->setEncryption('tls');
}
else
{
$transport->setEncryption('');
}
Mail::to(Auth::user())->send(new TestMailConfig($config['sender_name'], $config['sender_address']));
return response()->json(array('is_successful' => true, 'message' => trans('admin.settings_test_email_successful')));
}
catch (\Exception $ex)
{
return response()->json(array('is_successful' => false, 'message' => $ex->getMessage()));
}
}
}