1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-25 17:27:45 +01:00

Make development easier (#3504)

* Remove Certificate Steps from Setup

* Add Helpers to VSCode Tasks

* Force Ephermal Key in Integration Tests

* Add Property to Interface
This commit is contained in:
Justin Baur 2023-12-08 15:14:49 -05:00 committed by GitHub
parent 43eea0d297
commit 8d36dfa5d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 64 additions and 50 deletions

View File

@ -19,20 +19,11 @@ configure_other_vars() {
cp secrets.json .secrets.json.tmp
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)"
CERT_OUTPUT="$(./create_certificates_linux.sh)"
#shellcheck disable=SC2086
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
#shellcheck disable=SC2086
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True"
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT"
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT"
jq \
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" |
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" |
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" |
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" |
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\"" \
.secrets.json.tmp >secrets.json
rm -f .secrets.json.tmp
popd >/dev/null || exit
@ -51,7 +42,7 @@ Proceed? [y/N] " response
pushd ./dev >/dev/null || exit
pwsh ./setup_secrets.ps1 || true
popd >/dev/null || exit
echo "Running migrations..."
sleep 5 # wait for DB container to start
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING"

View File

@ -12,5 +12,11 @@
"extensions": ["ms-dotnettools.csdevkit"]
}
},
"postCreateCommand": "bash .devcontainer/internal_dev/postCreateCommand.sh"
"postCreateCommand": "bash .devcontainer/internal_dev/postCreateCommand.sh",
"portsAttributes": {
"1080": {
"label": "Mail Catcher",
"onAutoForward": "notify"
}
}
}

View File

@ -29,20 +29,11 @@ configure_other_vars() {
cp secrets.json .secrets.json.tmp
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)"
CERT_OUTPUT="$(./create_certificates_linux.sh)"
#shellcheck disable=SC2086
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
#shellcheck disable=SC2086
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True"
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT"
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT"
jq \
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" |
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" |
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" |
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" |
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\"" \
.secrets.json.tmp >secrets.json
rm .secrets.json.tmp
popd >/dev/null || exit
@ -74,7 +65,7 @@ Press <Enter> to continue."
echo "Injecting dotnet secrets..."
pwsh ./setup_secrets.ps1 || true
popd >/dev/null || exit
echo "Running migrations..."
sleep 5 # wait for DB container to start
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING"

36
.vscode/tasks.json vendored
View File

@ -211,6 +211,42 @@
"clear": false
},
"problemMatcher": "$msCompile"
},
{
"label": "Setup Secrets",
"type": "shell",
"command": "pwsh -WorkingDirectory ${workspaceFolder}/dev -Command '${workspaceFolder}/dev/setup_secrets.ps1 -clear:$${input:setupSecretsClear}'",
"problemMatcher": []
},
{
"label": "Install Dev Cert",
"type": "shell",
"command": "dotnet tool install -g dotnet-certificate-tool -g && certificate-tool add --file ${workspaceFolder}/dev/dev.pfx --password '${input:certPassword}'",
"problemMatcher": []
}
],
"inputs": [
{
"id": "setupSecretsClear",
"type": "pickString",
"default": "true",
"description": "Whether or not to clear existing secrets",
"options": [
{
"label": "true",
"value": "true"
},
{
"label": "false",
"value": "false"
}
]
},
{
"id": "certPassword",
"type": "promptString",
"description": "Password for your dev certificate.",
"password": true
}
]
}

View File

@ -23,6 +23,7 @@
},
"storage": {
"connectionString": "UseDevelopmentStorage=true"
}
},
"developmentDirectory": "../../../dev"
}
}

2
dev/.gitignore vendored
View File

@ -15,5 +15,7 @@ data_protection_dev.crt
data_protection_dev.key
data_protection_dev.pfx
signingkey.jwk
# Reverse Proxy Conifg
reverse-proxy.conf

View File

@ -4,9 +4,6 @@
IDENTITY_SERVER_KEY=identity_server_dev.key
IDENTITY_SERVER_CERT=identity_server_dev.crt
IDENTITY_SERVER_CN="Bitwarden Identity Server Dev"
DATA_PROTECTION_KEY=data_protection_dev.key
DATA_PROTECTION_CERT=data_protection_dev.crt
DATA_PROTECTION_CN="Bitwarden Data Protection Dev"
# Detect management command to trust generated certificates.
if [ -x "$(command -v update-ca-certificates)" ]; then
@ -30,19 +27,10 @@ openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 3650 \
sudo cp $IDENTITY_SERVER_CERT $CA_CERT_DIR
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 3650 \
-keyout $DATA_PROTECTION_KEY \
-out $DATA_PROTECTION_CERT \
-subj "/CN=$DATA_PROTECTION_CN"
sudo cp $DATA_PROTECTION_CERT $CA_CERT_DIR
sudo $UPDATE_CA_CMD
identity=($(openssl x509 -in $IDENTITY_SERVER_CERT -outform der | sha1sum | tr a-z A-Z))
data=($(openssl x509 -in $DATA_PROTECTION_CERT -outform der | sha1sum | tr a-z A-Z))
echo "Certificate fingerprints:"
echo "Identity Server Dev: ${identity}"
echo "Data Protection Dev: ${data}"

View File

@ -7,17 +7,8 @@ openssl pkcs12 -export -legacy -out identity_server_dev.pfx -inkey identity_serv
security import ./identity_server_dev.pfx -k ~/Library/Keychains/Login.keychain
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout data_protection_dev.key -out data_protection_dev.crt \
-subj "/CN=Bitwarden Data Protection Dev" -days 3650
openssl pkcs12 -export -legacy -out data_protection_dev.pfx -inkey data_protection_dev.key -in data_protection_dev.crt \
-certfile data_protection_dev.crt
security import ./data_protection_dev.pfx -k ~/Library/Keychains/Login.keychain
identity=($(openssl x509 -in identity_server_dev.crt -outform der | shasum -a 1 | tr a-z A-Z));
data=($(openssl x509 -in data_protection_dev.crt -outform der | shasum -a 1 | tr a-z A-Z));
echo "Certificate fingerprints:"
echo "Identity Server Dev: ${identity}"
echo "Data Protection Dev: ${data}"

View File

@ -9,6 +9,3 @@ $params = @{
$params['Subject'] = 'CN=Bitwarden Identity Server Dev';
New-SelfSignedCertificate @params;
$params['Subject'] = 'CN=Bitwarden Data Protection Dev';
New-SelfSignedCertificate @params;

View File

@ -80,6 +80,7 @@ public class GlobalSettings : IGlobalSettings
public virtual IPasswordlessAuthSettings PasswordlessAuth { get; set; } = new PasswordlessAuthSettings();
public virtual IDomainVerificationSettings DomainVerification { get; set; } = new DomainVerificationSettings();
public virtual ILaunchDarklySettings LaunchDarkly { get; set; } = new LaunchDarklySettings();
public virtual string DevelopmentDirectory { get; set; }
public string BuildExternalUri(string explicitValue, string name)
{
@ -401,7 +402,7 @@ public class GlobalSettings : IGlobalSettings
/// <value></value>
public string CertificatePassword { get; set; }
/// <summary>
/// The thumbprint of the certificate in the X.509 certificate store for personal certificates for the user account running Bitwarden.
/// The thumbprint of the certificate in the X.509 certificate store for personal certificates for the user account running Bitwarden.
/// </summary>
/// <value></value>
public string CertificateThumbprint { get; set; }

View File

@ -23,4 +23,5 @@ public interface IGlobalSettings
IPasswordlessAuthSettings PasswordlessAuth { get; set; }
IDomainVerificationSettings DomainVerification { get; set; }
ILaunchDarklySettings LaunchDarkly { get; set; }
string DevelopmentDirectory { get; set; }
}

View File

@ -25,6 +25,7 @@
},
"storage": {
"connectionString": "UseDevelopmentStorage=true"
}
},
"developmentDirectory": "../../dev"
}
}

View File

@ -511,6 +511,11 @@ public static class ServiceCollectionExtensions
{
identityServerBuilder.AddSigningCredential(certificate);
}
else if (env.IsDevelopment() && !string.IsNullOrEmpty(globalSettings.DevelopmentDirectory))
{
var developerSigningKeyPath = Path.Combine(globalSettings.DevelopmentDirectory, "signingkey.jwk");
identityServerBuilder.AddDeveloperSigningCredential(true, developerSigningKeyPath);
}
else if (env.IsDevelopment())
{
identityServerBuilder.AddDeveloperSigningCredential(false);

View File

@ -88,6 +88,9 @@ public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
{ "globalSettings:send:connectionString", null},
{ "globalSettings:notifications:connectionString", null},
{ "globalSettings:storage:connectionString", null},
// This will force it to use an ephemeral key for IdentityServer
{ "globalSettings:developmentDirectory", null }
});
});