It’s been over a year since I covered how to protect adminpanel routes in Laravel using Gates. Some people kept reminding me about my promise to cover ACL and user roles, and I kept putting off fulfilling that promise.
Finally I run into that on one of my projects, and that’s the sign I was waiting for to continue giving back to the community I learned so much from.
What is ACL
Although some computer science theorists enjoy using baffling definitions of the term (looking at you, MSDN), in reality it’s pretty simple and straightforward. ACL stands for Access Control List, and specifies what users are allowed to do.
Today we’ll learn how to protect adminpanel and enhance authorization component of a Laravel application by adding user roles. We will assign each user with a role (e.g. superadmin, admin, member), create an Auth Gate, modify the User model, and utilize the Authenticate middleware to help them get along. Furthermore, we’ll build a skeleton of your future ACL system, which you can adjust and improve according to your needs.
Laravel provides us with a chance to save enormous amount of time on one condition – we should know how to use it. I’m pretty sure anybody who learned Laravel was not only impressed by how simple a complex task can be done, but also by complexity of seemingly simple tasks. The perfect example is authentication – you can create it with a single Artisan command and Laravel will take care of the rest. On the other hand, many beginners struggle with authorization and don’t know how to approach protecting the admin area. Obviously, it’s a trivial task if you have some PHP experience, but doing it the Laravel Way may be tricky.
It’s no secret that many WordPress plugins are poorly designed. Some have been started as simple tools and grew larger until they became unmanageable, others were created by inexperienced developers who did their best. The sad truth is that WordPress provides complete freedom in designing plugins while many developers aren’t ready to take the responsibility. I’ll explain how I design plugins, and the cornerstone of this architecture is utilizing namespaces.
So why do we need namespaces in the first place? The most straightforward answer is shortening names of our classes and functions. Anybody who used to work with Zend Framework v1 (or almost every PHP framework created prior to PHP 5.3) has seen names like this: Zend_View_Helper_Placeholder_Container_Abstract. Imagine every single class name being this long and you get the idea. WordPress plugins often have the same problem – every class, every function you create has to have a unique name among all plugins ever created, so they often end up being too long to be convenient.
PHP references are tricky. They’ve always been. People question their performance, compliance with modern software architecture practices and trends. However, show me a single PHP language construct people do not question and I’ll buy you a beer.
I have to admit, it’s been much better since PHP5 came out. We do not have myriad of unintentionally cloned objects anymore, and the ampersand madness has stopped (however I know somebody who continues using it despite all the years passed since it lost its meaning):
$object =& new MyClass();
Don’t get me wrong, I love PHP, and I’ve been advocating its strength for years. Every time I heard somebody criticizing it I responded with a “You just don’t use it right” kind of answer, and was right every single time (well, you know, you can’t be wrong on the internet, it’s always the other guy who is wrong). Continue reading »
Everybody loves ObjectId. It’s convenient, you never run out of numbers, and you feel yourself a hardcore programmer working with hex. You can even extract a timestamp out of it, which comes in handy quite often. After all, you can freely move data between collections and databases being sure every ID is unique.
However, some timid souls do not like it. I can’t take out of my head the picture of a customer trying to tell his 12-symbol-long receipt number by phone I recently witnessed, poor thing barely managed to provide it to the customer service. So, the task was clear – we need a simple transaction number that corresponds with following requirements:
Consists of a predefined prefix followed by a number: AZ1854
Numbers are consequent providing the prefix is the same
We want it to be created as easily as possible, lazy programmers are good programmers (are they?)
We continue using ObjectId for internal purposes as primary key (_id), which means the custom ID will be stored in another field.