コード例 #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public ForgeOSS(IHttpClientFactory clientFactory, IOptions <ForgeConfiguration> optionsAccessor, ILogger <ForgeOSS> logger)
        {
            _clientFactory = clientFactory;
            _logger        = logger;
            Configuration  = optionsAccessor.Value.Validate();

            string apiBaseUrl = Configuration.AuthenticationAddress.GetLeftPart(System.UriPartial.Authority);

            Autodesk.Forge.Client.Configuration.Default.setApiClientUsingDefault(new ApiClient(apiBaseUrl));

            RefreshApiToken();

            // create policy to refresh API token on expiration (401 error code)
            var refreshTokenPolicy = Policy
                                     .Handle <ApiException>(e => e.ErrorCode == StatusCodes.Status401Unauthorized)
                                     .RetryAsync(5, (_, __) => RefreshApiToken());

            var bulkHeadPolicy       = Policy.BulkheadAsync(10, int.MaxValue);
            var rateLimitRetryPolicy = Policy
                                       .Handle <ApiException>(e => e.ErrorCode == StatusCodes.Status429TooManyRequests)
                                       .WaitAndRetryAsync(new[] {
                TimeSpan.FromSeconds(10),
                TimeSpan.FromSeconds(20),
                TimeSpan.FromSeconds(40)
            });

            _ossResiliencyPolicy = refreshTokenPolicy.WrapAsync(rateLimitRetryPolicy).WrapAsync(bulkHeadPolicy);
        }
コード例 #2
0
 public LoginController(ILogger <LoginController> logger, IOptions <ForgeConfiguration> optionsAccessor, UserResolver userResolver, IOptions <InviteOnlyModeConfiguration> inviteOnlyModeOptionsAccessor)
 {
     _logger               = logger;
     _userResolver         = userResolver;
     Configuration         = optionsAccessor.Value.Validate();
     _inviteOnlyModeConfig = inviteOnlyModeOptionsAccessor.Value;
 }
コード例 #3
0
 public LoginController(ILogger <LoginController> logger, IOptions <ForgeConfiguration> optionsAccessor, ProfileProvider profileProvider, IOptions <InviteOnlyModeConfiguration> inviteOnlyModeOptionsAccessor)
 {
     _logger               = logger;
     _profileProvider      = profileProvider;
     Configuration         = optionsAccessor.Value.Validate();
     _inviteOnlyModeConfig = inviteOnlyModeOptionsAccessor.Value;
 }
コード例 #4
0
        public async void TestFirstCallAuthenticates()
        {
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().SetupSequence(o => o.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(JsonConvert.SerializeObject(new Dictionary <string, string> {
                    { "token_type", "Bearer" }, { "access_token", "blablabla" }, { "expires_in", "3" }
                })),
                StatusCode = System.Net.HttpStatusCode.OK
            })
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var fh = new HttpMessageInvoker(new ForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            });

            var req = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            req.Options.Set(ForgeConfiguration.ScopeKey, "somescope");
            await fh.SendAsync(req, CancellationToken.None);

            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == config.AuthenticationAddress), It.IsAny <CancellationToken>()), Times.Once());
            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri), It.IsAny <CancellationToken>()), Times.Once());
        }
コード例 #5
0
        public async void TestTimeout()
        {
            var cachedToken = "cachedToken";
            var req         = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == cachedToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.GatewayTimeout
            }, TimeSpan.FromSeconds(12));

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(10));

            var invoker = new HttpMessageInvoker(fh);

            req.Properties.Add(ForgeConfiguration.ScopeKey, scope);
            await Assert.ThrowsAsync <Polly.Timeout.TimeoutRejectedException>(async() => await invoker.SendAsync(req, new CancellationToken()));

            sink.VerifyAll();
        }
        public LoggedInUserBucketKeyProvider(IOptions<ForgeConfiguration> forgeConfiguration, ProfileProvider profileProvider, BucketPrefixProvider bucketPrefixProvider, ResourceProvider resourceProvider)
        {
            _profileProvider = profileProvider;
            _forgeConfig = forgeConfiguration.Value;
            _bucketPrefixProvider = bucketPrefixProvider;
            _resourceProvider = resourceProvider;

            AnonymousBucketKey = resourceProvider.BucketKey;
        }
コード例 #7
0
        public async void TestRefreshExpiredTokenByOneThreadOnly()
        {
            var newToken    = "newToken";
            var cachedToken = "cachedToken";
            var requestUri  = new Uri("http://example.com");
            var config      = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == config.AuthenticationAddress), It.IsAny <CancellationToken>()))
            // some artifical delay to ensure that the other thread will attempt to enter the critical section
            .ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(JsonConvert.SerializeObject(new Dictionary <string, string> {
                    { "token_type", "Bearer" }, { "access_token", newToken }, { "expires_in", "3" }
                })),
                StatusCode = System.Net.HttpStatusCode.OK
            }, TweakableForgeHandler.DefaultTimeout / 2
                          );
            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == requestUri && r.Headers.Authorization.Parameter == newToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            //we have token but it is expired already
            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(0));

            //launch 2 threads to make parallel requests
            Func <Task> lambda = async() =>
            {
                var req = new HttpRequestMessage();
                req.RequestUri = requestUri;
                var invoker = new HttpMessageInvoker(fh);

                req.Options.Set(ForgeConfiguration.ScopeKey, scope);
                await invoker.SendAsync(req, CancellationToken.None);
            };

            await Task.WhenAll(lambda(), lambda());

            // We expect exactly one auth call
            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == config.AuthenticationAddress), It.IsAny <CancellationToken>()), Times.Once());

            sink.VerifyAll();
        }
コード例 #8
0
 public static byte[] Hash(this ForgeConfiguration configuration)
 {
     // https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing?view=aspnetcore-3.1
     return(KeyDerivation.Pbkdf2(
                password: configuration.ClientId,
                salt: Encoding.UTF8.GetBytes(configuration.ClientSecret + configuration.ClientId),                  // TODO Is it OK? Or safer to not use the secret at all?
                prf: KeyDerivationPrf.HMACSHA1,
                iterationCount: 10,
                numBytesRequested: 12));
 }
コード例 #9
0
        public ResourceProvider(IOptions <ForgeConfiguration> forgeConfigOptionsAccessor, DesignAutomationClient client, IConfiguration configuration, BucketPrefixProvider bucketPrefixProvider, string bucketKey = null)
        {
            _forgeConfiguration   = forgeConfigOptionsAccessor.Value.Validate();
            _configuration        = configuration;
            _bucketPrefixProvider = bucketPrefixProvider;

            BucketKey = bucketKey ?? AnonymousBucketKey();

            _nickname = new Lazy <Task <string> >(async() => await client.GetNicknameAsync("me"));
        }
コード例 #10
0
        public async void TestCorrectNumberOfRetries()
        {
            var cachedToken = "cachedToken";
            var req         = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };

            var gatewayTimeout = new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.GatewayTimeout
            };
            var tooManyRequests = new HttpResponseMessage {
                StatusCode = (System.Net.HttpStatusCode) 429
            };

            tooManyRequests.Headers.RetryAfter = new System.Net.Http.Headers.RetryConditionHeaderValue(TimeSpan.FromSeconds(2));
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().SetupSequence(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == cachedToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(tooManyRequests)
            .ReturnsAsync(tooManyRequests)
            .ReturnsAsync(tooManyRequests)
            .ThrowsAsync(new HttpRequestException())
            .ReturnsAsync(gatewayTimeout)
            .ReturnsAsync(gatewayTimeout);


            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(10));

            var invoker = new HttpMessageInvoker(fh);

            req.Options.Set(ForgeConfiguration.ScopeKey, scope);
            var resp = await invoker.SendAsync(req, CancellationToken.None);

            Assert.Equal(System.Net.HttpStatusCode.GatewayTimeout, resp.StatusCode);

            // We retry 5 times so expect 6 calls
            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(6));

            sink.VerifyAll();
        }
コード例 #11
0
        private ForgeService CreateForgeService(string forgeClientId, string forgeClientSecret)
        {
            var forgeConfig = new ForgeConfiguration();

            forgeConfig.ClientId     = forgeClientId;
            forgeConfig.ClientSecret = forgeClientSecret;
            var httpMessageHandler = new ForgeHandler(Options.Create(forgeConfig))
            {
                InnerHandler = new HttpClientHandler()
            };

            return(new ForgeService(new HttpClient(httpMessageHandler)));
        }
コード例 #12
0
        public UserResolver(ResourceProvider resourceProvider, IForgeOSS forgeOSS,
                            IOptions <ForgeConfiguration> forgeConfiguration, LocalCache localCache, ILogger <UserResolver> logger, IConfiguration configuration)
        {
            _forgeOSS      = forgeOSS;
            _localCache    = localCache;
            _logger        = logger;
            _configuration = configuration;
            _forgeConfig   = forgeConfiguration.Value;

            AnonymousBucket = new OssBucket(_forgeOSS, resourceProvider.BucketKey, logger);

            _lazyProfile = new Lazy <Task <dynamic> >(async() => await _forgeOSS.GetProfileAsync(Token));
        }
コード例 #13
0
        /// <summary>
        /// Ensure the configuration is valid.
        /// </summary>
        public static ForgeConfiguration Validate(this ForgeConfiguration configuration)
        {
            if (string.IsNullOrEmpty(configuration.ClientId))
            {
                throw new ArgumentException("Forge Client ID is not provided.");
            }
            if (string.IsNullOrEmpty(configuration.ClientSecret))
            {
                throw new ArgumentException("Forge Client Secret is not provided.");
            }

            return(configuration);
        }
コード例 #14
0
        public async void TestRetryOnceOnAuthenticationFailure()
        {
            var newToken    = "newToken";
            var cachedToken = "cachedToken";
            var req         = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == cachedToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode     = System.Net.HttpStatusCode.Unauthorized,
                RequestMessage = req
            });
            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == config.AuthenticationAddress), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(JsonConvert.SerializeObject(new Dictionary <string, string> {
                    { "token_type", "Bearer" }, { "access_token", newToken }, { "expires_in", "3" }
                })),
                StatusCode = System.Net.HttpStatusCode.OK
            });
            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == newToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            //we have token but it bad for some reason (maybe revoked)
            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(300));

            var invoker = new HttpMessageInvoker(fh);

            req.Options.Set(ForgeConfiguration.ScopeKey, scope);
            await invoker.SendAsync(req, CancellationToken.None);

            sink.VerifyAll();
        }
コード例 #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DesignAutomationController"/> class.
 /// </summary>
 /// <param name="clientApi">The clientApi<see cref="DesignAutomationClient"/>.</param>
 /// <param name="env">The env<see cref="IWebHostEnvironment"/>.</param>
 /// <param name="hub">The hub<see cref="IHubContext{DesignAutomationHub}"/>.</param>
 /// <param name="config">The config<see cref="IConfiguration"/>.</param>
 public DesignAutomationController(DesignAutomationClient clientApi,
                                   IWebHostEnvironment env,
                                   IHubContext <DesignAutomationHub> hub,
                                   IOptions <ForgeConfiguration> config)
 {
     hubContext      = hub;
     configuration   = config.Value;
     FORGE_CLIENT_ID =
         Environment.GetEnvironmentVariable("FORGE_CLIENT_ID")
         ?? configuration.ClientId;
     FORGE_CLIENT_SECRET =
         Environment.GetEnvironmentVariable("FORGE_CLIENT_SECRET")
         ?? configuration.ClientSecret;
     FORGE_WEBHOOK_URL = Environment.GetEnvironmentVariable("FORGE_WEBHOOK_URL");
     _env = env;
     api  = clientApi;
 }
コード例 #16
0
        public async void TestCircuitBreaker()
        {
            var cachedToken = "cachedToken";
            var req         = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == cachedToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.InternalServerError
            });

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(10));

            var invoker = new HttpMessageInvoker(fh);

            req.Options.Set(ForgeConfiguration.ScopeKey, scope);
            // We tolerate 3 failures before we break the circuit
            for (int i = 0; i < 3; i++)
            {
                var resp = await invoker.SendAsync(req, CancellationToken.None);

                Assert.Equal(System.Net.HttpStatusCode.InternalServerError, resp.StatusCode);
            }

            await Assert.ThrowsAsync <Polly.CircuitBreaker.BrokenCircuitException <HttpResponseMessage> >(async() => await invoker.SendAsync(req, CancellationToken.None));


            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(3));

            sink.VerifyAll();
        }
コード例 #17
0
        public async void TestUseGoodToken()
        {
            var cachedToken = "cachedToken";
            var req         = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == cachedToken), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            fh.TokenCache.Add(scope, $"Bearer {cachedToken}", TimeSpan.FromSeconds(10));

            var invoker = new HttpMessageInvoker(fh);

            req.Options.Set(ForgeConfiguration.ScopeKey, scope);
            var resp = await invoker.SendAsync(req, CancellationToken.None);

            Assert.Equal(System.Net.HttpStatusCode.OK, resp.StatusCode);

            // We expect exactly one network call
            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Once());

            sink.VerifyAll();
        }
コード例 #18
0
        public async void TestNoRefreshOnClientProvidedToken()
        {
            var token = "blabla";
            var req   = new HttpRequestMessage();

            req.RequestUri = new Uri("http://example.com");
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret"
            };
            var sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri && r.Headers.Authorization.Parameter == token), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.Unauthorized
            });

            var fh = new TweakableForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            };

            var scope = "somescope";

            var invoker = new HttpMessageInvoker(fh);

            req.Options.Set(ForgeConfiguration.ScopeKey, scope);
            req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            var resp = await invoker.SendAsync(req, CancellationToken.None);

            Assert.Equal(System.Net.HttpStatusCode.Unauthorized, resp.StatusCode);

            // We expect exactly one network call
            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Once());

            sink.VerifyAll();
        }
コード例 #19
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public ForgeOSS(IHttpClientFactory clientFactory, IOptions <ForgeConfiguration> optionsAccessor, ILogger <ForgeOSS> logger)
        {
            _clientFactory = clientFactory;
            _logger        = logger;
            Configuration  = optionsAccessor.Value.Validate();

            RefreshApiToken();

            // create policy to refresh API token on expiration (401 error code)
            var refreshTokenPolicy = Policy
                                     .Handle <ApiException>(e => e.ErrorCode == StatusCodes.Status401Unauthorized)
                                     .RetryAsync(5, (_, __) => RefreshApiToken());

            var bulkHeadPolicy       = Policy.BulkheadAsync(10, int.MaxValue);
            var rateLimitRetryPolicy = Policy
                                       .Handle <ApiException>(e => e.ErrorCode == StatusCodes.Status429TooManyRequests)
                                       .WaitAndRetryAsync(new[] {
                TimeSpan.FromSeconds(10),
                TimeSpan.FromSeconds(20),
                TimeSpan.FromSeconds(40)
            });

            _ossResiliencyPolicy = refreshTokenPolicy.WrapAsync(rateLimitRetryPolicy).WrapAsync(bulkHeadPolicy);
        }
コード例 #20
0
        public InitializerTestBase(DefaultProjectsConfiguration defaultProjectsConfiguration)
        {
            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile("appsettings.json", false)
                                .AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true)
                                .AddEnvironmentVariables()
                                .AddForgeAlternativeEnvironmentVariables()
                                .Build();

            IServiceCollection services = new ServiceCollection();

            services.AddHttpClient();
            var serviceProvider = services.BuildServiceProvider();

            ForgeConfiguration            forgeConfiguration = configuration.GetSection("Forge").Get <ForgeConfiguration>();
            IOptions <ForgeConfiguration> forgeConfigOptions = Options.Create(forgeConfiguration);

            var httpClientFactory = serviceProvider.GetRequiredService <IHttpClientFactory>();

            forgeOSS = new ForgeOSS(httpClientFactory, forgeConfigOptions, new NullLogger <ForgeOSS>());

            var httpMessageHandler = new ForgeHandler(Options.Create(forgeConfiguration))
            {
                InnerHandler = new HttpClientHandler()
            };
            var forgeService           = new ForgeService(new HttpClient(httpMessageHandler));
            var designAutomationClient = new DesignAutomationClient(forgeService);

            projectsBucketKey = Guid.NewGuid().ToString();

            localCache = new LocalCache();
            var bucketPrefixProvider = new BucketPrefixProvider(forgeConfigOptions, configuration);
            var resourceProvider     = new ResourceProvider(forgeConfigOptions, designAutomationClient, configuration, bucketPrefixProvider, projectsBucketKey);
            var postProcessing       = new PostProcessing(httpClientFactory, new NullLogger <PostProcessing>(), localCache, Options.Create(new ProcessingOptions()));
            var publisher            = new Publisher(designAutomationClient, new NullLogger <Publisher>(), resourceProvider,
                                                     postProcessing, Options.Create(new PublisherConfiguration()),
                                                     new WorkItemsApi(forgeService), null, new TaskUtil());

            var appBundleZipPathsConfiguration = new AppBundleZipPaths
            {
                EmptyExe          = "../../../../WebApplication/AppBundles/EmptyExePlugin.bundle.zip",
                DataChecker       = "../../../../WebApplication/AppBundles/DataCheckerPlugin.bundle.zip",
                CreateSVF         = "../../../../WebApplication/AppBundles/CreateSVFPlugin.bundle.zip",
                CreateThumbnail   = "../../../../WebApplication/AppBundles/CreateThumbnailPlugin.bundle.zip",
                ExtractParameters = "../../../../WebApplication/AppBundles/ExtractParametersPlugin.bundle.zip",
                UpdateParameters  = "../../../../WebApplication/AppBundles/UpdateParametersPlugin.bundle.zip",
                CreateRFA         = "../../../../WebApplication/AppBundles/RFAExportRCEPlugin.bundle.zip",
                CreateBOM         = "../../../../WebApplication/AppBundles/ExportBOMPlugin.bundle.zip",
                ExportDrawing     = "../../../../WebApplication/AppBundles/ExportDrawingAsPdfPlugin.bundle.zip",
                UpdateDrawings    = "../../../../WebApplication/AppBundles/UpdateDrawingsPlugin.bundle.zip"
            };
            IOptions <AppBundleZipPaths> appBundleZipPathsOptions = Options.Create(appBundleZipPathsConfiguration);

            var fdaClient = new FdaClient(publisher, appBundleZipPathsOptions);
            IOptions <DefaultProjectsConfiguration> defaultProjectsOptions = Options.Create(defaultProjectsConfiguration);
            var profileProvider   = new ProfileProvider(forgeOSS);
            var bucketKeyProvider = new LoggedInUserBucketKeyProvider(profileProvider, resourceProvider);
            var userResolver      = new UserResolver(forgeOSS, bucketKeyProvider, localCache, NullLogger <UserResolver> .Instance, profileProvider);
            var arranger          = new Arranger(httpClientFactory, userResolver);

            // TODO: linkGenerator should be mocked
            var dtoGenerator = new DtoGenerator(linkGenerator: null, localCache);
            var projectWork  = new ProjectWork(new NullLogger <ProjectWork>(), arranger, fdaClient, dtoGenerator, userResolver);

            var projectService = new ProjectService(new NullLogger <ProjectService>(), userResolver, projectWork, dtoGenerator);

            initializer = new Initializer(new NullLogger <Initializer>(), fdaClient,
                                          defaultProjectsOptions, projectWork, userResolver, localCache,
                                          projectService, bucketPrefixProvider);

            testFileDirectory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()));
            httpClient        = new HttpClient();
        }
コード例 #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="App"/> class.
 /// </summary>
 /// <param name="api">The api<see cref="DesignAutomationClient"/>.</param>
 /// <param name="config">The config<see cref="IOptions{ForgeConfiguration}"/>.</param>
 /// <param name="storageConfig">The storageConfig<see cref="IOptions{AzureStorageConfig}"/>.</param>
 public App(DesignAutomationClient api, IOptions <ForgeConfiguration> config, IOptions <AzureStorageConfig> storageConfig)
 {
     this.api           = api;
     this.config        = config.Value;
     this.storageConfig = storageConfig.Value;
 }
コード例 #22
0
        public void TestDefault()
        {
            var config = new ForgeConfiguration();

            Assert.NotNull(config.AuthenticationAddress);
        }
コード例 #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="App"/> class.
 /// </summary>
 /// <param name="api">The api<see cref="DesignAutomationClient"/>.</param>
 /// <param name="config">The config<see cref="IOptions{ForgeConfiguration}"/>.</param>
 public App(DesignAutomationClient api, IOptions <ForgeConfiguration> config)
 {
     this.api    = api;
     this.config = config.Value;
 }
コード例 #24
0
 public BucketPrefixProvider(IOptions <ForgeConfiguration> forgeConfiguration, IConfiguration configuration)
 {
     _configuration = configuration;
     _forgeConfig   = forgeConfiguration.Value;
 }
コード例 #25
0
        public static string HashString(this ForgeConfiguration configuration)
        {
            var hashBytes = configuration.Hash();

            return(Crypto.BytesToString(hashBytes));
        }
コード例 #26
0
        public async void TestFirstCallAuthenticatesNonDefaultUser()
        {
            var req    = new HttpRequestMessage();
            var config = new ForgeConfiguration()
            {
                ClientId     = "ClientId",
                ClientSecret = "ClientSecret",
                Agents       = new Dictionary <string, ForgeAgentConfiguration>()
                {
                    {
                        "user1", new ForgeAgentConfiguration()
                        {
                            ClientId     = "user1-bla",
                            ClientSecret = "user1-blabla"
                        }
                    }
                }
            };
            string actualClientId     = null;
            string actualClientSecret = null;
            var    sink = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == config.AuthenticationAddress), It.IsAny <CancellationToken>()))
            .Callback <HttpRequestMessage, CancellationToken>((r, ct) =>
            {
                var stream = r.Content.ReadAsStream();
                int length = (int)stream.Length;
                var buffer = new byte[length];
                stream.Read(buffer, 0, length);
                var content        = Encoding.UTF8.GetString(buffer);
                var matches        = Regex.Matches(content, "(?<key>[^=&]+)=(?<value>[^&]+)");
                actualClientId     = GetValue("client_id");
                actualClientSecret = GetValue("client_secret");
                string GetValue(string key)
                {
                    return((from m in matches where m.Groups["key"].Value == key select m.Groups["value"].Value).Single());
                }
            })
            .ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(JsonConvert.SerializeObject(new Dictionary <string, string> {
                    { "token_type", "Bearer" }, { "access_token", "blablabla" }, { "expires_in", "3" }
                })),
                StatusCode = System.Net.HttpStatusCode.OK
            });
            sink.Protected().As <HttpMessageInvoker>().Setup(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });

            var fh = new HttpMessageInvoker(new ForgeHandler(Options.Create(config))
            {
                InnerHandler = sink.Object
            });

            req.RequestUri = new Uri("http://example.com");
            req.Options.Set(ForgeConfiguration.ScopeKey, "somescope");
            req.Options.Set(ForgeConfiguration.AgentKey, "user1");
            await fh.SendAsync(req, CancellationToken.None);

            Assert.Equal(config.Agents["user1"].ClientId, actualClientId);
            Assert.Equal(config.Agents["user1"].ClientSecret, actualClientSecret);

            sink.Protected().As <HttpMessageInvoker>().Verify(o => o.SendAsync(It.Is <HttpRequestMessage>(r => r.RequestUri == req.RequestUri), It.IsAny <CancellationToken>()), Times.Once());
        }