I am creating an azure function that has a blob trigger. When the blob is uploaded, it is encrypted and transferred to another container. The issue I am facing is that when i transfer the blob to the second container the name of the blob file is the same and the only thing i was capable of doing is adding ".pgp" at the end of the file name. I would like to trim the last 4 characters of the blob (.txt) and replace them with .pgp.
The following is my code:
namespace EncryptAndTransfer
{
public class EncryptAndTransfer
{
[FunctionName("EncryptAndTransfer")]
public async Task Run([BlobTrigger("send-decrypted/{name}", Connection = "bctofabstorgacc_Storage")]Stream myBlob,
string name,
[Blob("send-encrypted/{name}.pgp", FileAccess.Write, Connection = "bctofabstorgacc_Storage")] Stream outBlob,
[Blob("send-decrypted/fabtraderhubtest.asc", FileAccess.Read, Connection = "bctofabstorgacc_Storage")] Stream publicKeyBlob,
ILogger log)
{
//Getting the secrets required for the function
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
// Load the public key
PgpPublicKey publicKey = LoadPublicKey(publicKeyBlob, log);
if (publicKey == null)
{
log.LogError("Failed to load the public key.");
return;
}
// Encrypt the content
byte[] encryptedData = EncryptData(myBlob, publicKey, log);
// Write the encrypted content to the output blob
outBlob.Write(encryptedData, 0, encryptedData.Length);
}
private static PgpPublicKey LoadPublicKey(Stream publicKeyStream, ILogger log)
{
try
{
using (StreamReader reader = new StreamReader(publicKeyStream, Encoding.ASCII))
{
PgpPublicKeyRing publicKeyRing = new PgpPublicKeyRing(
PgpUtilities.GetDecoderStream(reader.BaseStream)
);
PgpPublicKey publicKey = publicKeyRing.GetPublicKeys().OfType<PgpPublicKey>().FirstOrDefault();
if (publicKey != null)
{
return publicKey;
}
}
}
catch (PgpException ex)
{
log.LogError("PgpException caught in LoadPublicKey: " + ex.Message);
}
catch (IOException ex)
{
log.LogError("IOException caught in LoadPublicKey: " + ex.Message);
}
return null;
}
private static byte[] EncryptData(Stream inputData, PgpPublicKey publicKey, ILogger log)
{
try
{
using (MemoryStream encryptedStream = new MemoryStream())
{
// Create the encrypted data generator
PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Aes256, true);
// Add the public key to the encrypted data generator
encryptedDataGenerator.AddMethod(publicKey);
// Create an output stream connected to the encrypted data generator
using (Stream outputStream = encryptedDataGenerator.Open(encryptedStream, new byte[1 << 16]))
{
// Copy the input data to the output stream
inputData.CopyTo(outputStream);
}
// Return the encrypted data
return encryptedStream.ToArray();
}
}
catch (Exception ex)
{
log.LogError("Exception caught in EncryptData: " + ex.Message);
throw; // rethrow the exception after logging
}
}
}
}
I have tried to add .pgp to the output blob which worked but i cannot remove the .txt from it.
How to change the name of the blob file when transferring it from one container to another?
This is not possible. Renaming is not supported and also refer this SO-thread.
Alternatively to change name, Firstly, you can use your code and send the file to temporary container2.
Whenever a blob comes in container2 with more than one extension in name, use below function and send the renamed file to container3:
But if you want to rename a blob use this function:
using System;
using System.IO;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace FunctionApp72
{
public class Function1
{
private readonly IConfiguration configg;
public Function1(IConfiguration configuration)
{
configg = configuration;
}
[FunctionName("Function1")]
public async Task Run([BlobTrigger("test/{name}", Connection = "rithcon")] Stream myBlob, string name, ILogger log)
{
using var blobStreamReader = new StreamReader(myBlob);
var data = await blobStreamReader.ReadToEndAsync();
string withoutext1 = RemoveExtension(name);
Console.WriteLine($"Uploaded File Name: {name}");
Console.WriteLine($"After removing unwanted extensions: {withoutext1}");
string value = configg.GetValue<string>("rithcon");
var bsc = new BlobServiceClient(value);
var bcc = bsc.GetBlobContainerClient("test2");
var bc = bcc.GetBlobClient(withoutext1);
using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(data)))
{
await bc.UploadAsync(stream, true);
}
// Delete the original blob
var obc = bcc.GetBlobClient(name);
await obc.DeleteIfExistsAsync();
}
static string RemoveExtension(string fn)
{
int Index = fn.LastIndexOf('.');
if (Index != -1)
{
string dir = Path.GetDirectoryName(fn);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn);
int firDIndex = fileNameWithoutExtension.IndexOf('.');
if (firDIndex != -1)
{
fileNameWithoutExtension = fileNameWithoutExtension.Substring(0, firDIndex);
}
fn = Path.Combine(dir, $"{fileNameWithoutExtension}{Path.GetExtension(fn)}");
}
return fn;
}
}
}
Uploaded file to test
container:
Output:
In container 3 test2
file name is changed: