# **Chapter 13: Profile & Permission Management System in SartajPHP**
## Profile & Permission Management System in SartajPHP
This chapter explains **how profiles and permissions are created, stored, assigned, and enforced** in SartajPHP, and how Apps like `mebProfile` and `mebProfilePermission` work together to provide a flexible authorization system.
---
## 13.1 Why SartajPHP Uses Profile-Based Permissions
SartajPHP separates **authentication** from **authorization**:
* **Authentication** → Who the user is
* **Authorization** → What the user can do
Instead of assigning permissions directly to users, SartajPHP assigns permissions to **profiles**, and users are linked to profiles.
This design provides:
* Easier permission management
* Reusable permission sets
* Safer delegation
* Scalable multi-user systems
---
## 13.2 Core Database Tables Involved
The permission system relies on two core tables:
### 1. `member` Table
Represents users.
Key fields used by the permission system:
* `id` → User Record ID (Primary Key)
* `profile_id` → Linked profile
* `userid` → Creator user ID
* `parentid` → Parent user ID
* `spcmpid` → Company identifier
* `usertype` → `ADMIN` or `MEMBER`
---
### 2. `profile_permission` Table
Represents profiles and their assigned permissions.
Important fields:
* `id` → Profile ID (Primary Key)
* `profile_name` → Human-readable profile name
* `permission_id` → Permission list (CSV or serialized)
* `userid`, `parentid`, `spcmpid`
* `submit_timestamp`, `update_timestamp`
Each record represents **one profile**.
---
## 13.3 How Permissions Are Defined (Registration Time)
Permissions are declared **when an Gate is registered**, not in the database.
Example:
```php
uuregisterGate(
"mebProfile",
"{$slibpath}/apps/permis/uumebProfileGate.php",
"",
"Profile",
[
["view","Profile View"],
["add","Add Record"],
["delete","Delete Record"]
]
);
```
Meaning:
* `"view"` → Internal permission name (developer-facing)
* `"Profile View"` → Display label (user-facing)
Internally, SartajPHP expands this into:
```
mebProfile-view
mebProfile-add
mebProfile-delete
```
These expanded permission keys are what the framework actually checks.
---
## 13.4 Profile Creation Workflow (`uumebProfileGate.php`)
The Profile Gate allows administrators to:
* Create new profiles
* Edit existing profiles
* Assign permissions
Typical flow:
1. Admin opens Profile App
2. Uses **list FrontFile** to browse profiles
3. Uses **edit FrontFile** to create or update profiles
4. Permissions are saved as text in `permission_id`
The Gate itself does not need to understand permissions deeply — it only stores them.
---
## 13.5 Permission Assignment UI (`uumebProfilePermissionGate.php`)
The Permission Gate provides a UI that:
* Reads all registered Apps
* Reads permissions declared by each App
* Displays them as grouped checkboxes
* Prevents users from assigning permissions they do not own
This ensures **permission inheritance safety**.
---
## 13.6 Permission Inheritance Rule (Very Important)
A user can **only assign permissions that they already have**.
This rule prevents:
* Privilege escalation
* Unauthorized permission granting
If an admin does not have:
```
mebProfile-delete
```
They cannot assign that permission to any profile.
This rule is enforced at runtime using:
```php
SphpBase::sphp_permissions()->hasPermission()
```
---
## 13.7 How Permissions Are Stored
Permissions are stored as a **text list** inside:
```sql
profile_permission.permission_id
```
Example value:
```
mebProfile-view,mebProfile-add,mebProfilePermission-view
```
Why text storage?
* Database-agnostic
* Easy migration
* No join overhead
* Faster permission checks
Parsing is handled internally by SartajPHP.
---
## 13.8 Permission Evaluation at Runtime
When a request is processed:
1. User logs in
2. Profile ID is loaded from `member.profile_id`
3. Permissions are loaded from `profile_permission.permission_id`
4. Permissions are cached in session:
```php
$this->Client->session('lstpermis', $row['permission_id']);
```
5. Permission checks are executed using:
```php
$this->page->hasPermission("view");
```
The Gate does **not** need to know:
* Which profile the user has
* Where permissions came from
* How they are stored
---
## 13.9 Permission Checks Inside Apps
Inside an App, permission checks are explicit:
```php
if ($this->page->hasPermission("add")) {
// allow insert
}
```
Or globally at Gate entry:
```php
$this->page->getAuthenticatePerm("view");
```
This ensures:
* No hidden logic
* No magic behavior
* Full developer control
---
## 13.10 Why `PermisApp` Makes This Easier
`PermisApp` is a **helper parent class**, not a framework requirement.
It provides:
* Standard CRUD flow
* Permission checks for common operations
* Automatic DB binding
* Reduced boilerplate
But:
* You can build permission-based Apps without it
* The real parent class is always `BasicGate`
---
## 13.11 Common Mistakes to Avoid
1. Assuming permissions auto-apply
→ They don’t. You must check them.
2. Naming Apps poorly
→ AppGate name defines permission namespace.
3. Mixing role logic with permission logic
→ Keep them separate.
4. Forgetting `id` as primary key
→ Many components rely on it.
---
## 13.12 Design Philosophy
SartajPHP treats permissions as:
* **Data-driven**
* **Developer-defined**
* **User-assignable**
* **Framework-enforced**
Nothing is hidden.
Nothing is forced.
Everything is explicit.
That is why SartajPHP can scale from:
* Small admin panels
* To multi-company SaaS platforms
---
### End of Chapter 13
---