2014-07-09 25 views
7

Temel olarak bir kullanıcının izinleri için verileri döndüren bir kod geliştirdik. Örneğin , bir varlık aşağıdakilerden biri olabilir:Kullanıcı izinlerini depolamak için kullanılacak veri türü

-Create 
-Edit 
-Delete 
-Export 

: Kullanıcının bir eylemi gerçekleştirmek için izin

-Company 
-Contact 
-Project 
-Issue etc... 

Sonra ilkeleri atayabilir (ve bir kişinin birden çok politikaları alabilirsiniz) Temel olarak bir politika, A kullanıcısının bir şirket oluşturma hakkına sahip olduğunu, ancak aynı kullanıcının bir şirket oluşturma hakkına sahip olmadığını belirttiği bir başka politikayı söyleyebilir. Bu durumda izin verilmeyen haklardan önce izin veren hakları alırız. Bu örnekte, bir şirket oluşturmasına izin verilebilirdi.

Yani temelde şöyle veriler oluşursa:

Policy1 Company Create Yes 
Policy1 Company Edit Yes 
Policy1 Company Delete No 
Policy2 Company Create No 
Policy2 Company Edit Yes 
Policy2 Company Delete No 

Biz tartıştığımız kurallara dayalı bu kullanıcının izni ne dönmek için kullandıkları bir sorgu var.

sorguyu çalıştıran Bu durumda sonuç olacaktır:

Company create yes 
Company edit yes 
Company delete no 

Bizim app evet/hayır onlar eylemi gerçekleştirmek mi yapamaz mı için sadece biraz değil. Biz sadece evet/hayır/sahip sahibiz (yalnızca sahibi tarafından düzenlenecek/silinecek kayıtlar için. Bizim sorgumuz harika ve doğru veriyi döndürüyor.

Sorum şu C# dilinde hangi veri türünü kullanmalıyım? temelde ki:

  Create  Edit  Delete 
Company  Yes  Owner Only Yes 
Contact  No  No   No 
Project  Yes  Yes   Owner Only 

:. bir eylem (oluştur) şöyle bir matris oluşturmak istiyorsanız temelde günün sonunda değerinin ne verilen bir varlık (şirket) verilen

İlk sütundaki satırlar varlığı temsil eder, bundan sonraki sütunlar eylemleri temsil eder (oluşturma, düzenleme, silme) Örneğin 2 endeksi kombinasyonu: [Company][Create] = Yes, kuruluşa dayalı eylem hakkını size verir.

Peki, bu tür bir modele uyarlayabilmem için şu türde bir veri türü: [Contact][Edit]=No. Ayrıca, bu nesneyi oturuma/bir varlığa ve eyleme dayanarak sonuca ulaşmak için bir yolla (belki dinamik olarak) gelmeliyiz.

Oturumun iyi olacağını düşündüm, böylece kullanıcı oturumunu kapatana dek hakları bir kez ve yalnızca bir kez kontrol edebiliriz.

cevap

2

Biz ile sona erdi ... Muhtemelen en iyi çözüm değil ama işe düşünüyorum:

public class EntityPermission 
    { 
     private readonly List<GetUserPermissionsResult> _userPermissionDataSet; 
     private readonly Dictionary<int, Dictionary<int, int>> _permissions; 
     /// <summary> 
     /// Constructor to generate permissions for a user 
     /// </summary> 
     /// <param name="ds"> 
     /// Dataset of type List GetUserPermissionsResult 
     /// based on a stored procedure which brings back the 
     /// valid permissions of a user. 
     /// The result is a matrix of size [Enitities] * [Actions] 
     /// Where each entity action [index] is the value (right). 
     /// In general terms, the entity e with action a has right r. 
     /// </param> 
     public EntityPermission(List<GetUserPermissionsResult> ds) 
     { 
      _userPermissionDataSet = ds; 
      _permissions = new Dictionary<int, Dictionary<int, int>>(); 
      SetPermissions(); 
     } 

     /// <summary> 
     /// Called from the constructor of EntityPermission. 
     /// This method fills our matrix of size entity * action with 
     /// the valid rights. 
     /// </summary> 
     public void SetPermissions() 
     { 
      var dt = _userPermissionDataSet; 
      for (int i = 1; i<=Enum.GetNames(typeof(Module)).Length; i++) 
      { 
       var actionDictionary = new Dictionary<int, int>(); 
       for (int j = 1; j<=Enum.GetNames(typeof(ActionEnum)).Length; j++) 
       { 
        var value = (from a in dt where a.EntityID == i && a.ActionID == j select a.Answer).FirstOrDefault(); 
        if (value != null) 
         actionDictionary.Add(j , (int) value); 
        else actionDictionary.Add(j, (int)Answer.No); 
       } 
       _permissions.Add(i, actionDictionary); 
      } 
     } 

     /// <summary> 
     /// Method to get the rights provided an entity (a module) 
     /// and an action on that module. 
     /// </summary> 
     /// <param name="entityIdKey"></param> 
     /// <param name="actionIdKey"></param> 
     /// <returns></returns> 
     public int GetPermission(int entityIdKey, int actionIdKey) 
     { 
      return _permissions[entityIdKey][actionIdKey]; 
     } 
    } 

ReadOnly List<GetUserPermissionsResult> sorumu dayalı bir matris döndürülen bir sproc bir iade tip oldu - çok fazla detay vermeden:

GROUP BY 
    e.EntityID, 
    a.ActionID 
:

SELECT 
    e.EntityID AS EntityID, 
    a.ActionID AS ActionID, 
    CASE MAX(ar.[Rank]) 
     WHEN 3 THEN 1 --yes 
     WHEN 2 THEN 3 --originator only 
     WHEN 1 THEN 2 --no 
    END AS [Answer] 
FROM 
.... 

Bu sproc ama temelde aşağıdaki göre gruplandırılmış birleşimler bir demet vardı

Bu, bir modülde (varlık) bir eylem yapılmasını sağlar.

Biz kullanıcı oturumunun parçası olarak bu nesneyi saklanan

:

if (((int)Answer.Yes == 
       MySession.Current.Permission.GetPermission((int)Module.SubProject, (int)ActionEnum.Edit)) 
: sonuç almak için

public EntityPermission Permission { get; set; }

Sonra basitçe GetPermission çağrısı yapabilir

3

Bu son bir cevap değil, ama bunun hakkında düşündüm ve belki geri bildirim alabilirim. İşte ben buyum:

İzinleri nasıl saklayacağımı düşünüyordum ve sanırım işe yarayabilecek bir şey buldum.

Tüm bunlar boyunca düşünmeye devam ettim - tek ihtiyacım olan bir 2d matris… o zaman bariz bana vurdu, neden basit bir 2d int matrisi kullanmıyoruz? En azından kağıda çalışır.Bildiğiniz gibi
bazı Çeteleler var: bu nedenle boyutta bir matris gerek matris dayalı 54 olası girdileri üretmek için [9x6] biz 6 eylem türleri ile 9 modüllere sahip Bu durumda

Modules   Answer     Action 
Contact = 1  Yes = 1    Create = 1 
Corp = 2   No = 2     Edit = 2 
Company = 3  Originator Only = 3 Delete = 3 
Program = 4        View = 4 
Project = 5        List =5 
SubProject = 6       Export = 6 
Issue = 7  
LL = 8  
User = 9   

[ i, j]. Daha fazla modül ve daha fazla eylem eklese bile bu işe yarar.

tip

basitçe: int[,] permissions = new int[9,6]

Şimdiye kadar bu bize boş bir matris olarak matrisi verir: int[,] permissions = new int[Enum.GetNames(typeof(Modules)).Length, Enum.GetNames(typeof(Action)).Length];

basitçe çevirir. C# 'da diziler/matrislerin sıfır temelli olduğunu hatırlamalıyız. Zaten bu yüzden gibi verileri döndüren bir saklı yordam var:

for(int i=0; i<Enum.GetNames(typeof(Modules)).Length; i++) { 
    Reader.read(); //read the first row from the database 
    For(int j=0; j<Enum.GetNames(typeof(Action)).Length; j++) { 
     Permissions[i,j] = reader[“Answer”]; //assign the answer from the returned row to the array 
     If(j<Enum.GetNames(typeof(Action)).Length-1) { 
      Reader.read(); //read next row in database 
     } //end if condition 
    } //end for j 
} //end for i 

Bu döngü basitçe üretecek: Biz şu var diziyi doldurmak için Şimdi

Module  Action   Answer 
1 (Contact) 1 (Create)  1 (Yes) 
1 (Contact) 2 (Edit)  1 (Yes) 
1 (Contact) 3 (Delete)  2 (No) 
…..  
2 (Corp)  1 (Create)  1 (Yes) 
2 (Corp)  2 (Edit)  1 (Yes) 
Etc…etc… 

, bu sadece C# sözde kodu Bunun sonucu:

   1 Create 2 Edit 3 Delete 4 View 5 List 6 Export 
1(Contact)  1   1  2   1 1   1 
2(Corp)  1   3  2   1 1   1 
3(Company)  1   1  1   1 1   1 
4(Program)  1   1  1   1 1   1 
5(Project)  1   1  2   1 1   1 
6(SubProject) 1   1  2   1 1   1 
7(Issues)  1   1  1   2 1   1 
8(LL)   1   1  1   1 1   1 
9(User)  2   2  2   1 2   2 

Bu kullanıcı başına olurdu ... Ve ben (bu sadece pseduo hatırlıyorum) bu kod dağılımları benzer yazmak istiyorum çünkü bu benim istediğim tam olarak ne:

If(MySession.Current.Permission[(int)Module.Contact – 1, (int)Action.Create] == (int)Answer.Yes) 
{ 
    //this allows contact create 
} 

Bu, herhangi bir şeyi etkilemeden yeni modül ekleyebileceğimiz için çok esnektir. Sadece Permission[Module.ModuleIWant – 1, Action.ActionIWant – 1] ile ilgili şeyleri referans gösterebilirim.

Dizilim sıfır temelli olduğundan sadece 1 tane aldığımızdan emin oluyoruz… Başka bir şeye ihtiyacımız yok.

İlgili konular