What I learnt
Things I’ve learnt:
FOR MYSELF - I don’t know how to priortise great
Yeah I already know. ADHD blah blah. I’m trying though! I’m trying to get this app done!
I also don’t remember great. Heh. Kill me sometimes.
NEW EVOLUTION: Debug console
What is really needed is a debug console. That way we can easily call functions / methods directly and as authenticated by a particular user.
This allows us to test much more easily specific things - including checking to see what users can and cannot see.
This should mean that we have an option to log in as a user to the home page or to just a specific module.
Also do function calls are important to getting responses from the database and correctly verifiying that all of these things are working in order.
NEW DEVELOPMENT ASPECT: Control repositories, matricies, and children…?
Ok so basically I’ve been killing myself trying to figure out how we can simplify the permissions and CRUD into a more cohesive solution. I think I’ve got it:
Control-Based Permission System
Objective:
To create a flexible and scalable permission system that combines CRUD operations and high-level module-specific permissions into a unified concept of ‘controls’. This system aims to simplify the coordination of database security rules, CRUD operations, and module-specific permissions.
Components:
ControlRepository:
- A repository that defines a set of controls.
- The basic
**ControlRepository**
includes the following controls: Create, Read, Update, Delete, and Access (CRUDA). - Specific modules can have their own
**childControlRepository**
if they require more granular or additional controls.
ControlMatrix:
- A matrix that maps user roles to the controls they have for a specific module.
- Each module will have its associated
**controlMatrix**
that specifies what each user role can do within that module. - Specific modules can also have a
**childControlMatrix**
if they use a**childControlRepository**
.
Modules:
- Different parts or functionalities of the application.
- Each module uses a
**controlMatrix**
to determine what each user role can do within that module. - Modules can use the parent
**ControlRepository**
and**controlMatrix**
, but they also have the flexibility to use a specific**childControlMatrix**
and**childControlRepository**
if needed.
Workflow:
User Authentication:
- Every user, upon logging in, will have their permissions checked against the
**controlMatrix**
of the modules they access. - This ensures real-time permission checks, allowing for quick updates to user permissions without requiring software updates.
Module Access:
- When a user tries to access a module, the system checks the
**controlMatrix**
of that module to see if the user has the Access control. - If the user has the required control, they can access the module and their other controls (like CRUD operations) are determined based on the
**controlMatrix**
.
Database Security Rules:
- The CRUD controls from the
**ControlRepository**
are used to set database security rules, ensuring data integrity and security. - For instance, if a user role doesn’t have the Delete control for a module, they won’t be able to delete data related to that module in the database.
Storage
ControlRepository:
- Basic ControlRepository (CRUDA):
- Stored as a collection named
**controlRepository**
. - Each document in this collection represents a control (Create, Read, Update, Delete, Access).
- Each document can have fields detailing the control’s properties or metadata.
- Stored as a collection named
- ChildControlRepository:
- Stored as sub-collections under specific modules in the database.
- For instance, if there’s a module named “AdminPanel”, there could be a sub-collection named
**adminPanelControlRepository**
containing the specific controls for that module.
ControlMatrix:
- Stored as a collection named
**controlMatrix**
. - Each document in this collection corresponds to a module.
- Each document contains fields for each user role, and the value of each field is an array or map of the controls that role has for that module.
- For modules using a
**childControlRepository**
, the**controlMatrix**
document for that module would reference the specific controls from the child repository.
Retrieval and Usage:
- When a user logs into the application, the system fetches the relevant
**controlMatrix**
documents to determine the user’s permissions for various modules. - If a module uses a
**childControlRepository**
, the system will also fetch the specific controls from the associated sub-collection. - The fetched controls are then used to determine the user’s access and CRUD permissions in real-time.
Caching:
- Every time a user log ins - the app retreives the relevant
**controlMatrix**
and**controlRepository**
. Let’s call it the**controlData**
. - The
**controlData**
is then cached locally to the device. Everytime the user navigates between modules the app is checking the**controlData**
to determine what the user can do / see / access. - There is a manual “Refresh Permissions” button in the main home page drawer menu in case of error - or the user can log out and in again to refresh.
- The cached data will need to be encrypted, and no unauthorised access is allowed.
- Optimising the database for a single document read is essential.
Security
When it comes to security, it’s necessary to have in place specific methods that enforces the users**controlData**
controls.
To put this in perspective - consider the basic controls (CRUDA) - and ways to enforce them:
- CRUD - All can be enforced with matching security rules for Firestore
- A (Access) - Implementing a navigator that checks the users controls and does not show specific buttons / links to other modules. Then if the user somehow accesses this then the application directs them to a “sorry you’re not authorised” security page. This could also log the relevant user data as well. This of this like a medieval gatehouse. All users have to travel through them. For those that have the permission they can actually “see” the gatehouse, and can pass through. For those who don’t have permission they can’t even see the gatehouse, but even if they did guards are waiting on the other end to apprehend them before anything happens.
For more specific uses maybe something like this could be implemented:
- Location - create a widget that filters out any data not relevant to the users location.
- Territory - create a widget that filters in all data within that territory
- Role - create a widget that filters out any data not relevant to the users role.
Et cetera.