Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cake5 #20

Merged
merged 11 commits into from
Sep 27, 2023
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Total Downloads](https://img.shields.io/packagist/dt/muffin/obfuscate.svg?style=flat-square)](https://packagist.org/packages/muffin/obfuscate)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)

Primary key obfuscation for CakePHP using HashIds, Optimus, Tiny and/or custom obfuscation strategies.
Primary key obfuscation for CakePHP using HashIds, Optimus, Tiny, Base62 and/or custom obfuscation strategies.

## Installation

Expand Down Expand Up @@ -33,7 +33,7 @@ want to use in your application:
```
composer require hashids/hashids
composer require jenssegers/optimus
composer require zackkitzmiller/tiny
composer require tuupola/base62
```

## Built-in obfuscation strategies
Expand All @@ -48,7 +48,7 @@ Use the [OptimusStrategy](https://github.com/jenssegers/optimus) if you want to:
- obfuscate your primary keys with integers based on Knuth's integer hash
- present record ids like 347 as integers like 372555994

Use the [TinyStrategy](https://github.com/zackkitzmiller/tiny-php) if you want to:
Use the [Base62Strategy](https://github.com/tuupola/base62) (or [TinyStrategy] for backward compatibility) if you want to:

- obfuscate your primary keys with base62 strings and integers
- present record ids like 347 as strings like "vk"
Expand Down Expand Up @@ -90,12 +90,12 @@ $this->addBehavior('Muffin/Obfuscate.Obfuscate', [
```

```php
use Muffin\Obfuscate\Model\Behavior\Strategy\TinyStrategy;
use Muffin\Obfuscate\Model\Behavior\Strategy\Base62Strategy;

$this->addBehavior('Muffin/Obfuscate.Obfuscate', [
// Strategy constructor parameters:
// $set - Random alpha-numeric set where each character must only be used exactly once
'strategy' => new TinyStrategy('5SX0TEjkR1mLOw8Gvq2VyJxIFhgCAYidrclDWaM3so9bfzZpuUenKtP74QNH6B')
'strategy' => new Base62Strategy('5SX0TEjkR1mLOw8Gvq2VyJxIFhgCAYidrclDWaM3so9bfzZpuUenKtP74QNH6B')
]);
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
use Tuupola\Base62;

/**
* Class TuupolaStrategy
* Class Base62Strategy
*/
class TuupolaStrategy implements StrategyInterface
class Base62Strategy implements StrategyInterface
arusinowski marked this conversation as resolved.
Show resolved Hide resolved
{
/**
* Obfuscator.
*
* @var \Tuupola\Base62
*/
private Base62 $tuupola;
private Base62 $base62;
arusinowski marked this conversation as resolved.
Show resolved Hide resolved

/**
* Constructor.
Expand All @@ -26,7 +26,7 @@ class TuupolaStrategy implements StrategyInterface
public function __construct(?string $set = null)
arusinowski marked this conversation as resolved.
Show resolved Hide resolved
{
$options = $set ? ['characters' => $set] : [];
$this->tuupola = new Base62($options);
$this->base62 = new Base62($options);
}

/**
Expand All @@ -38,14 +38,14 @@ public function obfuscate(int|string $str): string
throw new InvalidArgumentException('Argument should be an integer');
}

return $this->tuupola->encodeInteger((int)$str);
return $this->base62->encodeInteger((int)$str);
}

/**
* @inheritDoc
*/
public function elucidate(int|string $str): int
{
return $this->tuupola->decodeInteger((string)$str);
return $this->base62->decodeInteger((string)$str);
}
}
12 changes: 5 additions & 7 deletions src/Model/Behavior/Strategy/TinyStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@

/**
* Class TinyStrategy
*
* @deprecated Use Muffin\Obfuscate\Model\Behavior\Strategy\TuupolaStrategy instead
*/
class TinyStrategy implements StrategyInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we should just drop this TinyStragtegy. Existing users will have to change the underlying lib anyway, so they can change the strategy name too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, we may drop the TinyStrategy completely

{
/**
* TuupolaStrategy
*
* @var \Muffin\Obfuscate\Model\Behavior\Strategy\TuupolaStrategy
* @var \Muffin\Obfuscate\Model\Behavior\Strategy\Base62Strategy
*/
private TuupolaStrategy $tuupolaStrategy;
private Base62Strategy $base62Strategy;

/**
* Constructor.
Expand All @@ -24,22 +22,22 @@ class TinyStrategy implements StrategyInterface
*/
public function __construct(string $set)
{
$this->tuupolaStrategy = new TuupolaStrategy($set);
$this->base62Strategy = new Base62Strategy($set);
}

/**
* @inheritDoc
*/
public function obfuscate(string|int $str): string
{
return $this->tuupolaStrategy->obfuscate($str);
return $this->base62Strategy->obfuscate($str);
}

/**
* @inheritDoc
*/
public function elucidate(string|int $str): int
{
return $this->tuupolaStrategy->elucidate($str);
return $this->base62Strategy->elucidate($str);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
namespace Model\Behavior\Strategy;

use Cake\TestSuite\TestCase;
use Muffin\Obfuscate\Model\Behavior\Strategy\TuupolaStrategy;
use Muffin\Obfuscate\Model\Behavior\Strategy\Base62Strategy;

class TuupolaStrategyTest extends TestCase
class Base62StrategyTest extends TestCase
{
/**
* @var \Muffin\Obfuscate\Model\Behavior\Strategy\TuupolaStrategy
* @var \Muffin\Obfuscate\Model\Behavior\Strategy\Base62Strategy
*/
public TuupolaStrategy $strategy;
public Base62Strategy $strategy;

public function setUp(): void
{
$this->strategy = new TuupolaStrategy('5SX0TEjkR1mLOw8Gvq2VyJxIFhgCAYidrclDWaM3so9bfzZpuUenKtP74QNH6B');
$this->strategy = new Base62Strategy('5SX0TEjkR1mLOw8Gvq2VyJxIFhgCAYidrclDWaM3so9bfzZpuUenKtP74QNH6B');
}

public function testObfuscate(): void
Expand Down
121 changes: 19 additions & 102 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,115 +1,32 @@
<?php
declare(strict_types=1);

use Cake\Core\Plugin;
use Cake\TestSuite\Fixture\SchemaLoader;
use Muffin\Obfuscate\ObfuscatePlugin;
use function Cake\Core\env;

/**
* Test suite bootstrap.
*
* This function is used to find the location of CakePHP whether CakePHP
* has been installed as a dependency of the plugin, or the plugin is itself
* installed as a dependency of an application.
*/

use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Datasource\ConnectionManager;
use Cake\Log\Log;
use Cake\TestSuite\Fixture\SchemaLoader;
use Muffin\Obfuscate\ObfuscatePlugin;

require_once 'vendor/autoload.php';

// Path constants to a few helpful things.
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
define('ROOT', dirname(__DIR__));
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp');
define('CORE_PATH', ROOT . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp' . DS);
define('CAKE', CORE_PATH . 'src' . DS);
define('TESTS', ROOT . DS . 'tests');
define('APP', ROOT . DS . 'tests' . DS . 'test_app' . DS);
define('APP_DIR', 'test_app');
define('WEBROOT_DIR', 'webroot');
define('WWW_ROOT', APP . 'webroot' . DS);
define('TMP', sys_get_temp_dir() . DS);
define('CONFIG', APP . 'config' . DS);
define('CACHE', TMP);
define('LOGS', TMP);

require_once CORE_PATH . 'config/bootstrap.php';
require_once CAKE . 'Core/functions_global.php';
require_once CAKE . 'Collection/functions_global.php';

date_default_timezone_set('UTC');
mb_internal_encoding('UTF-8');

Configure::write('debug', true);
Configure::write('App', [
'namespace' => 'Muffin\Obfuscate',
'encoding' => 'UTF-8',
'base' => false,
'baseUrl' => false,
'dir' => 'src',
'webroot' => 'webroot',
'www_root' => APP . 'webroot',
'fullBaseUrl' => 'http://localhost',
'imageBaseUrl' => 'img/',
'jsBaseUrl' => 'js/',
'cssBaseUrl' => 'css/',
'paths' => [
'plugins' => [APP . 'Plugin' . DS],
'templates' => [APP . 'templates' . DS],
],
]);
Configure::write('Session', [
'defaults' => 'php',
]);

Cache::setConfig([
'_cake_core_' => [
'engine' => 'File',
'prefix' => 'cake_core_',
'serialize' => true,
],
'_cake_model_' => [
'engine' => 'File',
'prefix' => 'cake_model_',
'serialize' => true,
],
'default' => [
'engine' => 'File',
'prefix' => 'default_',
'serialize' => true,
],
]);

// Ensure default test connection is defined
if (!getenv('DB_URL')) {
putenv('DB_URL=sqlite://127.0.0.1/' . TMP . 'test.sqlite');
}

$config = [
'url' => getenv('DB_URL'),
'timezone' => 'UTC',
];

ConnectionManager::setConfig('test', $config);

Log::setConfig([
'debug' => [
'engine' => 'Cake\Log\Engine\FileLog',
'path' => LOGS,
'levels' => ['notice', 'info', 'debug'],
'file' => 'debug',
],
'error' => [
'engine' => 'Cake\Log\Engine\FileLog',
'path' => LOGS,
'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
'file' => 'error',
],
]);
$findRoot = function ($root) {
do {
$lastRoot = $root;
$root = dirname($root);
if (is_dir($root . '/vendor/cakephp/cakephp')) {
return $root;
}
} while ($root !== $lastRoot);
throw new Exception('Cannot find the root of the application, unable to run tests');
};
$root = $findRoot(__FILE__);
unset($findRoot);
chdir($root);
require $root . '/vendor/cakephp/cakephp/tests/bootstrap.php';

Plugin::getCollection()->add(new ObfuscatePlugin());

Expand Down
Loading