public Task <IHttpResponse> ValidateRequest( KeyValuePair <ParameterInfo, object>[] parameterSelection, MethodInfo method, IApplication httpApp, IHttpRequest request, ValidateHttpDelegate boundCallback) { Func <string, bool> roleInterigator = request.Properties.TryGetValueNullSafe(Token.PropertyName, out object tokenObj) ? (roll) => ((Token)tokenObj).IsAuthorizedForRoll(roll) : (roll) => request.IsAuthorizedForRole(roll); return(ProcessClaimsAsync(roleInterigator)); Task <IHttpResponse> ProcessClaimsAsync(Func <string, bool> doesContainRole) { return(RolesDenied .NullToEmpty() .Where(rollAllowed => doesContainRole(rollAllowed)) .First( (rollDenied, next) => { return DenyAsync("denies", rollDenied); }, () => { if (!RolesAllowed.Any()) { return boundCallback(parameterSelection, method, httpApp, request); } return RolesAllowed .Where(rollAllowed => doesContainRole(rollAllowed)) .First( (rollAllowed, next) => boundCallback(parameterSelection, method, httpApp, request), () => DenyAsync("requires one of", RolesAllowed.Join(','))); })); } Task <IHttpResponse> DenyAsync(string action, string equals) { return(request .CreateResponse(System.Net.HttpStatusCode.Unauthorized) .AddReason($"{method.DeclaringType.FullName}..{method.Name} {action} role claim ({ClaimTypes.Role}) = `{equals}`") .AsTask()); } }
public Task <IHttpResponse> ValidateRequest( KeyValuePair <ParameterInfo, object>[] parameterSelection, MethodInfo method, IApplication httpApp, IHttpRequest request, ValidateHttpDelegate boundCallback) { if (!request.IsAuthorizedForRole(ClaimValue)) { return(request .CreateResponse(System.Net.HttpStatusCode.Unauthorized) .AddReason($"{method.DeclaringType.FullName}..{method.Name} requires roll claim `{ClaimValue}`") .AsTask()); } return(boundCallback(parameterSelection, method, httpApp, request)); }
protected virtual async Task <IHttpResponse> InvokeMethod( IEnumerable <MethodInfo> matchingActionMethods, string[] componentsMatched, IApplication httpApp, IHttpRequest routeData, CastDelegate bodyCastDelegate, string[] bodyValues) { var evaluatedMethods = matchingActionMethods .Select( method => { var routeMatcher = method.GetAttributesInterface <IMatchRoute>().Single(); return(routeMatcher.IsRouteMatch(method, componentsMatched, this, routeData, httpApp, bodyValues, bodyCastDelegate)); }); var validMethods = evaluatedMethods .Where(methodCast => methodCast.isValid); return(await validMethods .First( (methodCast, next) => { return methodCast.parametersWithValues .Aggregate <SelectParameterResult, ValidateHttpDelegate>( (parameterSelectionUnvalidated, methodFinalUnvalidated, httpAppFinalUnvalidated, requestFinalUnvalidated) => { return methodFinalUnvalidated .GetAttributesInterface <IValidateHttpRequest>(true, true) .Aggregate <IValidateHttpRequest, ValidateHttpDelegate>( (parameterSelection, methodFinal, httpAppFinal, routeDataFinal) => { return InvokeValidatedMethodAsync( httpAppFinal, routeDataFinal, methodFinal, parameterSelection); }, (callback, validator) => { return (parametersSelected, methodCurrent, httpAppCurrent, requestCurrent) => { return validator.ValidateRequest(parametersSelected, methodCurrent, httpAppCurrent, requestCurrent, callback); }; }) .Invoke( parameterSelectionUnvalidated, methodFinalUnvalidated, httpAppFinalUnvalidated, requestFinalUnvalidated); }, (callback, parameterSelection) => { ValidateHttpDelegate boundCallback = (parametersSelected, methodCurrent, httpAppCurrent, requestCurrent) => { var paramKvp = parameterSelection.parameterInfo .PairWithValue(parameterSelection.value); var updatedParameters = parametersSelected .Append(paramKvp) .ToArray(); return callback(updatedParameters, methodCurrent, httpAppCurrent, requestCurrent); }; var validators = parameterSelection.parameterInfo.ParameterType .GetAttributesInterface <IValidateHttpRequest>(true, true); if (!validators.Any()) { return boundCallback; } var validator = validators.First(); return (parametersSelected, methodCurrent, httpAppCurrent, requestCurrent) => { return validator.ValidateRequest(parametersSelected, methodCurrent, httpAppCurrent, requestCurrent, boundCallback); }; }) .Invoke( new KeyValuePair <ParameterInfo, object>[] { }, methodCast.method, httpApp, routeData); }, () => { return Issues(evaluatedMethods).AsTask(); })); IHttpResponse Issues(IEnumerable <RouteMatch> methodsCasts) { var reasonStrings = methodsCasts .Select( methodCast => { var errorMessage = methodCast.ErrorMessage; return(errorMessage); }) .ToArray(); if (!reasonStrings.Any()) { return(routeData .CreateResponse(System.Net.HttpStatusCode.NotImplemented) .AddReason("No methods that implement Action")); } var content = reasonStrings.Join(";"); return(routeData .CreateResponse(System.Net.HttpStatusCode.NotImplemented) .AddReason(content)); } }