Repository: opentofu/opentofu
File: internal/command/e2etest/encryption_test.go (Go)

Code before:
		// Unconfigured encryption clearly fails on encrypted state
		apply().Failure().StderrContains("can not be read without an encryption configuration")
	}

	with("required.tf", func() {
		// Encryption works with fallback removed
		apply().Success()
		requireEncryptedState()

		// Can't apply unencrypted plan
		applyPlan(unencryptedPlan).Failure().StderrContains("encountered unencrypted payload without unencrypted method")
		requireEncryptedState()

		// Apply encrypted plan
		applyPlan(encryptedPlan).StderrContains("Saved plan is stale")
		requireEncryptedState()
	})

	with("broken.tf", func() {
		// Make sure changes to encryption keys notify the user correctly
		apply().Failure().StderrContains("decryption failed for state")
		requireEncryptedState()

		tofuResultError := applyPlan(encryptedPlan).Failure()
		SanitizeStderr(&tofuResultError)
		tofuResultError.StderrContains("decryption failed: cipher: message authentication failed")

		requireEncryptedState()
	})

	with("migratefrom.tf", func() {
		// Apply migration from encrypted state
		apply().Success()
		requireUnencryptedState()
		// Make changes and confirm it's still encrypted (even with migration enabled)
		apply().Success()
		requireUnencryptedState()

		// Apply unencrypted plan (with migration active)
		applyPlan(unencryptedPlan).StderrContains("Saved plan is stale")
		requireUnencryptedState()

		// Apply encrypted plan (with migration active)
		applyPlan(encryptedPlan).StderrContains("Saved plan is stale")
		requireUnencryptedState()
	})

	{
		// Back to no encryption configuration with unencrypted state
		apply().Success()
		requireUnencryptedState()

Review comment (security):
`suggestion`
As a continuation of the comment on `SanitizeStderr`, once you have a new function created to handle the sanitisation of the stderr, would be better to call that func inside `StderrContains`. That way, all the testing structure in here will be able to make use of it.


Code after:
		// Unconfigured encryption clearly fails on encrypted state
		apply().Failure().StderrContains("can not be read without an encryption configuration")
	}

	with("required.tf", func() {
		// Encryption works with fallback removed
		apply().Success()
		requireEncryptedState()

		// Can't apply unencrypted plan
		applyPlan(unencryptedPlan).Failure().StderrContains("encountered unencrypted payload without unencrypted method")
		requireEncryptedState()

		// Apply encrypted plan
		applyPlan(encryptedPlan).StderrContains("Saved plan is stale")
		requireEncryptedState()
	})

	with("broken.tf", func() {
		// Make sure changes to encryption keys notify the user correctly
		apply().Failure().StderrContains("decryption failed for state")
		requireEncryptedState()

		applyPlan(encryptedPlan).Failure().StderrContains("decryption failed: cipher: message authentication failed")

		requireEncryptedState()
	})

	with("migratefrom.tf", func() {
		// Apply migration from encrypted state
		apply().Success()
		requireUnencryptedState()
		// Make changes and confirm it's still encrypted (even with migration enabled)
		apply().Success()
		requireUnencryptedState()

		// Apply unencrypted plan (with migration active)
		applyPlan(unencryptedPlan).StderrContains("Saved plan is stale")
		requireUnencryptedState()

		// Apply encrypted plan (with migration active)
		applyPlan(encryptedPlan).StderrContains("Saved plan is stale")
		requireUnencryptedState()
	})

	{
		// Back to no encryption configuration with unencrypted state
		apply().Success()
		requireUnencryptedState()

		// Apply unencrypted plan