Yetkilendirme Kütüphanesi
"Ajax işleminde 'url' parametresi doğru yol bilgisi için URL::site('controller/method') biçiminde ifade edilmelidir. "
ZN Framework kullanıcı rol değerlerine göre kullanıcıların nelere erişip erişemeyeceğini düzenleyen yetkilendirme kütüphanesine sahiptir. Yapılandırma dosyası veya veritabanı üzerinden entegreli bir şekilde yapılandırma sistemi oluşturabilmenize ortam sağlar.
ZN Framework ile aşağıdaki 3 yapının kullanıcı rollerine göre erişim alanını düzenleyebilirsiniz.
● Kontrolcü ve yöntemler [page]
● Post veya Get ile gönderilen anahtarlar [method]
● Form ve HTML nesneleri [process]
Permission:: kütüphanesi ile bir projede yetkilendirme gereken her alana yetki tanımlaması yapabilirsiniz.
# Kurulum
ZN dağıtımları için kurulum gerekmez.
↓ composer require znframework/package-authorization
# Yapılandırma
Permission | |
array $method = [] | Veri istek yetkilerini ayarlamak için kullanılır. |
array $page = [] | Sayfa ziyaret yetkilerini ayarlamak için kullanılır. |
array $process = [] | Nesne görünüm yetkilerini ayarlamak için kullanılır. |
# Yetki Anahtarları
any | Hiç bir yetkisi yok. |
all | Tam yetkili. |
noperm | İzin verilmeyen sayfa veya nesneler. |
perm | İzin verilen sayfa veya nesneler. |
Buna göre hangi id nin hangi sayfalara veya nesnelere izin verilip verilmeyeceği belirlenir. Eğer bir yetki noperm ile sınırlandırılmışsa onun dışındaki her şeye yetkili demektir. Şayet bir yetki perm ile sınırlandırılmışsa onun dışındaki hiç bir şeye yetkisi yok demektir.
# Yöntemler
# Page
İstek yapılan kontrolcü ve yöntemlerin erişim alanlarını tanımlamak için kullanılır. Hangi sayfalara erişileceği veya erişilemeyeceği gibi düzenlemeleri kapsar.
Kullanıcı rollerine göre yetkiler iki yerde saklanabilir;
● Config/Auth.php
● Veritabanı
Eğer yetkiler yapılandırması dosyası üzerinden düzenlenecekse aşağıdakine benzer bir içeriğe sahip olmalıdır.
'page' =>
[
1 => 'all',
2 => ['noperm' => ['profile/delete']],
3 => ['noperm' => ['update', 'delete']]
4 => 'any'
]
Yukarıdaki kullanımın anlamları şöyledir;
Role ID | Erişim Kapsamı |
1 | Her sayfaya girebilir |
2 | Sadece profile/delete sayfasına giremez. |
3 | İçinde update veya delete geçen hiç bir sayfaya giremez. |
4 | Hiç bir sayfaya giremez. |
scalar $roleId = self::roleId() |
Ön tanımlı olarak Permission::roleId() yöntemi ile tanımlanan rol değerini kabul eder. |
return bool |
$user = User::data();
if( Permission::page($user->role_id) === false )
{
redirect('show404');
}
Dosyadan çalışmak yerine veritabanı tercih ediyorsanız böyle bir kullanımına da imkan sağlanır.
scalar $roleId | Kullanıcı rol değeri. Bu parametre aynı zamanda Permission::roleId() yöntemi parametre yapılandırması gibi işlev görür. | |
array $tableMatch | Kullanıcı rol ve yetkilerinin tutulduğu tablo ile eşleştirme bilgileri. | |
key | perm | İzin verilen |
noperm | İzin verilmeyen | |
value |
table[role_id]:column |
Bu kullanım table tablosundan role_id kolon değerine göre column kolonunda yer alan JSON formatında veriyi alıp diziye dönüştürülmesini sağlar. |
mixed $callback | Kurallara aykırı istek durumunda yapılacak olanlar. | |
string | string parametre gönderilmesi durumunda ilgili dizgeye redirect eder. | |
callable | Yönlendirme işlemi ile beraber çalıştırılmak istenen kodlar için geri çağrım işlevi tanımlanabilir. | |
return bool |
Aşağıdaki gibi örnek bir tablonun olduğunu varsayalım.
permissions | ||
id | role_id | data |
1 | 1 | all |
2 | 2 | ["account/delete"] |
3 | 3 | ["account/update", "account/delete"] |
4 | 4 | ["update", "delete"] |
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
$user = User::data();
Permission::page($user->role_id, ['noperm' => 'permissions[role_id]:data'], function()
{
redirect('Home/noaccess');
});
}
}
Yukarıdaki örnekte key olarak noperm anahtarı kullanıldığı için tabloda yer alan bilgiler ilgili role göre izin verilmeyen veriler olarak algılanır.
Role ID | Erişim Kapsamı |
1 | Her sayfaya girebilir |
2 | Sadece account/delete sayfasına giremez. |
3 | Sadece account/update ve account/delete sayfasına giremez. |
4 | İçinde update ve delete geçen hiç bir sayfaya giremez. |
Sadece Permission::page() yöntemi ile kullanılabilir Permission::realpath() yöntemi eklendi.
Permission::realpath(string $realpath = CURRENT_CFURI) : this |
Bu yöntemle yapılan isteğin ne tür bir metin içinde bulunup bulunmadığı kontrol edilebilmektedir. Bu yöntem kullanılmadığı taktirde mevcut URI içerisinde kontrol yapılmaktadır.
if( ! Permission::realpath()->page($roleId) ) # CURRENT_CFURI [controller/function]
{
redirect();
}
[$realpath]
Kontrol edilecek URI alanını genişletelim.
if( ! Permission::realpath(URI::get(1, 3))->page($roleId) )
{
redirect();
}
# Post / Get / Request
Post, Get veya Request (Get, Post, Cookie) süper küresellerden gelen değerlere sınırlama getirebilirsiniz. Mesela form nesnesinden veya uzaktan post ile delete verisi gönderilmesi halinde kullanıcı rollerine göre işleme devam edilip edilmeyeceğine karar verdirebilirsiniz. Çünkü bazen bazı rollerin bazı sayfalara girmesi o sayfadaki her işlemi gerçekleştirebileceği anlamına gelmez. Bu kontrol için get(), post() ve request() yöntemlerinden yararlanılır.
scalar $roleId = self::roleId() | Ön tanımlı olarak Permission::roleId() yöntemi ile tanımlanan rol değerini kabul eder. |
return bool |
Aşağıdaki gibi bir yapılandırma örneği düşünün.
'method' =>
[
'1' => 'all',
'2' => ['noperm' => ['delete']],
'3' => ['noperm' => ['add', 'update', 'delete']]
];
Aşağıdaki örnekte kullanıcının rol id değerine göre yukarıdaki ayarlar devreye girer.
if( ! Permission::post(User::data()->role_id) )
{
redirect('show404');
}
Role ID | Kapsam Erişimi |
1 | Tüm veri gönderimlerine izin verilir. |
2 | $_POST['delete'] verisi gönderilemez. |
3 | $_POST['add'], $_POST['update'] ve $_POST['delete'] verileri gönderilemez. |
Get gönderim kontrolü için Permission::get() hem post hem de get gönderim kontrolü için Permission::request() yöntemini aynı mantıkta kullanabilirsiniz.
Kullanım tekniği olarak Permission::page() yöntemi ile aynıdır.
Aşağıdaki gibi örnek bir tablonun olduğunu varsayalım.
data_permissions | ||
id | role_id | data |
1 | 1 | all |
2 | 2 | ["delete"] |
3 | 3 | ["update", "delete"] |
4 | 4 | ["insert", "update", "delete"] |
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
$user = User::data();
Permission::post($user->role_id, ['noperm' => 'data_permissions[role_id]:data'], 'Home/noaccess');
}
}
Yukarıdaki örnekte key olarak noperm anahtarı kullanıldığı için tabloda yer alan bilgiler ilgili role göre izin verilmeyen veriler olarak algılanır.
Role ID | Erişim Kapsamı |
1 | Tüm veri gönderilmelerine izin verilir. |
2 | Sadece $_POST['delete'] gönderimine izin verilmez. |
3 | Sadece $_POST['update|delete'] gönderimine izin verilmez. |
4 | Sadece $_POST['insert|update|delete'] gönderimine izin verilmez. |
# RoleID
Permission:: sınıfına ait tüm yöntemlerin $roleId parametresini tek bir kez tanımlamak için kullanılır. Böylece her yöntemde tekrar tekrar role id değerinin belirtilmesine gerek kalmaz. Permission::process() yöntemi için gereklidir. Aksi halde bu yöntemin her kullanılışında tekrar ve tekrar role id belirtme zorunluluğu oluşur.
scalar $role | Role değeri. Genellikle kullanıcı tablolarında yer alan role kolonundan gelen değeri temsil eder. Hangi role'e göre kısıtlamanın nasıl yapılacağı belirlenir. |
Özellikle başlangıç kontrolcüleri ile kullanımı tavsiye edilir. Her kontrolcüde her seferinde yeniden tanımlamakla uğramak yerine başlangıç kontrolcüsünde bir kez tanımlamak daha doğru bir kullanım olur.
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
$user = User::data();
Permission::roleId($user->role_id);
if( ! Permission::page() )
{
redirect('home/noaccess');
}
}
}
# Process
Nesnelere erişim yöntemi belirlemek için kullanılır.
string $process = NULL | İşlem adı. |
string $obj = NULL | Kapsama alınacak nesne. |
return string |
Yetki ayarları dosyasını aşağıdaki gibi düzenleyip bir örnek üzerinde tekrar inceleyecelim.
'process' =>
[
'1' => 'any',
'2' => 'any',
'3' => ['perm' => ['update']],
'4' => ['perm' => ['update', 'add']],
'5' => ['perm' => ['update', 'add', 'delete']],
'6' => ['noperm' => ['edit'],
'7' => 'all'
];
Buna göre;
echo Permission::process('update', '<b>Update Process</b>');
echo Permission::process('add', '<b>Add Process</b>');
echo Permission::process('delete', '<b>Delete Process</b>');
echo Permission::process('edit', '<b>Edit Process</b>');
# Rol ID 4 için;
Add Process
Eğer görünüm nesnelerini Form:: ve Html:: kütüphaneleri ile oluşturuyorsanız yetki kontrolünü aşağıdaki gibi de yapabilirsiniz.
echo Html::perm('update')->bold('Update Process');
echo Html::perm('add')->bold('Add Process');
echo Html::perm('delete')->bold('Delete Process');
echo Html::perm('edit')->bold('Edit Process');
# Rol ID 6 için;
Add Process
Delete Process
# Rol ID 7 için;
Add Process
Delete Process
Edit Process
Kullanım tekniği olarak Permission::page() yöntemi ile benzerdir.
scalar $roleId | Kullanıcı rol değeri. Bu parametre aynı zamanda Permission::roleId() yöntemi parametre yapılandırması gibi işlev görür. | |
array $tableMatch | Kullanıcı rol ve yetkilerinin tutulduğu tablo ile eşleştirme bilgileri. | |
key | perm | İzin verilen |
noperm | İzin verilmeyen | |
value |
table[role_id]:column |
Bu kullanım table tablosundan role_id kolon değerine göre column kolonunda yer alan JSON formatında veriyi alıp diziye dönüştürülmesini sağlar. |
return bool |
Aşağıdaki gibi örnek bir tablonun olduğunu varsayalım.
object_permissions | ||
id | role_id | data |
1 | 1 | all |
2 | 2 | ["add", "update", "delete"] |
3 | 3 | ["add", "update"] |
4 | 4 | ["add"] |
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
$user = User::data();
Permission::process($user->role_id, ['perm' => 'data_permissions[role_id]:data']);
}
}
Buna göre;
echo Html::perm('add')->bold('Add Process');
echo Html::perm('update')->bold('Update Process');
echo Html::perm('delete')->bold('Delete Process');
echo Html::perm('other')->bold('Other Process');
# Rol ID 1 için;
Update Process
Delete Process
Other Process
# Rol ID 2 için;
Update Process
Delete Process
# Rol ID 3 için;
Update Process
# Rol ID 4 için;
# Start
Bir kod bloğuna erişim kontrolü yapmak için kullanılır. Erişim kontrolünden geçecek kod bloğunun başına yazılır.
string $process = NULL | İşlem adı. |
'process' =>
[
'1' => 'all',
'2' => ['perm' => ['add', 'update']],
'3' => ['perm' => ['add']],
'4' => 'any'
];
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
$user = User::data();
Permission::roleId($user->role_id);
}
}
@Permission::start('add')
<strong>Ekleme işlemi</strong>
@Permission::end()
Rol 1, 2 ve 3 için;
@Permission::start('update')
<strong>Güncelleme işlemi</strong>
@Permission::end()
Rol 1 ve 2 için;
@Permission::start('delete')
<strong>Silme işlemi</strong>
@Permission::end()
Rol 1 için;
Yukarıda hangi rollerin hangi çıktıyı aldığına dikat edin.
Şablon sihirbazı kullanılan sayfalarda Permission::start() yerine @perm() Permission::end() yerine de @endperm kullanılabilir.
@perm('delete')
<strong>Silme işlemi</strong>
@endperm
# Uygulama
Bu örnekte bir veri tablosunda yer alan silme butonunun rollere göre görüntülenip görüntülenemeyeceği üzerinedir.
Ayarların Yapılandırılması
'process' =>
[
1 => 'all',
2 => ['noperm' => ['delete']],
3 => ['noperm' => ['delete', 'edit']]
]
Yukarıdaki yapılandırmada id değeri 1 olan tüm işlemleri yapabilirken 2 olan sadece silme 3 olan silme ve düzenleme işlemi yapamamaktadır.
Başlangıç Kontrolcüsünde Kullanım
<?php namespace Project\Controllers;
use Permission, User;
class Initialize
{
public function main()
{
View::user($user = User::data());
Permission::roleId($user->role_id);
}
}
Kontrolcünün İçeriği
<?php namespace Project\Controllers;
class Users
{
public function main()
{
# Views/Users/main.wizard.php dosyasını otomatik yükler.
}
public function list()
{
# Views/Users/list.wizard.php dosyasını otomatik yükler.
}
}
Görünümde Kullanımı
@foreach( $user as $data )
{{ $data->username }}-
{{ Html::perm('edit')->anchor('users/edit'.$data->id, 'Düzenle') }}-
{{ Html::perm('delete')->anchor('users/delete'.$data->id, 'Sil') }}<br>
@endforeach
Yukarıdaki kullanımda Permission::process() yöntemi sayesinde hangi rollerin ilgili butonları görüp göremeyeceği gösterilmiştir.