Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 92 #95

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Issue 92 #95

wants to merge 3 commits into from

Conversation

MichalFrends1
Copy link
Contributor

@MichalFrends1 MichalFrends1 commented Dec 11, 2024

issue 92

Summary by CodeRabbit

  • New Features

    • Introduced a new parameter, Destination.TargetFolder, allowing users to specify a target folder for blob uploads.
  • Improvements

    • Renamed parameters for clarity:
      • Source.BlobName to Source.RenameToBlobName
      • Source.BlobFolderName to Source.RenameToFolderName
  • Bug Fixes

    • Enhanced validation for ContainerName to prevent invalid characters.
    • Improved error handling with more descriptive messages during upload operations.

…olderName to RenameToFolderName, modifed UploadBlob method and existing tests to cover the TargetFolder field.
Copy link

coderabbitai bot commented Dec 11, 2024

Walkthrough

The pull request introduces several updates to the Frends.AzureBlobStorage.UploadBlob module, including the addition of a new parameter Destination.TargetFolder for specifying upload paths. Existing parameters Source.BlobName and Source.BlobFolderName have been renamed to Source.RenameToBlobName and Source.RenameToFolderName respectively for clarity. Unit tests have been modified to reflect these changes, ensuring that blob uploads correctly reference the new parameter names and target folder functionality.

Changes

File Change Summary
Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md Updated changelog for version 3.0.0; added Destination.TargetFolder; renamed parameters for clarity.
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob.Tests/UnitTests.cs Renamed properties in Source class; added TargetFolder to Destination; updated test methods.
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Destination.cs Added public string TargetFolder property to Destination class.
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Source.cs Renamed properties: BlobName to RenameToBlobName and BlobFolderName to RenameToFolderName.
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/UploadBlob.cs Updated UploadBlob method to include validation; changed parameter names to reflect new naming.

Possibly related PRs

  • AzureBlobStorage tasks - update Azure.Identity #89: The changes in this PR involve updates to environment variables related to Azure Blob Storage tasks, which may indirectly relate to the overall functionality of the UploadBlob module, although it does not directly modify the same parameters or methods.

🐇 In the land of Azure where blobs do play,
A new folder's born to brighten the day!
With names that now sing, so clear and so bright,
Uploads are easier, oh what a delight!
So hop along, friends, to the cloud we shall go,
With targets in sight, watch our storage grow! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (6)
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Destination.cs (1)

Line range hint 134-141: Update HandleExistingFile documentation to clarify target folder behavior.

The HandleExistingFile property's documentation should be updated to clarify how it interacts with the new TargetFolder property.

Apply this diff to enhance the documentation:

     /// <summary>
     /// How the existing blob will be handled.
     /// Append: Append the blob with Source.SourceFile. Block and Page blobs will be downloaded as a temp file which will be deleted after local append and upload processes are complete. No downloading needed for Append Blob.
     /// Overwrite: The original blob will be deleted before uploading the new one.
     /// Error: Depending on Options.ThrowErrorOnFailure, throw an exception or Result will contain an error message instead of the blob's URL.
+    /// Note: When TargetFolder is specified, the existence check and operations will be performed on the full path including the target folder.
     /// </summary>
     /// <example>HandleExistingFile.Error</example>
     [DefaultValue(HandleExistingFile.Error)]
     public HandleExistingFile HandleExistingFile { get; set; }
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Source.cs (1)

44-57: Consider adding migration guidance for breaking changes.

Both property renames (BlobNameRenameToBlobName and BlobFolderNameRenameToFolderName) are breaking changes that improve clarity but may affect existing users. Consider adding migration guidance in the changelog or documentation to help users update their code.

Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/UploadBlob.cs (2)

62-65: Trim leading slashes from TargetFolder to avoid unintended paths

If TargetFolder contains leading slashes, it may result in incorrect blob paths. Consider trimming both leading and trailing slashes.

Apply this diff:

- blobName = $"{destination.TargetFolder.TrimEnd('/', '\\')}/{blobName}";
+ blobName = $"{destination.TargetFolder.Trim('/', '\\')}/{blobName}";

84-88: Consistent trimming of slashes for TargetFolder in directory uploads

Similar to previous, consider trimming both leading and trailing slashes from TargetFolder to maintain consistent blob paths when uploading directories.

Apply this diff:

- blobName = $"{destination.TargetFolder.TrimEnd('/', '\\')}/{blobName}";
+ blobName = $"{destination.TargetFolder.Trim('/', '\\')}/{blobName}";
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob.Tests/UnitTests.cs (2)

20-20: Avoid hardcoding storage account name in tests

Consider retrieving the storage account name from an environment variable to improve flexibility and security.

Apply this diff:

- private readonly string _storageAccount = "stataskdevelopment";
+ private readonly string _storageAccount = Environment.GetEnvironmentVariable("Frends_AzureBlobStorage_StorageAccount");

291-293: Clarify the use of empty string for TargetFolder

Setting TargetFolder to an empty string may cause unintended behavior. Consider using null or adding validation to handle this scenario.

Apply this diff:

- _destinationCS.TargetFolder = "";
+ _destinationCS.TargetFolder = null;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b747ce0 and 3b20248.

📒 Files selected for processing (5)
  • Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md (1 hunks)
  • Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob.Tests/UnitTests.cs (11 hunks)
  • Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Destination.cs (1 hunks)
  • Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Source.cs (1 hunks)
  • Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/UploadBlob.cs (4 hunks)
🔇 Additional comments (7)
Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Destination.cs (1)

64-69: Verify the impact of this new property on existing blob operations.

The addition of TargetFolder could affect how blobs are stored and accessed. Let's verify the implementation details.

✅ Verification successful

Let me gather more information about how this new property is being used in the implementation.


Based on the results, I can now provide a final response:

The TargetFolder property implementation is properly handled and tested

The implementation shows that:

  • The property is correctly used to prepend folder paths to blob names during upload
  • Path separators are properly normalized using TrimEnd('/', '\\')
  • The feature is well-tested in UnitTests.cs with various scenarios:
    • Null/empty target folder
    • Target folder with actual value
    • Both connection string and OAuth2 authentication methods
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing blob path handling and potential impacts

# Look for existing blob path construction logic
rg -l 'blob.*path|path.*blob' | while read -r file; do
  echo "=== $file ==="
  rg -A 5 'blob.*path|path.*blob' "$file"
done

# Check for existing tests related to blob paths
ast-grep --pattern 'class $_ {
  $$$
  [Test]
  $$$
  void $_($$$) {
    $$$
    blob$$$path$$$
    $$$
  }
  $$$
}'

Length of output: 2229


Script:

#!/bin/bash
# Check the implementation to see how TargetFolder is used
rg -A 10 "TargetFolder" 

# Look for blob name construction or manipulation
ast-grep --pattern 'BlobClient($$$)'

# Check for tests that might verify the TargetFolder functionality
fd -e cs test -x rg -l "TargetFolder" {}

Length of output: 13992

Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/Definitions/Source.cs (2)

52-57: Fix documentation typo and verify breaking change.

The rename from BlobFolderName to RenameToFolderName improves clarity, but there's a typo in the documentation (double period after "Storage..").

Apply this fix:

-    /// Specifies a custom name for the blob folder in Azure Blob Storage.. If left empty, blob folder's name will be the same as source directory (e.g., 'Example' in C:\temp\Example).
+    /// Specifies a custom name for the blob folder in Azure Blob Storage. If left empty, blob folder's name will be the same as source directory (e.g., 'Example' in C:\temp\Example).

Let's verify the impact of this breaking change:

✅ Verification successful

Fix documentation typo in property comment.

The property rename from BlobFolderName to RenameToFolderName is properly documented in the changelog as part of version 3.0.0. The breaking change is well-communicated and justified for improved clarity. Only the documentation typo needs to be fixed.

-    /// Specifies a custom name for the blob folder in Azure Blob Storage.. If left empty, blob folder's name will be the same as source directory (e.g., 'Example' in C:\temp\Example).
+    /// Specifies a custom name for the blob folder in Azure Blob Storage. If left empty, blob folder's name will be the same as source directory (e.g., 'Example' in C:\temp\Example).
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to the old property name
rg "BlobFolderName" --type cs

# Check if the breaking change is documented in changelog
cat CHANGELOG.md

Length of output: 93


Script:

#!/bin/bash
# Let's check if there's a changelog file with a different name pattern
fd -i changelog

# Search for any references to the old property name in the entire codebase
rg "BlobFolderName" -l

# Let's also check the test files specifically for any usage
fd -e cs -e Tests test

Length of output: 1953


Script:

#!/bin/bash
# Let's check the changelog content for this specific component
cat "Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md"

# Let's also check the actual occurrences of BlobFolderName with context
rg "BlobFolderName" -C 2

Length of output: 2856


44-49: Property rename improves clarity but requires verification of breaking changes.

The rename from BlobName to RenameToBlobName makes the property's purpose more explicit. The updated documentation clearly explains the default behavior.

Let's verify the impact of this breaking change:

✅ Verification successful

The previous search revealed:

  1. The property rename is consistently updated in the UploadBlob project
  2. Other projects (ReadBlob, DownloadBlob, DeleteBlob) use their own BlobName properties which are unrelated
  3. No CHANGELOG.md found, so we need to check other documentation files for breaking changes

Let's verify if there's documentation about breaking changes in other locations.


Let's try a different approach to locate and check documentation files. The previous fd command had syntax issues, so switching to find for basic file discovery.


Let's check the changelog for breaking changes documentation and any remaining references to the old property name in the documentation.


Property rename is properly documented as a breaking change

The rename from BlobName to RenameToBlobName is properly documented in the changelog under version 3.0.0 as a breaking change. The code changes are consistent across the UploadBlob project, and the property is not referenced by other projects in the solution. No further action is needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to the old property name
rg "BlobName" --type cs

# Check if the breaking change is documented in changelog
cat CHANGELOG.md

Length of output: 7204


Script:

#!/bin/bash
# Check for changelog or release notes in other common locations
fd -g "*CHANGELOG*" -g "*RELEASE*" -g "*HISTORY*" -i

# Check for documentation files that might contain breaking changes
fd -g "README*" -g "BREAKING*" -g "UPGRADE*" -i

Length of output: 409


Script:

#!/bin/bash
# Search for documentation files from the repository root
find . -type f -iname "README*" -o -iname "CHANGELOG*" -o -iname "RELEASE*" -o -iname "HISTORY*"

# Check content of README if found in the UploadBlob project directory
cat Frends.AzureBlobStorage.UploadBlob/README.md 2>/dev/null

Length of output: 1640


Script:

#!/bin/bash
# Check the changelog content for the UploadBlob project
cat Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md

# Check if there are any references to the old property name in documentation
rg "BlobName" Frends.AzureBlobStorage.UploadBlob/README.md Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md

Length of output: 2204

Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob/UploadBlob.cs (2)

60-61: Blob renaming logic is appropriate

The updated logic correctly handles renaming the blob when RenameToBlobName is specified or when compression is enabled.


78-80: Ensure RenameToFolderName is validated properly

When using source.RenameToFolderName, validate it for any invalid path characters to prevent potential errors during path construction.

Frends.AzureBlobStorage.UploadBlob/CHANGELOG.md (1)

3-7: Changelog updates are clear and well-documented

The addition of version 3.0.0 with detailed descriptions of added and changed features enhances the clarity of the project's history.

Frends.AzureBlobStorage.UploadBlob/Frends.AzureBlobStorage.UploadBlob.Tests/UnitTests.cs (1)

144-150: Verify handling of invalid FileEncoding in tests

The FileEncoding is set to "foo/bar", which is not a standard encoding. Ensure that the test is designed to handle this case and asserts the expected behavior.

Comment on lines +64 to +69
/// <summary>
/// Specifies the target folder path for the blob in Azure Blob Storage.
/// This value will be prepended to blob names during upload, effectively creating a virtual directory structure.
/// </summary>
/// <example>backups/2024/</example>
public string TargetFolder { get; set; }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation and improve documentation for the TargetFolder property.

While the property implementation is functionally correct, consider these improvements:

  1. Add validation to ensure proper folder path format
  2. Document path format requirements (e.g., handling of slashes)
  3. Add UI hints for better user experience

Apply this diff to enhance the property:

     /// <summary>
     /// Specifies the target folder path for the blob in Azure Blob Storage.
     /// This value will be prepended to blob names during upload, effectively creating a virtual directory structure.
+    /// The path should:
+    /// - Use forward slashes (/) as directory separators
+    /// - Not start with a forward slash
+    /// - Optionally end with a forward slash (will be normalized during upload)
+    /// - Not contain invalid characters: \ " [ ] < > |
     /// </summary>
     /// <example>backups/2024/</example>
+    [DisplayFormat(DataFormatString = "Text")]
+    [RegularExpression(@"^[^\\<>\[\]""|]+(\/[^\\<>\[\]""|]+)*\/?$", 
+        ErrorMessage = "Invalid folder path format. Use forward slashes and avoid special characters.")]
+    [Description("Virtual directory path where the blob will be stored.")]
     public string TargetFolder { get; set; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <summary>
/// Specifies the target folder path for the blob in Azure Blob Storage.
/// This value will be prepended to blob names during upload, effectively creating a virtual directory structure.
/// </summary>
/// <example>backups/2024/</example>
public string TargetFolder { get; set; }
/// <summary>
/// Specifies the target folder path for the blob in Azure Blob Storage.
/// This value will be prepended to blob names during upload, effectively creating a virtual directory structure.
/// The path should:
/// - Use forward slashes (/) as directory separators
/// - Not start with a forward slash
/// - Optionally end with a forward slash (will be normalized during upload)
/// - Not contain invalid characters: \ " [ ] < > |
/// </summary>
/// <example>backups/2024/</example>
[DisplayFormat(DataFormatString = "Text")]
[RegularExpression(@"^[^\\<>\[\]""|]+(\/[^\\<>\[\]""|]+)*\/?$",
ErrorMessage = "Invalid folder path format. Use forward slashes and avoid special characters.")]
[Description("Virtual directory path where the blob will be stored.")]
public string TargetFolder { get; set; }

Comment on lines +36 to +39
if (destination.ContainerName.Contains('/') || destination.ContainerName.Contains('\\'))
{
throw new Exception("The container name cannot contain '/' or '\\'.");
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use a more specific exception type for container name validation

Instead of throwing a general Exception, consider throwing an ArgumentException to provide more context about the invalid ContainerName parameter.

Apply this diff to improve exception handling:

- throw new Exception("The container name cannot contain '/' or '\\'.");
+ throw new ArgumentException("The container name cannot contain '/' or '\\'.", nameof(destination.ContainerName));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (destination.ContainerName.Contains('/') || destination.ContainerName.Contains('\\'))
{
throw new Exception("The container name cannot contain '/' or '\\'.");
}
if (destination.ContainerName.Contains('/') || destination.ContainerName.Contains('\\'))
{
throw new ArgumentException("The container name cannot contain '/' or '\\'.", nameof(destination.ContainerName));
}

Comment on lines +399 to +408
string normalizedBlobName = blobName.Replace('/', '\\');

var tempFile = Path.Combine(Path.GetTempPath(), normalizedBlobName);

string directoryPath = Path.GetDirectoryName(tempFile);

if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate blobName to prevent path traversal vulnerabilities

Using blobName directly in file paths without validation can lead to security issues if it contains path traversal characters. Sanitize blobName to ensure only valid file names are used when creating temporary files.

Apply this diff to sanitize blobName:

- string normalizedBlobName = blobName.Replace('/', '\\');
+ string normalizedBlobName = Path.GetFileName(blobName.Replace('/', '\\'));

This change uses Path.GetFileName to extract only the file name, preventing directory traversal.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
string normalizedBlobName = blobName.Replace('/', '\\');
var tempFile = Path.Combine(Path.GetTempPath(), normalizedBlobName);
string directoryPath = Path.GetDirectoryName(tempFile);
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
string normalizedBlobName = Path.GetFileName(blobName.Replace('/', '\\'));
var tempFile = Path.Combine(Path.GetTempPath(), normalizedBlobName);
string directoryPath = Path.GetDirectoryName(tempFile);
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant