Imagine a data model of an electric company and the city it powers. The company has several departments that manage at least one neighborhood each in the city. The company database includes information for the homes in each neighborhood, the meters installed at homes, billing history, etc... Any employee in a department can login and view all of the different types of data, but they can only view data for the neighborhoods that their department manages. Example schema:
Departments
- ID
- Name
Neighborhoods
- ID
- Name
DepartmentsToNeighborHoods (LinkTable)
- DepartmentID
- NeighborhoodID
Employees
- ID
- Name
- DepartmentID (Foreign Key)
Homes
- ID
- Address
- NeighborhoodID (Foreign Key)
Meters
- ID
- HomeID (Foreign Key)
Given this data model, I'm trying to implement a restful interface where employees can pull data but only on resources within their own department. For example if an employee wants to access the billing history on a particular home, they can only do so if that home is in a neighborhood managed by the employee's department.
The only way I can think of doing this is by implementing a permissions function that checks whether a user can access a particular resource given their user id. A possible implementation (pseudocode):
getMeterDetails(meterID, employeeID) {
permissionQuery = "
select 1
from Meters
join Homes on Homes.ID = Meters.HomeID
join Neighborhoods on NeighborHoods.ID = Homes.NeighborHoodID
join DepartmentsToNeighborhoods as DTN on DTN.NeighborhoodID = Neighborhoods.ID
join Employees on Employees.DepartmentID = DTN.DepartmentID
where Meters.ID = ?
and Employees.ID = ?
"
result = db.runQuery(permissionsQuery, meterID, employeeID)
if (result == 1) {
return MeterModel.get(meterID);
}
else {
return ERROR_VALUE;
}
}
The general issue is that I want to restrict access to particular resources based on membership in another distantly related resource. My current method requires that an additional database query is made each time a resource is requested. I also have to write custom permission queries for each resource I expose because each one uses a different set of relations to determine if the current employee is allowed to access this particular resource. Is there a better method I can use to implement this sort of permission control?