Laravel authorization - passing multiple values to a policy - php

I've got a method that deletes a user from a company and would like to do a check to make sure the company will still have a admin left within it.
I'm using the method below, and the snippet is not working when adding a third parameter. How can I pass more than one variable to it?
$this->authorize('companyHasAdminAfterDelete', $privilege->company, $user );

Can you just perform a simple check before deleting the user to check how many people with admin role are left?
If there's only one before delete then you know that probably he should not be deleted etc.

Related

Laravel: Is it possible to save all actions of users in logs or db?

I know you can save sessions actions of user in a file (logs) or database. But this file (or line in database) is rewrited in every action that user make, for example:
If user start in login and then go to home, later go to about; this file is rewrite to from: home > to about.
I know it is not the complete quote generated in log/db. Is it possible to storage the first action (from login to home) and the second (from home to about)? How can I do it?
Thanks
I've been using Laravel Audits and it's pretty cool, give it a try.
It tracks pretty much everything you need, and shows you what was created and the old and new values when something is edited. but downfall is it does not track changes pivot tables
Check it out here: Laravel Audits
Maybe have a look at https://github.com/spatie/laravel-activitylog which allows you to specify your own logging requirements.
Laravel requests allow to get a lot of informations.
You can create a table in your database and a middleware which get the request anytime a route is called and store informations like the route called, the user id or even his referer in the table.
Check it out for more info about requests

Symfony Doctrine Filter and 404

I have a problem with the following scenario:
I have a list of products and every product has a flag to be public or not, meaning can be viewable by logged only users or both logged and anonymous.
In order to achieve the filtering in doctrine level I created a filter which checks if user is logged and if not filters only the products that are public.
My problem now is that if someone not logged tries to view a non public product Symfony throws 404. Of course it does the right thing but in my side I would like to return 403 if product really exists but is non public.
So my question is:
1) Remove filter and change whole implementation using voters?
or
2) Add an an exception listener on kernel request and there check if product really exists and transform response from 404 to 403? (well redundant db queries then :( )
or
3) Something else?
This need to be done on every single action, I need to do it in a level where actions won't get involved (otherwise it will use same logic to many places in the code and also there is big possibility to forget to do this check in a single check and break security).

Laravel 4 Custom User Permissions

So I'm new to Laravel and trying to make a permissions system for the users on my application. Here is my approach:
1) Place a column in users table with the name 'permissions'
2) Create a table of permissions with columns id and page-name
Here's how it will work:
Each page will be assigned an ID. For example, the page Manage Accounts has id 1 and the page Manage Customers has the id 2 in the permissions table.
In order to give user full access to Manage Accounts and view only access to Manage Customers, I will make the following entry in the permissions column for the user 1.1111,2.1000
Now when the user will land on the Manage Accounts page, I will get the page id for the current page from the permissions table, i.e. 1. I will then convert the string value from the users.permissions column in the following format: array('1' => '1111', '2' => '1000');. Now I can get the user permissions saved against the ID of the page by $permissions['1'];.
I will then have a function to parse the 4 digits and get boolean values for the following in the exact order:
$canView = true;
$canAdd = true;
$canEdit = true;
$canDelete = true;
Now inside my page, I can easily put checks and display items accordingly.
Questions
1) So first question. Is this a good approach? Or are there better ways for going about this? I like this approach because I only have to add one more table in the database and it will only have as many entries as there are pages on my application, which aren't many. And it also means that I will only have to access the database once and I can then keep on using the values in the variable.
2) Should I create a separate class for permissions? I'm new so I don't completely understand the Eloquent class. But is that something I should be using for this? Or should I just add the functions that I need to create to the users class?
3) Where should I store the values of $canView, $CanEdit etc. Should I place them in the class for permissions and create an object for it? Or should I just use the Users class and access them using Auth::? I do not want to use Session, I don't think it to be safe.
4) Can I somehow have the permissions autoload every time a page is opened? I was looking into beforeFilter, and thinking of creating adding it to the constructor of each controller. Is that a good idea?
Thank you so much for your time and help.
Cheers
Why reinventing the wheel? take a look to https://github.com/Zizaco/entrust

How to enable 2 logged in users to my app?

I'm developing a basic ERP in PHP for a small firm, they need to maintain accounts of 2 separate companies within it. Working in Code Igniter as I am most familiar with that framework.
I need to allow the user to be logged in on both companies at the same time accross tabs, how can I ensure that while saving data from one form it only posts to that company's records? I'm using only one db, with 2 users - hence user_id will be the foreign key in all tables.
I need to ensure that when saving an invoice of one company it doesnt take the other company's user_id, which may happen if i use sessions.
Would the best approach be to use hidden user_id fields on all forms? Or is there any other method I can use for this?
Thanks :)
You can store the company id in the url, so in the one tab you have
/edit/company/1
and in the ohter
/edit/company/2
Then you can let them choose either one of the companies, and make sure that id is at every url. Make sure that the correct permissions are set though, if you maintain a lot of users/companies.
i think that you can use a global variable, bool i guess and always check after session_start() whether is company 1 or 2

secure way to delete records with php

I have the following code snippet to delete records from a database given a primary key. This is called via an AJAX request, through GET. Anyone who were to examine my JavaScript could work out the URL and delete arbitrary records. What can I do to prevent this?
Not use GET?
Use sessions?
if($cmd=="deleterec") {
$deleteQuery = "DELETE FROM AUCTIONS1 WHERE ARTICLE_NO = ?";
if ($delRecord = $con->prepare($deleteQuery)) {
$delRecord->bind_param("s", $pk);
$delRecord->execute();
$delRecord->close();
echo "true";
} else {
echo "false";
}
}
Not using GET won't change a thing. You have to use sessions to manage 'access control' before you even get to this point in the code.
That is to say, when the AJAX request is made you should at that point confirm via the session that the person making the request is allowed to do the delete, before actually doing it.
Think about how you would check permissions in a 'non-AJAX' way and do the same here.
You can give your records a non-sequential random unique id to use in AJAX requests.
Still not the most secure solution although should be easy to integrate into your current system.
Use post rather than get
Embed hidden unique ids in any forms that will perform this action, and check that the id that comes back has been issued by you
Obfuscate the URL/parameter names
Generate unique IDs for the rows, and dont expose them externally, so an attacker cannot pick a row to delete.
Well, if not everyone can delete a record, make sure this one is behind a password, so only the authorized users can do deletes. Make yourself a login that adds a 'Delete' button on the page afterwards and on the PHP side make sure the user is authorized when processing the commands.
Oh and yes, make sure you always pass a confirmation value through POST to validate, not just a GET parameter, it's best practice, even with authorized users.
There are two important aspect to your question.
Are authorized user supposed to be able to delete any record they see fit? If that's the case your issue is one of making sure the request came from an authorized user. In that case using PHP's session is one way of making sure that it's the user you authenticated that made the request. Of course, with all technologies you have to make sure you use PHP session the right way. There are a bunch of articles on that mather. PHPsec.org has one here.
If a user cannot delete any row, in addition to doing authentication and sessions you'll also need to had a check in your code for the verify if the record being deleted can be deleted by that user. Now this is highly dependant on your application. For example, in a project management software, one could be allowed to delete tasks associated with one project but not with another one. That's part of your business logic.
The best would be to perform both check. One, your application must verify if the user making the deletion is a valid user and is allowed to delete (very simple to implement with php sessions) and two make sure that the user can delete the specific record based on some form of ownership.
Don't expose CRUD methods via Ajax.
You have to check before deleting records if user is authorized and allowed to delete.

Categories