private static Schema CreateSchema()
        {
            var eventManager = new InMemoryEventRegistry();

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton <CharacterRepository>();
            serviceCollection.AddSingleton <IEventSender>(eventManager);
            serviceCollection.AddSingleton <IEventRegistry>(eventManager);
            serviceCollection.AddDataLoaderRegistry();
            serviceCollection.AddSingleton <Query>();
            serviceCollection.AddSingleton <Mutation>();
            serviceCollection.AddSingleton <Subscription>();

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            services.GetRequiredService <IDataLoaderRegistry>()
            .Register <HumanDataLoader>();

            return(Schema.Create(c =>
            {
                c.RegisterServiceProvider(services);

                c.RegisterQueryType <QueryType>();
                c.RegisterMutationType <MutationType>();
                c.RegisterSubscriptionType <SubscriptionType>();

                c.RegisterType <HumanType>();
                c.RegisterType <DroidType>();
                c.RegisterType <EpisodeType>();
            }));
        }
Exemple #2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton <Query>();

            // Add in-memory event provider
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // Add GraphQL Services
            services.AddGraphQL(sp => Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);

                // Adds the authorize directive and
                // enables the authorization middleware.
                c.RegisterAuthorizeDirectiveType();

                c.RegisterQueryType <QueryType>();

                c.RegisterType <SettingsType>();
            }));

            // Add Authorization Policies
            // services.AddAuthorization(options =>
            // {
            //   options.AddPolicy("HasCountry", policy =>
            //             policy.RequireAssertion(context =>
            //                 context.User.HasClaim(c =>
            //                     (c.Type == ClaimTypes.Country))));
            // });
        }
        public async Task Subscribe_ObjectValueArgument_Send_MessageReceived()
        {
            // arrange
            var eventRegistry = new InMemoryEventRegistry();

            var a = new EventDescription("event",
                                         new ArgumentNode("foo", new ObjectValueNode(
                                                              new ObjectFieldNode("a", 123),
                                                              new ObjectFieldNode("b", true),
                                                              new ObjectFieldNode("c", "abc"))));

            var b = new EventDescription("event",
                                         new ArgumentNode("foo", new ObjectValueNode(
                                                              new ObjectFieldNode("b", true),
                                                              new ObjectFieldNode("a", 123),
                                                              new ObjectFieldNode("c", "abc"))));

            // act
            IEventStream stream =
                await eventRegistry.SubscribeAsync(a);

            // assert
            var incoming = new EventMessage(b, "foo");
            await eventRegistry.SendAsync(incoming);

            IEventMessage outgoing = await stream.ReadAsync();

            Assert.Equal(incoming, outgoing);
        }
        public async Task Subscribe_ObjectValueArgument_Send_MessageReceived()
        {
            // arrange
            using var cts = new CancellationTokenSource(30000);
            var eventRegistry = new InMemoryEventRegistry();

            var a = new EventDescription("event",
                                         new ArgumentNode("foo", new ObjectValueNode(
                                                              new ObjectFieldNode("a", 123),
                                                              new ObjectFieldNode("b", true),
                                                              new ObjectFieldNode("c", "abc"))));

            var b = new EventDescription("event",
                                         new ArgumentNode("foo", new ObjectValueNode(
                                                              new ObjectFieldNode("b", true),
                                                              new ObjectFieldNode("a", 123),
                                                              new ObjectFieldNode("c", "abc"))));

            // act
            IEventStream stream = await eventRegistry.SubscribeAsync(a);

            IAsyncEnumerator <IEventMessage> enumerator = stream.GetAsyncEnumerator(cts.Token);

            // assert
            var incoming = new EventMessage(b, "foo");
            await eventRegistry.SendAsync(incoming);

            Assert.True(await enumerator.MoveNextAsync());
            Assert.Equal(incoming, enumerator.Current);
        }
Exemple #5
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = "My API", Version = "v1"
                });
            });

            // Add the custom services like repositories etc ...
            services.AddSingleton <CharacterRepository>();
            services.AddSingleton <ReviewRepository>();

            services.AddSingleton <Query>();
            services.AddSingleton <Mutation>();
            services.AddSingleton <Subscription>();

            // Add in-memory event provider
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // Add GraphQL Services
            services.AddGraphQL(sp => HotChocolate.Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);

                // Adds the authorize directive and
                // enables the authorization middleware.
                c.RegisterAuthorizeDirectiveType();

                c.RegisterQueryType <QueryType>();
                c.RegisterMutationType <MutationType>();
                c.RegisterSubscriptionType <SubscriptionType>();

                c.RegisterType <HumanType>();
                c.RegisterType <DroidType>();
                c.RegisterType <EpisodeType>();
            }));

            // Add Authorization Policies
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HasCountry", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim(c =>
                                                                                (c.Type == ClaimTypes.Country))));
            });
        }
        private DatabaseSystem(ServiceContainer container, bool ownsContainer, IConfiguration configuration)
        {
            this.container = container;

            Configuration = configuration;
            container.RegisterInstance <IDatabaseSystem>(this);

            this.ownsContainer = ownsContainer;

            scope = container.OpenScope(KnownScopes.System);

            eventRegistry = new InMemoryEventRegistry();
        }
        private static Schema CreateSchema()
        {
            var repository    = new CharacterRepository();
            var eventRegistry = new InMemoryEventRegistry();
            var registry      = new DataLoaderRegistry(new EmptyServiceProvider());

            var services = new Dictionary <Type, object>
            {
                [typeof(CharacterRepository)] = repository,
                [typeof(Query)]               = new Query(repository),
                [typeof(Mutation)]            = new Mutation(),
                [typeof(Subscription)]        = new Subscription(),
                [typeof(IEventSender)]        = eventRegistry,
                [typeof(IEventRegistry)]      = eventRegistry,
                [typeof(IDataLoaderRegistry)] = registry
            };

            var serviceResolver = new Func <Type, object>(
                t =>
            {
                if (services.TryGetValue(t, out var s))
                {
                    return(s);
                }
                return(null);
            });

            var serviceProvider = new Mock <IServiceProvider>(
                MockBehavior.Strict);

            serviceProvider.Setup(t => t.GetService(It.IsAny <Type>()))
            .Returns(serviceResolver);

            registry.Register(typeof(HumanDataLoader).FullName,
                              s => new HumanDataLoader(repository));

            return(Schema.Create(c =>
            {
                c.RegisterServiceProvider(serviceProvider.Object);

                c.RegisterQueryType <QueryType>();
                c.RegisterMutationType <MutationType>();
                c.RegisterSubscriptionType <SubscriptionType>();

                c.RegisterType <HumanType>();
                c.RegisterType <DroidType>();
                c.RegisterType <EpisodeType>();
            }));
        }
Exemple #8
0
        public static void InterceptEvent()
        {
            var transformer = new Mock <IEventTransformer>();

            transformer.Setup(x => x.Transform(It.IsAny <IEvent>()))
            .Returns <IEvent>(e => new LogEntry(null, e.EventData["message"].ToString())
            {
                Data = new Dictionary <string, object> {
                    { "os", e.EventSource.Metadata["env.os"] }
                }
            });

            var entries = new List <LogEntry>();

            var logger = new Mock <ILogger>();

            logger.Setup(x => x.IsInterestedIn(It.IsAny <LogLevel>()))
            .Returns(true);
            logger.Setup(x => x.LogAsync(It.IsAny <LogEntry>()))
            .Returns <LogEntry>(entry => {
                entries.Add(entry);

                return(Task.CompletedTask);
            });

            var registry = new InMemoryEventRegistry();
            var system   = new Mock <IDatabaseSystem>();

            system.As <IEventHandler>()
            .SetupGet(x => x.Registry)
            .Returns(registry);

            SystemEventLogger.Attach(system.Object, logger.Object, transformer.Object);

            var @event = new Event(EventSource.Environment)
            {
                Data = new Dictionary <string, object> {
                    { "message", "test message" }
                }
            };

            system.Object.RaiseEvent(@event);
            registry.Dispose();

            Assert.Single(entries);
            Assert.Equal(LogLevel.Information, entries[0].Level);
            Assert.Equal(@event.Data["message"], entries[0].Message);
            Assert.True(entries[0].Data.ContainsKey("os"));
        }
 private TestServer CreateTestServer()
 {
     return(TestServerFactory.Create(
                c =>
     {
         c.RegisterMutationType <Mutation>();
         c.RegisterSubscriptionType <Subscription>();
     },
                s =>
     {
         var eventRegistry = new InMemoryEventRegistry();
         s.AddSingleton <IEventRegistry>(eventRegistry);
         s.AddSingleton <IEventSender>(eventRegistry);
     },
                new QueryMiddlewareOptions()));
 }
Exemple #10
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            // Add the custom services like repositories etc ...
            services.AddSingleton <CharacterRepository>();
            services.AddSingleton <ReviewRepository>();

            services.AddSingleton <Query>();
            services.AddSingleton <Mutation>();
            services.AddSingleton <Subscription>();

            // Add in-memory event provider
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // Add GraphQL Services
            services.AddGraphQL(sp => Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);

                // Adds the authorize directive and
                // enable the authorization middleware.
                c.RegisterAuthorizeDirectiveType();

                c.RegisterQueryType <QueryType>();
                c.RegisterMutationType <MutationType>();
                c.RegisterSubscriptionType <SubscriptionType>();

                c.RegisterType <HumanType>();
                c.RegisterType <DroidType>();
                c.RegisterType <EpisodeType>();
            }),
                                new QueryExecutionOptions
            {
                EnableTracing = true
            });

            // Add Authorization Policy
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HasCountry", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim(c =>
                                                                                (c.Type == ClaimTypes.Country))));
            });
        }
        private static Schema CreateSchema(int executionDepth)
        {
            var repository    = new CharacterRepository();
            var eventRegistry = new InMemoryEventRegistry();

            var services = new Dictionary <Type, object>();

            services[typeof(CharacterRepository)] = repository;
            services[typeof(Query)]          = new Query(repository);
            services[typeof(Mutation)]       = new Mutation();
            services[typeof(Subscription)]   = new Subscription();
            services[typeof(IEventSender)]   = eventRegistry;
            services[typeof(IEventRegistry)] = eventRegistry;

            var serviceResolver = new Func <Type, object>(
                t =>
            {
                if (services.TryGetValue(t, out object s))
                {
                    return(s);
                }
                return(null);
            });

            Mock <IServiceProvider> serviceProvider =
                new Mock <IServiceProvider>(MockBehavior.Strict);

            serviceProvider.Setup(t => t.GetService(It.IsAny <Type>()))
            .Returns(serviceResolver);

            return(Schema.Create(c =>
            {
                c.Options.MaxExecutionDepth = executionDepth;

                c.RegisterServiceProvider(serviceProvider.Object);

                c.RegisterDataLoader <HumanDataLoader>();

                c.RegisterQueryType <QueryType>();
                c.RegisterMutationType <MutationType>();
                c.RegisterSubscriptionType <SubscriptionType>();

                c.RegisterType <HumanType>();
                c.RegisterType <DroidType>();
                c.RegisterType <EpisodeType>();
            }));
        }
Exemple #12
0
        public async Task Subscribe_Send_MessageReveived()
        {
            // arrange
            var eventDescription = new EventDescription("foo");
            var eventRegistry    = new InMemoryEventRegistry();

            // act
            IEventStream stream =
                await eventRegistry.SubscribeAsync(eventDescription);

            // assert
            var incoming = new EventMessage("foo");
            await eventRegistry.SendAsync(incoming);

            IEventMessage outgoing = await stream.ReadAsync();

            Assert.Equal(incoming, outgoing);
        }
        public async Task Subscribe_Send_MessageReceived()
        {
            // arrange
            using var cts = new CancellationTokenSource(30000);
            var eventDescription = new EventDescription("foo");
            var eventRegistry    = new InMemoryEventRegistry();

            // act
            IEventStream stream = await eventRegistry.SubscribeAsync(eventDescription);

            IAsyncEnumerator <IEventMessage> enumerator = stream.GetAsyncEnumerator(cts.Token);

            // assert
            var incoming = new EventMessage("foo");
            await eventRegistry.SendAsync(incoming);

            Assert.True(await enumerator.MoveNextAsync());
            Assert.Equal(incoming, enumerator.Current);
        }
Exemple #14
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext <ApplicationDbContext>(options =>
                                                         options.UseSqlServer(
                                                             Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity <IdentityUser>()
            .AddEntityFrameworkStores <ApplicationDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddDbContext <MVCDbContext>(options =>
                                                 options.UseSqlServer(Configuration.GetConnectionString("MVCDbContext")));

            // Add in-memory event provider - This is for subscriptions. NuGet Package HotChocolate.Subscriptions.InMemory
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // Add GraphQL Services
            services.AddGraphQL(sp => Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);

                // Adds the authorize directive and
                // enables the authorization middleware.
                // c.RegisterAuthorizeDirectiveType();
                c.RegisterQueryType <GraphQLActions.GraphQLQueryType>();
                c.RegisterMutationType <GraphQLActions.GraphQLMutationType>();
                c.RegisterSubscriptionType <GraphQLActions.GraphQLSubscriptionType>();
            }));
        }
Exemple #15
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            // Add the custom services like repositories etc ...
            services.AddSingleton <CharacterRepository>();
            services.AddSingleton <ReviewRepository>();

            services.AddSingleton <Query>();
            services.AddSingleton <Mutation>();
            services.AddSingleton <Subscription>();

            // Add in-memory event provider
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // Add GraphQL Services
            services.AddGraphQL(sp => SchemaBuilder.New()
                                .AddServices(sp)
                                .AddQueryType <QueryType>()
                                .AddMutationType <MutationType>()
                                .AddSubscriptionType <SubscriptionType>()
                                .AddType <HumanType>()
                                .AddType <DroidType>()
                                .AddType <EpisodeType>()
                                .AddDirectiveType <AuthorizeDirectiveType>()
                                .Create());

            // Add Authorization Policies
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HasCountry", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim(c =>
                                                                                (c.Type == ClaimTypes.Country))));
            });
        }
Exemple #16
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext <ApplicationDbContext>(options =>
                                                         options.UseSqlServer(
                                                             Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity <IdentityUser>()
            .AddDefaultUI(UIFramework.Bootstrap4)
            .AddEntityFrameworkStores <ApplicationDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddDbContext <MVCDbContext>(options =>
                                                 options.UseSqlServer(Configuration.GetConnectionString("MVCDbContext")));

            // Add in-memory event provider - This is for subscriptions. NuGet Package HotChocolate.Subscriptions.InMemory
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            // https://jonhilton.net/security/apis/secure-your-asp.net-core-2.0-api-part-2---jwt-bearer-authentication/

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    ValidateLifetime         = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer      = "https://*****:*****@345"))//_configuration["SecurityKey"]))
                };
            });

            // this enables you to use DataLoader in your resolvers.
            services.AddDataLoaderRegistry();

            // Add GraphQL Services
            services.AddGraphQL(sp => Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);

                // Adds the authorize directive and
                // enables the authorization middleware.
                c.RegisterAuthorizeDirectiveType();
                c.RegisterQueryType <GraphQLActions.GraphQLQueryType>();
                c.RegisterMutationType <GraphQLActions.GraphQLMutationType>();
                c.RegisterSubscriptionType <GraphQLActions.GraphQLSubscriptionType>();
                c.RegisterExtendedScalarTypes(); //Needed to fix: CommentInput.created: Cannot resolve input-type `System.DateTime` - Type: CommentInput'
            }));

            services.AddAuthorization(options =>
            {
                // Using Token
                options.AddPolicy("CompletedTrainingToken", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim("CompletedBasicTraining", "Yes")
                                                          ));

                // Using ApplicationDbContext Database claims
                options.AddPolicy("OnlyManagersDb", policy =>
                                  policy.Requirements.Add(
                                      new ClaimInDatabaseRequirement(new Claim("EmployeeStatus", "Manager")))
                                  );
            });

            services.AddSingleton <IAuthorizationHandler, ClaimInDatabaseHandler>();
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            // Add DataAccessLayer
            services.AddDbContext <ApplicationDbContext>(options =>
                                                         options.UseSqlServer(
                                                             Configuration.GetConnectionString("DefaultConnection")),
                                                         ServiceLifetime.Transient
                                                         );

            // Add Identity Server
            services.AddDefaultIdentity <IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
            .AddEntityFrameworkStores <ApplicationDbContext>()
            .AddDefaultTokenProviders()
            .AddTokenProvider("MyApp", typeof(DataProtectorTokenProvider <IdentityUser>));

            IdentityModelEventSource.ShowPII = true;

            // Add in-memory event provider - This is for subscriptions. NuGet Package HotChocolate.Subscriptions.InMemory
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry); //*/

            // Add GraphQL
            services
            .AddDataLoaderRegistry()
            .AddGraphQL((sp =>
                         SchemaBuilder.New()
                         .AddServices(sp)
                         .AddQueryType(d => d.Name("Query"))
                         .AddType <AuthServiceQueries>()
                         .AddMutationType(d => d.Name("Mutation"))
                         .AddType <AuthServiceMutations>()

                         /*.AddType<PersonMutations>()
                         *  .AddType<UserMutations>()
                         *  .AddSubscriptionType(d => d.Name("Subscription"))
                         *  .AddType<MessageSubscriptions>()
                         *  .AddType<PersonSubscriptions>()
                         *  .AddType<MessageExtension>()
                         *  .AddType<PersonExtension>()*/
                         .AddAuthorizeDirectiveType()
                         .BindClrType <string, StringType>()
                         .BindClrType <Guid, IdType>()
                         .Create()),
                        new QueryExecutionOptions
            {
                TracingPreference = TracingPreference.OnDemand
            }
                        );

            // Add Authorization
            var    tokenSection             = Configuration.GetSection("JwtSettings");
            string APSecretKey              = tokenSection["JwtSecurityKey"];
            string ValidateIssuer           = "true";
            string ValidateAudience         = "true";
            string ValidateLifetime         = "true";
            string ValidateIssuerSigningKey = "true";
            string ValidIssuer              = tokenSection["JwtIssuer"];
            string ValidAudience            = tokenSection["JwtAudience"];

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer           = Convert.ToBoolean(ValidateIssuer),
                    ValidateAudience         = Convert.ToBoolean(ValidateAudience),
                    ValidateLifetime         = Convert.ToBoolean(ValidateLifetime),
                    ValidateIssuerSigningKey = Convert.ToBoolean(ValidateIssuerSigningKey),
                    ValidIssuer      = ValidIssuer,
                    ValidAudience    = ValidAudience,
                    IssuerSigningKey = new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(APSecretKey)),
                    TokenDecryptionKey = new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(APSecretKey))
                };
            });

            /*
             * services.AddQueryRequestInterceptor((context, builder, ct) =>
             * {
             *
             *  /* To do something with the incoming user
             *  //var claims = ctx.User.Claims;
             *
             *  System.Diagnostics.Debug.WriteLine("Claims ---->");
             *  foreach (var item in ctx.User.Claims)
             *  {
             *      System.Diagnostics.Debug.WriteLine("Claim: " + item.Type + " - " + item.Value);
             *  }
             *
             *  var identity = new ClaimsIdentity();
             *  identity.AddClaim(new Claim(ClaimTypes.Country, "us"));
             *  identity.AddClaim(new Claim("IsNewUser", "Yes"));
             *  ctx.User.AddIdentity(identity);
             *  /
             *
             *  return Task.CompletedTask;
             * });*/

            services.AddQueryRequestInterceptor(async(context, builder, ct) =>
            {
                if (context.User.Identity.IsAuthenticated)
                {
                    await Task.Delay(1);
                    // The name in the token is the UserAppId
                    builder.AddProperty(
                        "currentUserId",
                        context.User.FindFirst(ClaimTypes.Name).Value);

                    builder.AddProperty(
                        "currentEmail",
                        context.User.FindFirst(ClaimTypes.Email).Value);

                    builder.AddProperty(
                        "currentIdentityId",
                        context.User.FindFirst("Identity").Value);

                    /*IPersonRepository personRepository =
                     *  context.RequestServices.GetRequiredService<IPersonRepository>();
                     * await personRepository.UpdateLastSeenAsync(personId, DateTime.UtcNow, ct);*/
                }
            });

            services.AddAuthorization(options =>
            {
                // Using Token
                options.AddPolicy("IsNewUser", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim("IsUser", "Yes")
                                                          ));
                //*/

                /*/ Reevalute DB claims, because GraphQl calls the method everytime,
                 * // so if it's 5 users with one Auth Field, there will be 5 calls to the Auth Service and DB
                 * // Using ApplicationDbContext Database claims
                 * options.AddPolicy("IsNewUser", policy =>policy.Requirements.Add(
                 *  new ClaimInDatabaseRequirement(new Claim("UserType", "user")))
                 * );
                 */
            });

            services.AddSingleton <IAuthorizationHandler, ClaimInDatabaseHandler>();
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            // Add the custom services like repositories etc ...
            services.AddSingleton <CharacterRepository>();
            services.AddSingleton <ReviewRepository>();

            services.AddSingleton <Query>();
            services.AddSingleton <Mutation>();
            services.AddSingleton <Subscription>();

            // Add in-memory event provider
            var eventRegistry = new InMemoryEventRegistry();

            services.AddSingleton <IEventRegistry>(eventRegistry);
            services.AddSingleton <IEventSender>(eventRegistry);

            /*Authorization not working*/
            services.AddStitchedSchema(builder => builder
                                       //.AddSchemaFromHttp("remoteA")

                                       .AddSchema("starwars", Schema.Create(config =>
            {
                /* When I register auth here, I don't see the claims principle in ContextData at AuthorizeAsync
                 * in AuthorizeDirectiveType, while debugging. I do see it earlier in the pipeline where it's
                 * added to the builder, in QueryMiddlewareBase.
                 */
                config.RegisterAuthorizeDirectiveType();

                config.RegisterQueryType <QueryType>();
                config.RegisterMutationType <MutationType>();
                config.RegisterSubscriptionType <SubscriptionType>();

                config.RegisterType <HumanType>();
                config.RegisterType <DroidType>();
                config.RegisterType <EpisodeType>();
            }))

                                       .AddSchemaConfiguration(config =>
            {
                /*
                 * Calling register auth here doesn't invoke auth check in starwars schema.
                 */
                //config.RegisterAuthorizeDirectiveType();
                config.RegisterExtendedScalarTypes();
                config.RegisterType <PaginationAmountType>();
            })

                                       //.AddExtensionsFromFile("Extensions.graphql")
                                       );

            /*Authorization works this way*/
            //services.AddGraphQL(sp => Schema.Create(c =>
            //{
            //    c.RegisterServiceProvider(sp);

            //    // Adds the authorize directive and
            //    // enable the authorization middleware.
            //    c.RegisterAuthorizeDirectiveType();

            //    c.RegisterQueryType<QueryType>();
            //    c.RegisterMutationType<MutationType>();
            //    c.RegisterSubscriptionType<SubscriptionType>();

            //    c.RegisterType<HumanType>();
            //    c.RegisterType<DroidType>();
            //    c.RegisterType<EpisodeType>();
            //}),
            //new QueryExecutionOptions
            //{
            //    TracingPreference = TracingPreference.Always
            //});

            // Add Authorization Policy
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HasCountry", policy =>
                                  policy.RequireAssertion(context =>
                                                          context.User.HasClaim(c =>
                                                                                (c.Type == ClaimTypes.Country))));
            });
        }