public DocumentValidatorTests() { var testSchema = new Schema() { new Property { Name = "wrongType", Type = typeof(string) }, new Property { Name = "required", Type = typeof(string), Options = new ValidationOptions(required: true) }, new Property { Name = "unique", Type = typeof(string), Options = new ValidationOptions(unique: true) }, new Property { Name = "pattern", Type = typeof(string), Options = new ValidationOptions(pattern: "test") }, new Property { Name = "patternNotString", Type = typeof(int), Options = new ValidationOptions(pattern: "test") } }; var mongoDatabaseMock = new Mocks.MongoDatabase("DATABASENAME"); var collection = new Collection("COLLECTIONNAME", mongoDatabaseMock); DocumentValidator = new DocumentValidator(testSchema, collection); }
private async Task ExecuteAsync(HttpContext context, ISchema schema) { string body; using (var streamReader = new StreamReader(context.Request.Body)) { body = await streamReader.ReadToEndAsync().ConfigureAwait(true); } var request = JsonConvert.DeserializeObject <GraphQLQuery>(body); var result = await _executer.ExecuteAsync(_ => { _.Schema = schema; _.Query = request.Query; _.OperationName = request.OperationName; _.Inputs = request.Variables.ToInputs(); _.UserContext = _options.BuildUserContext?.Invoke(context); _.ExposeExceptions = _options.ExposeExceptions; _.ValidationRules = _options.ValidationRules.Concat(DocumentValidator.CoreRules()).ToList(); }); await WriteResponseAsync(context, result); }
private void bValidateNew_Click(object sender, RoutedEventArgs e) { DocumentValidator validator = new DocumentValidator(); validator.ValidateDocument(diagramNewVersion, tbNewDoc.Text); }
/// <summary> /// Process nodes with KDL tag. /// </summary> /// <param name="request">Incoming request</param> /// <param name="compileErrors">list of errors during compilation</param> /// <param name="kentity">project language</param> /// <param name="customVariables">output list to hold custom variables</param> /// <param name="rootUrl">root url</param> /// <param name="filePath">file path</param> /// <param name="classNameAlias">aliases used either with k-repeat or k-object</param> /// <param name="classNameAliasdepth">depth based storage of aliases</param> /// <param name="depth">depth of the node in DOM</param> /// <param name="dynamicAttribute">key-value pair of the k-tag</param> public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { var pattern = dynamicAttribute.Value; if (!string.IsNullOrWhiteSpace(pattern)) { pattern = pattern.Trim().Trim('/'); if (pattern.IndexOf("currentpagenumber.urlencode()") < 0) { pattern = pattern.Replace("currentpagenumber", "currentpagenumber.urlencode()"); } KEntity kentity = documentValidator.GetKEntityFromEntityName(documentValidator.defaultEntity); #region Validate unique id exist for detailspage if (request.PageType == Models.Project.KitsunePageType.DETAILS) { //added support for multiple kobjects, check for the last objetcts unique param var kobjects = request.KObject.Split(':')[0].Split(','); var kobjParam = kobjects[kobjects.Length - 1].ToLower(); var kidRegex = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}._kid"); var _idRegex = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}._id"); var indexRegex = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}.index"); var idRegex = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}.id"); if (!(_idRegex.IsMatch(pattern.ToLower()) || kidRegex.IsMatch(pattern.ToLower()) || indexRegex.IsMatch(pattern.ToLower()) || idRegex.IsMatch(pattern.ToLower()))) { compileErrors.Add(new CompilerError() { LineNumber = dynamicAttribute.Line, LinePosition = dynamicAttribute.LinePosition, Message = string.Format(ErrorCodeConstants.MissingUniqueIndexForDetailsPage, request.KObject.Split(':').Length > 1 ? request.KObject.Split(':')[1] : kobjParam) }); } } #endregion var viewExist = KitsuneCompiler.ValidateView(ref pattern, kentity); if (viewExist != null) { viewExist.LineNumber = dynamicAttribute.Line; viewExist.LinePosition = dynamicAttribute.LinePosition; compileErrors.Add(viewExist); } var pagination = Kitsune.Helper.Constants.PaginationRegularExpression.Match(pattern); if (pagination != null && pagination.Success) { var matches = Kitsune.Helper.Constants.FunctionParameterExpression.Match(pagination.Value); if (matches != null && matches.Groups?.Count > 0) { request.UrlPattern = string.Format("[[{0}]]/{1}-[[{2}.currentpagenumber]]", rootUrl, matches.Groups[1].Value.Substring(matches.Groups[1].Value.IndexOf('.') + 1), request.ClassName); } } else { var expressions = Helper.HtmlHelper.GetExpressionFromElement(pattern, 0); //Add urlencode if (expressions != null && expressions.Any()) { var tmp = ""; var tmpValue = ""; var groupCout = 0; foreach (var exp in expressions) { groupCout++; tmp = exp.Value.Trim('[', ']'); tmpValue = exp.Value; if (!tmp.ToLower().EndsWith(".urlencode()")) { pattern = pattern.Replace(tmpValue, exp.Value.Replace(tmp, $"{tmp}.urlencode()")); } var objects = Parser.GetObjects(tmp); if (objects != null && objects.Any()) { foreach (var custObj in objects) { if (custObj.Split('.').Length == 1) { IList <KClass> allClasses = new List <KClass>(); if (documentValidator != null && documentValidator.entities != null && documentValidator.entities.Keys.Any(x => x == custObj.Trim('[', ']').ToLower())) { allClasses = documentValidator.entities[custObj.Trim('[', ']').ToLower()].Classes; } if (!allClasses.Any(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == custObj.Trim('[', ']'))) { if (!customVariables.ContainsKey(custObj.Trim('[', ']')?.ToLower())) { customVariables.Add(custObj.Trim('[', ']')?.ToLower(), groupCout); } } } } } } } request.UrlPattern = string.Format("[[{0}]]/{1}", rootUrl, pattern); if (pattern != null && pattern.ToLower().IndexOf(@"search/") != -1) { request.PageType = Models.Project.KitsunePageType.SEARCH; } } //req.UrlPattern = pattern.Replace(kdl, req.UrlPattern); dynamicAttribute.Value = request.UrlPattern; } else if (filePath.ToLower().EndsWith(".dl")) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.NoDLTagInDLPage)); } else if (string.IsNullOrEmpty(request.UrlPattern)) { request.UrlPattern = string.Format("[[{0}]]/{1}", rootUrl, filePath.ToLower()); } }
private async Task <ExecutionResult> ExecuteAsync(HttpRequest request, ISchema schema, IScSession session, IGraphQLAuthenticationValidator _graphqlAuthenticationValidator) { string requestBodyText; using (var streamReader = new StreamReader(request.Body)) { requestBodyText = await streamReader.ReadToEndAsync().ConfigureAwait(true); } JObject o = JObject.Parse(requestBodyText); var graphqlRequest = new GraphQLRequest { Query = o["query"]?.ToString(), Variables = o["variables"]?.ToString(), Mutation = o["mutation"]?.ToString(), OperationName = o["operationName"]?.ToString() }; var result = await new DocumentExecuter().ExecuteAsync(new ExecutionOptions { Schema = schema, Query = o["query"]?.ToString(), OperationName = o["operationName"]?.ToString(), Inputs = o["variables"]?.ToString().ToInputs(), UserContext = session, ValidationRules = (new [] { _graphqlAuthenticationValidator }).Concat(DocumentValidator.CoreRules()) }).ConfigureAwait(true); return(result); }
public void ConfigureServices(IServiceCollection services) { services.AddLogging(); services.AddHealthChecks(); services.AddControllers(); services.AddEntityFrameworkSqlite() .AddDbContext <IContext, Context>(ops => ops.UseSqlite(@"Data Source=.\Data\Data.db"), ServiceLifetime.Transient); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); //grahql stuff services.AddSingleton <IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService)); services.AddSingleton <ISchema, RootSchema>(); services.AddGraphQL(o => { o.EnableMetrics = true; o.ExposeExceptions = !_env.IsProduction(); }) .AddGraphTypes(); // out of the box auth stuff services.TryAddSingleton <IAuthorizationEvaluator, AuthorizationEvaluator>(); // comment out below for diy role-based auth //services.AddTransient<IValidationRule, AuthorizationValidationRule>(); // attribute based auth services.AddScoped <IValidationRule, ProductIdValidator>(); services.AddScoped <IDocumentExecutionListener, AttributeBasedAuthDocumentListener>(); services.TryAddSingleton(s => { var authSettings = new AuthorizationSettings(); authSettings.AddPolicy("AdminPolicy", _ => _.RequireClaim("role", "Admin")); return(authSettings); }); services.AddScoped <ExecutionOptions>(s => { var ops = new ExecutionOptions { Schema = s.GetRequiredService <ISchema>(), ValidationRules = s.GetRequiredService <IEnumerable <IValidationRule> >().Concat(DocumentValidator.CoreRules()), FieldMiddleware = new FieldMiddlewareBuilder().Use <AuthorizeMiddleware>(), EnableMetrics = true, ExposeExceptions = !_env.IsProduction() }; foreach (var listener in s.GetRequiredService <IEnumerable <IDocumentExecutionListener> >()) { ops.Listeners.Add(listener); } return(ops); }); }
static FixIdTypeRule() { //initialize a static field in case anyone wants to use it without creating a list validationRules = DocumentValidator.CoreRules(); validationRules.Insert(0, new FixIdTypeRule()); }
public abstract void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator);
/// <summary> /// Process nodes with k-object tags. /// </summary> /// <param name="request">Incoming request</param> /// <param name="compileErrors">list of errors during compilation</param> /// <param name="kentity">project language</param> /// <param name="customVariables">output list to hold custom variables</param> /// <param name="rootUrl">root url</param> /// <param name="filePath">file path</param> /// <param name="classNameAlias">aliases used either with k-repeat or k-object</param> /// <param name="classNameAliasdepth">depth based storage of aliases</param> /// <param name="depth">depth of the node in DOM</param> /// <param name="dynamicAttribute">key-value pair of the k-tag</param> public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { if (Kitsune.Helper.Constants.WidgetRegulerExpression.IsMatch(dynamicAttribute.Value)) { var property = Kitsune.Helper.Constants.WidgetRegulerExpression.Match(dynamicAttribute.Value).Groups[1].Value; KClass kClassOb; if (!IsSearchableProperty(property, out kClassOb, documentValidator)) { compileErrors.Add(new CompilerError { Message = "Invalid search property", LineNumber = node.Line, LinePosition = node.LinePosition }); } request.PageType = Models.Project.KitsunePageType.SEARCH; } }
public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { Node result = LexerGenerator.Parse(dynamicAttribute.Value.Trim('[', ']')); if (result?.Token?.Value == ACTIONS.Loop) { string referenceObject = result.Children[0].Children[0].Token.Value; string iterator = result.Children[2].Children[0].Token.Value; //Fix issue with same iterator being used at same depth. if (classNameAlias.ContainsKey(iterator) && classNameAliasdepth.ContainsKey(depth) && classNameAliasdepth[depth].Contains(iterator)) { classNameAlias.Remove(iterator); string oldAliasDepth = classNameAliasdepth[depth]; classNameAliasdepth.Remove(depth); oldAliasDepth = oldAliasDepth.Replace(iterator, "").Replace(",,", ","); classNameAliasdepth.Add(depth, oldAliasDepth); } if (!classNameAlias.ContainsKey(iterator)) { classNameAlias.Add(iterator, ""); if (classNameAliasdepth.ContainsKey(depth)) { string oldAliasDepth = classNameAliasdepth[depth]; classNameAliasdepth.Remove(depth); classNameAliasdepth.Add(depth, oldAliasDepth + ',' + iterator); } else { classNameAliasdepth.Add(depth, iterator); } objectNamesToValidate.Add(new MatchNode { Value = referenceObject, Line = dynamicAttribute.Line, Column = dynamicAttribute.LinePosition }); try { if (result?.Children[4]?.Token?.Value?.ToString() == "ViewProperty" && result?.Children[4]?.Children[1]?.Token?.Value?.ToLower() == "offset") { //Added list type in condition as there might update in the offset and reference object so we have to update the meta also if (request.PageType == Models.Project.KitsunePageType.LIST || request.PageType == Models.Project.KitsunePageType.DEFAULT || request.PageType == Models.Project.KitsunePageType.DETAILS) { request.PageType = Models.Project.KitsunePageType.LIST; request.Offset = result.Children[6]?.Children[0]?.Token?.Value; request.KObject = referenceObject; } } } catch { } string[] classHierarchyList = referenceObject.Split('.'); if (classHierarchyList[0].StartsWith("kresult", System.StringComparison.InvariantCultureIgnoreCase) || classHierarchyList[0].Equals("search", System.StringComparison.InvariantCultureIgnoreCase)) { //pass } else if (classHierarchyList.Length >= 2) { KProperty kProperty = GetProperty(compileErrors, dynamicAttribute, documentValidator, referenceObject, classNameAlias); if (kProperty == null) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KRepeatVariableNotArray, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } if (iterator.Split('.').Length > 1) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KRepeatInvalidIterator, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } KEntity entity = documentValidator?.GetKEntityFromEntityName(classHierarchyList[0]) ?? documentValidator?.GetKEntityFromEntityName(documentValidator.defaultEntity); if (entity?.Classes?.Where(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == iterator.ToLower()).FirstOrDefault() != null) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.BaseClassAsKRepeatIterator, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } } } else { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KRepeatVariableAlreadyInUse, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } } else if (result?.Token?.Value == ACTIONS.InLoop) { string loopVariable = result.Children[0].Children[0].Token.Value.ToLower(); string referenceObject = result.Children[2].Children[0].Token.Value.ToLower() + $"[{GenerateVariableName(5)}]"; objectNamesToValidate.Add(new MatchNode { Value = referenceObject, Line = dynamicAttribute.Line, Column = dynamicAttribute.LinePosition }); if (classNameAlias.ContainsKey(loopVariable)) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KRepeatVariableAlreadyInUse, dynamicAttribute.Line, dynamicAttribute.LinePosition)); return; } KEntity entity = documentValidator?.GetKEntityFromEntityName(loopVariable) ?? documentValidator?.GetKEntityFromEntityName(documentValidator.defaultEntity); if (entity.Classes.Where(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == loopVariable).Any()) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.BaseClassAsKRepeatVariable, dynamicAttribute.Line, dynamicAttribute.LinePosition)); return; } classNameAlias.Add(loopVariable, referenceObject); if (classNameAliasdepth.ContainsKey(depth)) { string oldAliasDepth = classNameAliasdepth[depth]; classNameAliasdepth.Remove(depth); classNameAliasdepth.Add(depth, oldAliasDepth + ',' + loopVariable); } else { classNameAliasdepth.Add(depth, loopVariable); } } else { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.InvalidKRepeatSyntax, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } dynamicAttribute.Value = ""; }
/// <summary> /// Process nodes with k-object tags. /// </summary> /// <param name="request">Incoming request</param> /// <param name="compileErrors">list of errors during compilation</param> /// <param name="kentity">project language</param> /// <param name="customVariables">output list to hold custom variables</param> /// <param name="rootUrl">root url</param> /// <param name="filePath">file path</param> /// <param name="classNameAlias">aliases used either with k-repeat or k-object</param> /// <param name="classNameAliasdepth">depth based storage of aliases</param> /// <param name="depth">depth of the node in DOM</param> /// <param name="dynamicAttribute">key-value pair of the k-tag</param> public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { Node result = LexerGenerator.Parse(dynamicAttribute.Value.Trim('[', ']')); if (result?.Children?.Count == 3) { string referenceNames = result.Token.Value == ACTIONS.KObject ? result.Children[0].Token.Value : result.Children[0].Children[0].Token.Value.ToLower(); string referenceObject = result.Children[2].Children[0].Token.Value.ToLower(); var referenceKObjectArray = referenceNames.Split(','); KEntity kentity = documentValidator.GetKEntityFromEntityName(documentValidator.defaultEntity); var referenceObjectWithIterator = UpdateIterator(referenceObject, documentValidator); var tempRefObj = referenceObjectWithIterator.Trim(); for (int i = referenceKObjectArray.Length - 1, j = 0; i >= 0; i--, j++) { KEntity commEntity = documentValidator.GetKEntityFromEntityName(referenceKObjectArray[i]); if (commEntity != null || (kentity != null && kentity.Classes.Where(x => x.Name?.ToLower() == referenceObject?.Split('.')?[0] && x.ClassType == KClassType.BaseClass).Count() == 0)) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.BaseClassAsKObjectVariable, dynamicAttribute.Line, dynamicAttribute.LinePosition)); return; } else { if (commEntity != null) { kentity = commEntity; } if (j > 0) { tempRefObj = tempRefObj.Substring(0, tempRefObj.LastIndexOf('.')); } KProperty property = GetProperty(compileErrors, dynamicAttribute, documentValidator, tempRefObj, classNameAlias); if (property == null) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.InvalidKObjectClass, dynamicAttribute.Line, dynamicAttribute.LinePosition)); return; } else if (property.Type == PropertyType.array) { classNameAlias.Add(referenceKObjectArray[i], tempRefObj); objectNamesToValidate.Add(new MatchNode { Value = tempRefObj, Line = dynamicAttribute.Line, Column = dynamicAttribute.LinePosition }); } else { classNameAlias.Add(referenceKObjectArray[i], tempRefObj); objectNamesToValidate.Add(new MatchNode { Value = tempRefObj, Line = dynamicAttribute.Line, Column = dynamicAttribute.LinePosition }); } } } request.PageType = Models.Project.KitsunePageType.DETAILS; var searchableProperty = IsSearchableProperty(referenceObject, out KClass kobjClass, documentValidator); if (referenceObject.StartsWith("webactions.") || kobjClass != null) { request.KObject = referenceNames.Trim() + ":" + referenceObject; } else { request.KObject = referenceNames.Trim(); } } else { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.InvalidKObjectSyntax, dynamicAttribute.Line, dynamicAttribute.LinePosition)); } dynamicAttribute.Value = ""; }
static FixIdTypeRule() { validationRules = DocumentValidator.CoreRules(); validationRules.Insert(0, new FixIdTypeRule()); }
public EncodeController(ILogger <EncodeController> logger, DocumentValidator documentValidator) { _logger = logger; _documentValidator = documentValidator; }
private async Task ExecuteAsync(HttpContext context, ISchema schema) { // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/ var httpRequest = context.Request; var gqlRequest = new GraphQLRequest(); if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(GraphQLRequest.QueryKey))) { ExtractGraphQLRequestFromQueryString(httpRequest.Query, gqlRequest); } else if (HttpMethods.IsPost(httpRequest.Method)) { if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out MediaTypeHeaderValue mediaTypeHeader)) { await WriteResponseAsync(context, HttpStatusCode.BadRequest, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed."); return; } switch (mediaTypeHeader.MediaType) { case JsonContentType: gqlRequest = Deserialize <GraphQLRequest>(httpRequest.Body); break; case GraphQLContentType: gqlRequest.Query = await ReadAsStringAsync(httpRequest.Body); break; default: await WriteResponseAsync(context, HttpStatusCode.BadRequest, $"Invalid 'Content-Type' header: non-supported media type. Must be of '{JsonContentType}' or '{GraphQLContentType}'. See: http://graphql.org/learn/serving-over-http/."); return; } } object userContext = null; var userContextBuilder = context.RequestServices.GetService <IUserContextBuilder>(); if (userContextBuilder != null) { userContext = await userContextBuilder.BuildUserContext(context); } else { userContext = _options.BuildUserContext?.Invoke(context); } var result = await _executer.ExecuteAsync(x => { x.Schema = schema; x.Query = gqlRequest.Query; x.OperationName = gqlRequest.OperationName; x.Inputs = gqlRequest.Variables.ToInputs(); x.UserContext = userContext; x.EnableMetrics = true; x.ExposeExceptions = true; x.SetFieldMiddleware = true; x.ValidationRules = _options.ValidationRules.Concat(DocumentValidator.CoreRules()).ToList(); if (_executionListeners != null) { foreach (var listener in _executionListeners) { x.Listeners.Add(listener); } } }); await WriteResponseAsync(context, result); }
private async Task ExecuteAsync(HttpContext context, ISchemaFactory schemaService) { var schema = await schemaService.GetSchemaAsync(); GraphQLRequest request = null; // c.f. https://graphql.org/learn/serving-over-http/#post-request if (HttpMethods.IsPost(context.Request.Method)) { var mediaType = new MediaType(context.Request.ContentType); try { if (mediaType.IsSubsetOf(_jsonMediaType)) { using (var sr = new StreamReader(context.Request.Body)) { // Asynchronous read is mandatory. var json = await sr.ReadToEndAsync(); request = JObject.Parse(json).ToObject <GraphQLRequest>(); } } else if (mediaType.IsSubsetOf(_graphQlMediaType)) { request = new GraphQLRequest(); using (var sr = new StreamReader(context.Request.Body)) { request.Query = await sr.ReadToEndAsync(); } } else if (context.Request.Query.ContainsKey("query")) { request = new GraphQLRequest { Query = context.Request.Query["query"] }; if (context.Request.Query.ContainsKey("variables")) { request.Variables = JObject.Parse(context.Request.Query["variables"]); } if (context.Request.Query.ContainsKey("operationName")) { request.OperationName = context.Request.Query["operationName"]; } } } catch (Exception e) { await WriteErrorAsync(context, "An error occurred while processing the GraphQL query", e); return; } } else if (HttpMethods.IsGet(context.Request.Method)) { if (!context.Request.Query.ContainsKey("query")) { await WriteErrorAsync(context, "The 'query' query string parameter is missing"); return; } request = new GraphQLRequest { Query = context.Request.Query["query"] }; } var queryToExecute = request.Query; if (!String.IsNullOrEmpty(request.NamedQuery)) { var namedQueries = context.RequestServices.GetServices <INamedQueryProvider>(); var queries = namedQueries .SelectMany(dict => dict.Resolve()) .ToDictionary(pair => pair.Key, pair => pair.Value); queryToExecute = queries[request.NamedQuery]; } var dataLoaderDocumentListener = context.RequestServices.GetRequiredService <IDocumentExecutionListener>(); var result = await _executer.ExecuteAsync(_ => { _.Schema = schema; _.Query = queryToExecute; _.OperationName = request.OperationName; _.Inputs = request.Variables.ToInputs(); _.UserContext = _settings.BuildUserContext?.Invoke(context); _.ExposeExceptions = _settings.ExposeExceptions; _.ValidationRules = DocumentValidator.CoreRules() .Concat(context.RequestServices.GetServices <IValidationRule>()); _.ComplexityConfiguration = new ComplexityConfiguration { MaxDepth = _settings.MaxDepth, MaxComplexity = _settings.MaxComplexity, FieldImpact = _settings.FieldImpact }; _.Listeners.Add(dataLoaderDocumentListener); }); context.Response.StatusCode = (int)(result.Errors == null || result.Errors.Count == 0 ? HttpStatusCode.OK : result.Errors.Any(x => x.Code == RequiresPermissionValidationRule.ErrorCode) ? HttpStatusCode.Unauthorized : HttpStatusCode.BadRequest); context.Response.ContentType = "application/json"; // Asynchronous write to the response body is mandatory. var encodedBytes = _utf8Encoding.GetBytes(JObject.FromObject(result).ToString()); await context.Response.Body.WriteAsync(encodedBytes, 0, encodedBytes.Length); }
internal KProperty GetProperty(List <CompilerError> compileErrors, HtmlAttribute dynamicAttribute, DocumentValidator documentValidator, string referenceObject, Dictionary <string, string> classNameAlias) { KProperty kProperty = null; KClass kClass = null; string expression = referenceObject; string baseExpression = expression.Split('.')[0].Split('[')[0].ToLower(); while (baseExpression != "kresult" && baseExpression != "search" && classNameAlias.ContainsKey(baseExpression)) { string[] expressionParts = expression.Split('.'); expressionParts[0] = classNameAlias[baseExpression]; expression = String.Join(".", expressionParts); baseExpression = expression.Split('.')[0].Split('[')[0].ToLower(); } string[] classHierarchyList = expression.Split('.'); KEntity entity = documentValidator?.GetKEntityFromEntityName(classHierarchyList[0]) ?? documentValidator?.GetKEntityFromEntityName(documentValidator.defaultEntity); if (entity != null) { kClass = entity.Classes.Where(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == classHierarchyList[0].ToLower()).FirstOrDefault(); if (kClass == null) { compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedType, classHierarchyList[0]), dynamicAttribute.Line, dynamicAttribute.LinePosition)); return(null); } for (int i = 1; i < classHierarchyList.Length - 1; i++) { string propName = classHierarchyList[i].Split('[')[0]; KProperty prop = kClass.PropertyList.Where(x => x.Name.ToLower() == propName.ToLower()).FirstOrDefault(); if (prop == null) { compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedProperty, propName), dynamicAttribute.Line, dynamicAttribute.LinePosition)); return(null); } kClass = entity.Classes.Where(x => x.Name.ToLower() == prop.DataType.Name.ToLower()).FirstOrDefault(); if (kClass == null) { compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedType, prop.DataType.Name), dynamicAttribute.Line, dynamicAttribute.LinePosition)); return(null); } } string finalPropName = classHierarchyList[classHierarchyList.Length - 1].Split('[')[0].ToLower(); kProperty = kClass.PropertyList.Where(x => x.Name == finalPropName && x.Type == PropertyType.array).FirstOrDefault(); } return(kProperty); }
public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (context.WebSockets.IsWebSocketRequest || !context.Request.Path.StartsWithSegments(_path)) { await next(context); return; } // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/ var httpRequest = context.Request; var gqlRequest = new GraphQLRequest(); var documentWriter = new DocumentWriter(Formatting.Indented, _schema.GetJsonSerializerSettings()); if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(GraphQLRequest.QueryKey))) { ExtractGraphQLRequestFromQueryString(httpRequest.Query, gqlRequest); } else if (HttpMethods.IsPost(httpRequest.Method)) { if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader)) { await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed."); return; } switch (mediaTypeHeader.MediaType) { case JsonContentType: gqlRequest = Deserialize <GraphQLRequest>(httpRequest.Body); break; case GraphQLContentType: gqlRequest.Query = await ReadAsStringAsync(httpRequest.Body); break; case FormUrlEncodedContentType: var formCollection = await httpRequest.ReadFormAsync(); ExtractGraphQLRequestFromPostBody(formCollection, gqlRequest); break; default: await WriteBadRequestResponseAsync(context, documentWriter, $"Invalid 'Content-Type' header: non-supported media type. Must be of '{JsonContentType}', '{GraphQLContentType}', or '{FormUrlEncodedContentType}'. See: http://graphql.org/learn/serving-over-http/."); return; } } var executer = new DocumentExecuter(); var result = await executer.ExecuteAsync(x => { x.Schema = _schema; x.OperationName = gqlRequest.OperationName; x.Query = gqlRequest.Query; x.Inputs = gqlRequest.GetInputs(); x.UserContext = _userContextBuilder.BuildContext(); x.ValidationRules = new[] { new AuthenticationValidationRule() }.Concat(DocumentValidator.CoreRules()); x.CancellationToken = context.RequestAborted; x.ComplexityConfiguration = _complexityConfigurationFactory.GetComplexityConfiguration(); }); if (result.Errors != null) { _logger.LogError("GraphQL execution error(s): {Errors}", result.Errors); } await WriteResponseAsync(context, documentWriter, result); }
internal static bool IsSearchableProperty(string propertyPath, out KClass kClass, DocumentValidator documentValidator) { kClass = null; var objectPathArray = propertyPath.ToLower().Split('.'); if (objectPathArray.Length > 1 && documentValidator != null && documentValidator.entities != null && documentValidator.entities.Count > 0) { var obClass = new KClass(); var obProperty = new KProperty(); IList <KClass> allClasses = null; if (documentValidator.entities.Keys.Any(x => x == objectPathArray[0].ToLower())) { allClasses = documentValidator.entities[objectPathArray[0].ToLower()].Classes; } else if (documentValidator.entities.First().Value.Classes.Any(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == objectPathArray[0].ToLower())) { allClasses = documentValidator.entities.First().Value.Classes; } if (allClasses != null && allClasses.Any()) { var dataTypeClasses = Kitsune.Helper.Constants.DataTypeClasses; for (var i = 0; i < objectPathArray.Length; i++) { if (i == 0) { obClass = allClasses.FirstOrDefault(x => x.ClassType == KClassType.BaseClass && x.Name == objectPathArray[i]); if (obClass == null) { return(false); } } else { obProperty = obClass.PropertyList.FirstOrDefault(x => x.Name.ToLower() == objectPathArray[i]); if (obProperty == null) { return(false); } else if ((obProperty.Type == PropertyType.array && !dataTypeClasses.Contains(obProperty.DataType?.Name?.ToLower())) || obProperty.Type == PropertyType.obj) { obClass = allClasses.FirstOrDefault(x => x.ClassType == KClassType.UserDefinedClass && x.Name?.ToLower() == obProperty.DataType?.Name?.ToLower()); } else { return(false); } } } if (obClass != null) { kClass = obClass; if (obProperty != null && obProperty.Type == PropertyType.array) { return(true); } } } } return(false); }
public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { List <string> objects = Parser.GetObjects(dynamicAttribute.Value); foreach (string obj in objects) { objectNamesToValidate.Add(new MatchNode { Value = obj.Replace("[[", "").Replace("]]", "").ToLower(), Line = dynamicAttribute.Line, Column = dynamicAttribute.LinePosition }); } dynamicAttribute.Value = ""; }
public void TestValidationOnRandomFiles(string filename) { Console.WriteLine("Testing file {0}.", filename); //string filename = "Attributes\\Attributes5.XCase"; XmlDeserializatorVersions deserializator = new XmlDeserializatorVersions(); VersionManager versionManager = deserializator.RestoreVersionedProject(TEST_BASE_DIR + filename); Assert.IsTrue(versionManager != null && versionManager.VersionedProjects.Count == 2 && versionManager.Versions.Count == 2); Version oldVersion = versionManager.Versions[0]; Version newVersion = versionManager.Versions[1]; PSMDiagram diagramNewVersion = versionManager.VersionedProjects[newVersion].PSMDiagrams[0]; PSMDiagram diagramOldVersion = versionManager.VersionedProjects[oldVersion].PSMDiagrams[0]; ChangesDetector detector = new ChangesDetector(); List <EvolutionChange> evolutionChanges = detector.Translate(diagramOldVersion, diagramNewVersion); XsltTemplateGenerator xsltGenerator = new XsltTemplateGenerator(diagramNewVersion); string xsltTransformation = xsltGenerator.Generate(evolutionChanges, oldVersion, newVersion); SampleDataGenerator g = new SampleDataGenerator(); DocumentValidator validator = new DocumentValidator { SilentMode = true }; string outputFileDir = TEST_BASE_DIR + Path.GetDirectoryName(filename) + "\\" + Path.GetFileNameWithoutExtension(filename) + "-error"; int fails = 0; for (int i = 0; i < RANDOM_FILE_COUNT; i++) { string input = g.Translate(diagramOldVersion); if (!validator.ValidateDocument(diagramOldVersion, input)) { if (!Directory.Exists(outputFileDir)) { Directory.CreateDirectory(outputFileDir); } File.WriteAllText(string.Format("{0}\\i{1}.xml", outputFileDir, i), input); Console.WriteLine("Input document INVALID: " + validator.ErrorMessage); fails++; continue; } string result = XsltProcessing.Transform(input, xsltTransformation, TEST_BASE_DIR); if (!validator.ValidateDocument(diagramNewVersion, result)) { if (!Directory.Exists(outputFileDir)) { Directory.CreateDirectory(outputFileDir); } File.WriteAllText(string.Format("{0}\\i{1}.xml", outputFileDir, i), input); File.WriteAllText(string.Format("{0}\\o{1}.xml", outputFileDir, i), result); Console.WriteLine("Result document INVALID: " + validator.ErrorMessage); fails++; continue; } Console.WriteLine("Test passed on file {0}/{1}", i, RANDOM_FILE_COUNT); } Console.WriteLine("Altogether tested on {0} random files. ", RANDOM_FILE_COUNT); if (fails != 0) { Console.WriteLine("{0} out of {1} files failed to pass. ", fails, RANDOM_FILE_COUNT); Assert.Fail("{0} out of {1} files failed to pass. ", fails, RANDOM_FILE_COUNT); } else { Console.WriteLine("All {0} files passed. ", RANDOM_FILE_COUNT); } }
public void TestByCompare(string filename) { //string filename = "Attributes\\Attributes5.XCase"; XmlDeserializatorVersions deserializator = new XmlDeserializatorVersions(); VersionManager versionManager = deserializator.RestoreVersionedProject(TEST_BASE_DIR + filename); Assert.IsTrue(versionManager != null && versionManager.VersionedProjects.Count == 2 && versionManager.Versions.Count == 2); Version oldVersion = versionManager.Versions[0]; Version newVersion = versionManager.Versions[1]; PSMDiagram diagramNewVersion = versionManager.VersionedProjects[newVersion].PSMDiagrams[0]; PSMDiagram diagramOldVersion = versionManager.VersionedProjects[oldVersion].PSMDiagrams[0]; ChangesDetector detector = new ChangesDetector(); List <EvolutionChange> evolutionChanges = detector.Translate(diagramOldVersion, diagramNewVersion); XsltTemplateGenerator xsltGenerator = new XsltTemplateGenerator(diagramNewVersion); string xsltTransformation = xsltGenerator.Generate(evolutionChanges, oldVersion, newVersion); string inputFileDir = TEST_BASE_DIR + Path.GetDirectoryName(filename) + "\\" + Path.GetFileNameWithoutExtension(filename) + "-in"; string outputFileDir = TEST_BASE_DIR + Path.GetDirectoryName(filename) + "\\" + Path.GetFileNameWithoutExtension(filename) + "-out"; if (!Directory.Exists(inputFileDir)) { Console.WriteLine("No input files. "); Assert.Inconclusive(string.Format("Input file directory does not exist : {0}", inputFileDir)); } if (!Directory.Exists(outputFileDir)) { Console.WriteLine("No reference files. "); Assert.Inconclusive(string.Format("Output file directory does not exist: {0}", outputFileDir)); } DirectoryInfo dir = new DirectoryInfo(inputFileDir); FileInfo[] files = dir.GetFiles("*.xml"); bool fail = false; int failedFiles = 0; foreach (FileInfo fileInfo in files) { Console.WriteLine(string.Format("File: {0}", fileInfo.Name)); string input = File.ReadAllText(fileInfo.FullName); string result = XsltProcessing.Transform(input, xsltTransformation, TEST_BASE_DIR); File.WriteAllText(outputFileDir + "//" + fileInfo, result); DocumentValidator validator = new DocumentValidator { SilentMode = true }; bool inputInvalid = false; bool resultInvalid = false; bool compareFail = false; if (!validator.ValidateDocument(diagramOldVersion, input)) { inputInvalid = true; } if (!validator.ValidateDocument(diagramNewVersion, result)) { Console.WriteLine("Result document INVALID: " + validator.ErrorMessage); resultInvalid = true; } string referenceFile = outputFileDir + "//" + Path.GetFileNameWithoutExtension(fileInfo.Name) + "-reference.xml"; Assert.IsTrue(File.Exists(referenceFile), "Reference output file does not exist for: " + fileInfo.Name); string referenceOutput = File.ReadAllText(referenceFile); File.WriteAllText(outputFileDir + "//" + "last-stylesheet.xslt", xsltTransformation); if ((!inputInvalid && !resultInvalid) && result != referenceOutput) { Console.WriteLine("Output and REFERENCE output DIFFERS for: " + fileInfo.Name); compareFail = true; Console.WriteLine("Input file: "); Console.WriteLine(input); Console.WriteLine("Result file: "); Console.WriteLine(result); Console.WriteLine("Reference file: "); Console.WriteLine(referenceOutput); } else if (!inputInvalid && !resultInvalid && result == referenceOutput) { Console.WriteLine("Comparison succeeded."); File.WriteAllText(outputFileDir + "//" + "last-working-stylesheet.xslt", xsltTransformation); } if (inputInvalid) { Console.WriteLine("Input document INVALID: " + validator.ErrorMessage); Console.WriteLine("Input file: "); Console.WriteLine(input); fail = true; failedFiles++; } if (resultInvalid) { Console.WriteLine("Result document INVALID: " + validator.ErrorMessage); Console.WriteLine("Result file: "); Console.WriteLine(result); fail = true; failedFiles++; } if (compareFail) { Console.WriteLine("Result of {0} DIFFERS from expected result.", fileInfo.Name); fail = true; failedFiles++; } } if (files.Length == 0) { Console.WriteLine("No input files. "); Assert.Inconclusive("No input files. "); } if (fail) { Console.WriteLine("{0} out of {1} files FAILED. ", failedFiles, files.Length); Assert.Fail("{0} out of {1} files FAILED. ", failedFiles, files.Length); } Console.WriteLine("Altogether tested on {0} files.", files.Length); }
/// <summary> /// Process nodes with k-script tags. /// </summary> /// <param name="request">Incoming request</param> /// <param name="compileErrors">list of errors during compilation</param> /// <param name="kentity">project language</param> /// <param name="customVariables">output list to hold custom variables</param> /// <param name="rootUrl">root url</param> /// <param name="filePath">file path</param> /// <param name="classNameAlias">aliases used either with k-repeat or k-object</param> /// <param name="classNameAliasdepth">depth based storage of aliases</param> /// <param name="depth">depth of the node in DOM</param> /// <param name="dynamicAttribute">key-value pair of the k-tag</param> public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator) { Regex urlPattern = new Regex("http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?", RegexOptions.IgnoreCase); string getApiURL = node.Attributes["get-api"]?.Value; string postApiURL = node.Attributes["post-api"]?.Value; if (getApiURL == null && postApiURL == null) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KScriptNoApi, node.Line, node.LinePosition)); } else if (getApiURL != null && postApiURL != null) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KScriptMultipleApi, node.Line, node.LinePosition)); } else if (getApiURL != null && !urlPattern.IsMatch(getApiURL)) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KScriptGetApiNoURL, node.Line, node.LinePosition)); } else if (postApiURL != null && !urlPattern.IsMatch(postApiURL)) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KScriptPostApiNoURL, node.Line, node.LinePosition)); } else if (classNameAlias.ContainsKey("kresult")) { compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.KScriptNested, node.Line, node.LinePosition)); } else { classNameAlias.Add("kresult", "-1"); if (classNameAliasdepth.ContainsKey(depth)) { string oldAliasDepth = classNameAliasdepth[depth]; classNameAliasdepth.Remove(depth); classNameAliasdepth.Add(depth, classNameAliasdepth[depth] + ",kresult"); } else { classNameAliasdepth.Add(depth, "kresult"); } } }
public void CompatibilityRuleAttributesValidationTest() { var validator = new DocumentValidator(new ValidationCache(FileFormatVersions.Office2007)); var element = new Paragraph(); var run = new Run(); element.AppendChild(run); var result = validator.Validate(element); Assert.Empty(result); element.AddNamespaceDeclaration("o15", "http://o15.com"); result = validator.Validate(element); Assert.Empty(result); run.MCAttributes = new MarkupCompatibilityAttributes(); run.MCAttributes.Ignorable = "o15"; result = validator.Validate(element); Assert.Empty(result); run.AddNamespaceDeclaration("w15", "http://w15.com"); result = validator.Validate(element); Assert.Empty(result); run.MCAttributes.Ignorable = "o15 w15"; result = validator.Validate(element); Assert.Empty(result); run.MCAttributes.PreserveAttributes = " o15:id w15:*"; run.MCAttributes.PreserveElements = "o15:* w15:* "; run.MCAttributes.ProcessContent = " o15:newE w15:newW "; result = validator.Validate(element); Assert.Empty(result); run.MCAttributes.PreserveElements = "x15:* "; result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidPreserveElementsAttribute", result[0].Id); run.MCAttributes.Ignorable = null; run.MCAttributes.PreserveAttributes = null; run.MCAttributes.PreserveElements = "w15:*"; run.MCAttributes.ProcessContent = string.Empty; result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidPreserveElementsAttribute", result[0].Id); run.MCAttributes.Ignorable = "o15"; run.MCAttributes.PreserveAttributes = string.Empty; run.MCAttributes.PreserveElements = "w15:*"; result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidPreserveElementsAttribute", result[0].Id); run.MCAttributes.PreserveElements = null; run.MCAttributes.ProcessContent = "w14:newW"; result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidProcessContentAttribute", result[0].Id); run.MCAttributes.ProcessContent = null; var spaceAttribute = new OpenXmlAttribute("xml:space", "http://www.w3.org/XML/1998/namespace", "preserve"); run.MCAttributes.ProcessContent = "o15:newP"; run.SetAttribute(spaceAttribute); result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidXmlAttributeWithProcessContent", result[0].Id); run.MCAttributes.ProcessContent = null; run.SetAttribute(new OpenXmlAttribute("o15:id", "http://o15.com", "1")); result = validator.Validate(element); Assert.Empty(result); run.MCAttributes.Ignorable = "o15 w15 x15"; result = validator.Validate(element); Assert.Single(result); Assert.Equal(ValidationErrorType.MarkupCompatibility, result[0].ErrorType); Assert.Equal("MC_InvalidIgnorableAttribute", result[0].Id); run.MCAttributes.Ignorable = "o15 w15"; run.SetAttribute(new OpenXmlAttribute("x15:id", "http://x15.com", "1")); result = validator.Validate(element); Assert.Single(result); }
public async Task <IActionResult> PostGraphQL([FromBody] GraphQLQuery graphQuery) { if (graphQuery == null) { return(BadRequest("No Query")); } var inputs = graphQuery.Variables.ToInputs(); if (inputs.ContainsKey("participantId")) { var user = await _userManager.GetUserAsync(User); var participant = await _db.Participants .FirstOrDefaultAsync(p => p.IdentityUser.Id == user.Id); if (participant == null) { return(BadRequest("Not a valid participant")); } inputs["participantId"] = participant.ParticipantId.ToString(); } if (inputs.ContainsKey("teamId")) { var user = await _userManager.GetUserAsync(User); var participant = await _db.Participants .FirstOrDefaultAsync(p => p.IdentityUser.Id == user.Id); if (participant == null) { return(BadRequest("Not a valid participant")); } inputs["teamId"] = participant.TeamId.ToString(); } var context = _httpContextAccessor.HttpContext; var graphQlUserContext = new GraphQLUserContext { User = context.User }; var result = await new DocumentExecuter().ExecuteAsync(_ => { _.Schema = _schema; _.Query = graphQuery.Query; _.OperationName = graphQuery.OperationName; _.Inputs = inputs; _.UserContext = graphQlUserContext; _.ValidationRules = DocumentValidator.CoreRules().Concat(new IValidationRule[] { new AuthorizationValidationRule(_authorizationEvaluator) }); }).ConfigureAwait(false); if (result.Errors?.Count > 0) { var msg = ""; foreach (var err in result.Errors) { msg = msg + " " + err.Message; } return(BadRequest(result.Errors.Select(e => e.Message))); } return(Ok(result.Data)); }
public void AcbSyntaxValidationTest() { var validator = new DocumentValidator(new ValidationCache(FileFormatVersions.Office2007)); var element = new Run(); var acFallback = new AlternateContentFallback(); var ac = element.AppendChild(new AlternateContent()); var errors = validator.Validate(ac); // Error case: must have one choice, can not have AlternateContent as ID Assert.Single(errors); Assert.Equal("Sch_IncompleteContentExpectingComplex", errors[0].Id); ac.AddNamespaceDeclaration("o15", "http://o15.com"); // ac.NamespaceDeclarations ac.AppendChild(new AlternateContentChoice() { Requires = "o15" }); errors = validator.Validate(ac); Assert.Empty(errors); ac.AddNamespaceDeclaration("o14", "http://o14.com"); ac.PrependChild(new AlternateContentChoice() { Requires = "o14" }); errors = validator.Validate(ac); Assert.Empty(errors); ac.AppendChild(acFallback); errors = validator.Validate(ac); Assert.Empty(errors); // Error case: should not contains AlternateContent directly as child. ac.AppendChild(new AlternateContent()); errors = validator.Validate(ac); Assert.Single(errors); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("Sch_InvalidElementContentExpectingComplex", errors[0].Id); ac.RemoveChild(ac.LastChild); // Error case: can only contains one Fallback. ac.AppendChild(new AlternateContentFallback()); errors = validator.Validate(ac); Assert.Single(errors); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("Sch_InvalidElementContentExpectingComplex", errors[0].Id); ac.RemoveChild(ac.LastChild); ac.RemoveChild(acFallback); // Error case: wrong sequence ac.PrependChild(acFallback); errors = validator.Validate(ac); Assert.Single(errors); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("Sch_IncompleteContentExpectingComplex", errors[0].Id); ac.RemoveChild(acFallback); ac.Append(acFallback); var langAttribute = new OpenXmlAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace", "en-us"); ac.SetAttribute(langAttribute); errors = validator.Validate(ac); Assert.Single(errors); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("MC_InvalidXmlAttribute", errors[0].Id); Assert.Equal("The AlternateContent element should not have an xml:lang or xml:space attribute.", errors[0].Description); ac.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri); ac.FirstChild.SetAttribute(langAttribute); errors = validator.Validate(ac); Assert.Single(errors); Assert.Same(ac.FirstChild, errors[0].Node); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("MC_InvalidXmlAttribute", errors[0].Id); Assert.Equal("The Choice element should not have an xml:lang or xml:space attribute.", errors[0].Description); ac.FirstChild.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri); ac.LastChild.SetAttribute(langAttribute); errors = validator.Validate(ac); Assert.Single(errors); Assert.Same(ac.LastChild, errors[0].Node); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Equal("MC_InvalidXmlAttribute", errors[0].Id); Assert.Equal("The Fallback element should not have an xml:lang or xml:space attribute.", errors[0].Description); ac.LastChild.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri); AlternateContentChoice choice1 = ac.FirstChild as AlternateContentChoice; choice1.Requires = "o17 o15"; errors = validator.Validate(ac); Assert.Single(errors); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Same(choice1, errors[0].Node); Assert.Equal("MC_InvalidRequiresAttribute", errors[0].Id); Assert.Equal("The Requires attribute is invalid - The value 'o17 o15' contains an invalid prefix that is not defined.", errors[0].Description); choice1.Requires = null; errors = validator.Validate(ac); Assert.Equal(ValidationErrorType.MarkupCompatibility, errors[0].ErrorType); Assert.Single(errors); Assert.Same(choice1, errors[0].Node); Assert.Equal("MC_MissedRequiresAttribute", errors[0].Id); Assert.Equal("All Choice elements must have a Requires attribute whose value contains a whitespace delimited list of namespace prefixes.", errors[0].Description); }
public async Task InvokeAsync(HttpContext context, ISchema schema) { if (!context.Request.Path.StartsWithSegments(_settings.Path)) { await _next(context); return; } // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/ var httpRequest = context.Request; var request = new Request(); if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(Request.QueryKey))) { ExtractGraphQLRequestFromQueryString(httpRequest.Query, request); } else if (HttpMethods.IsPost(httpRequest.Method)) { if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader)) { await WriteBadRequestResponseAsync(context, _writer, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed."); return; } switch (mediaTypeHeader.MediaType) { case "application/json": request = Deserialize <Request>(httpRequest.Body); break; case "application/graphql": request.Query = await ReadAsStringAsync(httpRequest.Body); break; case "application/x-www-form-urlencoded": var formCollection = await httpRequest.ReadFormAsync(); ExtractGraphQLRequestFromPostBody(formCollection, request); break; default: await WriteBadRequestResponseAsync(context, _writer, "Invalid 'Content-Type' header: non-supported media type. See: http://graphql.org/learn/serving-over-http/."); return; } } else { await WriteBadRequestResponseAsync(context, _writer, $"Invalid request method: value '{httpRequest.Method}' could not be handled. See: http://graphql.org/learn/serving-over-http/."); } var start = DateTime.UtcNow; var result = await _executer.ExecuteAsync(_ => { _.Schema = schema; _.Query = request?.Query; _.OperationName = request?.OperationName; _.Inputs = request?.Variables.ToInputs(); _.UserContext = new UserContext { User = context.User }; _.FieldMiddleware.Use <InstrumentFieldsMiddleware>(); _.ValidationRules = DocumentValidator.CoreRules().Concat(_rules); _.EnableMetrics = _settings.EnableMetrics; _.ExposeExceptions = _settings.ExposeExceptions; }); if (_settings.EnableMetrics && result.Errors == null) { result.EnrichWithApolloTracing(start); } if (result.Errors != null) { _logger.LogError("GraphQL execution error(s): {Errors}", result.Errors); } await WriteResponseAsync(context, result); }
public DocumentValidatorTests() { validator = new DocumentValidator(); }