Skip to content
Merged
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
11 changes: 6 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ env:
FTP_USER: username
FTP_PASSWORD: password
FTP_PORT: 21
FTP_ROOT: /tmp

jobs:
lunix-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
php: [8.1, 8.2]
php: [8.1, 8.2, 8.3]
os: [ubuntu-latest]
stability: [prefer-lowest, prefer-stable]

Expand Down Expand Up @@ -41,7 +42,7 @@ jobs:
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysql, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, redis
coverage: none

- run: docker run --net=host -p 21:21 -e USER=$FTP_USER -e PASS=$FTP_PASSWORD -d --name ftp -v $(pwd)/:/ftp/$FTP_USER emilybache/vsftpd-server
- run: docker run -p 21:21 -p 20:20 -p 12020:12020 -p 12021:12021 -p 12022:12022 -p 12023:12023 -p 12024:12024 -p 12025:12025 -e USER=$FTP_USER -e PASS=$FTP_PASSWORD -d --name ftp papacdev/vsftpd
- run: docker run -p 1080:1080 -p 1025:1025 -d --name maildev soulteary/maildev
- run: docker run -p 6379:6379 -d --name redis redis
- run: docker run -p 5432:5432 --name postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres -e POSTGRES_PASSWORD=postgres -d postgis/postgis
Expand All @@ -57,13 +58,13 @@ jobs:
${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}

- name: Copy the php ini config
run: cp php.dist.ini php.ini
run: sudo cp php.dist.ini php.ini

- name: Install dependencies
run: composer update --prefer-dist --no-interaction
run: sudo composer update --prefer-dist --no-interaction

- name: Create test cache directory
run: if [ ! -d /tmp/bowphp_testing ]; then mkdir -p /tmp/bowphp_testing; fi;

- name: Run test suite
run: composer run-script test
run: sudo composer run-script test
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
"nesbot/carbon": "^2.16",
"psy/psysh": "v0.10.*",
"fakerphp/faker": "^1.20",
"neitanod/forceutf8": "^2.0"
"neitanod/forceutf8": "^2.0",
"ramsey/uuid": "^4.7"
},
"require-dev": {
"pda/pheanstalk": "^4.0",
"phpunit/phpunit": "^8",
"phpunit/phpunit": "^9",
"monolog/monolog": "^1.22",
"twig/twig": "^2.5",
"twig/twig": "^3",
"squizlabs/php_codesniffer": "3.*",
"aws/aws-sdk-php": "^3.87",
"phpstan/phpstan": "^0.12.87",
Expand Down
16 changes: 4 additions & 12 deletions src/Router/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Route
/**
* The callback has launched if the url of the query has matched.
*
* @var callable
* @var mixed
*/
private mixed $cb;

Expand Down Expand Up @@ -70,7 +70,7 @@ class Route
* Route constructor
*
* @param string $path
* @param callable $cb
* @param mixed $cb
*
* @throws
*/
Expand Down Expand Up @@ -124,11 +124,7 @@ public function middleware(array|string $middleware): Route
return $this;
}

if (!isset($this->cb['middleware'])) {
$this->cb['middleware'] = $middleware;
} else {
$this->cb['middleware'] = array_merge((array) $this->cb['middleware'], $middleware);
}
$this->cb['middleware'] = !isset($this->cb['middleware']) ? $middleware : array_merge((array) $this->cb['middleware'], $middleware);

return $this;
}
Expand All @@ -142,11 +138,7 @@ public function middleware(array|string $middleware): Route
*/
public function where(array|string $where, $regex_constraint = null): Route
{
if (is_array($where)) {
$other_rule = $where;
} else {
$other_rule = [$where => $regex_constraint];
}
$other_rule = is_array($where) ? $where : [$where => $regex_constraint];

$this->with = array_merge($this->with, $other_rule);

Expand Down
60 changes: 31 additions & 29 deletions src/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,7 @@ public function middleware(array|string $middlewares): Router
$collection = [];

foreach ($middlewares as $middleware) {
if (class_exists($middleware, true)) {
$collection[] = [new $middleware(), 'process'];
} else {
$collection[] = $middleware;
}
$collection[] = class_exists($middleware, true) ? [new $middleware(), 'process'] : $middleware;
}

return new Router($this->method, $this->magic_method, $this->base_route, $collection);
Expand Down Expand Up @@ -341,66 +337,72 @@ public function code(int $code, callable|array|string $cb): Router
* @param callable|string|array $cb
* @return Router
*/
public function match(array $methods, string $path, callable|string|array $cb): Router
public function match(array $methods, string $path, callable|string|array $cb): Route
{
foreach ($methods as $method) {
if ($this->method == strtoupper($method)) {
$this->pushHttpVerb(strtoupper($method), $path, $cb);
}
}
$methods = array_map('strtoupper', $methods);

return $this;
return $this->pushHttpVerb($methods, $path, $cb);
}

/**
* Add other HTTP verbs [PUT, DELETE, UPDATE, HEAD, PATCH]
*
* @param string $method
* @param string|array $methods
* @param string $path
* @param callable|array|string $cb
* @return Route
*/
private function pushHttpVerb(string $method, string $path, callable|string|array $cb): Route
private function pushHttpVerb(string|array $methods, string $path, callable|string|array $cb): Route
{
if ($this->magic_method) {
$methods = (array) $methods;

if (!$this->magic_method) {
return $this->routeLoader($methods, $path, $cb);
}

foreach ($methods as $key => $method) {
if ($this->magic_method === $method) {
$method = $this->magic_method;
$methods[$key] = $this->magic_method;
}
}

return $this->routeLoader($method, $path, $cb);
return $this->routeLoader($methods, $path, $cb);
}

/**
* Start loading a route.
*
* @param string $method
* @param string|array $method
* @param string $path
* @param Callable|string|array $cb
* @param callable|string|array $cb
* @return Route
*/
private function routeLoader(string $method, string $path, callable|string|array $cb): Route
private function routeLoader(string|array $methods, string $path, callable|string|array $cb): Route
{
$methods = (array) $methods;

$path = '/' . trim($path, '/');

// We build the original path based on the Router loader
$path = $this->base_route . $this->prefix . $path;

// We define the current route and current method
$this->current = ['path' => $path, 'method' => $method];

// We add the new route
$route = new Route($path, $cb);

$route->middleware($this->middlewares);

static::$routes[$method][] = $route;
foreach ($methods as $method) {
static::$routes[$method][] = $route;

// We define the current route and current method
$this->current = ['path' => $path, 'method' => $method];

if (
$this->auto_csrf === true
&& in_array($method, ['POST', 'DELETE', 'PUT'])
) {
$route->middleware('csrf');
if (
$this->auto_csrf === true
&& in_array($method, ['POST', 'DELETE', 'PUT'])
) {
$route->middleware('csrf');
}
}

return $route;
Expand Down
41 changes: 20 additions & 21 deletions src/Storage/Service/FTPService.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ public function connect()
$this->connection = $connection;

$this->login();
$this->setConnectionRoot();
$this->setConnectionPassiveMode();
$this->changePath();
$this->activePassiveMode();
}

/**
Expand All @@ -139,15 +139,8 @@ private function login(): bool
{
['username' => $username, 'password' => $password] = $this->config;

// We disable error handling to avoid credentials leak :+1:
set_error_handler(
fn () => error_log("set_error_handler muted for hidden the ftp credential to user")
);

$is_logged_in = ftp_login($this->connection, $username, $password);

restore_error_handler();

if ($is_logged_in) {
return true;
}
Expand All @@ -165,20 +158,19 @@ private function login(): bool
}

/**
* Set the connection root.
* Change path.
*
* @param string $path
* @return void
*/
public function setConnectionRoot(string $path = '')
public function changePath(?string $path = null)
{
$base_path = $path ?: $this->config['root'];

if ($base_path && (!@ftp_chdir($this->connection, $base_path))) {
throw new RuntimeException('Root is invalid or does not exist: ' . $base_path);
}

// Store absolute path for further reference.
ftp_pwd($this->connection);
}

Expand Down Expand Up @@ -359,13 +351,13 @@ public function makeDirectory(string $dirname, int $mode = 0777): bool

foreach ($directories as $directory) {
if (false === $this->makeActualDirectory($directory)) {
$this->setConnectionRoot();
$this->changePath();
return false;
}
ftp_chdir($connection, $directory);
}

$this->setConnectionRoot();
$this->changePath();

return true;
}
Expand Down Expand Up @@ -486,13 +478,18 @@ public function isFile(string $filename): bool
*/
public function isDirectory(string $dirname): bool
{
$listing = $this->listDirectoryContents();
$original_directory = ftp_pwd($this->connection);

$dirname_info = array_filter($listing, function ($item) use ($dirname) {
return $item['type'] === 'directory' && $item['name'] === $dirname;
});
// Test if you can change directory to $dirname
// suppress errors in case $dir is not a file or not a directory
if (!@ftp_chdir($this->connection, $dirname)) {
return false;
}

return count($dirname_info) !== 0;
// If it is a directory, then change the directory back to the original directory
ftp_chdir($this->connection, $original_directory);

return true;
}

/**
Expand Down Expand Up @@ -567,7 +564,7 @@ protected function listDirectoryContents($directory = '.')

$listing = @ftp_rawlist($this->getConnection(), '.') ?: [];

$this->setConnectionRoot();
$this->changePath();

return $this->normalizeDirectoryListing($listing);
}
Expand Down Expand Up @@ -638,8 +635,10 @@ private function readStream(string $path): mixed
*
* @throws RuntimeException
*/
private function setConnectionPassiveMode()
private function activePassiveMode()
{
@ftp_set_option($this->connection, FTP_USEPASVADDRESS, false);

if (!ftp_pasv($this->connection, $this->use_passive_mode)) {
throw new RuntimeException(
'Could not set passive mode for connection: '
Expand Down
4 changes: 2 additions & 2 deletions tests/Auth/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function test_attempt_login_with_jwt_provider()
$this->assertInstanceOf(Authentication::class, $user);
$this->assertTrue($auth->check());
$this->assertEquals($auth->id(), $user->id);
$this->assertRegExp("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token);
$this->assertMatchesRegularExpression("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token);
}

public function test_direct_login_with_jwt_provider()
Expand All @@ -119,7 +119,7 @@ public function test_direct_login_with_jwt_provider()
$this->assertTrue($auth->check());
$this->assertInstanceOf(Authentication::class, $user);
$this->assertEquals($auth->id(), $user->id);
$this->assertRegExp("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token);
$this->assertMatchesRegularExpression("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token);
}

public function test_attempt_login_with_jwt_provider_fail()
Expand Down
2 changes: 1 addition & 1 deletion tests/Config/stubs/storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
'password' => app_env('FTP_PASSWORD', 'password'),
'username' => app_env('FTP_USERNAME', 'username'),
'port' => app_env('FTP_PORT', 21),
'root' => app_env('FTP_ROOT', sys_get_temp_dir()), // Start directory
'root' => app_env('FTP_ROOT', '/tmp'), // Start directory
'tls' => app_env('FTP_SSL', false), // `true` enable the secure connexion.
'timeout' => app_env('FTP_TIMEOUT', 90) // Temps d'attente de connection
],
Expand Down
8 changes: 4 additions & 4 deletions tests/Console/GeneratorBasicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public function test_generate_stubs()
]);

$this->assertNotNull($content);
$this->assertRegExp("@\nnamespace\sGenerator\\\Testing;\n@", $content);
$this->assertRegExp("@\nclass\sCreateUserCommand\sextends\sConsoleCommand\n@", $content);
$this->assertMatchesRegularExpression("@\nnamespace\sGenerator\\\Testing;\n@", $content);
$this->assertMatchesRegularExpression("@\nclass\sCreateUserCommand\sextends\sConsoleCommand\n@", $content);
}

public function test_generate_stub_without_data()
Expand All @@ -26,8 +26,8 @@ public function test_generate_stub_without_data()
$content = $generator->makeStubContent('command', []);

$this->assertNotNull($content);
$this->assertRegExp("@\nnamespace\s\{baseNamespace\}\{namespace\};\n@", $content);
$this->assertRegExp("@\nclass\s\{className\}\sextends\sConsoleCommand\n@", $content);
$this->assertMatchesRegularExpression("@\nnamespace\s\{baseNamespace\}\{namespace\};\n@", $content);
$this->assertMatchesRegularExpression("@\nclass\s\{className\}\sextends\sConsoleCommand\n@", $content);
}

public function test_generate_by_writing_file()
Expand Down
Loading