I have done a lot of reading on this but nothing stands out. I already have a authentication and authorisation system that can handle multiple guards and user roles (user, admin, super admin etc.)
I am trying to find out what is the best way to separate the system into totally separate accounts which have the following;
No login section
Landing page. Anyone can see without login.
Admin Section
Admin side of the system has a super-admins and then multiple admin-users.
These users can see all data from every user who has an account on the client side.
Client Section
Each user account has an owner who deals with billing, their own user admin etc.
Each client account also has a number of users (admin-users, editor-users etc.) with varying permissions.
Users on this side should only ever be able to see their own accounts data. They should not be able to ever see other accounts data.
Before Laravel, I would have an accounts table and assign a unique key to each account. Then a separate users table would contain the user along with their account key.
All database tables from this point onwards (posts, products, shipments etc.) would also have this key to ensure that the user account could only see their own data.
On top of this there would be permission tables, for granular control of what each user from either side can see.
Is my original way still suited to Laravel or is there a better way?
To separate out the accounts into their own "ecosystems" within the same code base is called multi tenancy. Basically, you scope your applications queries based on the user id and/or role which limits the available data to any given user.
Have a look at the Landlord Package.
In a very basic summary, what it does is add a where('tenant_id, auth()->id()) clause to every applicable query.
You can of course either omit the clause entirely for super admins to access all data, or apply even tighter constraints, say by adding a check for the user's role in addition to the clause, further limiting what a user can access within their respective account/organization/group etc.
Scoping can be done by any kind of relationship, you're not necessarily limited to the authenticated user's id. If your application has organizations for multiple user's you can use the organization id.
Multiple tenant ids is also possible, where a user must belong to an organization and a certain division within that organization.
Another package I've used previously is Hyn's multi-tenant.
We have same project as you mention . We create a company table and put it on the top of the hierarchy.
Then add new field all tables as company_id
And manage models over Policy -> https://laravel.com/docs/5.8/authorization
I hope this help
Related
I am quite new to Laravel, but get most of the basics by now.
Currently, I build an application, where multiple companies each get an account that represents their main user, let's call him CompanyAdmin.
This user is allowed to create new users for this company and able to view all quotes from the company.
The newly created users, call them CompanyEmployee, can not create new users and only view the quotes they created themselves, as well as creating new quotes.
Now there is of course one SuperAdmin, which sits on the other side of the table. He views all quotes from all companies, is able to do create users as he pleases and can accept/edit quotes.
My current approach to do this would be to attach a user_id to all quotes and attach the users to a company, as well as giving them a role.
All the logic would take place in the controller, where I would check the role of the user and therefore read/save only the quotes, the user is able to edit.
However, it feels very dirty to do so and sounds like a lot of effort to maintain. If you would e.g. make another role for an employee of the SuperAdmin, you would need to change every controller.
I could not find a way to define the access rights per role per model, so when I call Quotes::all() it only retrieves the legal ones (same goes for saving of course).
Please guide me to a Laravel feature (or even package, but I have not used one before) that helps me get things done.
Looking forward to possible solutions that lead to low maintainance.
Best regards!
For authenticating different types of users and protecting group of routes that particular type can access you can use guards, for authorizing CRUD actions you can use FormRequest, I think you have everything you need under these 2 links, ofcourse you will need to read up on these, this is a good starting point. As for tables, you can have these:
users, roles, companies, user_role, user_company
And models:
User, Role, Company
from the doc
In addition to providing authentication services out of the box,
Laravel also provides a simple way to authorize user actions against a
given resource. Like authentication, Laravel's approach to
authorization is simple, and there are two primary ways of authorizing
actions: gates and policies.
Laravel has 2 concepts called Gates and Policies which we can inject it on models,(specially Gates), So when ever the queries are called upon the Model, the Gates make sure that the user has appropriate permissions.
You can read more here
Scenario
I am working on a multitenant solution in yii2 following the Multi-Tenant Strategy walkthrough.
Currently, I have separated concerns for the tenants. Let's call tenants "organizations". Organizations are able to view only their data.
I am currently trying to make a signup for users under organizations. In order for the user to signup under an organization, normally, it would have to select which organization it's signing up under. If I use a dropdown, this would mean every incoming user would know all organizations using this solution which I do not want.
Question
How do I make a user signup under his/her organization automatically without having to select the organization?
What do I need to put in place to achieve this?
What I tried
Using a dropdown to select the organization: I dropped this idea for reasons listed above
Having each organization use a give a code to their users. This would work for the organization's employees, not for the organizations clients as they cannot possibly know all their clients beforehand.
I have based my multi-tenant application on the fact that tenancy selective element are associated to the user.
In my case during the sign-on phase an administrator assign which organisation ( or organisations) are available for this user..
Then if the user is assigned at one only organisation the multi-tenancy configuration is directly assigned by application otherwise, if the user is related to more organisations, after login in a combo are provided only the proper organisations for the user.
In the case of client organisation tipically is provided a sign-in for each organisation or a subsequent invite by admin or by app to access to other organisation .. depending of the kind or organisation are related to the client
I'm making a school management system using CodeIgniter framework of PHP.
I'm stuck in a situation where I want to make super user that the Principal of school will use and manage new students and teachers and other stuff related to school. He will obviously login first and then manage other details.
i. I want to know where should I place this super user. In database or hard coded it's username and password? (I know it is not good to make a table which would have just one row)
ii. And if I should "hard code" it then where should I write it's login detail so that it's secure.
You should keep the data in database keeping relation with multiple tables which wil help you later for givings roles to the users. Such as:
tbl_user -> Will contain users information
tbl_roles -> Contains the roles of the user
tbl_user_permission -> Would contain the user given permission to certain user.
Hence, the super user/ admin will have all the contained permissions whereas the super admin has also the facility to gib certain permission to other users as well.
Depending upon your SMS it will contain multiple users and different levels of users, so it is probably best to entry the data into database. Dividing into multiple tables.
I'm building a PHP application where users can design products and then check out to a shopping cart if they want to.
To let the user create a design, I need to assign a user ID and design ID to store it in the database.
There are two types of users who can build designs:
registed users. To take care of this, I have no problem.
non-registered users. These are guest visitors who might play around with product designs, and then when they hit check out, only then will I ask them to sign up. But in order to store their designs, I do need to have some kind of user ID.
I thought of using a timestamp as this user's ID, but what if two users in different parts of the world create designs at the same time? What's a good strategy for generating IDs for temporary/guest user accounts? I don't just mean temporary in the php session sense, because I want them to be able to access their partially saved designs later on if they visit the site again, just like any other registered user. I will only ask them to sign up before checking out for payment.
A simple approach might be:
Use a single user table (for registered users and guests)
Assign a "user_type" flag. E.g. registered/guest
Use the table primary key or other unique value for both "types" of user
When guests check out later on, switch their "user_type".
Store other related customer details in a separate table.
I'm going to develop a multiuser system, where people can register an account, log in, store and manage the data of the account. For example, email address idetifiers a user.
Could you tell, please, how to provide the user of one account access to the data of another account. For example, by providing a link in the account that gives access to another account.
It looks like Google Analytics uses a mechanism similar to this one to give access of one user access to the account of another user.
Thanky you very much, Oleg.
Providing code will be impossible here but, I'm going to guess at your setup and we'll see what happens.
So, you perhaps have a users table and a data table.
One option, is to allow Private and Public options on the data table. Public can data can be accessed by anyone.
The other option is to have another table dataPermissions where you associate data ids to user ids. When listing data, if the data item isn't owned by the current user, they must have a corresponding entry in the dataPermissions table.
Remember though, providing code and examples of you database structure is the best way to get a good answer.
Update
Okay, so we know that users are identified by email and can have one or many links to data. Those links can be shared to other users. Therefore, you are going to have a table for users, identified by email, and a table for data which is identified by its link.
Therefore, a user can choose to add more users to a link. For this, you would need a new table that associated users and links, i.e. a userLinks table.