From 94712fbe082aae38fe85b2fcb80139469a0e7ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20G=C3=B3mez?= Date: Fri, 3 Jan 2025 14:42:59 -0500 Subject: [PATCH 1/3] Support for AWS and GCP --- .gitignore | 3 + res/AzureExplorerLogo.pdn | Bin 51062 -> 82206 bytes src/StorageLibrary/AWS/AWSBucket.cs | 164 ++++++++++++++++++ .../{ => Azure}/AzureContainer.cs | 6 +- src/StorageLibrary/{ => Azure}/AzureFile.cs | 2 +- src/StorageLibrary/{ => Azure}/AzureQueue.cs | 2 +- src/StorageLibrary/{ => Azure}/AzureTable.cs | 2 +- src/StorageLibrary/Common/BlobItemWrapper.cs | 31 +++- src/StorageLibrary/GCP/GCPBucket.cs | 154 ++++++++++++++++ src/StorageLibrary/Mocks/MockContainer.cs | 2 +- src/StorageLibrary/StorageFactory.cs | 58 ++++++- src/StorageLibrary/StorageLibrary.csproj | 4 + src/StorageLibrary/StorageObject.cs | 24 +-- src/web/Pages/BaseComponent.razor | 2 +- src/web/Pages/Home.razor | 24 ++- src/web/Pages/Login.razor.cs | 36 ++++ src/web/Shared/NavMenu.razor | 44 +++-- src/web/Utils/Credentials.cs | 47 ++++- src/web/Utils/Util.cs | 22 ++- src/web/wwwroot/css/azurewebexplorer.css | 11 +- src/web/wwwroot/res/AWSExplorerLogo.png | Bin 0 -> 15207 bytes src/web/wwwroot/res/GCPExplorerLogo.png | Bin 0 -> 13027 bytes utils/azurite.sh | 2 +- 23 files changed, 579 insertions(+), 61 deletions(-) create mode 100644 src/StorageLibrary/AWS/AWSBucket.cs rename src/StorageLibrary/{ => Azure}/AzureContainer.cs (96%) rename src/StorageLibrary/{ => Azure}/AzureFile.cs (99%) rename src/StorageLibrary/{ => Azure}/AzureQueue.cs (98%) rename src/StorageLibrary/{ => Azure}/AzureTable.cs (98%) create mode 100644 src/StorageLibrary/GCP/GCPBucket.cs create mode 100644 src/web/wwwroot/res/AWSExplorerLogo.png create mode 100644 src/web/wwwroot/res/GCPExplorerLogo.png diff --git a/.gitignore b/.gitignore index b69f001..f9793f8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ __azurite*.json private*.data azurestorageexplorer.sln +credentials.json +.vscode/ + diff --git a/res/AzureExplorerLogo.pdn b/res/AzureExplorerLogo.pdn index 2b23b5f89ec17ad31d92e4416fcaa463188d950f..874641872111fc4dde6f1a94baadabbfe1fb0771 100644 GIT binary patch literal 82206 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

t~#)H5Xwgiho{0XsOeDU?^Q#*T4K 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�!lE?g851x3Ulh=70+5tSyrgGy8BQlx_* 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 literal 51062 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 diff --git a/src/StorageLibrary/AWS/AWSBucket.cs b/src/StorageLibrary/AWS/AWSBucket.cs new file mode 100644 index 0000000..eaf8df6 --- /dev/null +++ b/src/StorageLibrary/AWS/AWSBucket.cs @@ -0,0 +1,164 @@ +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using System.Threading.Tasks; + +using Amazon; +using Amazon.Runtime; +using Amazon.S3; +using Amazon.S3.Model; + +using StorageLibrary.Common; +using StorageLibrary.Interfaces; + +namespace StorageLibrary.AWS +{ + internal class AWSBucket : StorageObject, IContainer + { + protected AmazonS3Client _s3Client; + public AWSBucket(StorageFactoryConfig config): base(config) + { + var credentials = new BasicAWSCredentials(config.AwsKey, config.AwsSecret); + _s3Client = new AmazonS3Client(credentials, RegionEndpoint.GetBySystemName(config.AwsRegion)); + } + + public async Task CreateAsync(string bucket, bool publicAccess) + { + var putBucketRequest = new PutBucketRequest + { + BucketName = bucket, + }; + + await _s3Client.PutBucketAsync(putBucketRequest); + + if (publicAccess) + { + await SetBucketPolicyAsync(bucket); + } + } + + public async Task SetBucketPolicyAsync(string bucket) + { + var bucketPolicy = new + { + Version = "2012-10-17", + Statement = new[] + { + new + { + Sid = "AddPerm", + Effect = "Allow", + Principal = "*", + Action = "s3:GetObject", + Resource = $"arn:aws:s3:::{bucket}/*" + } + } + }; + + var policyJson = JsonSerializer.Serialize(bucketPolicy); + + var putBucketPolicyRequest = new PutBucketPolicyRequest + { + BucketName = bucket, + Policy = policyJson + }; + + await _s3Client.PutBucketPolicyAsync(putBucketPolicyRequest); + } + + public async Task CreateBlobAsync(string bucket, string key, Stream fileContent) + { + var putRequest = new PutObjectRequest + { + BucketName = bucket, + Key = key, + InputStream = fileContent + }; + + await _s3Client.PutObjectAsync(putRequest); + } + + public async Task DeleteAsync(string bucket) + { + var deleteBucketRequest = new DeleteBucketRequest + { + BucketName = bucket + }; + + await _s3Client.DeleteBucketAsync(deleteBucketRequest); + } + + public async Task DeleteBlobAsync(string bucket, string key) + { + var deleteObjectRequest = new DeleteObjectRequest + { + BucketName = bucket, + Key = key + }; + + await _s3Client.DeleteObjectAsync(deleteObjectRequest); + } + + public async Task GetBlobAsync(string bucket, string key) + { + string tmpPath = Util.File.GetTempFileName(); + + var getRequest = new GetObjectRequest + { + BucketName = bucket, + Key = key + }; + + using (GetObjectResponse response = await _s3Client.GetObjectAsync(getRequest)) + using (Stream responseStream = response.ResponseStream) + using (FileStream fileStream = File.Create(tmpPath)) + { + await responseStream.CopyToAsync(fileStream); + } + + return tmpPath; + } + + public async Task> ListBlobsAsync(string bucket, string path) + { + var request = new ListObjectsV2Request + { + BucketName = bucket, + Prefix = path, + Delimiter = Path.AltDirectorySeparatorChar.ToString() + }; + + + var blobs = new List(); + var response = await _s3Client.ListObjectsV2Async(request); + + var uriTemplate = $"https://{bucket}.s3.{RegionEndpoint.USEast1.SystemName}.amazonaws.com/"; + + foreach (S3Object entry in response.S3Objects) + { + if (entry.Key == path) + continue; + + blobs.Add(new BlobItemWrapper($"{uriTemplate}{entry.Key}", entry.Size, CloudProvider.AWS)); + } + + foreach (string commonPrefix in response.CommonPrefixes) + blobs.Add(new BlobItemWrapper($"{uriTemplate}{commonPrefix}", 0, CloudProvider.AWS)); + + return blobs; + } + + public async Task> ListContainersAsync() + { + var buckets = new List(); + + ListBucketsResponse response = await _s3Client.ListBucketsAsync(); + foreach (S3Bucket bucket in response.Buckets) + { + buckets.Add(new CloudBlobContainerWrapper() { Name = bucket.BucketName }); + } + + return buckets; + } + } +} \ No newline at end of file diff --git a/src/StorageLibrary/AzureContainer.cs b/src/StorageLibrary/Azure/AzureContainer.cs similarity index 96% rename from src/StorageLibrary/AzureContainer.cs rename to src/StorageLibrary/Azure/AzureContainer.cs index 54db206..118f5cf 100644 --- a/src/StorageLibrary/AzureContainer.cs +++ b/src/StorageLibrary/Azure/AzureContainer.cs @@ -9,7 +9,7 @@ using StorageLibrary.Common; using StorageLibrary.Interfaces; -namespace StorageLibrary +namespace StorageLibrary.Azure { internal class AzureContainer : StorageObject, IContainer { @@ -45,11 +45,11 @@ public async Task> ListBlobsAsync(string containerName, st { BlobClient blobClient = container.GetBlobClient(blobItem.Blob.Name); - wrapper = new BlobItemWrapper(blobClient.Uri.AbsoluteUri, blobItem.Blob.Properties.ContentLength.HasValue ? blobItem.Blob.Properties.ContentLength.Value : 0, IsAzurite); + wrapper = new BlobItemWrapper(blobClient.Uri.AbsoluteUri, blobItem.Blob.Properties.ContentLength.HasValue ? blobItem.Blob.Properties.ContentLength.Value : 0, CloudProvider.Azure, IsAzurite); } else if (blobItem.IsPrefix) { - wrapper = new BlobItemWrapper($"{container.Uri}/{blobItem.Prefix}", 0, IsAzurite); + wrapper = new BlobItemWrapper($"{container.Uri}/{blobItem.Prefix}", 0, CloudProvider.Azure, IsAzurite); } if (wrapper != null && !results.Contains(wrapper)) diff --git a/src/StorageLibrary/AzureFile.cs b/src/StorageLibrary/Azure/AzureFile.cs similarity index 99% rename from src/StorageLibrary/AzureFile.cs rename to src/StorageLibrary/Azure/AzureFile.cs index b2bd224..2a263da 100644 --- a/src/StorageLibrary/AzureFile.cs +++ b/src/StorageLibrary/Azure/AzureFile.cs @@ -10,7 +10,7 @@ using StorageLibrary.Common; using StorageLibrary.Interfaces; -namespace StorageLibrary +namespace StorageLibrary.Azure { internal class AzureFile : StorageObject, IFile { diff --git a/src/StorageLibrary/AzureQueue.cs b/src/StorageLibrary/Azure/AzureQueue.cs similarity index 98% rename from src/StorageLibrary/AzureQueue.cs rename to src/StorageLibrary/Azure/AzureQueue.cs index f243baa..996dded 100644 --- a/src/StorageLibrary/AzureQueue.cs +++ b/src/StorageLibrary/Azure/AzureQueue.cs @@ -7,7 +7,7 @@ using StorageLibrary.Common; using StorageLibrary.Interfaces; -namespace StorageLibrary +namespace StorageLibrary.Azure { internal class AzureQueue : StorageObject, IQueue { diff --git a/src/StorageLibrary/AzureTable.cs b/src/StorageLibrary/Azure/AzureTable.cs similarity index 98% rename from src/StorageLibrary/AzureTable.cs rename to src/StorageLibrary/Azure/AzureTable.cs index 78eeda6..122f1ba 100644 --- a/src/StorageLibrary/AzureTable.cs +++ b/src/StorageLibrary/Azure/AzureTable.cs @@ -6,7 +6,7 @@ using StorageLibrary.Common; using StorageLibrary.Interfaces; -namespace StorageLibrary +namespace StorageLibrary.Azure { internal class AzureTable : StorageObject, ITable { diff --git a/src/StorageLibrary/Common/BlobItemWrapper.cs b/src/StorageLibrary/Common/BlobItemWrapper.cs index b7c972c..fc630b3 100644 --- a/src/StorageLibrary/Common/BlobItemWrapper.cs +++ b/src/StorageLibrary/Common/BlobItemWrapper.cs @@ -20,22 +20,43 @@ public string Url public long Size { get; private set; } + public CloudProvider Provider { get; private set; } + public decimal SizeInKBs { get => (decimal)Size / 1024; } public decimal SizeInMBs { get => (decimal)Size / 1024 / 1024; } - public BlobItemWrapper(string url) : this(url, 0) { } + public BlobItemWrapper(string url) : this(url, 0, CloudProvider.Azure) { } - public BlobItemWrapper(string url, long size, bool fromAzurite = false) + public BlobItemWrapper(string url, long size, CloudProvider provider, bool fromAzurite = false) { Url = url; Size = size; + Provider = provider; m_isAzurite = fromAzurite; IsFile = !m_internalUri.Segments[m_internalUri.Segments.Length - 1].EndsWith(System.IO.Path.AltDirectorySeparatorChar); - Container = m_isAzurite ? m_internalUri.Segments[2] : m_internalUri.Segments[1]; Name = HttpUtility.UrlDecode(m_internalUri.Segments[m_internalUri.Segments.Length - 1]); - int containerPos = m_internalUri.LocalPath.IndexOf(Container) + Container.Length; - Path = m_internalUri.LocalPath.Substring(containerPos, (m_internalUri.LocalPath.Length) - (containerPos) - Name.Length); + + switch (provider) + { + case CloudProvider.Azure: + Container = m_isAzurite ? m_internalUri.Segments[2] : m_internalUri.Segments[1]; + int containerPos = m_internalUri.LocalPath.IndexOf(Container) + Container.Length; + Path = m_internalUri.LocalPath.Substring(containerPos, (m_internalUri.LocalPath.Length) - (containerPos) - Name.Length); + break; + case CloudProvider.AWS: + Container = m_internalUri.Host.Split('.')[0]; + Path = m_internalUri.LocalPath.Substring(1, m_internalUri.LocalPath.Length - 1 - Name.Length); + break; + case CloudProvider.GCP: + Container = m_internalUri.Segments[1]; + int bucketPos = m_internalUri.LocalPath.IndexOf(Container) + Container.Length; + Path = m_internalUri.LocalPath.Substring(bucketPos, (m_internalUri.LocalPath.Length) - (bucketPos) - Name.Length); + break; + default: + throw new ApplicationException($"Invalid provider: {provider}"); + } + } public int CompareTo(BlobItemWrapper other) diff --git a/src/StorageLibrary/GCP/GCPBucket.cs b/src/StorageLibrary/GCP/GCPBucket.cs new file mode 100644 index 0000000..9dbf30e --- /dev/null +++ b/src/StorageLibrary/GCP/GCPBucket.cs @@ -0,0 +1,154 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +using Google.Apis.Auth.OAuth2; +using Google.Apis.Services; +using Google.Apis.Storage.v1; +using Google.Apis.Storage.v1.Data; +using GoogleStorageObject = Google.Apis.Storage.v1.Data.Object; + +using StorageLibrary.Common; +using StorageLibrary.Interfaces; + +namespace StorageLibrary.Google +{ + internal class GCPBucket : StorageObject, IContainer + { + const string AppName = "Sebagomez Cloud Storage Explorer"; + protected StorageService _storageService; + protected string _projectId; + + public GCPBucket(StorageFactoryConfig config) : base(config) + { + string serviceAccountPath = config.GcpCredentialsFile; + GoogleCredential credential; + using (var stream = new FileStream(serviceAccountPath, FileMode.Open, FileAccess.Read)) + { + credential = GoogleCredential.FromStream(stream).CreateScoped(StorageService.Scope.DevstorageFullControl); + } + // Create the Storage service. + _storageService = new StorageService(new BaseClientService.Initializer() + { + HttpClientInitializer = credential, + ApplicationName = AppName, + }); + + var underlyingCredential = credential.UnderlyingCredential as ServiceAccountCredential; + if (underlyingCredential != null) + _projectId = underlyingCredential.ProjectId; + } + + public async Task CreateAsync(string bucket, bool publicAccess) + { + var newBucket = new Bucket + { + Name = bucket + }; + + var insertRequest = _storageService.Buckets.Insert(newBucket, _projectId); + await insertRequest.ExecuteAsync(); + + if (publicAccess) + { + await SetBucketPolicyAsync(bucket); + } + } + + private async Task SetBucketPolicyAsync(string bucket) + { + var bucketIamPolicy = new Policy + { + Bindings = new List + { + new Policy.BindingsData + { + Role = "roles/storage.objectViewer", + Members = new List { "allUsers" } + } + } + }; + + var setIamPolicyRequest = new BucketsResource.SetIamPolicyRequest(_storageService, bucketIamPolicy, bucket); + await setIamPolicyRequest.ExecuteAsync(); + } + + public async Task CreateBlobAsync(string bucket, string objectName, Stream fileContent) + { + var uploadRequest = new GoogleStorageObject() + { + Bucket = bucket, + Name = objectName + }; + + var mediaUpload = new ObjectsResource.InsertMediaUpload(_storageService, uploadRequest, bucket, fileContent, "application/octet-stream"); + + await mediaUpload.UploadAsync(); + } + + public async Task DeleteAsync(string bucket) + { + var deleteRequest = _storageService.Buckets.Delete(bucket); + await deleteRequest.ExecuteAsync(); + } + + public async Task DeleteBlobAsync(string bucket, string objectName) + { + var deleteRequest = _storageService.Objects.Delete(bucket, objectName); + await deleteRequest.ExecuteAsync(); + } + + public async Task GetBlobAsync(string bucket, string objectName) + { + string tmpPath = Util.File.GetTempFileName(); + using (var outputFile = new FileStream(tmpPath, FileMode.Create, FileAccess.Write)) + { + var getRequest = _storageService.Objects.Get(bucket, objectName); + await getRequest.DownloadAsync(outputFile); + } + + return tmpPath; + } + + public async Task> ListBlobsAsync(string bucket, string path) + { + var listRequest = _storageService.Objects.List(bucket); + listRequest.Prefix = path; + listRequest.Delimiter = "/"; + + var listObjects = await listRequest.ExecuteAsync(); + + List blobs = new List(); + string uriTemplate = $"https://storage.cloud.google.com/sebagomeztestbucket/"; + if (listObjects.Items != null) + { + foreach (var obj in listObjects.Items) + { + if (obj.Name == path) + continue; + + blobs.Add(new BlobItemWrapper($"{uriTemplate}{obj.Name}", (long)obj.Size, CloudProvider.GCP)); + } + } + + if (listObjects.Prefixes != null) + foreach (string commonPrefix in listObjects.Prefixes) + blobs.Add(new BlobItemWrapper($"{uriTemplate}{commonPrefix}", 0, CloudProvider.GCP)); + + return blobs; + } + + public async Task> ListContainersAsync() + { + var buckets = await _storageService.Buckets.List(_projectId).ExecuteAsync(); + + List containers = new List(); + foreach (var bucket in buckets.Items) + { + containers.Add(new CloudBlobContainerWrapper() { Name = bucket.Name }); + } + + return containers; + } + } +} \ No newline at end of file diff --git a/src/StorageLibrary/Mocks/MockContainer.cs b/src/StorageLibrary/Mocks/MockContainer.cs index 7605429..46b5c0a 100644 --- a/src/StorageLibrary/Mocks/MockContainer.cs +++ b/src/StorageLibrary/Mocks/MockContainer.cs @@ -31,7 +31,7 @@ public async Task> ListBlobsAsync(string containerName, st List results = new List(); foreach(string url in MockUtils.GetItems(containerName, path)) - results.Add(new BlobItemWrapper(url, MockUtils.NewRandomSize)); + results.Add(new BlobItemWrapper(url, MockUtils.NewRandomSize, CloudProvider.Azure)); return results; }); diff --git a/src/StorageLibrary/StorageFactory.cs b/src/StorageLibrary/StorageFactory.cs index 385b8e4..35e3402 100644 --- a/src/StorageLibrary/StorageFactory.cs +++ b/src/StorageLibrary/StorageFactory.cs @@ -1,7 +1,12 @@ +using System; + using StorageLibrary.Common; using StorageLibrary.Interfaces; using StorageLibrary.Mocks; +using StorageLibrary.Azure; +using StorageLibrary.AWS; +using StorageLibrary.Google; namespace StorageLibrary { @@ -23,27 +28,62 @@ public StorageFactory() public StorageFactory(StorageFactoryConfig config) { m_currentConfig = config; - Queues = config.Mock ? new MockQueue() : new AzureQueue(config); - Containers = config.Mock ? new MockContainer() : new AzureContainer(config); - Tables = config.Mock ? new MockTable() : new AzureTable(config); - Files = config.Mock ? new MockFile() : new AzureFile(config); + if (config.Mock) + { + Queues = new MockQueue(); + Containers = new MockContainer(); + Tables = new MockTable(); + Files = new MockFile(); + } + else + { + switch (config.Provider) + { + case CloudProvider.Azure: + Queues = new AzureQueue(config); + Containers = new AzureContainer(config); + Tables = new AzureTable(config); + Files = new AzureFile(config); + break; + case CloudProvider.AWS: + Containers = new AWSBucket(config); + break; + case CloudProvider.GCP: + Containers = new GCPBucket(config); + break; + default: + throw new ApplicationException($"Invalid provider: {config.Provider}"); + } + } Instance = this; } public static BlobItemWrapper GetBlobItemWrapper(string url, long size = 0) { - return new BlobItemWrapper(url, size, Instance.m_currentConfig.IsAzurite); + return new BlobItemWrapper(url, size, Instance.m_currentConfig.Provider, Instance.m_currentConfig.IsAzurite); } } public class StorageFactoryConfig { - public string Account { get; set; } - public string Key { get; set; } - public string Endpoint { get; set; } = "core.windows.net"; - public string ConnectionString { get; set; } + public string AzureAccount { get; set; } + public string AzureKey { get; set; } + public string AzureEndpoint { get; set; } = "core.windows.net"; + public string AzureConnectionString { get; set; } public bool IsAzurite { get; set; } public bool Mock { get; set; } + public string AwsKey { get; set; } + public string AwsSecret { get; set; } + public string AwsRegion { get; set; } + public string GcpCredentialsFile { get; set; } + public CloudProvider Provider { get; set; } = CloudProvider.Azure; + } + + public enum CloudProvider + { + Azure, + AWS, + GCP } } \ No newline at end of file diff --git a/src/StorageLibrary/StorageLibrary.csproj b/src/StorageLibrary/StorageLibrary.csproj index e87c0d3..e158794 100644 --- a/src/StorageLibrary/StorageLibrary.csproj +++ b/src/StorageLibrary/StorageLibrary.csproj @@ -15,6 +15,10 @@ + + + + diff --git a/src/StorageLibrary/StorageObject.cs b/src/StorageLibrary/StorageObject.cs index a4ab245..2db3d3d 100644 --- a/src/StorageLibrary/StorageObject.cs +++ b/src/StorageLibrary/StorageObject.cs @@ -15,25 +15,25 @@ internal class StorageObject const string CONNSTRING_TEMPLATE = "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}"; public StorageObject(StorageFactoryConfig config) - : this(config.Account, config.Key, config.Endpoint, config.ConnectionString, config.IsAzurite){ } - - public StorageObject(string account, string key, string endpoint, string connectionString, bool azurite) { - IsAzurite = azurite; - if (!string.IsNullOrEmpty(connectionString)) + if (config.Provider != CloudProvider.Azure) + return; + + IsAzurite = config.IsAzurite; + if (!string.IsNullOrEmpty(config.AzureConnectionString)) { - ConnectionString = connectionString; + ConnectionString = config.AzureConnectionString; } - else if (key.Contains("SharedAccessSignature=")) + else if (config.AzureKey.Contains("SharedAccessSignature=")) { - ConnectionString = key; + ConnectionString = config.AzureKey; } else { - Account = account; - Key = key; - if (!string.IsNullOrEmpty(endpoint)) - Endpoint = endpoint; + Account = config.AzureAccount; + Key = config.AzureKey; + if (!string.IsNullOrEmpty(config.AzureEndpoint)) + Endpoint = config.AzureEndpoint; ConnectionString = string.Format(CONNSTRING_TEMPLATE, Account, Key, Endpoint); } diff --git a/src/web/Pages/BaseComponent.razor b/src/web/Pages/BaseComponent.razor index 0821b9a..63662e2 100644 --- a/src/web/Pages/BaseComponent.razor +++ b/src/web/Pages/BaseComponent.razor @@ -1,4 +1,4 @@ - + diff --git a/src/web/Pages/Home.razor b/src/web/Pages/Home.razor index 0c685cb..17b5171 100644 --- a/src/web/Pages/Home.razor +++ b/src/web/Pages/Home.razor @@ -3,16 +3,32 @@ +

Welcome to the revamped version of Azure Storage web explorer

+@if (Utils.Util.Provider != "Azure") +{ +

Congratulations! 🥳 you just found a new hidden feature that allows you to manage your @Utils.Util.Provider objects

+}

This is a side project that I work on whenever I find the time and will. Want to contribute in any way? head over to the repo at https://github.com/sebagomez/azurestorageexplorer

With this site you can manage

    -
  • Blobs: Create public or private Containers and Blobs (only BlockBlobs for now). Upload, download and delete blobs.
  • -
  • Queues: Create Queues and messages.
  • -
  • Tables: Create table and Entities. To create an Entity you'll have to add one property per line in the form of <PropertyName>=<PropertyValue>. You can also set the data type for a specific property adding the odata.type value. To retrieve data, you must provide a query (or leave blank) in the form of <PropertyName> <operator> '<PropertyValue>'(mind the quotes '), being <operator> one of the supported comparison operators
  • -
  • Files Shares: Navigate thrugh your file shares and directories. Upload, download and delete files.
  • + @switch (Utils.Util.Provider) + { + case "Azure": +
  • Blobs: Create public or private Containers and Blobs (only BlockBlobs for now). Upload, download and delete blobs.
  • +
  • Queues: Create Queues and messages.
  • +
  • Tables: Create table and Entities. To create an Entity you'll have to add one property per line in the form of <PropertyName>=<PropertyValue>. You can also set the data type for a specific property adding the odata.type value. To retrieve data, you must provide a query (or leave blank) in the form of <PropertyName> <operator> '<PropertyValue>'(mind the quotes '), being <operator> one of the supported comparison operators
  • +
  • Files Shares: Navigate thrugh your file shares and directories. Upload, download and delete files.
  • + break; + case "AWS": +
  • Buckets: Create public or private S3 Buckets and manage (upload, download, and delete) your S3 objects.
  • + break; + case "GCP": +
  • Buckets: Create public or private Buckets and manage (upload, download, and delete) your GCP objects.
  • + break; + }

More info in the project's README file. diff --git a/src/web/Pages/Login.razor.cs b/src/web/Pages/Login.razor.cs index ba349d6..a6a30d2 100644 --- a/src/web/Pages/Login.razor.cs +++ b/src/web/Pages/Login.razor.cs @@ -75,6 +75,42 @@ protected override async Task OnInitializedAsync() } } } + else //check if it's AWS or GCP + { + string? cloudProvider = Environment.GetEnvironmentVariable("CLOUD_PROVIDER"); + if (!string.IsNullOrEmpty(cloudProvider)) + { + if (cloudProvider.Equals("AWS", StringComparison.OrdinalIgnoreCase)) + { + string? awsAccessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY"); + string? awsSecretKey = Environment.GetEnvironmentVariable("AWS_SECRET_KEY"); + string? awsRegion = Environment.GetEnvironmentVariable("AWS_REGION"); + if (!string.IsNullOrEmpty(awsAccessKey) && !string.IsNullOrEmpty(awsSecretKey) && !string.IsNullOrEmpty(awsRegion)) + { + Credentials awsCredentials = new Credentials + { + Provider = "AWS", + AwsKey = awsAccessKey, + AwsSecret = awsSecretKey, + AwsRegion = awsRegion + }; + if (await awsCredentials.IsAuthenticated(SessionStorage!)) + NavManager!.NavigateTo("home"); + } + } + else if (cloudProvider.Equals("GCP", StringComparison.OrdinalIgnoreCase)) + { + string? gcpCredentials = Environment.GetEnvironmentVariable("GCP_CREDENTIALS_FILE"); + if (!string.IsNullOrEmpty(gcpCredentials)) + { + Credentials gcpCred = new Credentials { Provider = "GCP", GcpCredFile = gcpCredentials }; + if (await gcpCred.IsAuthenticated(SessionStorage!)) + NavManager!.NavigateTo("home"); + } + } + } + + } } } diff --git a/src/web/Shared/NavMenu.razor b/src/web/Shared/NavMenu.razor index 8511b82..77bdbfd 100644 --- a/src/web/Shared/NavMenu.razor +++ b/src/web/Shared/NavMenu.razor @@ -4,29 +4,53 @@

@code { + + [Parameter] + public string? Provider { get; set; } + + [Parameter] + public bool IsAzurite { get; set; } = false; + [Parameter] public string? Account { get; set; } @@ -49,7 +73,7 @@ private Dictionary QueueAtts = new Dictionary(); private Dictionary TableAtts = new Dictionary(); private Dictionary FileAtts = new Dictionary(); - + protected override void OnInitialized() { if (BlobAtts.ContainsKey("class")) @@ -64,16 +88,16 @@ switch (Selected) { case "Containers": - BlobAtts.Add("class", "selectedMenu"); + BlobAtts.Add("class", "selectedMenu " + Provider!.ToLower()); break; case "Tables": - TableAtts.Add("class", "selectedMenu"); + TableAtts.Add("class", "selectedMenu " + Provider!.ToLower()); break; case "Queues": - QueueAtts.Add("class", "selectedMenu"); + QueueAtts.Add("class", "selectedMenu " + Provider!.ToLower()); break; case "FileShares": - FileAtts.Add("class", "selectedMenu"); + FileAtts.Add("class", "selectedMenu " + Provider!.ToLower()); break; } diff --git a/src/web/Utils/Credentials.cs b/src/web/Utils/Credentials.cs index 44058f8..9022342 100644 --- a/src/web/Utils/Credentials.cs +++ b/src/web/Utils/Credentials.cs @@ -7,10 +7,18 @@ namespace web.Utils { public class Credentials { + const string PROVIDER = "wasm_provider"; const string ACCOUNT = "wasm_account"; const string KEY = "wasm_key"; const string ENDPOINT = "wasm_endpoint"; const string CONNECTION_STRING = "wasm_connectionString"; + const string AWS_KEY = "wasm_aws_key"; + const string AWS_SECRET = "wasm_aws_secret"; + const string AWS_REGION = "wasm_aws_region"; + const string GCP_CREDENTIALS_FILE = "wasm_gcp_credfile"; + + [DataMember] + public string? Provider { get; set; } = "Azure"; [DataMember] public string? Account { get; set; } @@ -20,31 +28,42 @@ public class Credentials public string? Endpoint { get; set; } [DataMember] public string? ConnectionString { get; set; } + [DataMember] + public string? AwsKey { get; set; } + [DataMember] + public string? AwsSecret { get; set; } + [DataMember] + public string? AwsRegion { get; set; } + [DataMember] + public string? GcpCredFile { get; set; } public Credentials() { } - public Credentials(string azure_account, string azure_key, string azure_endpoint, string azure_connectionString) - { - Account = azure_account; - Key = azure_key; - Endpoint = azure_endpoint; - ConnectionString = azure_connectionString; - } - public async Task SaveAsync(ProtectedBrowserStorage sessionStorage) { if (string.IsNullOrEmpty(Account) && !string.IsNullOrEmpty(ConnectionString)) Account = GetAccountName(); + if (string.IsNullOrEmpty(Account) && Provider != "Azure") + Account = Provider; + + await sessionStorage.SetAsync(PROVIDER, Provider!); await sessionStorage.SetAsync(ACCOUNT, Account!); await sessionStorage.SetAsync(KEY, Key!); await sessionStorage.SetAsync(ENDPOINT, Endpoint!); await sessionStorage.SetAsync(CONNECTION_STRING, ConnectionString!); + await sessionStorage.SetAsync(AWS_KEY, AwsKey!); + await sessionStorage.SetAsync(AWS_SECRET, AwsSecret!); + await sessionStorage.SetAsync(AWS_REGION, AwsRegion!); + await sessionStorage.SetAsync(GCP_CREDENTIALS_FILE, GcpCredFile!); } private string GetAccountName() { + if (Provider != "Azure") + return Provider!; + var connStringArray = ConnectionString!.Split(';', StringSplitOptions.RemoveEmptyEntries); var dictionary = new Dictionary(); foreach (var item in connStringArray) @@ -76,19 +95,29 @@ public static async Task LoadCredentialsAsync(ProtectedBrowserStora { return new Credentials { + Provider = (await sessionStorage.GetAsync(PROVIDER)).Value, Account = (await sessionStorage.GetAsync(ACCOUNT)).Value, Key = (await sessionStorage.GetAsync(KEY)).Value, Endpoint = (await sessionStorage.GetAsync(ENDPOINT)).Value, - ConnectionString = (await sessionStorage.GetAsync(CONNECTION_STRING)).Value + ConnectionString = (await sessionStorage.GetAsync(CONNECTION_STRING)).Value, + AwsKey = (await sessionStorage.GetAsync(AWS_KEY)).Value, + AwsSecret = (await sessionStorage.GetAsync(AWS_SECRET)).Value, + AwsRegion = (await sessionStorage.GetAsync(AWS_REGION)).Value, + GcpCredFile = (await sessionStorage.GetAsync(GCP_CREDENTIALS_FILE)).Value }; } public static async Task ClearAsync(ProtectedBrowserStorage sessionStorage) { + await sessionStorage.DeleteAsync(PROVIDER); await sessionStorage.DeleteAsync(ACCOUNT); await sessionStorage.DeleteAsync(KEY); await sessionStorage.DeleteAsync(ENDPOINT); await sessionStorage.DeleteAsync(CONNECTION_STRING); + await sessionStorage.DeleteAsync(AWS_KEY); + await sessionStorage.DeleteAsync(AWS_SECRET); + await sessionStorage.DeleteAsync(AWS_REGION); + await sessionStorage.DeleteAsync(GCP_CREDENTIALS_FILE); } public async Task IsAuthenticated(ProtectedBrowserStorage sessionStorage) diff --git a/src/web/Utils/Util.cs b/src/web/Utils/Util.cs index 99cf108..36d4fb3 100644 --- a/src/web/Utils/Util.cs +++ b/src/web/Utils/Util.cs @@ -13,15 +13,33 @@ public class Util public const string MOCK = "MOCK"; public const string AZURITE = "AZURITE"; + public static string Provider { get; set; } = "Azure"; + public static bool Azurite { get; set; } = false; + public static StorageFactory GetStorageFactory(Credentials cred) { + Provider = cred.Provider!; + string? mock = Environment.GetEnvironmentVariable(MOCK); bool mockEnabled = mock is not null && mock.ToLower() == bool.TrueString.ToLower(); string? azurite = Environment.GetEnvironmentVariable(AZURITE); - bool azuriteEnabled = azurite is not null && azurite.ToLower() == bool.TrueString.ToLower(); + Azurite = azurite is not null && azurite.ToLower() == bool.TrueString.ToLower(); - return new StorageFactory(new StorageFactoryConfig { Account = cred.Account, Key = cred.Key, Endpoint = cred.Endpoint, ConnectionString = cred.ConnectionString, IsAzurite = azuriteEnabled, Mock = mockEnabled }); + return new StorageFactory(new StorageFactoryConfig + { + Provider = Enum.Parse(cred.Provider!), + AzureAccount = cred.Account, + AzureKey = cred.Key, + AzureEndpoint = cred.Endpoint, + AzureConnectionString = cred.ConnectionString, + AwsKey = cred.AwsKey, + AwsSecret = cred.AwsSecret, + AwsRegion = cred.AwsRegion, + GcpCredentialsFile = cred.GcpCredFile, + IsAzurite = Azurite, + Mock = mockEnabled + }); } } } diff --git a/src/web/wwwroot/css/azurewebexplorer.css b/src/web/wwwroot/css/azurewebexplorer.css index 0ea507e..890501e 100644 --- a/src/web/wwwroot/css/azurewebexplorer.css +++ b/src/web/wwwroot/css/azurewebexplorer.css @@ -12,6 +12,16 @@ font-family: Segoe UI,SegoeUI,Segoe WP,Tahoma,Arial,sans-serif; } +.aws { + color: #FF9900 !important; + font-family: Segoe UI,SegoeUI,Segoe WP,Tahoma,Arial,sans-serif; +} + +.gcp { + color: #FF3E30 !important; + font-family: Segoe UI,SegoeUI,Segoe WP,Tahoma,Arial,sans-serif; +} + .errorMessage { position: fixed !important; width: 60%; @@ -84,7 +94,6 @@ .selectedMenu { font-weight: bold; - color: #00abec; } .contextMenu{ diff --git a/src/web/wwwroot/res/AWSExplorerLogo.png b/src/web/wwwroot/res/AWSExplorerLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..f03ff7f65e7b5e4e11853e2bb3a8be8644d31b26 GIT binary patch literal 15207 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 literal 0 HcmV?d00001 diff --git a/src/web/wwwroot/res/GCPExplorerLogo.png b/src/web/wwwroot/res/GCPExplorerLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..b1cfee1e259bc390e13e9a960fabc995b9b70e3a GIT binary patch literal 13027 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 s`w@3I0rj2# Date: Fri, 3 Jan 2025 14:45:48 -0500 Subject: [PATCH 2/3] Increase version --- src/web/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Directory.Build.props b/src/web/Directory.Build.props index 4afcd53..a98dd4d 100644 --- a/src/web/Directory.Build.props +++ b/src/web/Directory.Build.props @@ -1,5 +1,5 @@ - 2.17.2 + 3.0.0 \ No newline at end of file From 875c15f5f7297134c51465c82e75ef7844378bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20G=C3=B3mez?= Date: Fri, 3 Jan 2025 14:58:04 -0500 Subject: [PATCH 3/3] Add AWS and GCP support to README with environment variable instructions --- README.md | 10 ++++++++++ res/AWSExplorer.png | Bin 0 -> 25584 bytes 2 files changed, 10 insertions(+) create mode 100644 res/AWSExplorer.png diff --git a/README.md b/README.md index 12a13ad..a27f8f7 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,16 @@ These variables are `AZURE_STORAGE_CONNECTIONSTRING`, `AZURE_STORAGE_ACCOUNT`, ` If you want to test it against [Azurite](https://github.com/Azure/Azurite) (either locally, via Docker, Docker Compose, or Kubernetes) you'll have to add the `AZURITE` variable set to `true`. +#### AWS & GCP + +You can now also manager your AWS and GCP buckets. Just make sure you set the environment variable `CLOUD_PROVIDER` to either `AWS` or `GCP` and you also need to set up a few other environments depending the cloud provider. +If you want to connect to your AWS S3 account, you need to provider three environment variables `AWS_ACCESS_KEY`, `AWS_SECRET_KEY`, and `AWS_REGION`. +If in the other hand you want to connect to GCP, you need to donload the credentials file for your service account and set the `GCP_CREDENTIALS_FILE` environment variable to the full path to that file. + +![](./res/AWSExplorer.png) + +**This feature is in beta so feel free to provide feedback** + ## Exploring **Blobs**: Create public or private Containers and Blobs (only BlockBlobs for now). Download or delete your blobs. diff --git a/res/AWSExplorer.png b/res/AWSExplorer.png new file mode 100644 index 0000000000000000000000000000000000000000..d22faec067298016bb0cd3272dc1a698487d4211 GIT binary patch literal 25584 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 E05kX`JOBUy literal 0 HcmV?d00001