Organisasi, Peran, dan Izin
Pendahuluan
Dokumen ini mencakup fitur manajemen organisasi, peran, dan izin. Organisasi adalah entitas penyewa (tenant) tingkat atas, peran menyediakan pengelompokan akses, dan izin mendefinisikan kontrol akses granular. Model RBAC menggunakan hubungan banyak-ke-banyak antara peran dan izin, dengan pengguna yang ditetapkan ke peran melalui tabel junction. Semua logika bisnis dienkapsulasi dalam OrganizationService, RoleService, dan PermissionService, dengan controller yang bertindak sebagai lapisan transport HTTP tipis.
Model Data
Modul Organisasi
Definisi Entitas
File: Domain/Entities/Organization.cs
Tabel: organizations
| Kolom | Tipe | Batasan | Deskripsi |
|---|---|---|---|
id | uuid | PK | Kunci utama (UUIDv7) |
name | varchar(255) | Wajib | Nama organisasi |
email | varchar(255) | Wajib, Unik | Email kontak |
address | varchar(255) | Wajib | Alamat jalan |
province | varchar(255) | Wajib | Provinsi |
city | varchar(255) | Wajib | Kota |
phone_number | varchar(255) | Wajib | Nomor telepon kontak |
oinkcode | varchar(255) | Bisa null | Oinkcode untuk aturan IDS |
website | varchar(255) | Bisa null | Situs web organisasi |
created_at | timestamp | Stempel waktu pembuatan | |
updated_at | timestamp | Stempel waktu pembaruan terakhir |
Properti Navigasi
public ICollection<User> Users { get; set; }
public ICollection<OrganizationUserRole> OrganizationUserRoles { get; set; }
public ICollection<Role> Roles { get; set; }
public ICollection<Sensor> Sensors { get; set; }
public ICollection<Asset> Assets { get; set; }
Controller
File: API/Controllers/Organizations/OrganizationsController.cs
Rute: api/organizations
Titik akhir Organisasi menangani:
- Operasi CRUD Organisasi
- Daftar Organisasi
- Penetapan peran-pengguna-organisasi (Organization-user-role assignment)
- Penegakan kebijakan akses tingkat organisasi (
edit-organization)
Modul Peran (Role)
Definisi Entitas
File: Domain/Entities/Role.cs
Tabel: roles
| Kolom | Tipe | Batasan | Deskripsi |
|---|---|---|---|
id | uuid | PK | Kunci utama (UUIDv7) |
name | varchar(255) | Wajib | Nama peran |
organization_id | uuid | FK, Bisa null | Organisasi pemilik |
created_at | timestamp | Stempel waktu pembuatan | |
updated_at | timestamp | Stempel waktu pembaruan terakhir |
Properti Navigasi
[ForeignKey("OrganizationId")]
public Organization? Organization { get; set; }
public ICollection<Permission> Permissions { get; set; }
public ICollection<UserRole> UserRoles { get; set; }
Hubungan Peran-Izin
Hubungan banyak-ke-banyak antara peran dan izin dikonfigurasi di ApplicationDbContext.OnModelCreating:
modelBuilder.Entity<Role>()
.HasMany(r => r.Permissions)
.WithMany(p => p.Roles)
.UsingEntity<Dictionary<string, object>>(
"permission_role",
j => j.HasOne<Permission>().WithMany()
.HasForeignKey("permission_id").OnDelete(DeleteBehavior.Cascade),
j => j.HasOne<Role>().WithMany()
.HasForeignKey("role_id").OnDelete(DeleteBehavior.Cascade),
j =>
{
j.Property<DateTime>("created_at").HasDefaultValueSql("CURRENT_TIMESTAMP");
j.Property<DateTime>("updated_at").HasDefaultValueSql("CURRENT_TIMESTAMP");
}
);
Controller
File: API/Controllers/Roles/RolesController.cs
Rute: api/roles
Titik akhir Peran menangani:
- Operasi CRUD Peran
- Penetapan izin ke peran
- Detail peran dengan daftar izin
Izin Otomatis untuk Peran Admin
Ketika peran "Super Admin" atau "Admin" dibuat atau ditetapkan dan tidak memiliki izin, sistem secara otomatis menetapkan semua izin dari katalog:
private async Task EnsureAdminPermissionsAsync(Role role)
{
if (role.Name != "Super Admin" && role.Name != "Admin")
return;
var roleWithPermissions = await _context.Roles
.Include(r => r.Permissions)
.FirstOrDefaultAsync(r => r.Id == role.Id);
if (roleWithPermissions != null && !roleWithPermissions.Permissions.Any())
{
var allPermissions = await _context.Permissions.ToListAsync();
roleWithPermissions.Permissions = allPermissions;
await _context.SaveChangesAsync();
}
}
Modul Izin (Permission)
Definisi Entitas
File: Domain/Entities/Permission.cs
Tabel: permissions
| Kolom | Tipe | Batasan | Deskripsi |
|---|---|---|---|
id | uuid | PK | Kunci utama (UUIDv7) |
name | varchar(255) | Wajib | Nama yang mudah dibaca |
slug | varchar(255) | Wajib, Unik | Slug yang mudah dibaca mesin |
created_at | timestamp | Stempel waktu pembuatan | |
updated_at | timestamp | Stempel waktu pembaruan terakhir |
Izin yang Ditanam (Seeded Permissions)
Izin berikut ditanamkan melalui EF Core HasData di ApplicationDbContext:
| Izin | Slug | Kategori |
|---|---|---|
| Create User | create-user | Pengguna |
| Edit User | edit-user | Pengguna |
| Delete User | delete-user | Pengguna |
| Read User | read-user | Pengguna |
| Create Sensor | create-sensor | Sensor |
| Update Sensor | update-sensor | Sensor |
| Delete Sensor | delete-sensor | Sensor |
| Read Sensor | read-sensor | Sensor |
| Create Role | create-role | Peran |
| Edit Role | edit-role | Peran |
| Delete Role | delete-role | Peran |
| Read Role | read-role | Peran |
| Create Asset | create-asset | Aset |
| Edit Asset | edit-asset | Aset |
| Delete Asset | delete-asset | Aset |
| Read Asset | read-asset | Aset |
| Edit Organization | edit-organization | Organisasi |
Catatan: Izin yang ditanamkan menggunakan UUID deterministik (misalnya,
01936b7e-8000-7000-8000-000000000001) dan stempel waktu tetap (2025-11-19T00:00:00Z) untuk menghindari peringatan migrasi EF Core.
Controller
File: API/Controllers/Permissions/PermissionsController.cs
Rute: api/permissions
Titik akhir Izin memelihara katalog izin dan mendukung kueri izin yang digunakan oleh sistem otorisasi.
Tabel Junction
UserRole
File: Domain/Entities/UserRole.cs
Tabel: user_role
| Kolom | Tipe | Batasan | Deskripsi |
|---|---|---|---|
user_id | uuid | PK Komposit, FK | Referensi User |
role_id | uuid | PK Komposit, FK | Referensi Role |
created_at | timestamp | Pembuatan | |
updated_at | timestamp | Perbaruan terakhir |
Menggunakan kunci utama komposit (UserId, RoleId) yang dikonfigurasi di OnModelCreating.
OrganizationUserRole
File: Domain/Entities/OrganizationUserRole.cs
Tabel: organization_user_role
| Kolom | Tipe | Batasan | Deskripsi |
|---|---|---|---|
organization_id | uuid | PK Komposit, FK | Referensi Organisasi |
user_id | uuid | PK Komposit, FK | Referensi User |
role_id | uuid | PK Komposit, FK | Referensi Role |
created_at | timestamp | Pembuatan | |
updated_at | timestamp | Perbaruan terakhir |
Tabel ini menyediakan junction tiga arah untuk penetapan peran-pengguna dengan cakupan organisasi.
Model Akses
Akses efektif ditentukan oleh rantai berikut:
- Identitas: Identitas terautentikasi (memerlukan token JWT)
- Klaim (Claims): Klaim dalam JWT (
organization_id,role) - Cakupan (Scope): Cakupan organisasi (data difilter berdasarkan organisasi)
- Peran (Roles): Pemetaan Peran → Izin (banyak-ke-banyak)
- Kebijakan (Policies): Pernyataan kebijakan otorisasi (
manage-*danedit-organization)
Kebijakan Otorisasi (Authorization Policy)
Kebijakan otorisasi didefinisikan untuk operasi tulis:
services.AddAuthorizationBuilder()
.AddPolicy("manage-users", ...)
.AddPolicy("manage-sensors", ...)
.AddPolicy("manage-assets", ...)
.AddPolicy("manage-roles", ...)
.AddPolicy("edit-organization", ...);
Kebijakan ini ditegakkan pada titik akhir tulis di controller Users, Sensors, Assets, Roles, dan Organizations.
Aturan Cascade Delete
| Induk → Anak | Perilaku |
|---|---|
| Organisasi → Peran | Cascade |
| Organisasi → Sensor | Cascade |
| Organisasi → Aset | SetNull |
| Organisasi → OrgUserRole | Cascade |
| Peran → permission_role | Cascade |
| Peran → UserRole | Cascade |
| Peran → OrgUserRole | Cascade |
| Pengguna → UserRole | Cascade |
| Pengguna → OrgUserRole | Cascade |
Perbaikan di Masa Depan
Selesai
- Amplop kegagalan otorisasi standar (
ApiEnvelope). - Hook logging audit untuk perubahan peran/izin.
- Kebijakan izin cakupan organisasi di luar
edit-organization. - Logika bisnis manajemen peran di lapisan layanan.
- Logging perubahan peran pengguna untuk kepatuhan (compliance).
Terbuka
- Tidak ada item prioritas tinggi yang terbuka dalam modul ini saat ini.