Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/MySql/MySqlBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Publishing;
using Aspire.Hosting.Utils;

namespace Aspire.Hosting;

Expand All @@ -24,7 +25,7 @@ public static class MySqlBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{MySqlContainerResource}"/>.</returns>
public static IResourceBuilder<MySqlContainerResource> AddMySqlContainer(this IDistributedApplicationBuilder builder, string name, int? port = null, string? password = null)
{
password ??= Guid.NewGuid().ToString("N");
password ??= PasswordUtil.GeneratePassword();
var mySqlContainer = new MySqlContainerResource(name, password);
return builder.AddResource(mySqlContainer)
.WithManifestPublishingCallback(context => WriteMySqlContainerResourceToManifest(context, mySqlContainer))
Expand All @@ -51,7 +52,7 @@ public static IResourceBuilder<MySqlContainerResource> AddMySqlContainer(this ID
/// <returns>A reference to the <see cref="IResourceBuilder{MySqlContainerResource}"/>.</returns>
public static IResourceBuilder<MySqlServerResource> AddMySql(this IDistributedApplicationBuilder builder, string name)
{
var password = Guid.NewGuid().ToString("N");
var password = PasswordUtil.GeneratePassword();
var mySqlContainer = new MySqlServerResource(name, password);
return builder.AddResource(mySqlContainer)
.WithManifestPublishingCallback(WriteMySqlContainerToManifest)
Expand Down
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/Postgres/PostgresBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Publishing;
using Aspire.Hosting.Utils;

namespace Aspire.Hosting;

Expand All @@ -24,7 +25,7 @@ public static class PostgresBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{PostgresContainerResource}"/>.</returns>
public static IResourceBuilder<PostgresContainerResource> AddPostgresContainer(this IDistributedApplicationBuilder builder, string name, int? port = null, string? password = null)
{
password = password ?? Guid.NewGuid().ToString("N");
password = password ?? PasswordUtil.GeneratePassword();
var postgresContainer = new PostgresContainerResource(name, password);
return builder.AddResource(postgresContainer)
.WithManifestPublishingCallback(context => WritePostgresContainerResourceToManifest(context, postgresContainer))
Expand Down Expand Up @@ -53,7 +54,7 @@ public static IResourceBuilder<PostgresContainerResource> AddPostgresContainer(t
/// <returns>A reference to the <see cref="IResourceBuilder{PostgresContainerResource}"/>.</returns>
public static IResourceBuilder<PostgresServerResource> AddPostgres(this IDistributedApplicationBuilder builder, string name)
{
var password = Guid.NewGuid().ToString("N");
var password = PasswordUtil.GeneratePassword();
var postgresServer = new PostgresServerResource(name, password);
return builder.AddResource(postgresServer)
.WithManifestPublishingCallback(WritePostgresContainerToManifest)
Expand Down
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/RabbitMQ/RabbitMQBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Publishing;
using Aspire.Hosting.Utils;

namespace Aspire.Hosting;

Expand All @@ -22,7 +23,7 @@ public static class RabbitMQBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{RabbitMQContainerResource}"/>.</returns>
public static IResourceBuilder<RabbitMQContainerResource> AddRabbitMQContainer(this IDistributedApplicationBuilder builder, string name, int? port = null, string? password = null)
{
password ??= Guid.NewGuid().ToString("N");
password ??= PasswordUtil.GeneratePassword();
var rabbitMq = new RabbitMQContainerResource(name, password);
return builder.AddResource(rabbitMq)
.WithAnnotation(new ServiceBindingAnnotation(ProtocolType.Tcp, port: port, containerPort: 5672))
Expand Down Expand Up @@ -52,7 +53,7 @@ public static IResourceBuilder<RabbitMQContainerResource> AddRabbitMQContainer(t
/// <returns>A reference to the <see cref="IResourceBuilder{RabbitMQContainerResource}"/>.</returns>
public static IResourceBuilder<RabbitMQServerResource> AddRabbitMQ(this IDistributedApplicationBuilder builder, string name)
{
var password = Guid.NewGuid().ToString("N");
var password = PasswordUtil.GeneratePassword();
var rabbitMq = new RabbitMQServerResource(name, password);
return builder.AddResource(rabbitMq)
.WithAnnotation(new ServiceBindingAnnotation(ProtocolType.Tcp, containerPort: 5672))
Expand Down
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/SqlServer/SqlServerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Publishing;
using Aspire.Hosting.Utils;

namespace Aspire.Hosting;

Expand All @@ -22,7 +23,7 @@ public static class SqlServerBuilderExtensions
/// <returns>A reference to the <see cref="IResourceBuilder{SqlServerContainerResource}"/>.</returns>
public static IResourceBuilder<SqlServerContainerResource> AddSqlServerContainer(this IDistributedApplicationBuilder builder, string name, string? password = null, int? port = null)
{
password = password ?? Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N").ToUpper();
password = password ?? PasswordUtil.GeneratePassword();
var sqlServer = new SqlServerContainerResource(name, password);

return builder.AddResource(sqlServer)
Expand Down Expand Up @@ -52,7 +53,7 @@ public static IResourceBuilder<SqlServerContainerResource> AddSqlServerContainer
/// <returns>A reference to the <see cref="IResourceBuilder{SqlServerContainerResource}"/>.</returns>
public static IResourceBuilder<SqlServerServerResource> AddSqlServer(this IDistributedApplicationBuilder builder, string name)
{
var password = Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N").ToUpper();
var password = PasswordUtil.GeneratePassword();
var sqlServer = new SqlServerServerResource(name, password);

return builder.AddResource(sqlServer)
Expand Down
43 changes: 43 additions & 0 deletions src/Aspire.Hosting/Utils/PasswordUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,47 @@ namespace Aspire.Hosting.Utils;
internal static class PasswordUtil
{
internal static string EscapePassword(string password) => password.Replace("\"", "\"\"");

/// <summary>
/// Returns a random password of length <paramref name="length"/> that does not contain any characters that would be escaped by <see cref="EscapePassword(string)"/>.
/// </summary>
/// <remarks>If <paramref name="length"/> is greater than or equal to four, the password is guaranteed to contain an uppercase ASCII letter, a lowercase ASCII letter, a digit, and a symbol.</remarks>
internal static string GeneratePassword(int length = 20)
Copy link
Contributor

Choose a reason for hiding this comment

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

How cryptographically secure is this implementation? Writing a good password generator is probably more complicated than writing own cache.
There are quite a few related Qs on the web, e.g., https://stackoverflow.com/questions/54991/generating-random-passwords.

Also, having this implementation static essentially forces it for everyone. Shouldn't it be instead be injectable and replaceable?

{
return string.Create(length, 0, (buffer, _) =>
Copy link
Member

Choose a reason for hiding this comment

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

I think this password generation might be a problematic. Imagine that we set a password length of 6. We would already know that the first character is going to be in the range A-Z, second a-z, third 0-9, and forth one of the specials. Obviously, that becomes less of an issue the longer you get.

{
if (length >= 1)
{
// add an uppercase ASCII letter
Random.Shared.GetItems(PasswordChars.Slice(0, 26), buffer[..1]);

if (length >= 2)
{
// add a lowercase ASCII letter
Random.Shared.GetItems(PasswordChars.Slice(26, 26), buffer[1..2]);
Copy link
Member

Choose a reason for hiding this comment

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

Incorrect range?


if (length >= 3)
{
// add a digit
Random.Shared.GetItems(PasswordChars.Slice(52, 10), buffer[2..3]);

if (length >= 4)
{
// add a symbol
Random.Shared.GetItems(PasswordChars.Slice(62), buffer[3..4]);

if (length >= 5)
{
// use random password characters for the rest of the password
Random.Shared.GetItems(PasswordChars, buffer[4..]);
}
}
}
}
}
});
}

// Characters to use in a password that do not need to be escaped. They should be in the order: UPPER, lower, digits, symbols
private static ReadOnlySpan<char> PasswordChars => "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmonpqrstuvwxyz0123456789!@$^&*()[]{}':,._-";
}