2014-07-09 8 views
7

हमने कोड विकसित किया है जो मूल रूप से किसी इकाई पर उपयोगकर्ता की अनुमतियों के लिए डेटा देता है। उदाहरण के लिए, एक इकाई निम्न में से एक हो सकता है:उपयोगकर्ता अनुमतियों को संग्रहीत करने के लिए उपयोग करने के लिए डेटाटाइप

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

हम तो नीतियों असाइन कर सकते हैं (और एक व्यक्ति एक से अधिक नीतियों प्राप्त कर सकते हैं) है कि एक उपयोगकर्ता कोई कार्रवाई करने के लिए अनुमति देते हैं:

-Create 
-Edit 
-Delete 
-Export 

तो मूल रूप से एक नीति कह सकती है कि उपयोगकर्ता ए को कंपनी बनाने का अधिकार है, लेकिन एक और नीति जो इस उपयोगकर्ता ने कहा है कि उसे कंपनी बनाने का अधिकार नहीं है। इस मामले में हम ऐसे अधिकार लेते हैं जो उन अधिकारों से पहले अनुमति देते हैं जो अनुमति नहीं देते हैं। इस उदाहरण में, उसे एक कंपनी बनाने की अनुमति होगी।

तो बुनियादी तौर पर आप तो जैसे डेटा के साथ अंत:

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

मैं एक प्रश्न जो हम नियमों हम चर्चा के आधार पर इस उपयोगकर्ता की अनुमति है क्या वापस जाने के लिए उपयोग किया है।

इस मामले क्वेरी चलाने में परिणाम होगा:

Company create yes 
Company edit yes 
Company delete no 

हमारे एप्लिकेशन सिर्फ एक बिट हाँ/नहीं है कि क्या के लिए वे कार्रवाई या नहीं प्रदर्शन कर सकते हैं नहीं है। हमारे पास केवल हां/नहीं/मालिक है (रिकॉर्ड के लिए जिन्हें केवल स्वामी द्वारा ही संपादित/हटाया जाना चाहिए। हमारी क्वेरी बहुत अच्छी है और सही डेटा लौटा रही है।

मेरा प्रश्न यह है कि मैं सी # में किस डेटा प्रकार का उपयोग करना चाहिए मूल रूप से कहते हैं:

एक इकाई (कंपनी) को देखते हुए एक कार्रवाई (बनाने) मूल्य है क्या मूल रूप से दिन के अंत में मैं एक मैट्रिक्स है कि इस तरह दिखता है का निर्माण करना चाहते दिया:।

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

पहले कॉलम पर पंक्तियां इकाई का प्रतिनिधित्व करती हैं, उसके बाद कॉलम क्रियाओं का प्रतिनिधित्व करते हैं (बनाएं, संपादित करें, हटाएं)। उदाहरण के लिए 2 का संयोजन सूचकांक: [Company][Create] = Yes आपको इकाई के आधार पर कार्रवाई का अधिकार देगा।

तो क्या डेटाटाइप इस मॉडल को फिट करता है जहां मैं कुछ इंडेक्स कर सकता हूं जैसे: [Contact][Edit]=No। हमें किसी ऑब्जेक्ट और एक्शन के आधार पर परिणाम प्राप्त करने के लिए इस ऑब्जेक्ट को सत्र करना होगा (शायद गतिशील रूप से)।

मैंने सोचा कि सत्र अच्छा होगा ताकि उपयोगकर्ता एक बार और केवल एक बार उपयोगकर्ता लॉग आउट होने तक जांच कर सकें।

उत्तर

2

हम साथ समाप्त हो गया:

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]; 
     } 
    } 

केवल पढ़ने के लिए List<GetUserPermissionsResult> एक sproc कि मेरे सवाल के आधार पर एक मैट्रिक्स से लौटाए गए एक लौटे प्रकार था - भी कई जानकारी के बिना:

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 
.... 

यह sproc की मिलती है लेकिन मूल रूप से निम्नलिखित के आधार पर वर्गीकृत एक गुच्छा था

यह सुनिश्चित करता है कि हमें एक मॉड्यूल (इकाई) प्रति कार्यवाही मिलती है।

हम उपयोगकर्ता के सत्र के हिस्से के रूप में इस वस्तु संग्रहीत:

public EntityPermission Permission { get; set; }

और फिर हम बस GetPermission को कॉल कर सकते हैं परिणाम प्राप्त करने के:

if (((int)Answer.Yes == 
       MySession.Current.Permission.GetPermission((int)Module.SubProject, (int)ActionEnum.Edit)) 
3

यह अंतिम जवाब नहीं है, लेकिन मैंने इसके बारे में सोचा और शायद मुझे कुछ प्रतिक्रिया मिल सकती है। यहां मैं ये आया हूं:

मैं अनुमतियों को संग्रहीत करने के बारे में सोच रहा था और मुझे विश्वास है कि मैं कुछ ऐसा कर रहा हूं जो बस काम कर सकता है।

मैंने यह सब सोच लिया है - मुझे बस एक 2 डी मैट्रिक्स चाहिए ... तो मुझे स्पष्ट मारा, हम बस एक साधारण 2 डी इंट मैट्रिक्स का उपयोग क्यों नहीं करते? यह कम से कम कागज पर काम करता है।
कि आप जानते हैं कि हम कुछ enums है:

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   

इस मामले में हम 6 कार्य प्रकारों के साथ 9 मॉड्यूल है, इसलिए हम आकार के एक मैट्रिक्स की जरूरत है मैट्रिक्स के आधार पर 54 संभव प्रविष्टियों उत्पन्न करने के लिए [9x6] [ i, j]। यह तब भी काम करेगा जब हमने अधिक मॉड्यूल और अधिक क्रियाएं जोड़ दी हों।

प्रकार बस है: int[,] permissions = new int[Enum.GetNames(typeof(Modules)).Length, Enum.GetNames(typeof(Action)).Length];

बस वास्तविक रूप है: int[,] permissions = new int[9,6]

अभी तक यह हमें एक खाली मैट्रिक्स के रूप में मैट्रिक्स देता है। हमें याद रखना होगा कि सी # में सरणी/मैट्रिस शून्य आधारित हैं ... जो ठीक है। हम पहले से ही एक संग्रहीत प्रक्रिया है कि इतनी तरह डेटा देता है:

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 

इस पाश बस का उत्पादन करेगा:

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… 
तो अब

सरणी हम निम्नलिखित है भरने के लिए, यह सिर्फ सी # छद्म कोड है इसी का परिणाम:

   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 

यह प्रति उपयोगकर्ता होगा ... और यह है मैं वास्तव में क्या चाहते हैं, क्योंकि मैं (याद यह सिर्फ pseduo है) यह करने के लिए कोड समान लिखना चाहते हैं:

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

यह बहुत लचीला है क्योंकि हम किसी भी चीज़ को प्रभावित किए बिना संभावित रूप से कोई भी नया मॉड्यूल जोड़ सकते हैं। मैं बस Permission[Module.ModuleIWant – 1, Action.ActionIWant – 1] द्वारा चीजों का संदर्भ दे सकता हूं।

हम बस सुनिश्चित करते हैं कि हम शून्य से आधारित होने के बाद से 1 दूर ले लें ... हमें किसी और चीज की आवश्यकता नहीं है। यह शायद सबसे अच्छा समाधान नहीं है, लेकिन मुझे लगता है कि यह काम कर सकते हैं ...

संबंधित मुद्दे

 संबंधित मुद्दे