public string GetRouteSourceExpression() { var possibleVerbs = Enum .GetValues(typeof(WebServiceVerbs)) .OfType <WebServiceVerbs>() .Except(new[] { WebServiceVerbs.All, WebServiceVerbs.None }) .Select(x => x.ToString().ToUpper()) .ToArray(); var verbs = possibleVerbs .Where(x => AllowedVerbs.HasFlag((WebServiceVerbs)Enum.Parse(typeof(WebServiceVerbs), x, true))) .ToArray(); var verbString = verbs.Length == 1 ? verbs[0] : $"[ {string.Join(" | ", verbs)} ]"; if (AllowedVerbs == WebServiceVerbs.All) { verbString = "*"; } if (verbs.Length > possibleVerbs.Length / 2) { var deniedVerbs = possibleVerbs.Except(verbs).ToArray(); verbString = $"~[ {string.Join(" | ", deniedVerbs)} ]"; } return($"{verbString} /{Route?.Replace("{", "<").Replace("}", ">")}"); }
// Default constructor that accepts a condition for applicability // of this configuration public Configuration(Func <RequestContext, HandlerData, IPrincipal, bool> condition) { // Set defaults for all configuration settings Condition = condition; DeniedRoles = new List <string>(); RequiredRoles = new List <string>(); IsDenyAnonymousAccess = false; CustomRules = new List <Func <RequestContext, HandlerData, IPrincipal, bool> >(); AllowedVerbs = AllowedVerbs.GET | AllowedVerbs.POST | AllowedVerbs.PUT | AllowedVerbs.DELETE; }
public OnlyAttribute(AllowedVerbs verbs) => _verbs = verbs;
// Test // ---- // // Performs all applicable tests on the current handler request public static bool Test(RequestContext context, HandlerData data) { ICollection <Configuration> configs; bool hasConfigs = _config.TryGetValue(data.Type, out configs); bool hasApplicableConfig = false; bool configFailed = false; // If configurations exist for this handler if (hasConfigs) { // Grab some useful request information (verb and principal) AllowedVerbs verb = (AllowedVerbs)Enum.Parse( typeof(AllowedVerbs), context.HttpContext.Request.RequestType); IPrincipal principal = context.HttpContext.User; // iterate over each configuration for this handler and test // each sequentially foreach (Configuration config in configs) { // Test to see of this configuration is applicable at this // time if (config.Condition(context, data, principal)) { // Mark cycle as having an applicable configuration hasApplicableConfig = true; // Check if the verb is allowed bool acceptableVerb = (verb & config.AllowedVerbs) != 0; if (acceptableVerb) { // If the user is authenticated if (IsAuthenticated(context)) { // Configuration must pass 3 tests, // // 1. Ensure that all Required Roles (if any) are satisifed // 2. Ensure that all Denied Roles (if any) are not present // 3. Ensure that all custom rules (if any) are satisifed configFailed = config.RequiredRoles.Any(role => !IsInRole(role, context)) || config.DeniedRoles.Any(role => IsInRole(role, context)) || config.CustomRules.Any(rule => !rule(context, data, principal)); } // If the user is anonymous and we allow anonymous access else if (!config.IsDenyAnonymousAccess) { // Ensure that all custom rules (if any) are satisifed configFailed = config.CustomRules.Any(rule => !rule(context, data, principal)); } else { // If we have gotten this far then the config // has failed due to anonymous access being denied configFailed = true; } } else { // if we have gotten this far then the config has // failed due to an unaaceptable verb configFailed = true; } // if the config has failed the test we short circuit // and return immediatley if (configFailed) { break; } } } } // We can return true if, // // - there or no configs for the handler // - if there are no APPLICABLE configs for the handler, or, // - if all request-applicable configs have passed for this handler return(!hasConfigs || !hasApplicableConfig || (hasApplicableConfig && !configFailed)); }
// AllowVerbs // ---------- // // Allows developer to specify the HTTP verbs that can be used // against this handler public Configuration AllowVerbs(AllowedVerbs verbs) { AllowedVerbs = verbs; return(this); }