Separating user and admin accounts safer? - mysql

So currently I'm working on a web application for a game and stumbled upon the following "problem"/question: Is it actually safer to have an individual table for the players/users and administrators?
Personally I think it's not and storing them both in one table would also be easier and more efficient, since every administrator is considered a player as well, but some people tell me it's safer to separate them without a clear reason why.
As for now I have them both stored in one table and am using a role based permission system.

By separating them you could control permissions to the tables with more granularity, for example limiting access to the administrators table to only certain database user accounts (so that it cannot be accessed by "game" code/servers at all).
But outside of those kinds of scenarios, I can't really think of one and agree with the second comment to your question.

Related

Why wouldn't you set activate_all_roles_on_login?

I'm just getting my toes wet in MySQL DBA and created some users and assigned roles to them. It took me a long time to realize that this on its own didn't result in the user assuming the roll when they login. This led me to learn about activate_all_roles_on_login and SET DEFAULT ROLE. I understand what they do, but I'm struggling to imagine a scenario where you wouldn't want the users and roles you created to be active after logging it.
I know I must be missing something, what are some reasons you wouldn't want this as default behavior?
Are there any things to be aware of when setting activate_all_roles_on_login to true?
They're called roles for a reason. By the SQL3 standard, database users are supposed to be able to adopt only one role at a time. Like when a live stage play has too few actors, they need to play multiple characters by throwing on a different coat or a hat. The idea is that a user shouldn't have the union of the privileges of all roles they are permitted to use. They should use SET ROLE to choose one at a time.
This can be practical, for example a "backup" role may allow read-only access to data for purposes of making backups. You wouldn't want a user to have read-write access while using backup tools. But at other times, the same user doing transactions may need read-write access, though only to a limited set of tables. In some ways, this is like the principles behind SOX compliant security: No single user should have unlimited access by themselves.
MySQL does have a feature to allow a user to adopt multiple roles simultaneously. For many applications, this would be perfectly reasonable, which is no doubt why MySQL added this as an extension to standard SQL. If this is ordinary for all users at your site, you may therefore choose to enable activate_all_roles_on_login. But it's not standard SQL, so it's not enabled by default.

Dealing with many to many relationships in DDD

I've been reading about this so far, and I think that is just a design decision, but unfortanetly I couldn't figure out which is the best approach.
I have many entities, among them are Application, User, Role and Permissions. There are some rules as follows,
An Application must have at least one User.
An User must be in at least one Application.
Each User have different Roles, password, and others attributes in each Application it belongs.
Each Role have different Permissions, and so on.
My problem is how should I build each Aggregate?, my approaches have been the followings:
My first approach was create an Aggregate for Application, User, Role, etc. But should I create a different aggregate for the many to many relationship between Application and User because of the adittional attributes it will have?, or should I convert the many to many relationship in an one to many relationship?, if so, how could I achieve it?
The second one was create just one Aggregate for Application, and add User as a ChildEntity, but I'm not sure if it is appropiated for the given context, if so, should I have Role and Permission entities as ChildEnties in my Application Aggregate too?
Please let me to know your thoughts about this, and if there is another point of view that could help me, it will be great. thank you in advice.
Honestly these rules seem rather artificial. If you absolutely need strong consistency on all these then you need a giant ApplicationAccess aggregate which will certainly be very busy because any access rights changes for a given application would conflict with any other change for the same application.
That giant AR is not even enough on it's own to cover the "An User must be in at least one Application." rule which means you'd probably have to update the User AR along with the ApplicationAccess AR in every role member addition/removal.
e.g.
// Assume transactional
function removeUserFromRole(userId, applicationId, roleId) {
applicationAccess = applicationAccessRepo.existingOfId(applicationId);
user = userRepo.existingOfId(userId);
applicationAccess.removeUserRole(user, roleId);
user.trackRoleRemoved(); // decrement and throws if 0 (trackRoleAdded would increment)
}
Like you can guess this design doesn't seem very scalable. It might work for a small amount of users without too much concurrent access modifications but it's probably the wrong design otherwise. If you go for it you would probably want to use pessimistic locking rather than optimistic + retries.
If you want a more effective model I think you will have no choice but to explore the possibilities of loosening up the rules and allow them to be eventually consistent rather than strongly consistent.
For instance, why does it matter that much that a User has no access? Could you just run exception reports to list these? Could you just flag the Users so that their access need to be updated manually?
The same applies to all the other rules and there's endless possibilities to deal with eventual consistency. You could have automated compensating actions that reverts some actions if they are found to have violated some rules or just flag & have manual resolutions like described above etc.
Anyway, a good way to question the rules is to analyze the "cost" of a rule being violated through concurrent modifications and how often that might happen under expected concurrent usage should you put things in distinct ARs and have possibly stale checks of rules.

Separate user data from other data

Our client would like the user table to be separated from all other tables for "security reasons". Is this a good practice given that our application is built using RoR and MySQL and running on Unicorn and Nginx ?
I can think of two possible ways:
Create two different login accounts, one for the user table and one for the other tables.
OR
Have a separate database for the user data.
I think that both the solutions might create some problems with the migrations and other tasks and I don't know if this is an effective method of protecting user data. I am a junior developer and I am not familiar with some database and security concepts. Any suggestion?
A very common pattern is to have the users table literally just contain details of the user account and NO details of the actual person behind that account. ie, it would have username, email, password, or encrypted password & salt or whatever, but nothing else - not even name. So, all the "glue" that makes the system work stays in the users table in your regular database.
Then, the details of the real person behind the account (name, telephone number, address, card details etc etc) are stored in a different table, or tables, with a foreign key in either table pointing into the other one. You could store them in a different database but i don't know if this makes it more secure. A better way might be to encrypt just the table with the user's personal data, or perhaps encrypt the entire database. see
http://thinkdiff.net/mysql/encrypt-mysql-data-using-aes-techniques/
I get the feeling that your client doesn't know a lot about internet security and just needs to be reassured that some hacker isn't going to put all the customers' credit card details online, as has happened in several high profile cases recently. To satisfy them i would recommend that you research this well and implement at least two different security strategies, each of which on their own would be considered adequate.
Reassuring the client didn't work as this was an acceptance criteria for launch. In the end, I created two separate database with separate login credentials and user permissions. In order to manage multiple database migrations, I initially used multi-database-migrations gem and then customised it into my own gem.
I was new to SO when I posted this question (still am) and I now understand that the topic is too wide to be asked in a single SO question. Thanks for the suggestions anyway and I hope that the answer can help other people.

general question about database

I've kinda silly question. I have a small community website. I'm thinking to make specific pages which can be viewed only by the members who have permission. So I suppose i will add each member ID in the database and when a member will try to access the page then i will first check if the member is logged in and then i will check the user ID, if it exists in the database table of users which have permission to view that content. Now Im just wondering if the database grows up, wont it take a long time to check everythng before loading the page?
Premature optimization is the root of all evil (Donald Knuth)
You can easily handle several millions of users with a single database, so that won't be a problem until your community is huge. When you reach that step, you can switch to more scalable DB solutions like Cassandra.
Having that said, take Brad Christie's comment into account, and use a reasonable identity management that won't thrash your database unnecessarily.
"a long time" is subjective and depends on many factors. For a small community website, you will likely not run into any issues with the method you've described. Still, it is considered best practice, and will speed up queries significantly, if you make use of proper indexes. Columns that will be queried against, such as the user ID, should be indexed. Not using an index means that MySQL has to read every record in your table and check to see if it matches your criteria.
This article may be of use to you:
http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm
Also, if you are concerned about how your site will perform when your dataset grows, consider populating it with a bunch of dummy data and running a few tests. This site will help you generate a bunch of data to put in your database.
http://www.generatedata.com/#about
Lastly, if pages are not specific to a particular person or small group of people, consider using more general buckets for access control. For example, if only admins can view a page, tie that page to an "admin" permission and note which users are admins. Then, you can do a quick check to see what type or types of user a particular person is, and decide to show them the page or not. This type of system is typically refered to as an Access Control List (ACL).
http://en.wikipedia.org/wiki/Access_control_list

Two similar applications on different domains but same users

I'm planning on building two applications using Zend Framework that are very similar but serve two different purposes that can't be part of the same application or be combined into one. However, modules are something I'm considering.
The issue I'm running into is if a user registers for the first application I want that information be available to the second application, hence sharing a user table or user database. Because the applications are so similar that they have the same database tables with some having different fields, I'm not sure if I should have three, two or one databases. Three databases would be User Database, App1 Database, App2 Database. Two databases would be User Database and App1+2 Database with prefixed tables. One database would be User and App1+2 Database.
I'm trying to give as much information as possible, but because this is for a client I can't really discuss the details in depth. Also, this is something the client wants and other than not being able to figure out how to set it up, I'm not sure this is best.
My Questions
Of the options above, which would
serve best, or other?
Should I have a shared user dataset across two applications or should the users have to register again?
No matter of the choice you think is best, how would/should I implement it into Zend? Just a brief is needed no need for code.
I hope this is enough information to give me the best answer, but if more information is need, please let me know.
Thanks!
Why have multiple databases? Use just one database and prefix the tables that differ for the two applications. For example:
users
app1_otherdata
app2_otherdata
This way users' data will be easily accessible to both apps and you could still have a relatively independent database structures.
Question 2 is something you really should discuss with your client.
Once you know your clients' preference you could eg. suggest using a single sign-on approach for the sites, but I would certainly keep both DBs apart. So either your 2 DB (with separate user DB per app) or your 3 DB solution (with separate user DB/single sign-on) makes more sense to me.