Repository: getmoto/moto

Issue:
Error creating secret with moto_server
Hello, 

I'm using moto_server with command : `moto_server -p4566`.

When I try to create a simple aws secrets with Terraform, I get the following error, with no trace in moto :

```
│ Error: reading Secrets Manager Secret (arn:aws:secretsmanager:<region>:123456789012:secret:test-tls-20230308133703611100000001-RDLGSh) policy: parsing policy: unexpected result: (<nil>) "<nil>"
│
│   with aws_secretsmanager_secret.tls,
│   on secret.tf line 32, in resource "aws_secretsmanager_secret" "tls":
│   32: resource "aws_secretsmanager_secret" "tls" {
```

Here is the Terraform resource :

```hcl
resource "aws_secretsmanager_secret" "tls" {
  name_prefix = "test-tls-"
}

resource "aws_secretsmanager_secret_version" "tls" {
  secret_id     = aws_secretsmanager_secret.tls.id
  secret_string = local.secret
}
``` 

I try to add `policy=""` or `policy="{}"`, the result is the same.
And if I try to add a valid policy, I get an error because the `put_resource_policy` action is not supported.


Discussion:
Looks like we're returning a `None` value where TF expects an empty string, somehow, somewhere. Marking it as a bug.

Patch:
diff --git a/moto/secretsmanager/models.py b/moto/secretsmanager/models.py
--- a/moto/secretsmanager/models.py
+++ b/moto/secretsmanager/models.py
@@ -87,6 +87,7 @@ def __init__(
         self.rotation_lambda_arn = ""
         self.auto_rotate_after_days = 0
         self.deleted_date = None
+        self.policy = None
 
     def update(
         self, description=None, tags=None, kms_key_id=None, last_changed_date=None
@@ -825,29 +826,37 @@ def update_secret_version_stage(
 
         return secret_id
 
-    @staticmethod
-    def get_resource_policy(secret_id):
-        resource_policy = {
-            "Version": "2012-10-17",
-            "Statement": {
-                "Effect": "Allow",
-                "Principal": {
-                    "AWS": [
-                        "arn:aws:iam::111122223333:root",
-                        "arn:aws:iam::444455556666:root",
-                    ]
-                },
-                "Action": ["secretsmanager:GetSecretValue"],
-                "Resource": "*",
-            },
+    def put_resource_policy(self, secret_id: str, policy: str):
+        """
+        The BlockPublicPolicy-parameter is not yet implemented
+        """
+        if not self._is_valid_identifier(secret_id):
+            raise SecretNotFoundException()
+
+        secret = self.secrets[secret_id]
+        secret.policy = policy
+        return secret.arn, secret.name
+
+    def get_resource_policy(self, secret_id):
+        if not self._is_valid_identifier(secret_id):
+            raise SecretNotFoundException()
+
+        secret = self.secrets[secret_id]
+        resp = {
+            "ARN": secret.arn,
+            "Name": secret.name,
         }
-        return json.dumps(
-            {
-                "ARN": secret_id,
-                "Name": secret_id,
-                "ResourcePolicy": json.dumps(resource_policy),
-            }
-        )
+        if secret.policy is not None:
+            resp["ResourcePolicy"] = secret.policy
+        return json.dumps(resp)
+
+    def delete_resource_policy(self, secret_id):
+        if not self._is_valid_identifier(secret_id):
+            raise SecretNotFoundException()
+
+        secret = self.secrets[secret_id]
+        secret.policy = None
+        return secret.arn, secret.name
 
 
 secretsmanager_backends = BackendDict(SecretsManagerBackend, "secretsmanager")
diff --git a/moto/secretsmanager/responses.py b/moto/secretsmanager/responses.py
--- a/moto/secretsmanager/responses.py
+++ b/moto/secretsmanager/responses.py
@@ -174,6 +174,17 @@ def get_resource_policy(self):
         secret_id = self._get_param("SecretId")
         return self.backend.get_resource_policy(secret_id=secret_id)
 
+    def put_resource_policy(self):
+        secret_id = self._get_param("SecretId")
+        policy = self._get_param("ResourcePolicy")
+        arn, name = self.backend.put_resource_policy(secret_id, policy)
+        return json.dumps(dict(ARN=arn, Name=name))
+
+    def delete_resource_policy(self):
+        secret_id = self._get_param("SecretId")
+        arn, name = self.backend.delete_resource_policy(secret_id)
+        return json.dumps(dict(ARN=arn, Name=name))
+
     def tag_resource(self):
         secret_id = self._get_param("SecretId")
         tags = self._get_param("Tags", if_none=[])


Test patch:
diff --git a/tests/terraformtests/terraform-tests.success.txt b/tests/terraformtests/terraform-tests.success.txt
--- a/tests/terraformtests/terraform-tests.success.txt
+++ b/tests/terraformtests/terraform-tests.success.txt
@@ -452,6 +452,14 @@ s3:
   - TestAccS3ObjectsDataSource_fetchOwner
 sagemaker:
   - TestAccSageMakerPrebuiltECRImageDataSource
+secretsmanager:
+  - TestAccSecretsManagerSecretDataSource_basic
+  - TestAccSecretsManagerSecretPolicy_
+  - TestAccSecretsManagerSecret_RecoveryWindowInDays_recreate
+  - TestAccSecretsManagerSecret_tags
+  - TestAccSecretsManagerSecret_kmsKeyID
+  - TestAccSecretsManagerSecret_withNamePrefix
+  - TestAccSecretsManagerSecret_rotationRules
 servicediscovery:
   - TestAccServiceDiscoveryDNSNamespaceDataSource
   - TestAccServiceDiscoveryHTTPNamespace
diff --git a/tests/test_secretsmanager/test_policy.py b/tests/test_secretsmanager/test_policy.py
new file mode 100644
--- /dev/null
+++ b/tests/test_secretsmanager/test_policy.py
@@ -0,0 +1,77 @@
+import boto3
+import json
+import pytest
+
+from botocore.exceptions import ClientError
+from moto import mock_secretsmanager
+
+
+@mock_secretsmanager
+def test_get_initial_policy():
+    client = boto3.client("secretsmanager", region_name="us-west-2")
+    client.create_secret(Name="test-secret")
+
+    resp = client.get_resource_policy(SecretId="test-secret")
+    assert resp.get("Name") == "test-secret"
+    assert "ARN" in resp
+    assert "ResourcePolicy" not in resp
+
+
+@mock_secretsmanager
+def test_put_resource_policy():
+    client = boto3.client("secretsmanager", region_name="us-west-2")
+    client.create_secret(Name="test-secret")
+
+    policy = {
+        "Statement": [
+            {
+                "Action": "secretsmanager:GetSecretValue",
+                "Effect": "Allow",
+                "Principal": {
+                    "AWS": "arn:aws:iam::123456789012:role/tf-acc-test-655046176950657276"
+                },
+                "Resource": "*",
+                "Sid": "EnableAllPermissions",
+            }
+        ],
+        "Version": "2012-10-17",
+    }
+    resp = client.put_resource_policy(
+        SecretId="test-secret", ResourcePolicy=json.dumps(policy)
+    )
+    assert "ARN" in resp
+    assert "Name" in resp
+
+    resp = client.get_resource_policy(SecretId="test-secret")
+    assert "ResourcePolicy" in resp
+    assert json.loads(resp["ResourcePolicy"]) == policy
+
+
+@mock_secretsmanager
+def test_delete_resource_policy():
+    client = boto3.client("secretsmanager", region_name="us-west-2")
+    client.create_secret(Name="test-secret")
+
+    client.put_resource_policy(SecretId="test-secret", ResourcePolicy="some policy")
+
+    client.delete_resource_policy(SecretId="test-secret")
+
+    resp = client.get_resource_policy(SecretId="test-secret")
+    assert "ResourcePolicy" not in resp
+
+
+@mock_secretsmanager
+def test_policies_for_unknown_secrets():
+    client = boto3.client("secretsmanager", region_name="us-west-2")
+
+    with pytest.raises(ClientError) as exc:
+        client.put_resource_policy(SecretId="unknown secret", ResourcePolicy="p")
+    assert exc.value.response["Error"]["Code"] == "ResourceNotFoundException"
+
+    with pytest.raises(ClientError) as exc:
+        client.get_resource_policy(SecretId="unknown secret")
+    assert exc.value.response["Error"]["Code"] == "ResourceNotFoundException"
+
+    with pytest.raises(ClientError) as exc:
+        client.delete_resource_policy(SecretId="unknown secret")
+    assert exc.value.response["Error"]["Code"] == "ResourceNotFoundException"