Azure / azure-dev

A developer CLI that reduces the time it takes for you to get started on Azure. The Azure Developer CLI (azd) provides a set of developer-friendly commands that map to key stages in your workflow - code, build, deploy, monitor, repeat.
https://aka.ms/azd
MIT License
410 stars 198 forks source link

Aspire: Encode values inserted into URIs and connection strings #3598

Open DamianEdwards opened 7 months ago

DamianEdwards commented 7 months ago

See https://github.com/dotnet/aspire/issues/3117

When a value in an Aspire manifest is detected as a URI or connection string format, expressions within that value should be appropriately escaped, e.g. the expressions in the following value should be URL escaped: "amqp://{resources.rabbitusr.value}:{resources.rabbitpw.value}@{resources.rabbitmq.bindings.tcp.host}:{resources.rabbitmq.bindings.tcp.port}"

danm-de commented 1 month ago

Would it be possible to implement a projection function for ReferenceExpression in which we can modify the values? Are there any serialization scenarios in which the Func<T,TResult> would be a problem?

Example:

/// <summary>
/// Gets the connection string expression with credentials for the RabbitMQ server.
/// </summary>
public ReferenceExpression ConnectionStringExpression
{
    get
    {
        var encodedUserReference = UserReference.Select(value => HttpUtility.UrlEncode(value));
        var encodedPasswordReference = PasswordReference.Select(value => HttpUtility.UrlEncode(value));

        return ReferenceExpression.Create(
            $"amqp://{encodedUserReference}:{encodedPasswordReference}@{PrimaryEndpoint.Property(EndpointProperty.Host)}:{PrimaryEndpoint.Property(EndpointProperty.Port)}");
    }
}
DamianEdwards commented 1 month ago

I think the issue is the expression has to be evaluated by the reader, e.g. azd, so the encoding itself can't be implemented in the app host. Rather it needs a value written out to the manifest like amqp://{urlencode(resources.rabbitusr.value)}:{urlencode(resources.rabbitpw.value)}@{resources.rabbitmq.bindings.tcp.host}:{resources.rabbitmq.bindings.tcp.port}