author(s) | |
---|---|
|
Sistem üzerinde kullanıcıların erişebileceği işlevleri belirlemek ve sınırlandırmak için üç temel bileşen kullanılarak yetkilendirme yapısı oluşturulmuştur. Bu bileşenler;
Belirli bir kapsamda yapabilecek işler için oluşturulan genel bir tanımlayıcıdır. İzinler built-in olarak oluşturulur ve
sistem tarafından sunulan interface sayesinde kullanıcıların ilgili izne sahiplikleri sorgulanabilir. Örneğin, sistem
üzerinde dersler ile ilgili işlevleri yapabilmek için course_managemant
adında bir izin tanımlanabilir. İzin
tanımlamaları, ihtiyaçlara özgü olarak ders_olusturma_izni
şeklinde daha spesifik tanımlanabilir. Bu tanımlamalar
yetkilendirme ihtiyaçlarına göre geliştiriciler tarafından belirlenebilir.
İzinlerin gruplandırılarak kullanıcılara atanabilmesini sağlayan bileşendir. Kullanıcı ile izinler arasındaki bağlantı
kullanıcı-rol ilişkisi ile sağlanır. Yukarıda belirtilen görevi dışında diğer bir görevi ise kullanıcılar arasındaki üst
seviyeli yetki ayrımını sağlamaktır. Üst seviyeli yetki ayrımından kasıt Super Admin
, Admin
, Authorization Manager
, Student
ve Lecturer
gibi roller ile üst seviye erişim sınırlamalarını belirlemektir.
Kapsam, sistem üzerinde dinamik olarak veri erişim kısıtlanması sağlayan bileşendir. Web arayüzünde oluşturulan formlar
kullanılarak kapsamlar için sorgulama parametreleri oluşturulur. Bu parametreler QueryStore
adından bir modelde
tutulmaktadır. Oluşturulan kapsam sorgu parametreleri kullanıcılar ile ilişkilendirilerek, kullanıcıların veri
erişimleri kısıtlanır. (Bknz: Kapsam Oluşturması ve Kullanımı)
Rol ve izin bazlı yetkilendirme yönetimi için Pundit
gemi kullanılmıştır.
Sistem genelinde temel rollendirme için kullanılacak rol ve izinlerin built-in olarak oluşturulması gerekir. Dahili rol
ve izinler config/initializers/role_management.rb
dosyası üzerinden tanımlanır. Aşağıda rol ve izin tanımlama
örneğine görmektesiniz.
class RoleManagement
extend Patron::PermissionBuilder
extend Patron::RoleBuilder
# permissions
permission :foo,
name: 'Foo',
description: 'Foo için Temel İzin Açıklaması',
privileges: %i[read write destroy]
permission :foo,
name: 'Bar',
description: 'Bar için Temel İzin Açıklaması',
privileges: %i[read write]
# roles
role :authorization_manager,
name: 'Rol Adı',
permissions: {
foo: %i[read write destroy],
bar: %i[read]
}
end
permission(identifier, name:, description:, privileges:)
Parametreler:
identifier (String):
İznin tekil tanımlayıcısıname (String):
İznin yaptığı işi belirtebilecek açıklayıcı kısa addescription (String):
İzin için detaylı açıklamaprivileges (Array[Symbol]):
Desteklediği ayrıcalıklar
role(identifier, name:, permissions:)
Parametreler:
identifier (String):
Rolün tekil tanımlayıcısıname (String):
Rolün yaptığı işi belirtebilecek açıklayıcı kısa adpermissions (Hash):
Rolün sahip olduğu izinler ve bu rol için izinlere verilen ayrıcalıklar ({ izin_tanımlayıcısı: [Ayrıcalık Listesi] })
rails patron:all
rake görevini kullanarak veritabanı aktarım işlemini gerçekleştirebilirsiniz.
Unit
modeli için kapsam oluşturma örneği üzerinden anlatılacaktır.
# unit_scope.rb
# frozen_string_literal: true
class UnitScope < Patron::Scope::Base
filter :id
filter :name
filter :unit_type_id, collection: -> { UnitType.all },
multiple: true,
i18n_key: :unit_type
filter :unit_status_id, collection: -> { UnitStatus.all },
i18n_key: :unit_status
preview_attributes :name, :names_depth_cache, :code
dynamic_value :email, scope: :name do
user.email
end
dynamic_value :id_number, scope: %i[name unit_type_id] do
user.identity.first_name
end
def bypass?
user.role?(:admin)
end
end
-
app\scopes
dizini altınaunit_scope.rb
adından bir dosya oluşturulur. -
unit_scope.rb
dosyasınaUnitScope
adından vePatron::Scope::Base
sınıfından miras alan bir sınıf oluşturulur. Oluşturulan kapsam sınıfı için isimlendirmeler%<KapsamOlusturlanModelAdı>sScope
kuralı göre yapılır. -
Oluşturulan
UnitScope
sınıfınaPatron::Scope::Base
sınıfından gelenfilter
,preview_attributes
vebypass?
metodları kullanılarak gerekli tanımlamalar yapılır. -
Unit
modelinePatron::Scope::Model
modülüinclude
edilir. Bu modülün iclude edilemesi ile modelescope_for
adından bir class metod eklenmiş olur. Model için veri sınırlaması bu metod aracılığıyla yapılmaktadır.# bypass'ın varsayılan değeri kapsam sınıfına tanımlan bypass? metodundan dönen # değerdir. Bypass işlevinin dinamik olması istenen durumlarda scope_for metodu # üzerinden bypass değeri verilmemelidir. Unit.scope_for(current_user) # scope_for metodu üzerinden verilen bypass parametresinin değeri kapsam # sınıfına tanımlan bypass? metodunundan dönen değeri her zaman ezer. Unit.scope_for(current_user, bypass: true) Unit.scope_for(current_user, bypass: false)
Unit modelinde bulunan niteliklerden hangisinin kapsam sorgu üretiminde kullanılacağını belirlemek için kullanılan metoddur. Bu metodun kullanım şekli ve alabileceği parametreler aşağıdaki gibidir.
filter :attribute_name, collection: [], # opsiyonel
multiple: false, # opsiyonel
i18n_key: :key # opsiyonel
-
attribute_name: Kapsam oluşturulan modelde filtrelenecek niteliğin adı, bu nitelik sorgulanabilir olmalıdır.
-
collection: UI üzerinde filtre değeri için oluşturulan input'un
selectbox
türünde olmasını ve selectbox listesindeki değerlerin collection'a tanımlanan değerlerden oluşmasını sağlayan parametredir. Bu parametreye verilen değerProc
sınıfına ait olmalıdır. Eğercollection
tanımlanmaz ise filtre değeri için oluşturulan inputstring
türünde olacaktır. -
multiple: UI üzerinde filtre değeri için oluşturulan input'un
selectbox
olması durumunda liste üzerinden birden fazla değer seçimi yapılabilmesini sağlayan parametredir.true
veyafalse
olmak üzere iki değerden birini alır.true
olması durumundan çoklu seçim aktifleştirilmiş olur. -
i18n_key: UI üzerinde filtre ile ilgili çevirilerde kullanılacak anahtar kelimenin belirlenmesi sağlayan parametredir. Boş geçilmesi halinde
i18n_key
filtre tanımlanan nitelik adıyla aynı olur. Örnek üzerinden de belirtecek olursak filtre niteliğiunit_type_id
iken çevirilerde kullanılacak anahtar kelimeunit_type
olarak belirlenmiştir. Ek olarak filtreler için çevirileractiverecord.attributes.model
kapsamı altında aranır.
Filterelere statik ve dinamik türde iki değer atanabilir. Statik değer, kullanıcıdan kullanıcıya değişmeyen ve herhangi bir hesaplanma yapılmadan sabit olarak belirlenen değerlerdir. Dimanik değer ise, kullanıcıdan kullanıcıya değişiklik gösterebilecek, kapsam sınıfında tanımlanan ve her defasında belirlenen lojiğe göre hesaplanan değerdir.
Kapsam oluşturulurken filtrelere dinamik değer atayabilmek için kapsam sınıfı içerisine dynamic_value
tanımlamanız
ve dynamic_value
'nın scope
niteliğine dinamik değeri kullanabilecek filtreleri tanımlamanız gerekmektedir. Bir
dinamic_value sadece scope niteliği ile belirlenen filtrelere tanımlanabilir.
Not: Metod içisinde kapsamın uygulandığı kullanıcıya user
niteliğiyle
erişilir.
dynamic_value :foo, scope: %i[name] do
"foo#{user.id}"
end
dynamic_value :gorevlendirildigi_birimler, scope: %i[id] do
user.duties.ids
end
Ön izleme sırasında hangi niteliklerin görüntüleneceğinin belirlenmesini sağlayan metoddur. Eğer preview_attributes
tanımlanmamışsa, preview_attributes
olarak filtreler kullanılır.
Hangi durumlarda kapsamın bypass edileceğinin belirlendiği metoddur. Bu metod yardımıyla belirli rollere veya
koşullara sahip kullanıcılar için veri sınırlaması bypass edilebilir. Metod içisinde kapsamın uygulandığı kullanıcıya
user
niteliğiyle erişilir. Bu metodun true
veya false
bir değer döndürmesi gerekmektedir.