Lewati ke konten utama

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

1:N1:N1:N1:N1:N1:N1:NOrganizationTenantSensorEntityAssetEntityUserEntityRoleEntityOrgUserRoleJunction (3-way)UserRoleJunction (2-way)PermissionRoleJunctionPermissionEntity

Modul Organisasi

Definisi Entitas

File: Domain/Entities/Organization.cs Tabel: organizations

KolomTipeBatasanDeskripsi
iduuidPKKunci utama (UUIDv7)
namevarchar(255)WajibNama organisasi
emailvarchar(255)Wajib, UnikEmail kontak
addressvarchar(255)WajibAlamat jalan
provincevarchar(255)WajibProvinsi
cityvarchar(255)WajibKota
phone_numbervarchar(255)WajibNomor telepon kontak
oinkcodevarchar(255)Bisa nullOinkcode untuk aturan IDS
websitevarchar(255)Bisa nullSitus web organisasi
created_attimestampStempel waktu pembuatan
updated_attimestampStempel 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

KolomTipeBatasanDeskripsi
iduuidPKKunci utama (UUIDv7)
namevarchar(255)WajibNama peran
organization_iduuidFK, Bisa nullOrganisasi pemilik
created_attimestampStempel waktu pembuatan
updated_attimestampStempel 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

KolomTipeBatasanDeskripsi
iduuidPKKunci utama (UUIDv7)
namevarchar(255)WajibNama yang mudah dibaca
slugvarchar(255)Wajib, UnikSlug yang mudah dibaca mesin
created_attimestampStempel waktu pembuatan
updated_attimestampStempel waktu pembaruan terakhir

Izin yang Ditanam (Seeded Permissions)

Izin berikut ditanamkan melalui EF Core HasData di ApplicationDbContext:

IzinSlugKategori
Create Usercreate-userPengguna
Edit Useredit-userPengguna
Delete Userdelete-userPengguna
Read Userread-userPengguna
Create Sensorcreate-sensorSensor
Update Sensorupdate-sensorSensor
Delete Sensordelete-sensorSensor
Read Sensorread-sensorSensor
Create Rolecreate-rolePeran
Edit Roleedit-rolePeran
Delete Roledelete-rolePeran
Read Roleread-rolePeran
Create Assetcreate-assetAset
Edit Assetedit-assetAset
Delete Assetdelete-assetAset
Read Assetread-assetAset
Edit Organizationedit-organizationOrganisasi

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

KolomTipeBatasanDeskripsi
user_iduuidPK Komposit, FKReferensi User
role_iduuidPK Komposit, FKReferensi Role
created_attimestampPembuatan
updated_attimestampPerbaruan terakhir

Menggunakan kunci utama komposit (UserId, RoleId) yang dikonfigurasi di OnModelCreating.

OrganizationUserRole

File: Domain/Entities/OrganizationUserRole.cs Tabel: organization_user_role

KolomTipeBatasanDeskripsi
organization_iduuidPK Komposit, FKReferensi Organisasi
user_iduuidPK Komposit, FKReferensi User
role_iduuidPK Komposit, FKReferensi Role
created_attimestampPembuatan
updated_attimestampPerbaruan terakhir

Tabel ini menyediakan junction tiga arah untuk penetapan peran-pengguna dengan cakupan organisasi.


Model Akses

Akses efektif ditentukan oleh rantai berikut:

  1. Identitas: Identitas terautentikasi (memerlukan token JWT)
  2. Klaim (Claims): Klaim dalam JWT (organization_id, role)
  3. Cakupan (Scope): Cakupan organisasi (data difilter berdasarkan organisasi)
  4. Peran (Roles): Pemetaan Peran → Izin (banyak-ke-banyak)
  5. Kebijakan (Policies): Pernyataan kebijakan otorisasi (manage-* dan edit-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 → AnakPerilaku
Organisasi → PeranCascade
Organisasi → SensorCascade
Organisasi → AsetSetNull
Organisasi → OrgUserRoleCascade
Peran → permission_roleCascade
Peran → UserRoleCascade
Peran → OrgUserRoleCascade
Pengguna → UserRoleCascade
Pengguna → OrgUserRoleCascade

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.