Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jrdavidson's avatar

Permissions

@mstnorris

I'm trying to figure out what all of my permissions are that I should include in my permissions table. This is the first things of permissions I have.

$permissions = ['Can View All Users', 'Can Create A User', 'Can Store A User', 'Can Edit A User', 'Can Update A User', 'Can View A User', 'Can Delete A User'];

This is just trying to cover all CRUD tasks for the users resource. Now if I do all of these for all the other resources I could have which is approx. 20 different resources. Is there another way or am I just fine continuing to do it this way?

0 likes
29 replies
mstnorris's avatar

Yeah you can keep doing that as you want it to be as readable as possible so it is obvious that a Role has certain Permissions.

While it works, keep at it. When (if) it gets too cumbersome, refactor. But this will keep you going for a good while.

1 like
jrdavidson's avatar

@mstnorris

I'm still trying to figure out how I should seed my PermissionRoleTableSeeder file. Reason being lets say all Administrators, Owners, and Webmasters have the permission to do all of the currently listed permissions.

<?php

use Illuminate\Database\Seeder;


class PermissionRoleTableSeeder extends Seeder {

    public function run()
    {
        
    }
}
<?php

use Illuminate\Database\Seeder;
use App\Role;

class RolesTableSeeder extends Seeder {

    public function run()
    {
        $roles = ['User', 'Editor', 'Administrator', 'Owner', 'Webmaster'];

        foreach ($roles as $role)
        {
            Role::create([
                'name'  => $role
            ]);
        }
    }
}
<?php

use Illuminate\Database\Seeder;
use App\Permission;

class PermissionsTableSeeder extends Seeder {

    public function run()
    {
        $permissions = ['Can View All Users', 'Can Create A User', 'Can Store A User', 'Can Edit A User', 'Can Update A User', 'Can View A User', 'Can Delete A User'];

        foreach ($permissions as $permission)
        {
            Permission::create([
                'name'  => $permission
            ]);
        }
    }
}
rdelorier's avatar

If your going to do this for a lot of resources then it will be a good idea to come up with a naming convention and use constants for the permissions types. something like:

//Role.php
const VIEW         = 0;
const VIEW_ALL = 1;
const CREATE     = 2;
const STORE        = 3;
const EDIT            = 4;
const UPDATE      = 5;
const UPDATE      = 6;

then just prepend the controller name

var name = (new ReflectionClass(new SomeController()))->getShortName();
$permissions = [
  name.Role::VIEW,
  name.Role::VIEW_ALL,
  name.Role::CREATE,
  name.Role::STORE,
  name.Role::EDIT,
  name.Role::DELETE
]

then is should be fairly easy to check if a user has a role for a certain controller action

jrdavidson's avatar

@rdelorier Is this something I need to store in the database though? I ask because I was going to try and attach it to middleware.

mstnorris's avatar

@xtremer360 you don't seed the db using the PermissionRoleTableSeeder.

You do it like so using the relationships

$user->roles()->attach($superSystemAdminR); // $superSystemAdminR is a Role you set up earlier
$supersysadmin->roles()->attach($superSystemAdminR); // same for $superSystemAdminR
$sysadmin->roles()->attach($systemAdminR); // as above

$superSystemAdminR->permissions()->attach($superSystemAdminP); // attaching the permission $superSystemAdminP
$systemAdminR->permissions()->attach($systemAdminP); // again, as above
rdelorier's avatar

@xtremer360 Just curious but have you considered a package like entrust, tons of functionality already so you can spend less time figuring this out and more time on your business logic

jrdavidson's avatar

Packages like entrust are great but then I'd have to modify the package to my needs if it does things that I need to modify.

mstnorris's avatar

@xtremer360 I would suggest getting something basic working first (obviously if it works for your needs) and then you can grow and the app can adapt if and when you need it.

Packages do save you from reinventing the wheel at times, but often they rush you into using something that you don't need.

rdelorier's avatar

It sounds like you want to have roles and each role has various permission such as update user, delete user, etc etc. Thats exactly what entrust provides. also if you need to change things for your app you can fork the repo and tell composer to use your version instead

jrdavidson's avatar

@rdelorier According to https://github.com/Zizaco/entrust it says that the models should be in the models directory however what if I'm using 5.0 there is no models directory. Do I need to create one or can I modify something so that it knows that they are located inside of the app directory.

Also is this somethign I can use with middleware for my routes?

rdelorier's avatar

I think they just havn't updated the docs but I'm running it on my L5 app without any issue, has some really useful features for checking if a user has permission for something, also allows you to attach a specific permission to user if you dont want to give them the full role

rdelorier's avatar

Also I did have issues with the automatic route stiff from entrust so i just ignored those features, I'm using a middleware for each role and just setting which middleware i want to apply from the controllers constructor, luckily L5.1 will allow middleware params so that will make things much easier.

jrdavidson's avatar

@rdelorier and @mstnorris I'm utilizing Entrust however I'm still stuck on how many users of each role I really want in my database.

https://laracasts.com/discuss/channels/general-discussion/seeds

<?php

use Illuminate\Database\Seeder;
use App\Role;

class RolesTableSeeder extends Seeder {

    public function run()
    {
        Role::create([
            'name'  => 'user',
            'display_name' => 'Basic User',
            'description' => NULL
        ]);

        Role::create([
            'name'  => 'editor',
            'display_name' => 'Editor',
            'description' => NULL
        ]);

        Role::create([
            'name'  => 'addmin',
            'display_name' => 'Administrator',
            'description' => NULL
        ]);

        Role::create([
            'name'  => 'owner',
            'display_name' => 'Site Owner',
            'description' => NULL
        ]);

        Role::create([
            'name'  => 'webmaster',
            'display_name' => 'Webmaster',
            'description' => NULL
        ]);
    }
}
<?php namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Zizaco\Entrust\Traits\EntrustUserTrait;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

    use Authenticatable, CanResetPassword, EntrustUserTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['first_name', 'middle_name', 'last_name', 'username', 'email_address', 'password', 'confirmation_code', 'confirmed'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];
}
<?php

use Faker\Factory as Faker;
use Illuminate\Database\Seeder;
use App\User;

class UsersTableSeeder extends Seeder {

    public function run()
    {
        // use the factory to create a Faker\Generator instance
        $faker = Faker::create();

        User::create([
            'first_name'        => 'Jeffrey',
            'middle_name'        => 'Robert',
            'last_name'         => 'Davidson',
            'username'          => 'xtremer360',
            'email_address'     => 'xtremer360@gmail.com',
            'password'          => 'Disney14',
            'confirmed'         => 1,
            'confirmation_code' => null
        ]);

        for ($i = 1; $i < 500; $i ++)
        {
            $confirmed = $faker->boolean($chanceOfGettingTrue = 95);
            $confirmation_code = null;

            if ($confirmed == 0)
            {
                $confirmation_code = str_random(30);
            }

            User::create([
                'first_name'        => $faker->firstName,
                'middle_name'       => $faker->firstName,
                'last_name'         => $faker->lastName,
                'username'          => $faker->userName,
                'email_address'     => $faker->email,
                'password'          => $faker->word,
                'confirmed'         => $confirmed,
                'confirmation_code' => $confirmation_code
            ]);
        }
    }
} 
mstnorris's avatar

That's totally up to you. Why seed so many though when you're not sure?

If it were me, I would keep it small initially, write some tests and ensure that it works. From there, you know it will work.

jekinney's avatar

Agreed, seed the bare minimum. Then as you figure stuff out, write down what you need, like a plan. At the end of the day coding with out a clear plan and scope always leads to messy code. When you finish a aspect or feature you should strive to not touch it again. If you do many times it's a flag: a) didn't plan well, b) your going to slap code where it may introduce more issues, c) naming conventions and readability goes down the toilet, d) your going beyond the scope you planned for, which case you need to take a step back and think about it some and either not do it or update your plan.

jrdavidson's avatar

Well I'm only trying to work with the users resource first and see if that works and not sure how to do it then I guess.

jrdavidson's avatar

So it appears that I"m no further ahead using Entrust than I was without it.

mstnorris's avatar

@xtremer360 I won't say it...

I hate to say.... I told you so

Just kidding ;)

Always keep it simple until you need more.

mstnorris's avatar

So it appears that I"m no further ahead using Entrust than I was without it.

Have you made any progress?

jrdavidson's avatar

I tried but like I said I'm trying to seed but not getting anywhere.

mstnorris's avatar

You'll have to be a little more specific than that for us to be able to help.

Please or to participate in this conversation.