Question
I am creating a brand new Housing application which lets user rate or favourite the houses. The following are users of the application:
Owner
Agent
Guest (not logged in)
Visitor (logged in)
Tenant
Now, the Owner
can do CRUD
operations but only for the house he owns and can't rate the House
he owns. The Tenant
for example can R
any house and can only
rate the house which he has rented.
So, I see the pattern here; first is the CRUD
operation which are very low level stuff and eventually any business logic boils down to this, the second is the business logic itself so, for example there is a request to remove the house by an user and request is handled by the following controller:
// controller
function remove(req, res) {
const { userId, houseId } = req.body;
houseService.remove(userId, houseId);
...
}
// service
function add(userId, houseId) {
const user = getUser(userId)
if (user.hasRole(Roles.OWNER)) {
// check if the houseId is one of the houses owned by the owner
...
} else {
throw AuthrorizationError();
}
}
I am bit confused by the roles and business logic stuff.
Questions:
- Permission checking should go in service or controller?
- In the example above I am checking permission before performing any business logic, is this correct?
- Rating a house should create a new entry in rating
association
table, should I exposed rating as a permission rules to the users in the system i.e.CRUD
operation for each user type?
Update:
To be more clear about the ratings
I can have the following permission rules:
Tenant
House - Read only
Rating - Yes
Owner
House - CRUD
Rating - Yes
But it is somehow making me uncomfortable, should I hide rating related stuff deep down under my business logic and not expose it to Roles and Permissions?
La solution
Permission checking should go in service or controller?
Permission checking can go in the controller, unless you find it convenient to push it back into the service. It's the only substantial logic I usually put into a controller, and when I do, it's always a "go, no go" test (i.e. if the permissions check fails, the entire controller operation fails).
In the example above I am checking permission before performing any business logic, is this correct?
If your desired behavior is to prevent the business operation from happening if the caller doesn't have the necessary permissions, then yes, you must check permissions first.
Rating a house should create a new entry in rating association table, should I exposed rating as a permission rules to the users in the system i.e. CRUD operation for each user type?
If by that you mean "should I have a CRUD endpoint on my API to create rating association records," then I would say no. Your API endpoint should expose a rating system; rating association records can be created internally in your business logic.