{"action":"created","issue":{"url":"https://api.github.com/repos/JosephSilber/bouncer/issues/223","repository_url":"https://api.github.com/repos/JosephSilber/bouncer","labels_url":"https://api.github.com/repos/JosephSilber/bouncer/issues/223/labels{/name}","comments_url":"https://api.github.com/repos/JosephSilber/bouncer/issues/223/comments","events_url":"https://api.github.com/repos/JosephSilber/bouncer/issues/223/events","html_url":"https://github.com/JosephSilber/bouncer/issues/223","id":266246486,"number":223,"title":"PSA: removing role levels","user":{"login":"sausin","id":11542923,"avatar_url":"https://avatars2.githubusercontent.com/u/11542923?v=4","gravatar_id":"","url":"https://api.github.com/users/sausin","html_url":"https://github.com/sausin","followers_url":"https://api.github.com/users/sausin/followers","following_url":"https://api.github.com/users/sausin/following{/other_user}","gists_url":"https://api.github.com/users/sausin/gists{/gist_id}","starred_url":"https://api.github.com/users/sausin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sausin/subscriptions","organizations_url":"https://api.github.com/users/sausin/orgs","repos_url":"https://api.github.com/users/sausin/repos","events_url":"https://api.github.com/users/sausin/events{/privacy}","received_events_url":"https://api.github.com/users/sausin/received_events","type":"User","site_admin":false},"labels":[{"id":727312594,"url":"https://api.github.com/repos/JosephSilber/bouncer/labels/intend%20to%20remove","name":"intend to remove","color":"27f43f","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2017-10-17T19:18:40Z","updated_at":"2017-12-25T00:57:24Z","closed_at":null,"author_association":"NONE","body":"Hi,\r\n\r\nI noticed the table for `roles` had column entry for `level`. I had asked @JosephSilber about this and he mentioned that this was planned to be removed, and I agree that it probably has no use case.\r\n\r\nThe intent of opening issue is to document the removal of this feature and any reasons why people might think that they need `level` (but they really don't :wink:). I fully expect that this `issue` will be promptly closed once feedback is collected :smile: \r\n\r\nIn my simple implementation in a project I had something similar to enable access to the highest level a user had access to. Some other reasons may exist and I will try to list cases that I can image. If others have any other cases, it would be great to have them documented before the feature is up for removal.\r\n\r\n### Scenario 1 - Action Control\r\n\r\nA user has permissions to perform certain actions based on his/her access level. If a check is made for the higher level the user has and if it's found to be lower than the required access level, access is denied. If the user's highest role is greater than or equal to required, access is granted.\r\n\r\n*Why this is not required with bouncer?*\r\n\r\nEvery action can be defined as an ability. If the user has access to an ability, then he / she is allowed. This is much simpler!\r\n\r\n### Scenario 2 - Route Control\r\n\r\nSimilar to the previous one but this time if access control to certain routes is required and anyone with a higher than certain access level should be allowed. If the test is truthy, access is granted.\r\n\r\n*Why this is not required with bouncer?*\r\n\r\nThis can be checked and defined as an ability or as a role. It is also possible to assign multiple roles so there is no restriction. In fact I think having multiple roles is better as certain roles can be removed while leaving other access control functionality intact. Again, there is no need to have 'level' as a direct check on role can be made.\r\n\r\n### Any other reasons?\r\n\r\nLooking forward to getting reasons from other people. It would be even more awesome if someone can explain why this might really be _required_.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/JosephSilber/bouncer/issues/comments/353810817","html_url":"https://github.com/JosephSilber/bouncer/issues/223#issuecomment-353810817","issue_url":"https://api.github.com/repos/JosephSilber/bouncer/issues/223","id":353810817,"user":{"login":"JosephSilber","id":1403741,"avatar_url":"https://avatars2.githubusercontent.com/u/1403741?v=4","gravatar_id":"","url":"https://api.github.com/users/JosephSilber","html_url":"https://github.com/JosephSilber","followers_url":"https://api.github.com/users/JosephSilber/followers","following_url":"https://api.github.com/users/JosephSilber/following{/other_user}","gists_url":"https://api.github.com/users/JosephSilber/gists{/gist_id}","starred_url":"https://api.github.com/users/JosephSilber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JosephSilber/subscriptions","organizations_url":"https://api.github.com/users/JosephSilber/orgs","repos_url":"https://api.github.com/users/JosephSilber/repos","events_url":"https://api.github.com/users/JosephSilber/events{/privacy}","received_events_url":"https://api.github.com/users/JosephSilber/received_events","type":"User","site_admin":false},"created_at":"2017-12-25T00:57:24Z","updated_at":"2017-12-25T00:57:24Z","author_association":"OWNER","body":"@devinfd the UI itself does not have to become more complex. Assuming we remove role levels from Bouncer, this can still be easily handled in your code whenever a role is edited.\r\n\r\nHere's a short example:\r\n\r\n```php\r\npublic function update(Role $role)\r\n{\r\n    $existing = $role->abilities()->pluck('id');\r\n    $updated = collect(request('abilities_ids'));\r\n\r\n    $adding = $updatedAbilityIds->diff($existingAbilityIds);\r\n    $removing = $existingAbilityIds->diff($updatedAbilityIds);\r\n\r\n    // Add the abilities to the role, and all with a higher level\r\n    Bouncer::role()->where('level', '<', $role->level)->push($role)\r\n        ->forEach(function ($role) use ($adding) {\r\n            Bouncer::allow($role)->to($adding);\r\n        });\r\n\r\n    // Remove the abilities from the role, and all with a lower level\r\n    Bouncer::role()->where('level', '>', $role->level)->push($role)\r\n        ->forEach(function ($role) use ($removing) {\r\n            Bouncer::allow($role)->to($removing);\r\n        });\r\n}\r\n```\r\n\r\nI understand that this is more code than was needed before. This however lets us simplify Bouncer quite a bit while still allowing you to keep your elegant UI ."}}
{"actor":{"display_login":"JosephSilber"}}