I would like to implement a multiple user CMS website, where each user is able to execute CRUD actions on their own records. This means that security should be implemented on record-level, not on model-level.
I've come up with 2 solutions:
Have an owner_id field in each model.
Have a database per user for the models that they modify. Keep a main database for all the related records (such as users' data (name, email, username, password), models that are edited by admins, but not users, etc).
Solution 2, I was thinking of implementing with Apache's help. I would have http://user3_website.mydomain.com/ for user3, for example, where this would be a separate website to the main website at www.mydomain.com . I would symlink all the directories apart from /web/uploads and /config:
/config - I would need for the database configuration for user3
/web/uploads - I would use for their uploads.
Is there a best practice/design pattern to implement this with Symfony? I have never developed a website that can dynamically select a database based on the user (solution 2), so am wondering if this makes sense.
I have experience with Symfony 1.x , but haven't done any development on Symfony2 yet.
I would go with solution 1, have one database for all instances with an owner_id field. It's easier to maintain that way. At some point you may have to make changes to the database and having to do that on multiple databases can become a nightmare unless you automate that somehow.
There's hardly any advantage in doing it in separate databases unless you have some serious security issues to consider.
Related
I am developing a plain simple website using laravel 5 with different user accounts organized as follows:
Student and Admin inherit from User.
sample users table
name
username
password
is_active /* Only needed when admin is deleted. Every student will definitely be active (1) */
is_student
is_admin
sample students table
Contain some more unique fields for student
I could have thousands of students but just a few admins. Currently, my approach is to have a login box on the home page where both users can login and depending on the user type, display the appropriate profile page.
Are they any risks to this approach or is they some better way to tackle this?
Edit
App Domain
Students register and apply for internship
Admin can do the following:
Manage comments on website (publish, delete etc)
Manage FAQ (Create questions and answers)
Add another admin user
Well, you could go this way, i guess it's a matter of preference. I would use a different model.
On models: I like DDD (domain driven design) and event storming to get insight into the domain I'm solving a problem for. On DDD:
In order to create good software, you have to know what that software is all about. You cannot create a banking software system unless you have a good understanding of what banking is all about, one must understand the domain of banking.
From: Domain Driven Design by Eric Evans.
Event storming is a workshop format for quickly exploring complex business domains.
I don't know much about your domain, so my answer is based on many assumptions. Nevertheless, it might come in helpful to you.
In this case, I guess I would separate all three concepts (Admin, Student and User). Even though they might share some properties, in the real world they are involved in different domains. Ignore that fact and your code will soon cover annoying edge cases and contain unnecessary complexity.
So, two different classes for Admin and Student. Both have a User. In my case, that would result in three different tables aswell. It might be possible that a Student has an Admin aswell (to ease administration, to filter overviews, and so on), but I'm just plainly guessing there.
In all three contexts, I would make use of immurable value objects, not just for code completion, but more importantly for encapsulating data, validation and exposing related behavior.
A User logs in, and after successful validation is redirected to the view for either a Student or an Admin. You'll notice that separating these domains will be a huge advantage when your application grows and becomes more complex. You could consider having a separate administration backend on a different domain, but for now I'd say that it would only introduce complexity, and hardly any value.
Maybe it's valuable to model what one is allowed to do in your system with privileges. As in: an Admin is allowed to do anything, a Student has one or more Privileges. This would create a flexible system in which some students can help with the administration. For example: maybe some students are in lead of some random study groups and need to be able to access study group administration. It might not be necessary now, so make sure your code is future friendly.
Other subjects I would look into: using CQRS or CRUD, and using an event store instead of a relational database (very useful if you want to be able to peek into or go back into history).
In any case: don't choose the newest acronym, always choose what best fits your domain (or context, or application).
We are building a intranet web application in PHP with CakePHP.
However we have barely experience with CakePHP
Our Intranet will have two user portals.
Employee portal
Client portal
Both portals will use the same data but have their own user interface.
Employees can see other data than clients and vice versa.
We want to build a central core for both portals. For example, a single authentication system, a contact form, a notification functionality, same footer information, etc. We want to use this central core as much as possible so we don't have to rewrite code.
We use Git to manage our code. We want to make a branch for both portals and one for the shared core.
We hope you can give us some advise about how setting this up with CakePHP.
Is building multiple app's a good idea?
Or should we just run CakePHP and our core on two web servers? (one for each portal)
Or should we use plug-ins for the core functionalities?
Or should we use single controllers with multiple views (one for employee and one for client?)
Or something totally different?
Thanks for any advice
Eventually, you'll start noticing similarities between the 2 portals, and the code-base. If they are sharing same data, why don't you have a single code-base and have permissions around what users can see based on roles? We had to do this recently when we merged 3 pages into 1. 1 page was for admin, and the other 2 was for other roles. Then users started requesting features on page 2 that page 1 already has etc etc. it became a mess and we decided to consolidate these pages into 1, and have permissions around what each users can see based on their roles. Also read more about helpers as it will come handy, so you dont make your view bloated.
In my experience a portal is typically a very thin layer on top of some CRUD framework. I think the opportunity for code sharing between these two applications is very limited. You can share the authorization and authentication .. and that's about it and I don't know if sharing this part is a good idea (probably not).
If most of your code goes into building the HTML views you'll likely end up with two completely separate views for employee and client.
As Ayo mentioned... the permissions alone will separate the two user groups and you can take advantage of CakePHP's layout or the themes feature to give a totally two different look for each user group.
You may also want to take a look at CakePHP plugins feature. It allows you to easily add new functionalists to an existing app, without messing with the existing code base.
I'm looking into developing a multi-tenant SaaS application, and I found several sites that describe a solid way to separate the data using tenantIDs and updateable views. e.g. This blog post
It all hinges on the ability to have your user accounts authenticated from a master users table and then having their respective database connections use those user-specific credentials. This way, the views can pull the userid and map it to the tenantID to display that user's view. However, most PHP frameworks tend to be very static when it comes to database connections (stored in text config files). They appear to be at odds.
Does anyone know:
a) how to make CodeIgniter handle this gracefully?
b) a different PHP framework that might?
At a horrendously basic level you can do this:
http://philsturgeon.co.uk/blog/2009/06/How-to-Multi-site-CodeIgniter-Set-up
Expand it as required, or move the logic into MY_Controller for more flexibility.
There is a topic talking about this on the Code Igniter forums.
http://codeigniter.com/forums/viewthread/165227/#846845
It looks like you set up your users DB as your main database in the config file, then you generate a config array for a new connection for a user based upon information in that users DB. So, I guess you'd need to at least store the DB name in the users database.
Not sure how well this works though, as I haven't had an occasion to try it out yet.
Sorry if that's not quite what you were looking for, but it should give you an idea of a Code Igniter approach.
Zend Framework.
http://framework.zend.com/manual/en/learning.multiuser.intro.html
I'm writing an application that that I'm going to provide as a service and also as a standalone application.
It's written in Zend Framework and uses MySQL.
When providing it as a service I want users to register on my site and have subdomains like customer1.mysite.com, customer2.mysite.com.
I want to have everything in one database, not creating new database for each user.
But now I wonder how to do it better.
I came up with two solutions:
1. Have user id in each table and just add it to WHERE clause on each database request.
2. Recreate tables with unique prefix like 'customer1_tablename', 'customer2_tablename'.
Which approach is better? Pros and cons?
Is there another way to separate users on the same database?
Leonti
I would stick to keeping all the tables together, otherwise there's barely any point to using a single database. It also means that you could feasibly allow some sort of cross-site interaction down the track. Just make sure you put indexes on the differentiating field (customer_number or whatever), and you should be ok.
If the tables are getting really large and slow, look at table partitioning.
It depends on what you intend to do with the data. If the clients don't share data, segmenting by customer might be better; also, you may get better performance.
On the other hand, having many tables with an identical structure can be a nightmare when you want to alter the structure.
I'd recommend using separate databases for each user. This makes your application easier to code for, and makes MySQL maintenance (migration of single account, account removal and so on.)
The only exception to this rule would be if you need to access data across accounts or share data.
This is called a multi-tenant application and lots of people run them; see
multi tenant tag
For some other peoples' questions
I'm currently working on a small webapp where I work. I've created this for different departments. So, for example, let's say that: Marketing, Human Resources, and Sales uses it.
Right now, as it stands, I have 3 completely different directories for each dept:
http://mydomain.com/hr
http://mydomain.com/marketing
http://mydomain.com/sales
And each directory (department) has it's own MySQL database, with it's tables.
I have a few questions so that I can hopefully create this more efficiently:
1) Sometimes, I will have a user who will have access to two or more of the departments. For example, a user might have access to both HR and Marketing. I do not want to have this user create 2 different accounts. How can I "tie" this into one database?
2) Also, if I have a user who has access to both "areas", what would be a good way to 'direct' that user to change between both departments?
3) Finally, regarding the different directories, is there a more efficient way to do this? Each directory is essentially the same exact code, just with minor changes.
This is something that I've never done, so some help on creating this the 'right' way would be great. Especially while it's small, if I eventually expand this out to other departments.
Thanks!
Your company, like every other probably has one place to store all of their employee information. You should apply the same principle on your web application, meaning you should have one central database for all employees with privilegies information so that you can define employee's access to each department.
If you apply the above principle (one database for all users containing privilegies information) it should be pretty easy to redirect users to other departments if that is what you'r asking here.
You should split your project into smaller pieces so that you can identify the core part of your project and share that part among all departments. There are many ways to accomplish this but copy-pasting your code for every department is not efficient and it will get in your way later on. Even with three departments it is tedious to copy-paste changes to each one. Also note that if you use separate databases for departments you wont be able to share data among them (at least not in a nice, elegant way).
What you should do is leave your programming language on side for a couple of hours/days and write some design documents about that project. It doesn't have to be too detailed, just enough so you can see how modular it will be and what you can and shouldn't do to make it more modular.
With that said, you should wait for more answers as I'm not as professional as others on SO :-) And excuse my bad english.