If I two different type of accounts for my site (say user and admin; they are completely different, so an admin cannot be a user with administrative permissions.), what is the best way to create restful urls for it?
For one, I was just going to create a SessionsController with create,store,destroy, but with two, I need to create another controller, and I am not liking the naming that I need to create ...
There is no 'best way' to create restful api's. It depends on your design. The fact that users and admins will be mutually exclusive does not prevent you from storing them in 1 datastore or accessing them via 1 api. If your design calls for radically different approaches in interacting with both entities, you might choose two api's. If an admin is just another type of user, a single api might be a better choice. Ultimately, the choice is yours.
Related
I have 2 systems let's call them i and j. Each have it's own database.
Each have a registration page, where a user is inserted in a user table.
What is the best way to synchronize both tables, where if any user registers at system i it will be also registered at system j.
Notes:
I cannot read from each other databases directly.
I can do small changes in the code if needed and it will not affect the system performance or natural behavior.
I can create API's for both systems if needed.
I can add any tables or fields if needed.
I can create any cron jobs unless it will affect the performance of the system or server.
I'm using cPanel.
Technologies:
MySQL
PHP
REST API's
The fact that you list cpanel as a technology shows you're working with an inflexible budget hosting vendor. So it's unlikely they'll cooperate in setting up background tasks (cron jobs) to merge your user tables behind the scenes. (cpanel isn't a technology: it's a system administration user interface provided by hosting vendors who don't trust their customers' skills.)
So. you should design and implement a REST API in the code of both your apps to perform user registration and authentication tasks. You didn't show us the details of your app, so it's hard to design it for you. Still it seems likely you'll have to implement these operations:
PUT user
DELETE user
GET user
POST user to validate a user's password, etc. (Don't use GET to pass secret information: GET request parameters go into server logs.)
PATCH to update details of a user.
If you get the API working, whenever you create/retrieve/update/delete user information in one app, you'll use the API to change it in the other.
Your best bet would be to create a third app just for user management, and have both your existing apps use it. That way you're sure to have one coherent source of truth about users. But you can do it just within two apps.
I'm working on a SaaS product and trying to figure out the best way to design the database for my scenario, which I think is pretty standard.
I should not that I don't have an experience designing such a database.
I tired researched online, but there isn't really any info I could find about implementation. There are quite a few comparing the different multi-tenant architectures.
For the multi-tenant approach, I decided go with a single database - seemed to be the most fitting.
Here's the basic list of what should be supported:
Multiple clients, all separated, no sharing of data between them.
Each client has it's own user base (staff/employees).
The client's staff members have different access levels to the system (exposure to different areas, ability to perform certain actions)
Each client have it's own customers.
I can wrap my head around the basic concept of having the tenant_id on any table belongs to that tenant. I guess my issue is more with how to combine it with different access levels per client's staff member.
How would you go about it?
Any reference some implementation of such a DB?
Thanks
Update
After #dmfy answer, I gave it some thought and came up with this solution:
account
-id
-name
user
-id
-account_id
-username
-password
role
-id
-account_id
-name
user_role
-user_id
-role_id
access
-id
-role_id
-name
role_access
-role_id
-access_id
session
-account_id
-user_id
-token
I'll explain-
The role table is essentially a "group" of users associated with a list of permissions/access levels.
The access table represents a single permission. An area of the platform, an action that can (or cannot) be performed.
A row in the session table is created after a successful login. Each time there's a call to the server, if the user has been verified against the token, I will lookup the roles for that user (using the session.user_id on the user_roles and collect it's access list using role.id on role_access.role_id).
Once I have the access list I can check against the request and see if the user is permitted to perform the action.
Notes
role can be customized for each tenant/account (e.g one can have "Management" and "Employees" and another can have "Management", "Support", and "Sales" ), hence the association with account.
access on the other hand, is platform-wide. The platform have the same set of areas and actions across all tenants. So there is not need to associate it with a specific account.
An improvement to the access lookup could be to store the access list on the session on login, to eliminate the double join (get all the user's roles, get all the roles' access lists).
Questions
Firstly, what is your overall opinion on the design. Do you see any flaws?
Is saving the account_id on the session really needed/a good idea?
Is having the server check whether the user has access to a certain resource is the standard way of doing this? Is there a way to do this as part of the itself query (e.g get an error from the DB itself)?
You might get a better answer by describing the requirements before you outline the solution.
Your design seems to describe an authorisation scheme. It looks fairly credible - I'd summarize it in natural language as:
A tenant is an account.
An account has many users.
A user can have
many roles.
Roles grant access to many permissions.
The system
maintains a list of sessions, mapping requests to users; this in turn
allows the system to check whether the user has permissions for a
given action.
Without knowing your requirements, that seems fairly reasonable. You may want to include a link from "account" to something your application recognizes as "tenant".
The big question is how you will use this data in your application. Checking permissions - especially fine-grained permissions - for each request could be expensive.
The specific solution here depends heavily on your application framework - many have built-in authentication/authorization models, and it's usually a good idea to use those built-in features.
For ideas on how to implement this, you could look at CanCanCan, an authorization framework for Ruby on Rails, or Authority for Laravel.
It's also not clear how the actual data in your system will be linked to an account - if your system tracks widgets, does the "widgets" table have an "account_id" column? If so, how does your application track who is and is not allowed to access that row?
It sounds like you're conflating database users with application users. In a SaaS product with a shared-schema model, individual users won't have direct acess to the database; instead, your application connects as a single user with appropriate rights on all objects it needs. What you're worried about is what areas of the application users can access and what actions they can take. This means you need to build your authorization model into your schema.
The simplest possible model has two levels of access: regular users and administrators. This can be represented with a users table having a tenant_id to associate individual logins with the correct client, and an is_admin flag. Your application then ensures that only users with the flag set can access administrative functionality. If your authorization model is more complex, design your schema appropriately (users may have a many:many relationship with roles, for example).
Note also that a tenant_id column is only strictly required for tables directly related to tenants; if you have a profiles table with a user_id, you can trace the relationship back to the tenant through users. In some cases it may make sense to add the tenant_id to avoid long join chains.
This should be a pretty common issue: let's say I'm updating a users table as well as a users_organizations table. From the UI perspective, there is only one button "Save".
I can either:
1) Create a single API route
2) Create one API route for each resource (one for users, one for users_organizations)
And then, suppose I choose 1). Should I update both tables in a single database call or should I split it up into 2 database calls?
In general I'm never sure how to approach these problems. Sometimes there's an action that affects more than 2 database tables at once. How do I ensure robustness, proper error handling, and keep my code sane all at once?
Definitely a problem I struggle with as well.
From what I've seen in the past, most operations that go along with a UI action are related, and can be given a common action name like update-user when clicking "Save". I'd have a single API endpoint to update the user, such as PUT /api/users/123 in a REST API. The body of that request would contain updated fields and new organizations the user belongs to.
Then on the server side I would make 2 database calls, one to update the user table and one to update the user_organization table.
If you feel 2 operations are so different that it's difficult to come up with a common API endpoint name, or if they need to be called independently in other parts of the app, I would argue that they should be 2 different API endpoints.
At the end of the day I try to ask, if a new developer were to try to understand this code, what would be the simplest approach?
I have been trying to make a website as a side project since its summer and I have done a lot of tutorials and research with Firebase and HTML. Now I am stuck on the design aspect. My website requires making use of authentication with email and passwords.
For storing data about the user, what would be the base way to keep the user's data in Firebase database? Create childs named after the user's email, use the UID of the Firebase user, or are their other ways?
TLDR What is the best/recommended way to store a user data in a way that my website can retrieve what it needs when the user logs back on?
The idiomatic way to store user data is in a structure:
users
<uid1>
...
<uid2>
...
This allows quick and efficient lookup of the signed in user.
But you may need additional data for specific use-cases. For example: if you want to ensure that each user has a username that is unique across all users, you'll typically need to add a structure that maps from username to UID:
usernames
<username1>: UID
<username2>: UID
For more on this see one of the many examples: https://www.google.com/search?q=site:stackoverflow.com+firebase+unique+user+name
And for other use-cases you may need yet another structure.
To learn more about NoSQL data modeling in general, I recommend reading NoSQL data modeling. And for Firebase specifically I recommend watching Firebase for SQL developers.
I am rolling my own blogging system and I am wondering how to determine permissions and implement them in a blogging system?
What should be the permissions for a commenter, a blogger and an admin?
What is the best way to implement them?
You didn't mention what language/framework you're using. Django includes a very useful and complete set of permissions that you can get up and running with. I'd assume that there are a number of other web frameworks that do the same.
Therefore, my advice is to find a web framework that you like and think is fun (this sounds like a personal project after all) that will handle these kinds of things for you.
I'd go with a combination of a decoupled authentication component, that you can ask if the current user has the role X, and if so allow them to do the thing. That way you can leave the specifics of groups and expiry etcetera to the authentication component.
You could combine this with some specialized authentication for your blogging engine, eg. having a list of posters in the blog object, and always allowing those persons to make posts.
Give each user a "privilege" value and store it in the users table in the database.
for example:
0: plain user (can comment)
1: writer (can write new posts and modify his own posts)
2: moderator (accepts/deletes comments)
4: admin (access to all)
Use a combination of serverside sessions and cookies for logins.
For "advanced" user privileges, use bitmasks and create groups.
Bitmasking: for example, using previous values, user level 3 (2+1) would have both writer and moderator privileges.