Laravel multi-tenant approach. Where to start - laravel

I've a full application coded. Now, the only part missing is to make it multi-tenancy.
I want to allow clients to register into my application website and get an instance of the application with a completely empty database only for that account.
I've thought to play with environments, but I'm not sure if this is a good approach:
config
- user1
- database.php
- user2
- database.php
- ...
I've also thought about a unique config file containing the database information about every account and set the database connection based on the subdomain name. Something like I've seen in this post:
Multi-tenant in Laravel4
Any other idea or better approach to do this part?

Your solutions require 1000 folders for 1000 users.
1000 databases, thousand migrations if anything changes during application live cycle.
You don't want this, trust me.
Instead, create one database and use flags/foreign keys to assing data to users, simply said.

As Andreyco points out having 1000 users with 1000 databases will quickly become a joke, but if your user accounts (clients) will be a much smaller number then this is not such an issue.
The best approach is to have one "master database" which contains all of your generic client information, and this is controlled via a "Super Admin" panel which you have access too. This then lists the database configuration details for the other accounts, so store the database information for the other db's in a table in that one.
It's a little less secure, but essentially means that somebody has to hack the main database to get into the other databases, which is unlikely. You should also limit the firewalls of these databases so even if an attacker is in that main db they can't do shit without hacking into one of your web servers and SSHing from there onto the secondary DB's.

Related

Multi Domains in One Database

I have One Database with one domain. But my Database have 3 Websites available. I want my 2nd Website for publish in that Database. Is that possible ???
You might want to make sure that you're not violating the terms of service with the company who is hosting your database. Having many outside domains hitting an inside database may cause some undue stress on that server that the company is not counting on or eating up more bandwidth that is allotted for that machine.
In the same breath though, if you setup some type of data layered web service which you can connect to, then your many other domains are not directly hitting the database and do essentially the same thing, but in a more ordered fashion of predictable database calls. This may not be what you're looking for, but if setup correctly it could make developing against your database much easier.

Architecture/Technical Challenges in Handling Authentication/Permissions in Elixir Channels/Sockets

So I have decided to rewrite an application I have been writing in Node.js to Elixir because of all the extra complexity working with Node that Elixir comes with out of the box.
My issue was something I didn't have quite right in Node and is becoming just as complex in Elixir and I am not entirely sure how to go about approaching it.
I am trying to recreate a lot of how Discord does permissions. I am essentially building a CRM system, with different roles like "Sales Manager", "Sales", "Customer Service Rep" etc... But they all are able to do different things based on their "role".
Some things I need to do is be able to update a permission on the fly for a person or role. Maybe the "Sales Manager" role can't look at company financial data like an "Accountant" but we need to give that specific person access for a few days. Or I have a "Customer Service Rep" and we give that entire role the ability to add things to a calendar. I also would like to have the ability to kill sessions.
So there are a few ways I've seen said around Elixir forums, like:
Using Guardian, I really want to like tokens and think not having to hit the database every time sounds wonderful, but I don't think it's practical for this. Unless there is a good solution to updating tokens on the fly which I haven't found.
Giving each person their own process and just kill and start the process on changes with new changes. This seems pretty neat, but I'd rather not kill processes unless there is an actual error, I think this solution will come with big problems, like tracing problems. Although I am not familiar enough to know if this might actually cause problems, or if this is a bad solution for other reasons.
Use Guardian with Guardian_DB, which then defeats the purpose of using tokens, but at least I'd have a trackable session. My only problem with this is I do plan on using a load-balancer so that if a socket connection dies I can reconnect it to the same server and I am not sure there is a way to do that with tokens or if the socket itself has a session attached to it. This is not really that big of an issue though and is pretty close to what I had with Node.js.
Use Redis which I'd like to stay away from, and then update session data in Redis based on user_id when updates occur and hit Redis on every request to see if the user has permissions. I plan to put this across multiple servers eventually which means ETS is not viable unless I can load-balance socket connections like I could in Node.js.
So I guess my questions are,
Can I attach sessions to sockets? Is this a bad idea?
Should I still use a token, and just use Redis to check the token on every request?
Is a token still a better choice than a session?
Is there a much better/easier solution that I have not even mentioned?
I'm sorry this was pretty drawn out and long, I've never had to do something as permission bound as this project professionally and am pretty new to Elixir.
Phoenix channels are stateful. You can put data in the assigns field and it stays there for the duration of the connection. That is where you normally put your user_id after authenticating the user on join.
I also use the channels assigns to store client state that I need on the server.
WRT to the role to permissions question, I'm doing exactly this. What I do is load the load the role permissions from the database on startup and build an ETS store with them. You can do the same with a Task or a GenServer. If the permissions change for a given role, i update the database and the ETS table.
My user model supports a list of roles for each user.
When in need to validate the permissions for a given user, I call the Permission model api like Permission.has_permission?("create-room", user, scope). I have two level of permissions, global and per room. That is what the scope is used for.

Storing user profiles

I would like to store user profile information. After researching a bit online, I am confused between the following options:
Use a LDAP server (example: Open DJ) - I can write Java clients which can interact with the LDAP server using LDAP APIs.
Store user profile in a database as a JSON document (like in Elastic DB) - The No SQL databases can then index the documents to improve lookup time.
What are the factors that I should keep in mind before selecting one of the approaches?
For a start, if you are storing passwords, then using LDAP is a no brainer IMO. See http://smart421.com/smart-identity-and-fraud/why-bother-with-an-ldap-anyway/ .
Otherwise I would recommend you do a PoC with each solutions (do not forget to add indexes for OpenDJ and you may also use Rest2LDAP) see how they fill your needs. Both products are open source so its easy to get started.
If your user population is a known group that may already have accounts in an existing LDAP repository, or where user account information needs to be shared between systems, then it makes sense to use and add on to the existing LDAP repository.
If you are starting out from scratch and have mainly external, unknown users who have no other interaction with your infrastructure but this one application, then LDAP is not a good choice imo because of the overhead that you are getting for creating and managing the server. Then a lightweight JSON approach seems better suited (even thought the L in LDAP stands for "lightweight").
The number of expected users is less of a consideration - you need to thread carefully with very large populations in either scenario.
See this questions as well for additional insights Reasons to store users' data in LDAP instead of RDBMS

weblogic 12 / using plain jdbc connection

I have a WebApp where users log in using the database credentials and the backend runs prefab reports on a production database using the users credentials. Company policies does not allow a technical user in this special case.
Since a Datasource is tied to one user I use a plain JDBC connection
java.sql.Connection c = DriverManager.getConnection(aUrl, aUsername, aPassword);
This works but is this the preferred way to to this in an application server? Somehow this does not seem right.
This way will make your database run out of available open connections and result sets (open cursors) as soon as the user concurrency reaches a certain threshold.
The usual way to do this would be to define a database connection pool with a certain user with the appropiate grants. This connection pool should have some config settings that feel comfortable to your DBA, and should keep its open connections in thresholds that are acceptable to your data base, so you will never get into problems in case of excessive concurrency (you should not reach a database problem with, let's say, 250 concurrent users, which is likely to happen with the method you describe in your post).
The way to achieve this would be to provide sound arguments to your database folks in order to properly review the company policies on database users, in terms of
robustness: the initial implementation will surely take your database down with its first hundreds of concurrent users - this is not possible but certain
performance: a connection pool will always outperform the initial idea because opening a new connection is a very expensive operation
ease of monitoring and administration: a technical user will allow your DBAs to instantly know and better take decisions (for example, tablespace sizing and the like) over the running queries coming to their database from the java application servers
security: actually the matter of who can order which report is a business logic problem, that should be delegated to an upper tier - once this is solved, just let the java application order its reports
Good luck with this!

Tomcat Session Replication

I am trying to develope an application with tomcat running in several computers of same LAN trying representing several nodes and each of them runs an application with a single shared session(Ex. shared document editor such as google docs.). in my understanding so far I need a single shared session and several users need to update the doc symultaneously and each others updates are reflected on each others we interfaces almost imidietly. Can I acheve this with with tomcat's clustering feature. http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html#Configuration_Example or is this just a faluir recovery system.
Tomcat's clustering feature is meant for failover - if one node fails, user can carry on working while being transparently sent to another node without a need to log in again.
What you are trying to achieve is a totally different scenario and I think using session for this is just wrong. If you go back to Google Doc example, how would you achieve granting (revoking?) document access to another user? What do you do when session times out - create the document again? Also, how would you define which users would be able to access selected documents?
You would need to persist this data somewhere (DB?) anyway so implement or reuse some existing ACL system where you could share information about users and document permissions.

Resources