CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
AuthorizationRuleManager.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="AuthorizationRuleManager.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Manages the list of authorization </summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.Linq;
11using System.Text;
12using System.Reflection;
13using Csla.Reflection;
14
15namespace Csla.Rules
16{
22 {
23 private static Lazy<System.Collections.Concurrent.ConcurrentDictionary<RuleSetKey, AuthorizationRuleManager>> _perTypeRules =
24 new Lazy<System.Collections.Concurrent.ConcurrentDictionary<RuleSetKey, AuthorizationRuleManager>>();
25
26 internal static AuthorizationRuleManager GetRulesForType(Type type, string ruleSet)
27 {
28 type = ApplicationContext.DataPortalActivator.ResolveType(type);
29
30 if (ruleSet == ApplicationContext.DefaultRuleSet)
31 ruleSet = null;
32
33 var key = new RuleSetKey { Type = type, RuleSet = ruleSet };
34 var result = _perTypeRules.Value.GetOrAdd(key, (t) => { return new AuthorizationRuleManager(); });
35 InitializePerTypeRules(result, type);
36 return result;
37 }
38
39 private bool InitializingPerType { get; set; }
40
41 private static void InitializePerTypeRules(AuthorizationRuleManager mgr, Type type)
42 {
43 if (!mgr.InitializedPerType)
44 lock (mgr)
45 if (!mgr.InitializedPerType && !mgr.InitializingPerType)
46 {
47 // Only call AddObjectAuthorizationRules when there are no rules for this type
48 if (RulesExistForType(type))
49 {
50 mgr.InitializedPerType = true;
51 return;
52 }
53
54 try
55 {
56 mgr.InitializingPerType = true;
57
58 // invoke method to add auth roles
59 System.Reflection.MethodInfo method = FindObjectAuthorizationRulesMethod(type);
60 if (method != null)
61 method.Invoke(null, null);
62 mgr.InitializedPerType = true;
63 }
64 catch (Exception)
65 {
66 // remove all loaded rules for this type
67 CleanupRulesForType(type);
68 throw; // and rethrow the exception
69 }
70 finally
71 {
72 mgr.InitializingPerType = false;
73 }
74 }
75 }
76
77 private static System.Reflection.MethodInfo FindObjectAuthorizationRulesMethod(Type type)
78 {
79 System.Reflection.MethodInfo method;
80 method = type.GetMethods().Where(
81 m => m.IsStatic && m.CustomAttributes.Where(
82 a => a.AttributeType == typeof(ObjectAuthorizationRulesAttribute)).Any()).
83 FirstOrDefault();
84 if (method == null)
85 {
86 const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
87 method = type.GetMethod("AddObjectAuthorizationRules", flags);
88 }
89 return method;
90 }
91
92 private static bool RulesExistForType(Type type)
93 {
94 lock (_perTypeRules)
95 {
96 // the first RuleSet is already added to list when this check is executed so so if count > 1 then we have already initialized type rules.
97 return _perTypeRules.Value.Count(value => value.Key.Type == type) > 1;
98 }
99
100 }
101
102 private static void CleanupRulesForType(Type type)
103 {
104 lock (_perTypeRules)
105 {
106
107 // the first RuleSet is already added to list when this check is executed so so if count > 1 then we have already initialized type rules.
108 var typeRules = _perTypeRules.Value.Where(value => value.Key.Type == type);
109 foreach (var key in typeRules)
110 {
112 _perTypeRules.Value.TryRemove(key.Key, out manager);
113 }
114 }
115 }
116
117 private class RuleSetKey
118 {
119 public Type Type { get; set; }
120 public string RuleSet { get; set; }
121
122 public override bool Equals(object obj)
123 {
124 var other = obj as RuleSetKey;
125 if (other == null)
126 return false;
127 else
128 return this.Type.Equals(other.Type) && RuleSet == other.RuleSet;
129 }
130
131 public override int GetHashCode()
132 {
133 return (this.Type.FullName + RuleSet).GetHashCode();
134 }
135 }
136
140 public List<IAuthorizationRule> Rules { get; private set; }
141
146 public bool Initialized { get; internal set; }
151 public bool InitializedPerType { get; internal set; }
152
154 {
155 Rules = new List<IAuthorizationRule>();
156 }
157 }
158}
Attribute identifying static method invoked to add object authorization rules for type.
Manages the list of authorization rules for a business type.
bool Initialized
Gets or sets a value indicating whether the rules have been initialized.
bool InitializedPerType
Gets or sets a value indicating whether the rules have been initialized.
List< IAuthorizationRule > Rules
Gets the list of rule objects for the business type.
@ Any
Default value, rule can run in any context