You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
442 lines
13 KiB
442 lines
13 KiB
<?php
|
|
/**
|
|
* Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
|
|
*
|
|
* @package Fuel
|
|
* @version 1.8.1
|
|
* @author Fuel Development Team
|
|
* @license MIT License
|
|
* @copyright 2010 - 2018 Fuel Development Team
|
|
* @link http://fuelphp.com
|
|
*/
|
|
|
|
namespace Fuel\Tasks;
|
|
|
|
/**
|
|
* Converts a SimpleAuth ruleset to an OrmAuth one
|
|
*/
|
|
class Simple2orm
|
|
{
|
|
/*
|
|
* @var array collected data during validation
|
|
*/
|
|
protected static $data = array();
|
|
|
|
/**
|
|
* Show help.
|
|
*
|
|
* Usage (from command line):
|
|
*
|
|
* php oil refine simple2orm
|
|
*/
|
|
public static function run()
|
|
{
|
|
// fetch the commandline options
|
|
$run_migration = \Cli::option('migrate', \Cli::option('m', false));
|
|
$run_validation = $run_migration ? true : \Cli::option('validate', \Cli::option('v', false));
|
|
|
|
// if no run options are present, show the help
|
|
if ( ! $run_migration and ! $run_validation )
|
|
{
|
|
return static::help();
|
|
}
|
|
|
|
// step 1: run validation
|
|
$validated = true;
|
|
if ($run_validation)
|
|
{
|
|
$validated = static::run_validation();
|
|
}
|
|
|
|
// step 2: run migration
|
|
if ($run_migration)
|
|
{
|
|
if ($validated)
|
|
{
|
|
$migrated = static::run_migration();
|
|
if ($migrated)
|
|
{
|
|
\Cli::write('Migration succesfully finished', 'light_green');
|
|
}
|
|
else
|
|
{
|
|
\Cli::write("\n".'Migration failed. Skipping the remainder of the migration. Please correct the errors and run again.', 'light_red');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
\Cli::write("\n".'Validation failed. Skipping the actual migration. Please correct the errors.', 'light_red');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show help.
|
|
*
|
|
* Usage (from command line):
|
|
*
|
|
* php oil refine simple2orm:help
|
|
*/
|
|
public static function help()
|
|
{
|
|
$output = <<<HELP
|
|
|
|
Description:
|
|
The task converts an existing SimpleAuth setup to OrmAuth, migrating
|
|
all configured users, groups, roles and rights.
|
|
|
|
Before using this task, make sure your auth configuration is set to use
|
|
the Ormauth driver, you have an ormauth configuration file, and you have
|
|
run all auth migrations.
|
|
|
|
Runtime options:
|
|
-v, [--validate] # Validate the current installation, do not migrate
|
|
-m, [--migrate] # Run the migration
|
|
|
|
Commands:
|
|
php oil refine simple2orm
|
|
php oil refine simple2orm:help
|
|
php oil refine simple2orm --validate
|
|
php oil refine simple2orm
|
|
|
|
HELP;
|
|
\Cli::write($output);
|
|
}
|
|
|
|
/**
|
|
* Run the environment validation
|
|
*/
|
|
protected static function run_validation()
|
|
{
|
|
// storage for collected errors
|
|
$errors = array();
|
|
|
|
// validate the auth configuration file
|
|
if ( ! is_file($file = APPPATH.'config'.DS.'auth.php'))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not exist.';
|
|
}
|
|
else
|
|
{
|
|
\Config::load('auth', true);
|
|
if ( ! $driver = \Config::get('auth.driver', false))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not define an auth driver.';
|
|
}
|
|
elseif ($driver != 'Ormauth')
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' is not configured to use the Ormauth driver.';
|
|
}
|
|
}
|
|
|
|
// validate the simpleauth configuration file
|
|
if ( ! is_file($file = APPPATH.'config'.DS.'simpleauth.php'))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not exist.';
|
|
}
|
|
else
|
|
{
|
|
\Config::load('simpleauth', true);
|
|
if ( ! $table = \Config::get('simpleauth.table_name', false))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not define a user table.';
|
|
}
|
|
elseif ( ! \DBUtil::table_exists($table))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' defines a table that does not exist.';
|
|
}
|
|
else
|
|
{
|
|
// store the table name for future use
|
|
static::$data['simpleauth_table'] = $table;
|
|
}
|
|
}
|
|
|
|
// validate the ormauth configuration file
|
|
if ( ! is_file($file = APPPATH.'config'.DS.'ormauth.php'))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not exist.';
|
|
}
|
|
else
|
|
{
|
|
$config = \Config::load('ormauth', true);
|
|
if ( ! $table = \Config::get('ormauth.table_name', false))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not define a user table.';
|
|
}
|
|
elseif ( ! \DBUtil::table_exists($table))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' defines a table that does not exist.';
|
|
}
|
|
else
|
|
{
|
|
// store the table name for future use
|
|
static::$data['ormauth_table'] = $table;
|
|
}
|
|
|
|
if ( ! $cache_prefix = \Config::get('ormauth.cache_prefix', false) or empty($cache_prefix))
|
|
{
|
|
$errors[] = \Fuel::clean_path($file).' does not define a cache_prefix.';
|
|
}
|
|
else
|
|
{
|
|
// store the cache prefix for future use
|
|
static::$data['cache_prefix'] = $cache_prefix;
|
|
}
|
|
}
|
|
|
|
// check if all migrations have run, and the migration system is consistent
|
|
$migrations = \Config::load('migrations', true);
|
|
if ( ! isset($migrations['version']['package']['auth'][6]))
|
|
{
|
|
$errors[] = 'Auth database migrations haven\'t run (succesfully).';
|
|
}
|
|
else
|
|
{
|
|
$result = \DB::select('*')->from($migrations['table'])->where('type', '=', 'package')->where('name', '=', 'auth')->execute();
|
|
if (count($result) < 7)
|
|
{
|
|
$errors[] = 'Auth database migrations haven\'t run (succesfully).';
|
|
$errors[] = 'There is a discrepancy between your migration configuration file and the migration table.';
|
|
}
|
|
}
|
|
|
|
// check the fields of the users table
|
|
$usertable = array(
|
|
'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true),
|
|
'username' => array('type' => 'varchar', 'constraint' => 50, 'after' => 'id'),
|
|
'password' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'username'),
|
|
'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1, 'after' => 'password'),
|
|
'email' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'group_id'),
|
|
'last_login' => array('type' => 'varchar', 'constraint' => 25, 'after' => 'email'),
|
|
'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0, 'after' => 'last_login'),
|
|
'login_hash' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'previous_login'),
|
|
'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'login_hash'),
|
|
'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'user_id'),
|
|
'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'created_at'),
|
|
);
|
|
|
|
foreach ($usertable as $field => $value)
|
|
{
|
|
if (\DBUtil::field_exists(static::$data['ormauth_table'], $field))
|
|
{
|
|
unset($usertable[$field]);
|
|
}
|
|
}
|
|
if ( ! empty($usertable))
|
|
{
|
|
$errors[] = 'User table "'.static::$data['ormauth_table'].'" is missing the field(s): '.implode(', ', array_keys($usertable));
|
|
}
|
|
|
|
// process the results of the validation
|
|
if ($errors)
|
|
{
|
|
// display all errors
|
|
\Cli::write('You environment did not validate:', 'light_red');
|
|
|
|
foreach ($errors as $error)
|
|
{
|
|
\Cli::write('* '.$error);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// inform the user we're good to go
|
|
\Cli::write('Environment validated', 'light_green');
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Run the actual migration
|
|
*/
|
|
protected static function run_migration()
|
|
{
|
|
// make sure we've got a usertable we can work with
|
|
static::usertable();
|
|
|
|
// get the simpleauth config
|
|
\Config::load('simpleauth', true);
|
|
$simpleauth = \Config::get('simpleauth', array());
|
|
|
|
// process the defined roles
|
|
foreach (\Config::get('simpleauth.roles', array()) as $role => $config)
|
|
{
|
|
// skip all non-standard roles
|
|
if ($role == '#' or ! is_array($config))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// do we already have this role?
|
|
$result = \DB::select('id')->from(static::$data['ormauth_table'].'_roles')->where('name', '=', $role)->execute();
|
|
if (count($result))
|
|
{
|
|
$role_id = $result[0]['id'];
|
|
}
|
|
|
|
// no, add it
|
|
else
|
|
{
|
|
\Cli::write('- creating role: '.$role, 'light_green');
|
|
list($role_id, $rows_affected) = \DB::insert(static::$data['ormauth_table'].'_roles')->set(array('name' => $role))->execute();
|
|
}
|
|
|
|
// fetch the role as an ORM object, and assign the defined permissions to it
|
|
$role = \Model\Auth_Role::find($role_id);
|
|
if ($role)
|
|
{
|
|
foreach ($config as $area => $permissions)
|
|
{
|
|
foreach ($permissions as $permission)
|
|
{
|
|
$perm = \Model\Auth_Permission::query()->where('area', '=', $area)->where('permission', '=', $permission)->get_one();
|
|
if ( ! $perm)
|
|
{
|
|
\Cli::write('- creating permission: '.$area.'.'.$permission, 'light_green');
|
|
$perm = \Model\Auth_Permission::forge(array('area' => $area, 'permission' => $permission, 'description' => $area.'.'.$permission, 'actions' => serialize(array())));
|
|
}
|
|
$role->permissions[] = $perm;
|
|
}
|
|
}
|
|
|
|
// update the role and save the permissions
|
|
$role->save();
|
|
}
|
|
}
|
|
|
|
// process the defined groups
|
|
foreach (\Config::get('simpleauth.groups', array()) as $group => $config)
|
|
{
|
|
// ignore invalid entries
|
|
if ( ! isset($config['name']) or ! isset($config['roles']))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// do we already have this group?
|
|
$result = \DB::select('id')->from(static::$data['ormauth_table'].'_groups')->where('name', '=', $config['name'])->execute();
|
|
if (count($result))
|
|
{
|
|
$group_id = $result[0]['id'];
|
|
}
|
|
|
|
// no, add it
|
|
else
|
|
{
|
|
\Cli::write('- creating group: '.$config['name'], 'light_green');
|
|
list($group_id, $rows_affected) = \DB::insert(static::$data['ormauth_table'].'_groups')->set(array('name' => $config['name']))->execute();
|
|
}
|
|
|
|
// update the user group entries
|
|
\DB::update(static::$data['ormauth_table'])->set(array('group_id' => $group_id))->where('group_id', '=', $group)->execute();
|
|
|
|
// fetch the group as an ORM object, and assign the defined roles to it
|
|
$group = \Model\Auth_Group::find($group_id);
|
|
|
|
if ($group)
|
|
{
|
|
foreach ($config['roles'] as $role)
|
|
{
|
|
$role = \Model\Auth_Role::query()->where('name', '=', $role)->get_one();
|
|
if ( ! $role)
|
|
{
|
|
$role = \Model\Auth_Role::forge(array('name' => $role));
|
|
\Cli::write('- creating role: '.$role, 'light_green');
|
|
}
|
|
$group->roles[] = $role;
|
|
}
|
|
|
|
// update the group and save the roles
|
|
$group->save();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Deal with potential changes in users table layout between simpleauth and ormauth
|
|
*/
|
|
protected static function usertable()
|
|
{
|
|
if ( ! \DBUtil::table_exists(static::$data['ormauth_table']))
|
|
{
|
|
if ( ! \DBUtil::table_exists(static::$data['simpleauth_table']))
|
|
{
|
|
// table users
|
|
\DBUtil::create_table(static::$data['ormauth_table'], array(
|
|
'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true),
|
|
'username' => array('type' => 'varchar', 'constraint' => 50),
|
|
'password' => array('type' => 'varchar', 'constraint' => 255),
|
|
'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1),
|
|
'email' => array('type' => 'varchar', 'constraint' => 255),
|
|
'last_login' => array('type' => 'varchar', 'constraint' => 25),
|
|
'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0),
|
|
'login_hash' => array('type' => 'varchar', 'constraint' => 255),
|
|
'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0),
|
|
'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0),
|
|
'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0),
|
|
), array('id'));
|
|
|
|
// add a unique index on username and email
|
|
\DBUtil::create_index(static::$data['ormauth_table'], array('username', 'email'), 'username', 'UNIQUE');
|
|
}
|
|
else
|
|
{
|
|
\DBUtil::rename_table(static::$data['simpleauth_table'], static::$data['ormauth_table']);
|
|
}
|
|
}
|
|
|
|
// run a check on required fields, and deal with missing ones. we might be migrating from simpleauth
|
|
if (\DBUtil::field_exists(static::$data['ormauth_table'], 'group'))
|
|
{
|
|
\DBUtil::modify_fields(static::$data['ormauth_table'], array(
|
|
'group' => array('name' => 'group_id', 'type' => 'int', 'constraint' => 11),
|
|
));
|
|
}
|
|
if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'group_id'))
|
|
{
|
|
\DBUtil::add_fields(static::$data['ormauth_table'], array(
|
|
'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1, 'after' => 'password'),
|
|
));
|
|
}
|
|
if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'previous_login'))
|
|
{
|
|
\DBUtil::add_fields(static::$data['ormauth_table'], array(
|
|
'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0, 'after' => 'last_login'),
|
|
));
|
|
}
|
|
if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'user_id'))
|
|
{
|
|
\DBUtil::add_fields(static::$data['ormauth_table'], array(
|
|
'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'login_hash'),
|
|
));
|
|
}
|
|
if (\DBUtil::field_exists(static::$data['ormauth_table'], 'created'))
|
|
{
|
|
\DBUtil::modify_fields(static::$data['ormauth_table'], array(
|
|
'created' => array('name' => 'created_at', 'type' => 'int', 'constraint' => 11),
|
|
));
|
|
}
|
|
if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'created_at'))
|
|
{
|
|
\DBUtil::add_fields(static::$data['ormauth_table'], array(
|
|
'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'user_id'),
|
|
));
|
|
}
|
|
if (\DBUtil::field_exists(static::$data['ormauth_table'], 'updated'))
|
|
{
|
|
\DBUtil::modify_fields(static::$data['ormauth_table'], array(
|
|
'updated' => array('name' => 'updated_at', 'type' => 'int', 'constraint' => 11),
|
|
));
|
|
}
|
|
if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'updated_at'))
|
|
{
|
|
\DBUtil::add_fields(static::$data['ormauth_table'], array(
|
|
'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'created_at'),
|
|
));
|
|
}
|
|
}
|
|
}
|