/// <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); }
public LoginController(ILogger <LoginController> logger, IOptions <ForgeConfiguration> optionsAccessor, UserResolver userResolver, IOptions <InviteOnlyModeConfiguration> inviteOnlyModeOptionsAccessor) { _logger = logger; _userResolver = userResolver; Configuration = optionsAccessor.Value.Validate(); _inviteOnlyModeConfig = inviteOnlyModeOptionsAccessor.Value; }
public LoginController(ILogger <LoginController> logger, IOptions <ForgeConfiguration> optionsAccessor, ProfileProvider profileProvider, IOptions <InviteOnlyModeConfiguration> inviteOnlyModeOptionsAccessor) { _logger = logger; _profileProvider = profileProvider; Configuration = optionsAccessor.Value.Validate(); _inviteOnlyModeConfig = inviteOnlyModeOptionsAccessor.Value; }
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()); }
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; }
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(); }
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)); }
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")); }
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(); }
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))); }
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)); }
/// <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); }
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(); }
/// <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; }
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(); }
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(); }
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(); }
/// <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); }
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(); }
/// <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; }
public void TestDefault() { var config = new ForgeConfiguration(); Assert.NotNull(config.AuthenticationAddress); }
/// <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; }
public BucketPrefixProvider(IOptions <ForgeConfiguration> forgeConfiguration, IConfiguration configuration) { _configuration = configuration; _forgeConfig = forgeConfiguration.Value; }
public static string HashString(this ForgeConfiguration configuration) { var hashBytes = configuration.Hash(); return(Crypto.BytesToString(hashBytes)); }
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()); }