Skip to content

Commit

Permalink
Dev (#308)
Browse files Browse the repository at this point in the history
* Depend on elFinder repo itself instead of fmelfinder-php-connector

* Updated namespaces and class names to be consistent with studio-42/elfinder, added studio-42 as dependency

* Added ability to parse MySQL driver

* Added all options for mysql driver

* Added array for mysql_settings

* Coveralls removed src_dir

* Tests summernote configuration

* Attempt to pass tests

* Tweaked settings for mysql

* Added default data to expected configuration

* Added basic test for mysql driver

* Removed session statement

* Removed two statements

* Basic configuration for permissions handling

* Added security_voter option to DI configuration

* Added security_voter option to tests

* Added encoding option

* Added additional options to DI configuration

* Fixed misprint, rewrite docblock

* Rewritten some docblocks, added getter for volumes

* Updated readme
  • Loading branch information
helios-ag authored Apr 1, 2018
1 parent 5f8e13e commit c170d4a
Show file tree
Hide file tree
Showing 23 changed files with 663 additions and 70 deletions.
4 changes: 1 addition & 3 deletions .coveralls.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
service_name: travis-ci
src_dir: ./
coverage_clover: clover.xml
json_path: coveralls.json
coverage_clover: build/logs/clover.xml
39 changes: 34 additions & 5 deletions Bridge/ElFinderBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,37 @@

namespace FM\ElfinderBundle\Bridge;

use FM\ElFinderPHP\ElFinder;
use FM\ElFinderPHP\Driver\ElFinderVolumeDriver;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use FM\ElfinderBundle\ElFinder\ElFinder;
use elFinderVolumeDriver;

/**
* Class ElFinderBridge.
*
* Use Symfony services as regular VolumeDrivers.
*/
class ElFinderBridge extends ElFinder
{
/** @var SessionInterface */
protected $session;

/**
* ElFinderBridge constructor.
*
* @param $opts
*/
public function __construct($opts)
{
if ($this->session) {
$opts = array_merge($opts, ['session' => $this->session]);
}
parent::__construct($opts);
}

/** @param $session */
public function setSession($session)
{
$this->session = $session;
}

/**
* @param array $opts
*/
Expand All @@ -21,7 +42,7 @@ protected function mountVolumes($opts)
$volume = null;
if (isset($o['service'])) {
$driver = $o['service'];
if (is_object($driver) && $driver instanceof ElFinderVolumeDriver) {
if (is_object($driver) && $driver instanceof elFinderVolumeDriver) {
$volume = $driver;
unset($opts['roots'][$i]);
}
Expand All @@ -39,4 +60,12 @@ protected function mountVolumes($opts)
}
parent::mountVolumes($opts);
}

/**
* @return array
*/
public function getVolumes()
{
return $this->volumes;
}
}
74 changes: 70 additions & 4 deletions Configuration/ElFinderConfigurationReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace FM\ElfinderBundle\Configuration;

use FM\ElfinderBundle\Model\ElFinderConfigurationProviderInterface;
use FM\ElfinderBundle\Security\ElfinderSecurityInterface;
use League\Flysystem\AdapterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -65,6 +66,8 @@ public function __construct($parameters, RequestStack $requestStack, ContainerIn
* @param $instance
*
* @return array
*
* @throws \Exception
*/
public function getConfiguration($instance)
{
Expand Down Expand Up @@ -99,6 +102,7 @@ public function getConfiguration($instance)
'plugin' => $parameter['plugins'],
'path' => $pathAndHomeFolder,
'startPath' => $parameter['start_path'],
'encoding' => $parameter['encoding'],
'URL' => $this->getURL($parameter, $request, $homeFolder, $path),
'alias' => $parameter['alias'],
'mimeDetect' => $parameter['mime_detect'],
Expand Down Expand Up @@ -139,7 +143,14 @@ public function getConfiguration($instance)
$driverOptions['accessControl'] = array($this, 'access');
}

if ($parameter['driver'] == 'Flysystem') {
if ($parameter['security_voter']) {
/** @var ElfinderSecurityInterface $voter */
$voter = $this->container->get($parameter['security_voter']);

$driverOptions['disabled'] = $this->parseSecurityConfiguration($voter);
}

if ('Flysystem' == $parameter['driver']) {
$driverOptions['filesystem'] = $filesystem;
}
$options['roots'][] = array_merge($driverOptions, $this->configureDriver($parameter));
Expand All @@ -159,7 +170,7 @@ public function getConfiguration($instance)
private function getURL($parameter, Request $request, $homeFolder, $path)
{
if (isset($parameter['url']) && $parameter['url']) {
if (strpos($parameter['url'], 'http') === 0) {
if (0 === strpos($parameter['url'], 'http')) {
return $parameter['url'];
}

Expand All @@ -174,14 +185,18 @@ private function getURL($parameter, Request $request, $homeFolder, $path)
/**
* @param $opt
* @param $adapter
* @param $serviceName
*
* @return Filesystem
*
* @throws \MongoConnectionException
*/
private function configureFlysystem($opt, $adapter, $serviceName)
{
switch ($adapter) {
case 'local':
$filesystem = new Filesystem(new Local($opt['local']['path']));

break;
case 'ftp':
$settings = array(
Expand All @@ -198,6 +213,7 @@ private function configureFlysystem($opt, $adapter, $serviceName)
'directoryPerm' => $opt['ftp']['directoryPerm'],
);
$filesystem = (!$opt['ftp']['sftp']) ? new Filesystem(new Ftp($settings)) : new Filesystem(new SftpAdapter($settings));

break;
case 'aws_s3_v2':
$options = array(
Expand All @@ -210,6 +226,7 @@ private function configureFlysystem($opt, $adapter, $serviceName)
}
$client = S3Client::factory($options);
$filesystem = new Filesystem(new AwsS3v2($client, $opt['aws_s3_v2']['bucket_name'], $opt['aws_s3_v2']['optional_prefix']));

break;
case 'aws_s3_v3':
$client = new S3Client(array(
Expand All @@ -221,6 +238,7 @@ private function configureFlysystem($opt, $adapter, $serviceName)
'version' => $opt['aws_s3_v3']['version'],
));
$filesystem = new Filesystem(new AwsS3v3($client, $opt['aws_s3_v3']['bucket_name'], $opt['aws_s3_v3']['optional_prefix']));

break;
case 'copy_com':
$client = new API(
Expand All @@ -230,17 +248,21 @@ private function configureFlysystem($opt, $adapter, $serviceName)
$opt['copy_com']['token_secret']
);
$filesystem = new Filesystem(new CopyAdapter($client, $opt['copy_com']['optional_prefix']));

break;
case 'gridfs':
$mongoClient = new MongoClient();
$gridFs = $mongoClient->selectDB($opt['gridfs']['db_name'])->getGridFS();
$filesystem = new Filesystem(new GridFSAdapter($gridFs));

break;
case 'zip':
$filesystem = new Filesystem(new ZipArchiveAdapter($opt['zip']['path']));

break;
case 'dropbox':
$filesystem = new Filesystem(new DropboxAdapter(new Client($opt['dropbox']['token'], $opt['dropbox']['app'])));

break;
case 'rackspace':
$client = new Rackspace(Rackspace::$opt['rackspace']['endpoint'], array(
Expand All @@ -250,12 +272,14 @@ private function configureFlysystem($opt, $adapter, $serviceName)
$store = $client->objectStoreService('cloudFiles', $opt['rackspace']['region']);
$container = $store->getContainer($opt['rackspace']['container']);
$filesystem = new Filesystem(new RackspaceAdapter($container));

break;
case 'custom':
$adapter = $this->container->get($serviceName);
if (is_object($adapter) && $adapter instanceof AdapterInterface) {
$filesystem = new Filesystem($adapter);
}

break;
}

Expand All @@ -277,12 +301,28 @@ private function configureDriver(array $parameter)
$settings['user'] = $parameter['ftp_settings']['user'];
$settings['pass'] = $parameter['ftp_settings']['password'];
$settings['path'] = $parameter['ftp_settings']['path'];

break;
case 'mysql':
$settings['host'] = $parameter['mysql_settings']['host'];
$settings['user'] = $parameter['mysql_settings']['user'];
$settings['pass'] = $parameter['mysql_settings']['pass'];
$settings['db'] = $parameter['mysql_settings']['db'];
$settings['port'] = $parameter['mysql_settings']['port'];
$settings['socket'] = $parameter['mysql_settings']['socket'];
$settings['files_table'] = $parameter['mysql_settings']['files_table'];
$settings['tmbPath'] = $parameter['mysql_settings']['tmbPath'];
$settings['tmpPath'] = $parameter['mysql_settings']['tmpPath'];
$settings['rootCssClass'] = $parameter['mysql_settings']['rootCssClass'];
$settings['noSessionCache'] = explode(',', $parameter['mysql_settings']['noSessionCache']);

break;
case 'ftpiis':
$settings['host'] = $parameter['ftp_settings']['host'];
$settings['user'] = $parameter['ftp_settings']['user'];
$settings['pass'] = $parameter['ftp_settings']['password'];
$settings['path'] = $parameter['ftp_settings']['path'];

break;
case 'dropbox':
$settings['consumerKey'] = $parameter['dropbox_settings']['consumer_key'];
Expand All @@ -291,6 +331,7 @@ private function configureDriver(array $parameter)
$settings['accessTokenSecret'] = $parameter['dropbox_settings']['access_token_secret'];
$settings['dropboxUid'] = $parameter['dropbox_settings']['dropbox_uid'];
$settings['metaCachePath'] = $parameter['dropbox_settings']['meta_cache_path'];

break;
case 's3':
$settings['accesskey'] = $parameter['s3_settings']['access_key'];
Expand All @@ -299,6 +340,7 @@ private function configureDriver(array $parameter)
$settings['tmpPath'] = $parameter['s3_settings']['tmp_path'];
$settings['signature'] = $parameter['s3_settings']['signature'];
$settings['region'] = $parameter['s3_settings']['region'];

break;
default:
break;
Expand All @@ -320,8 +362,32 @@ private function configureDriver(array $parameter)
*/
public function access($attr, $path, $data, $volume)
{
return strpos(basename($path), '.') === 0 // if file/folder begins with '.' (dot)
? !($attr == 'read' || $attr == 'write') // set read+write to false, other (locked+hidden) set to true
return 0 === strpos(basename($path), '.') // if file/folder begins with '.' (dot)
? !('read' == $attr || 'write' == $attr) // set read+write to false, other (locked+hidden) set to true
: null; // else elFinder decide it itself
}

/**
* @param ElfinderSecurityInterface $voter
*
* @return array
*
* @throws \Exception
*/
protected function parseSecurityConfiguration(ElfinderSecurityInterface $voter)
{
$configuration = $voter->getConfiguration();

if (!is_array($configuration)) {
throw new \Exception('ElfinderSecurityVoter should return array');
}

foreach ($configuration as $role => $commands) {
if ($this->container->get('security.authorization_checker')->isGranted($role)) {
return $commands;
}
}

return [];
}
}
76 changes: 76 additions & 0 deletions Connector/ElFinderConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace FM\ElfinderBundle\Connector;

use elFinder;

/**
* Class ElFinderConnector.
*/
class ElFinderConnector extends \elFinderConnector
{
public function run($queryParameters = null)
{
if (null === $queryParameters) {
$queryParameters = $_GET;
}
exit(json_encode($this->execute($queryParameters)));
}

public function execute($queryParameters)
{
$isPost = 'POST' == $_SERVER['REQUEST_METHOD'];
$src = 'POST' == $_SERVER['REQUEST_METHOD'] ? array_merge($_POST, $queryParameters) : $queryParameters;
if ($isPost && !$src && $rawPostData = @file_get_contents('php://input')) {
// for support IE XDomainRequest()
$parts = explode('&', $rawPostData);
foreach ($parts as $part) {
list($key, $value) = array_pad(explode('=', $part), 2, '');
$src[$key] = rawurldecode($value);
}
$_POST = $src;
$_REQUEST = array_merge_recursive($src, $_REQUEST);
}
$cmd = isset($src['cmd']) ? $src['cmd'] : '';
$args = array();

if (!function_exists('json_encode')) {
$error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);

return $this->output(array('error' => '{"error":["'.implode('","', $error).'"]}', 'raw' => true));
}

if (!$this->elFinder->loaded()) {
return $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
}

// telepat_mode: on
if (!$cmd && $isPost) {
return $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
}
// telepat_mode: off

if (!$this->elFinder->commandExists($cmd)) {
return $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
}

// collect required arguments to exec command
foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
$arg = 'FILES' == $name
? $_FILES
: (isset($src[$name]) ? $src[$name] : '');

if (!is_array($arg)) {
$arg = trim($arg);
}
if ($req && (!isset($arg) || '' === $arg)) {
return $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
}
$args[$name] = $arg;
}

$args['debug'] = isset($src['debug']) ? (bool) $src['debug'] : false;

return $this->output($this->elFinder->exec($cmd, $this->input_filter($args)));
}
}
15 changes: 8 additions & 7 deletions Controller/ElFinderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace FM\ElfinderBundle\Controller;

use Exception;
use FM\ElfinderBundle\Loader\ElFinderLoader;
use FM\ElfinderBundle\Session\ElFinderSession;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
Expand All @@ -12,12 +14,7 @@
use FM\ElfinderBundle\Event\ElFinderPostExecutionEvent;

/**
* Loader service for Elfinder backend
* displays Elfinder.
*
* @author Al Ganiev <[email protected]>
* @copyright 2012-2015 Al Ganiev
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* Class ElFinderController.
*/
class ElFinderController extends Controller
{
Expand All @@ -29,6 +26,8 @@ class ElFinderController extends Controller
* @param string $homeFolder
*
* @return Response
*
* @throws Exception
*/
public function showAction(Request $request, $instance, $homeFolder)
{
Expand Down Expand Up @@ -217,7 +216,9 @@ public function loadAction(Request $request, $instance, $homeFolder)
{
$loader = $this->get('fm_elfinder.loader');
$loader->initBridge($instance); // builds up the Bridge object for the loader with the given instance

if ($loader instanceof ElFinderLoader) {
$loader->setSession(new ElFinderSession($this->get('session')));
}
$httpKernel = $this->get('http_kernel');
$preExecutionEvent = new ElFinderPreExecutionEvent($request, $httpKernel, $instance, $homeFolder);
$this->get('event_dispatcher')->dispatch(ElFinderEvents::PRE_EXECUTION, $preExecutionEvent);
Expand Down
Loading

0 comments on commit c170d4a

Please sign in to comment.