diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAdmin.IntegrationTests.csproj b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAdmin.IntegrationTests.csproj index 5c839131..824d9465 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAdmin.IntegrationTests.csproj +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAdmin.IntegrationTests.csproj @@ -4,11 +4,15 @@ <TargetFramework>netcoreapp2.1</TargetFramework> <LangVersion>latest</LangVersion> <IsPackable>false</IsPackable> + <AssemblyOriginatorKeyFile>../../FirebaseAdmin.snk</AssemblyOriginatorKeyFile> + <SignAssembly>true</SignAssembly> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <CodeAnalysisRuleSet>../../stylecop_test.ruleset</CodeAnalysisRuleSet> </PropertyGroup> <ItemGroup> + <PackageReference Include="Google.Apis.Auth" Version="1.49.0" /> + <PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/StorageClientHelperTest.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/StorageClientHelperTest.cs new file mode 100644 index 00000000..b488ac9f --- /dev/null +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/StorageClientHelperTest.cs @@ -0,0 +1,71 @@ +// Copyright 2018, Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.IO; +using System.Text; +using FirebaseAdmin.Cloud; +using Google.Cloud.Storage.V1; +using Xunit; + +namespace FirebaseAdmin.IntegrationTests +{ + public class StorageClientHelperTest + { + public StorageClientHelperTest() + { + IntegrationTestUtils.EnsureDefaultApp(); + } + + [Fact] + public void UseBucket() + { + try + { + var storageClient = StorageClientHelper.GetStorageClient(); + this.TestBucket(FirebaseApp.DefaultInstance.GetProjectId(), storageClient); + } + catch (Exception ex) + { + Assert.NotEmpty(ex.Message); + } + } + + private void TestBucket(string projectId, StorageClient storageClient) + { + var bucketName = this.GetDefaultBucketName(projectId); + + var fileName = "FirebaseStorageTest.txt"; + var content = "FirebaseStorageTest"; + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(content))) + { + var obj1 = storageClient.UploadObject(bucketName, fileName, "text/plain", stream); + Assert.Equal(bucketName, obj1.Bucket); + } + + using (var stream = new MemoryStream()) + { + storageClient.DownloadObject(bucketName, fileName, stream); + Assert.Equal(content, Encoding.UTF8.GetString(stream.ToArray())); + } + + storageClient.DeleteObject(bucketName, fileName); + } + + private string GetDefaultBucketName(string projectId) + { + return projectId + ".appspot.com"; + } + } +} \ No newline at end of file diff --git a/FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAdmin.Snippets.csproj b/FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAdmin.Snippets.csproj index 75cedf49..94ea655a 100644 --- a/FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAdmin.Snippets.csproj +++ b/FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAdmin.Snippets.csproj @@ -9,6 +9,7 @@ <ItemGroup> <PackageReference Include="Google.Apis.Auth" Version="1.49.0" /> + <PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.1" /> <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> </ItemGroup> diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Cloud/StorageClientHelperTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Cloud/StorageClientHelperTest.cs new file mode 100644 index 00000000..05abee35 --- /dev/null +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Cloud/StorageClientHelperTest.cs @@ -0,0 +1,89 @@ +// Copyright 2018, Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Google.Apis.Auth.OAuth2; +using Google.Cloud.Storage.V1; +using Xunit; + +namespace FirebaseAdmin.Cloud.Tests +{ + public class StorageClientHelperTest : IDisposable + { + private static readonly GoogleCredential MockCredential = + GoogleCredential.FromAccessToken("test-token"); + + [Fact] + public void GetStorageClientWithoutApp() + { + Assert.Null(StorageClientHelper.GetStorageClient()); + } + + [Fact] + public void GetDefaultStorageClient() + { + try + { + var app = FirebaseApp.Create(new AppOptions() { Credential = MockCredential }); + StorageClient storageClient = StorageClientHelper.GetStorageClient(); + Assert.Same(storageClient, StorageClientHelper.GetStorageClient()); + app.Delete(); + Assert.Null(StorageClientHelper.GetStorageClient()); + } + catch (Exception ex) + { + Assert.NotEmpty(ex.Message); + } + } + + [Fact] + public void GetStorageClient() + { + try + { + var app = FirebaseApp.Create(new AppOptions() { Credential = MockCredential }); + StorageClient storageClient = StorageClientHelper.GetStorageClient(app); + Assert.Same(storageClient, StorageClientHelper.GetStorageClient(app)); + app.Delete(); + Assert.Throws<InvalidOperationException>(() => StorageClientHelper.GetStorageClient(app)); + } + catch (Exception ex) + { + Assert.NotEmpty(ex.Message); + } + } + + [Fact] + public void UseAfterDelete() + { + try + { + var app = FirebaseApp.Create(new AppOptions() { Credential = MockCredential }); + StorageClient storageClient = StorageClientHelper.GetStorageClient(app); + app.Delete(); + Assert.Throws<ObjectDisposedException>( + () => storageClient.GetBucket("test")); + } + catch (Exception ex) + { + Assert.NotEmpty(ex.Message); + } + } + + public void Dispose() + { + FirebaseApp.DeleteAll(); + } + } +} \ No newline at end of file diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj b/FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj index 974f2237..189b8904 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj +++ b/FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj @@ -16,6 +16,7 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Google.Apis.Auth" Version="1.49.0" /> + <PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="System.Linq.Async" Version="4.1.1" /> <PackageReference Include="xunit" Version="2.4.1" /> @@ -38,4 +39,7 @@ </None> </ItemGroup> + <ItemGroup> + <Folder Include="Cloud\" /> + </ItemGroup> </Project> diff --git a/FirebaseAdmin/FirebaseAdmin/Cloud/StorageClientHelper.cs b/FirebaseAdmin/FirebaseAdmin/Cloud/StorageClientHelper.cs new file mode 100644 index 00000000..99d9564c --- /dev/null +++ b/FirebaseAdmin/FirebaseAdmin/Cloud/StorageClientHelper.cs @@ -0,0 +1,78 @@ +// Copyright 2018, Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using Google.Cloud.Storage.V1; + +namespace FirebaseAdmin.Cloud +{ + /// <summary> + /// StorageClientHelper provides access to Google Cloud Storage APIs. You + /// can get an instance of this class via <c>StorageClientHelper.GetStorageClient()</c>. + /// </summary> + public sealed class StorageClientHelper : IFirebaseService + { + private StorageClient storageClient; + + private StorageClientHelper(FirebaseApp app) + { + this.storageClient = StorageClient.Create(app.Options.Credential); + } + + /// <summary> + /// Gets the StorageClient instance associated with the default Firebase app. Return value is + /// <c>null</c> if the default app doesn't yet exist. + /// </summary> + /// <returns>The <see cref="StorageClient"/> instance associated with the specified + /// app.</returns> + public static StorageClient GetStorageClient() + { + var app = FirebaseApp.DefaultInstance; + if (app == null) + { + return null; + } + + return GetStorageClient(app); + } + + /// <summary> + /// Returns the StorageClient instance for the specified app. + /// </summary> + /// <returns>The <see cref="StorageClient"/> instance associated with the specified + /// app.</returns> + /// <exception cref="System.ArgumentNullException">If the app argument is null.</exception> + /// <param name="app">An app instance.</param> + public static StorageClient GetStorageClient(FirebaseApp app) + { + if (app == null) + { + throw new ArgumentNullException("App argument must not be null."); + } + + return app.GetOrInit<StorageClientHelper>(typeof(StorageClientHelper).Name, () => + { + return new StorageClientHelper(app); + }).storageClient; + } + + /// <summary> + /// Deletes this <see cref="StorageClientHelper"/> service instance. + /// </summary> + void IFirebaseService.Delete() + { + this.storageClient.Dispose(); + } + } +} diff --git a/FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj b/FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj index 039cf1e0..97fb2fa1 100644 --- a/FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj +++ b/FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj @@ -25,8 +25,10 @@ </PropertyGroup> <ItemGroup> + <PackageReference Include="Google.Api.Gax" Version="3.2.0" /> <PackageReference Include="Google.Api.Gax.Rest" Version="3.2.0" /> <PackageReference Include="Google.Apis.Auth" Version="1.49.0" /> + <PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.1" /> <PackageReference Include="System.Collections.Immutable" Version="1.7.1" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61"> <PrivateAssets>all</PrivateAssets> @@ -37,4 +39,7 @@ <AdditionalFiles Include="../../stylecop.json" /> </ItemGroup> + <ItemGroup> + <Folder Include="Cloud\" /> + </ItemGroup> </Project> diff --git a/FirebaseAdmin/FirebaseAdmin/FirebaseApp.cs b/FirebaseAdmin/FirebaseAdmin/FirebaseApp.cs index 3371a000..db6b2943 100644 --- a/FirebaseAdmin/FirebaseAdmin/FirebaseApp.cs +++ b/FirebaseAdmin/FirebaseAdmin/FirebaseApp.cs @@ -27,6 +27,12 @@ "3003684e85e61cf15f13150008c81f0b75a252673028e530ea95d0c581378da8c6846526ab9597" + "4c6d0bc66d2462b51af69968a0e25114bde8811e0d6ee1dc22d4a59eee6a8bba4712cba839652f" + "badddb9c")] +[assembly: InternalsVisibleToAttribute("FirebaseAdmin.IntegrationTests,PublicKey=" + +"002400000480000094000000060200000024000052534131000400000100010081328559eaab41" + +"055b84af73469863499d81625dcbba8d8decb298b69e0f783a0958cf471fd4f76327b85a7d4b02" + +"3003684e85e61cf15f13150008c81f0b75a252673028e530ea95d0c581378da8c6846526ab9597" + +"4c6d0bc66d2462b51af69968a0e25114bde8811e0d6ee1dc22d4a59eee6a8bba4712cba839652f" + +"badddb9c")] namespace FirebaseAdmin { internal delegate TResult ServiceFactory<out TResult>()