This repository has been archived by the owner on Dec 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
/
Extensions.cs
255 lines (233 loc) · 8.47 KB
/
Extensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Routing;
using FluentSecurity.Caching;
using FluentSecurity.Internals;
using FluentSecurity.Policy;
namespace FluentSecurity
{
public static class Extensions
{
/// <summary>
/// Gets a policycontainer matching the specified controller and actioname
/// </summary>
/// <param name="policyContainers">Policycontainers</param>
/// <param name="controllerName">The controllername</param>
/// <param name="actionName">The actionname</param>
/// <returns>A policycontainer</returns>
public static IPolicyContainer GetContainerFor(this IEnumerable<IPolicyContainer> policyContainers, string controllerName, string actionName)
{
return policyContainers.SingleOrDefault(x => x.ControllerName.ToLowerInvariant() == controllerName.ToLowerInvariant() && x.ActionName.ToLowerInvariant() == actionName.ToLowerInvariant());
}
///<summary>
/// Gets the controller name for the specified controller type
///</summary>
public static string GetControllerName(this Type controllerType)
{
return controllerType.FullName;
}
///<summary>
/// Gets the action name for the specified action expression
///</summary>
public static string GetActionName(this LambdaExpression actionExpression)
{
var expression = (MethodCallExpression)(actionExpression.Body is UnaryExpression ? ((UnaryExpression)actionExpression.Body).Operand : actionExpression.Body);
return expression.Method.GetActionName();
}
/// <summary>
/// Gets action name for the specified action method considering ActionName attribute
/// </summary>
public static String GetActionName(this MethodInfo actionMethod)
{
if (Attribute.IsDefined(actionMethod, ActionNameAttributeType))
{
var actionNameAttribute = (ActionNameAttribute) Attribute.GetCustomAttribute(actionMethod, ActionNameAttributeType);
return actionNameAttribute.Name;
}
return actionMethod.Name;
}
private static readonly Type ActionNameAttributeType = typeof(ActionNameAttribute);
/// <summary>
/// Gets the actual type of the ISecurityPolicy. Takes care of checking for lazy policies.
/// </summary>
public static Type GetPolicyType(this ISecurityPolicy securityPolicy)
{
var lazySecurityPolicy = securityPolicy as ILazySecurityPolicy;
return lazySecurityPolicy != null
? lazySecurityPolicy.PolicyType
: securityPolicy.GetType();
}
/// <summary>
/// Gets actionmethods for the specified controller type
/// </summary>
internal static IEnumerable<MethodInfo> GetActionMethods(this Type controllerType, Func<ControllerActionInfo, bool> actionFilter = null)
{
if (actionFilter == null) actionFilter = info => true;
return controllerType
.GetMethods(
BindingFlags.Public |
BindingFlags.Instance
)
.Where(IsValidActionMethod)
.Where(action => actionFilter.Invoke(new ControllerActionInfo(controllerType, action)))
.ToList();
}
internal static bool IsValidActionMethod(this MethodInfo methodInfo)
{
return methodInfo.ReturnType.IsControllerActionReturnType() &&
!methodInfo.IsSpecialName && !methodInfo.IsDeclaredBy<Controller>();
}
/// <summary>
/// Returns true if the passed method is declared by the type T.
/// </summary>
/// <param name="methodInfo"></param>
/// <returns></returns>
//(Chandu) The method below is to simulate the way System.Web.Mvc.ActionMethodSelector.IsValidActionMethod identifies methods of a controller as valid actions
internal static bool IsDeclaredBy<T>(this MethodInfo methodInfo)
{
var passedType = typeof (T);
var declaringType = methodInfo.GetBaseDefinition().DeclaringType;
return declaringType != null && declaringType.IsAssignableFrom(passedType);
}
/// <summary>
/// Returns true if the type matches a controller action return type.
/// </summary>
/// <param name="returnType"></param>
/// <returns></returns>
internal static bool IsControllerActionReturnType(this Type returnType)
{
return
(
typeof (ActionResult).IsAssignableFrom(returnType) ||
typeof (Task<ActionResult>).IsAssignableFromGenericType(returnType) ||
typeof(void).IsAssignableFrom(returnType)
);
}
/// <summary>
/// Gets the area name of the route
/// </summary>
/// <param name="routeData">Route data</param>
/// <returns>The name of the are</returns>
internal static string GetAreaName(this RouteData routeData)
{
object value;
if (routeData.DataTokens.TryGetValue("area", out value))
{
return (value as string);
}
return GetAreaName(routeData.Route);
}
/// <summary>
/// Gets the area name of the route
/// </summary>
/// <param name="route">Route</param>
/// <returns>The name of the are</returns>
internal static string GetAreaName(this RouteBase route)
{
var areRoute = route as IRouteWithArea;
if (areRoute != null)
{
return areRoute.Area;
}
var standardRoute = route as Route;
if ((standardRoute != null) && (standardRoute.DataTokens != null))
{
return (standardRoute.DataTokens["area"] as string) ?? string.Empty;
}
return string.Empty;
}
/// <summary>
/// Ensures we are working with the actual policy. Takes care of loading lazy policies.
/// </summary>
internal static ISecurityPolicy EnsureNonLazyPolicy(this ISecurityPolicy securityPolicy)
{
var lazySecurityPolicy = securityPolicy as ILazySecurityPolicy;
return lazySecurityPolicy != null
? lazySecurityPolicy.Load()
: securityPolicy;
}
/// <summary>
/// Ensures we are working with the expected policy type. Takes care of loading and casting lazy policies.
/// </summary>
internal static TSecurityPolicy EnsureNonLazyPolicyOf<TSecurityPolicy>(this ISecurityPolicy securityPolicy) where TSecurityPolicy : class, ISecurityPolicy
{
return securityPolicy.EnsureNonLazyPolicy() as TSecurityPolicy;
}
/// <summary>
/// Returns true if the policy is of the expected type. Takes care of checking for lazy policies.
/// </summary>
/// <param name="securityPolicy">The policy</param>
/// <returns>A boolean</returns>
internal static bool IsPolicyOf<TSecurityPolicy>(this ISecurityPolicy securityPolicy) where TSecurityPolicy : class, ISecurityPolicy
{
var isMatch = securityPolicy is TSecurityPolicy;
if (!isMatch) isMatch = securityPolicy.GetPolicyType() == typeof (TSecurityPolicy);
return isMatch;
}
/// <summary>
/// Returns true if the policy implements ICacheKeyProvider
/// </summary>
/// <param name="securityPolicy">The policy</param>
/// <returns>A boolean</returns>
internal static bool IsCacheKeyProvider(this ISecurityPolicy securityPolicy)
{
return typeof (ICacheKeyProvider).IsAssignableFrom(securityPolicy.GetPolicyType());
}
/// <summary>
/// Performs an action on each item
/// </summary>
internal static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
action(item);
}
/// <summary>
/// Ensures we are working with a list of T
/// </summary>
internal static IList<T> EnsureIsList<T>(this IEnumerable<T> items)
{
return items == null
? new List<T>()
: (items as IList<T> ?? items.ToList());
}
/// <summary>
/// Returns true if the value is null or empty
/// </summary>
/// <param name="value">The value</param>
/// <returns>A boolean</returns>
internal static bool IsNullOrEmpty(this string value)
{
return String.IsNullOrEmpty(value);
}
/// <summary>
/// Returns a formatted string
/// </summary>
/// <param name="format">The format</param>
/// <param name="values">The values</param>
/// <returns>A formatted string</returns>
internal static string FormatWith(this string format, params object[] values)
{
return string.Format(format, values);
}
/// <summary>
/// Converts policies to a text
/// </summary>
/// <param name="policies">The policies</param>
/// <returns>A string of policies</returns>
internal static string ToText(this IEnumerable<ISecurityPolicy> policies)
{
var builder = new StringBuilder();
foreach (var policy in policies)
{
builder.AppendFormat("\r\n\t{0}", policy);
}
return builder.ToString();
}
}
}