Пример #1
0
        public INodeVisitor Validate(ValidationContext context)
        {
            var userContext = context.UserContext.As <GraphQLUserContext>();
            var user        = userContext.HttpContextAccessor.HttpContext.User;


            var authenticated                  = user?.Identity.IsAuthenticated ?? false;
            var myEnterLeaveListenerSink       = new MyEnterLeaveListenerSink();
            var currentEnterLeaveListenerState = (ICurrentEnterLeaveListenerState)myEnterLeaveListenerSink;
            var myEnterLeaveListener           = new MyEnterLeaveListener(_ =>
            {
                _.Match <Operation>(op =>
                {
                    var opType = op.OperationType;
                    var query  = from item in op.SelectionSet.Selections
                                 select((GraphQL.Language.AST.Field)item).Name;
                });

                _.Match <Field>(fieldAst =>
                {
                    var currentPath = currentEnterLeaveListenerState.EnterLeaveListenerState.CurrentFieldPath;
                    var fieldDef    = context.TypeInfo.GetFieldDef();
                    var lastType    = context.TypeInfo.GetLastType() as IGraphType;
                    var parentType  = context.TypeInfo.GetParentType();
                    var name        = fieldAst.Name;
                });

                /*
                 * // this could leak info about hidden fields in error messages
                 * // it would be better to implement a filter on the schema so it
                 * // acts as if they just don't exist vs. an auth denied error
                 * // - filtering the schema is not currently supported
                 * _.Match<Field>(fieldAst =>
                 * {
                 *  var fieldDef = context.TypeInfo.GetFieldDef();
                 *  if (fieldDef.RequiresPermissions() &&
                 *      (!authenticated || !fieldDef.CanAccess(userContext.User.Claims)))
                 *  {
                 *      context.ReportError(new ValidationError(
                 *          context.OriginalQuery,
                 *          "auth-required",
                 *          $"You are not authorized to run this query.",
                 *          fieldAst));
                 *  }
                 * });
                 */
            });

            myEnterLeaveListener.RegisterEventSink(myEnterLeaveListenerSink);
            return(myEnterLeaveListener);
        }
Пример #2
0
        public INodeVisitor Validate(ValidationContext context)
        {
            var userContext = context.UserContext.As <GraphQLUserContext>();
            var user        = userContext.HttpContextAccessor.HttpContext.User;

            IEnumerable <string> claimsEnumerable = (from item in user.Claims
                                                     let c = item.Type
                                                             select c).ToList();
//            IEnumerable<string> claimsEnumerable = query.ToList();
            var authenticated                  = user?.Identity.IsAuthenticated ?? false;
            var myEnterLeaveListenerSink       = new MyEnterLeaveListenerSink();
            var currentEnterLeaveListenerState = (ICurrentEnterLeaveListenerState)myEnterLeaveListenerSink;
            var myEnterLeaveListener           = new MyEnterLeaveListener(_ =>
            {
                _.Match <Operation>(op =>
                {
                    if (!authenticated)
                    {
                        var usages = context.GetRecursiveVariables(op).Select(usage => usage.Node.Name);

                        var selectionSet = op.SelectionSet;
                        foreach (var selection in selectionSet.Selections)
                        {
                            var d  = selection;
                            var dd = selection.ToString();
                        }

                        /*
                         * var queryQ = from item in selectionSet.Selections
                         *  where _settings.Value.Query.OptOut.Contains(item.)
                         *  select item;
                         */
                    }
                    var opType = op.OperationType;
                    var query  = from item in op.SelectionSet.Selections
                                 select((GraphQL.Language.AST.Field)item).Name;
                    if (op.OperationType == OperationType.Mutation && !authenticated)
                    {
                        context.ReportError(new ValidationError(
                                                context.OriginalQuery,
                                                "auth-required",
                                                $"Authorization is required to access {op.Name}.",
                                                op));
                    }
                });

                _.Match <Field>(fieldAst =>
                {
                    var currentFieldPath     = currentEnterLeaveListenerState.EnterLeaveListenerState.CurrentFieldPath;
                    var currentOperationType = currentEnterLeaveListenerState.EnterLeaveListenerState.OperationType;
                    var requiredClaims       = _graphQLFieldAuthority
                                               .FetchRequiredClaimsAsync(currentOperationType, currentFieldPath).Result;
                    var canAccess = true;
                    if (requiredClaims != null)
                    {
                        var rcQuery = (from requiredClaim in requiredClaims
                                       let c = requiredClaim.Type
                                               select c).ToList();
                        canAccess = requiredClaims.All(x =>
                        {
                            var result = false;
                            foreach (var ce in user.Claims)
                            {
                                if (ce.Type == x.Type)
                                {
                                    if (string.IsNullOrEmpty(x.Value))
                                    {
                                        result = true;
                                    }
                                    else
                                    {
                                        result = x.Value == ce.Value;
                                    }
                                }
                            }
                            return(result);
                        });
                    }


                    //  var canAccess = rcQuery.All(x => claimsEnumerable?.Contains(x) ?? false);
                    if (!canAccess)
                    {
                        context.ReportError(new ValidationError(
                                                context.OriginalQuery,
                                                "auth-required",
                                                $"You are not authorized to run this query.",
                                                fieldAst));
                    }
                });

                /*
                 * // this could leak info about hidden fields in error messages
                 * // it would be better to implement a filter on the schema so it
                 * // acts as if they just don't exist vs. an auth denied error
                 * // - filtering the schema is not currently supported
                 * _.Match<Field>(fieldAst =>
                 * {
                 *  var fieldDef = context.TypeInfo.GetFieldDef();
                 *  if (fieldDef.RequiresPermissions() &&
                 *      (!authenticated || !fieldDef.CanAccess(userContext.User.Claims)))
                 *  {
                 *      context.ReportError(new ValidationError(
                 *          context.OriginalQuery,
                 *          "auth-required",
                 *          $"You are not authorized to run this query.",
                 *          fieldAst));
                 *  }
                 * });
                 */
            });

            myEnterLeaveListener.RegisterEventSink(myEnterLeaveListenerSink);
            return(myEnterLeaveListener);
        }
        public INodeVisitor Validate(ValidationContext context)
        {
            var myEnterLeaveListenerSink       = new MyEnterLeaveListenerSink();
            var currentEnterLeaveListenerState = (ICurrentEnterLeaveListenerState)myEnterLeaveListenerSink;
            var myEnterLeaveListener           = new MyEnterLeaveListener(_ =>
            {
                _.Match <Operation>(op =>
                {
                    var opType = op.OperationType;
                    var query  = from item in op.SelectionSet.Selections
                                 select((GraphQL.Language.AST.Field)item).Name;
                    if (op.OperationType == OperationType.Mutation)
                    {
                        context.ReportError(new ValidationError(
                                                context.OriginalQuery,
                                                "auth-required",
                                                $"Authorization is required to access {op.Name}.",
                                                op));
                    }
                });

                _.Match <Field>(fieldAst =>
                {
                    var currentFieldPath     = currentEnterLeaveListenerState.EnterLeaveListenerState.CurrentFieldPath;
                    var currentOperationType = currentEnterLeaveListenerState.EnterLeaveListenerState.OperationType;
                    var requiredClaims       = _graphQLFieldAuthority
                                               .FetchRequiredClaimsAsync(currentOperationType, currentFieldPath).Result;
                    var canAccess = true;



                    //  var canAccess = rcQuery.All(x => claimsEnumerable?.Contains(x) ?? false);
                    if (!canAccess)
                    {
                        context.ReportError(new ValidationError(
                                                context.OriginalQuery,
                                                "auth-required",
                                                $"You are not authorized to run this query.",
                                                fieldAst));
                    }
                });

                /*
                 * // this could leak info about hidden fields in error messages
                 * // it would be better to implement a filter on the schema so it
                 * // acts as if they just don't exist vs. an auth denied error
                 * // - filtering the schema is not currently supported
                 * _.Match<Field>(fieldAst =>
                 * {
                 *  var fieldDef = context.TypeInfo.GetFieldDef();
                 *  if (fieldDef.RequiresPermissions() &&
                 *      (!authenticated || !fieldDef.CanAccess(userContext.User.Claims)))
                 *  {
                 *      context.ReportError(new ValidationError(
                 *          context.OriginalQuery,
                 *          "auth-required",
                 *          $"You are not authorized to run this query.",
                 *          fieldAst));
                 *  }
                 * });
                 */
            });

            myEnterLeaveListener.RegisterEventSink(myEnterLeaveListenerSink);
            return(myEnterLeaveListener);
        }