Skip to content

Instantly share code, notes, and snippets.

@brandonferens
Last active November 14, 2021 16:43
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonferens/ee3ad68c97b589ff2798 to your computer and use it in GitHub Desktop.
Save brandonferens/ee3ad68c97b589ff2798 to your computer and use it in GitHub Desktop.
A Laravel 5 console command to upgrade the database from Cartalyst Sentry to Sentinel. The migrations are at the bottom of the file. Make sure to pull those out and use them instead of the default Sentinel migrations.
<?php namespace Potentia\Console\Commands;
use Activation;
use DB;
use Illuminate\Console\Command;
use Sentinel;
class UpgradeToSentinel extends Command
{
/**
* The console command name
*
* @var string
*/
protected $name = 'sentinel:upgrade';
/**
* The console command description
*
* @var string
*/
protected $description = 'Update existing Sentry data to Sentinel';
/**
* The table to use for users queries
*
* @var string
*/
protected $usersTable = 'users';
/**
* The table to use for groups queries
*
* @var string
*/
protected $groupsTable = 'groups';
/**
* The table to use for users_groups queries (the join table)
*
* @var string
*/
protected $usersGroupsTable = 'users_groups';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function fire()
{
$this->upgradeActivations();
$this->upgradeRoles();
$this->upgradeRoleAttachments();
$this->upgradeRolePermissions();
}
/**
* Upgrade existing Sentry activation data into Sentinel
*
* We first grab all user id's that are active and then create a new activation and complete it in one fell swoop.
* Then we grab all user id's that have not been activated and create a new activation.
*/
protected function upgradeActivations()
{
$activeIds = DB::table($this->usersTable)->where('activated', true)->lists('id');
foreach ($activeIds as $id) {
$user = Sentinel::findById($id);
if (!Activation::completed($user)) {
$activation = Activation::create($user);
Activation::complete($user, $activation->code);
}
}
$this->info('Existing active users have been upgraded');
$pendingIds = DB::table($this->usersTable)
->where('activated', true)
->lists('id');
foreach ($pendingIds as $id) {
$user = Sentinel::findById($id);
if (!Activation::exists($user) && !Activation::completed($user)) {
Activation::create($user);
}
}
$this->info('Existing pending users have been upgraded');
}
/**
* Upgrade existing groups into Sentinel's roles
*
* We grab all groups and then create new roles for each one.
*/
protected function upgradeRoles()
{
$groups = DB::table($this->groupsTable)->orderBy('id')->get();
foreach ($groups as $group) {
Sentinel::getRoleRepository()->createModel()->create(
[
'name' => $group->name,
'slug' => str_slug($group->name)
]
);
}
$this->info('Existing groups have been upgraded to roles');
}
/**
* Upgrade existing user group attachments into Sentinel's role attachments
*
* First we grab all users. Then we grab all records from the `users_groups` table based on the users returned from
* the first find. This will eliminate any potential duplicates or orphaned records. Then we grab all old groups so
* have some good group names to work with.
*
* Once we have all our good data, we can start recreating the user role attachments. We run through all the records
* from the user_groups table. We find the respective user, then find the role based off of the old group name. Then
* we use Sentinel's magic to create the new attachment.
*/
protected function upgradeRoleAttachments()
{
$users = DB::table($this->usersTable)->lists('id');
$userGroups = DB::table($this->usersGroupsTable)->whereIn('user_id', $users)->lists('group_id', 'user_id');
$groups = DB::table($this->groupsTable)->lists('name', 'id');
foreach ($userGroups as $key => $value) {
$user = Sentinel::findById($key);
$role = Sentinel::findRoleByName($groups[$value]);
$role->users()->attach($user);
}
$this->info('Existing groups have been attached to users as roles');
}
/**
* Upgrade existing group permissions into Sentinel's roles
*
* We need to grab all groups. Then we run through each one. We parse the permission json and add each permission to
* the respective role
*/
protected function upgradeRolePermissions()
{
$groups = DB::table($this->groupsTable)->get();
foreach ($groups as $group) {
$role = Sentinel::findRoleByName($group->name);
foreach (json_decode($group->permissions) as $permission => $value) {
$role->addPermission($permission, $value ? true : false)->save();
}
}
$this->info('Existing group permissions have been upgraded');
}
}
// Migrations
<?php
/**
* Part of the Sentinel package.
* NOTICE OF LICENSE
* Licensed under the Cartalyst PSL License.
* This source file is subject to the Cartalyst PSL License that is
* bundled with this package in the LICENSE file.
*
* @package Sentinels
* @version 2.0.1
* @author Cartalyst LLC
* @license Cartalyst PSL
* @copyright (c) 2011-2015, Cartalyst LLC
* @link http://cartalyst.com
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class UpgradeToSentinel extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'activations', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('code');
$table->boolean('completed')->default(0);
$table->timestamp('completed_at')->nullable();
$table->timestamps();
$table->engine = 'InnoDB';
}
);
Schema::create(
'persistences', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('code');
$table->timestamps();
$table->engine = 'InnoDB';
$table->unique('code');
}
);
Schema::create(
'reminders', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('code');
$table->boolean('completed')->default(0);
$table->timestamp('completed_at')->nullable();
$table->timestamps();
}
);
Schema::create(
'roles', function (Blueprint $table) {
$table->increments('id');
$table->string('slug');
$table->string('name');
$table->text('permissions')->nullable();
$table->timestamps();
$table->engine = 'InnoDB';
$table->unique('slug');
}
);
Schema::create(
'role_users', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->nullableTimestamps();
$table->engine = 'InnoDB';
$table->primary(['user_id', 'role_id']);
}
);
Schema::table(
'throttle', function (Blueprint $table) {
$table->string('type')->after('user_id');
$table->renameColumn('ip_address', 'ip');
$table->timestamps();
}
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('activations');
Schema::drop('persistences');
Schema::drop('reminders');
Schema::drop('roles');
Schema::drop('role_users');
}
}
@elpiel
Copy link

elpiel commented Oct 14, 2015

👍 Thank you very much. I am still migrating to 5.0, but soon I will run the migration and the command. Hope it works! :)

@dzanfardino
Copy link

hi @brandonferens, I'm using a slightly modified version of your command, I'm additionally importing users from a csv, and for some reason the passwords don't match when authenticating. I'm sure the hasher was the same as it is now.

Can you think of anything that can cause the issue ?
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment