description: "redacted-commands"

schemaVersion: "1.5"

runOnRequirements:
  - minServerVersion: "5.0"
    auth: false

createEntities:
  - client:
      id: &client client
      observeEvents:
        - commandStartedEvent
        - commandSucceededEvent
      observeSensitiveCommands: true
  - database:
      id: &database database
      client: *client
      databaseName: &databaseName command-monitoring-tests

tests:
  - description: "authenticate"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: authenticate
          command:
            authenticate: 1
            mechanism: "MONGODB-X509"
            user: "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"
            db: "$external"
        # An authentication error is expected, but we want to check that the
        # CommandStartedEvent is redacted
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: authenticate
              # We cannot simply assert that command is an empty document
              # because it's at root-level, so we make a best effort to make
              # sure sensitive fields are redacted.
              command:
                authenticate: { $$exists: false }
                mechanism: { $$exists: false }
                user: { $$exists: false }
                db: { $$exists: false }

  - description: "saslStart"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: saslStart
          command:
            saslStart: 1
            payload: "definitely-invalid-payload"
            db: "admin"
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: saslStart
              command:
                saslStart: { $$exists: false }
                payload: { $$exists: false }
                db: { $$exists: false }

  - description: "saslContinue"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: saslContinue
          command:
            saslContinue: 1
            conversationId: 0
            payload: "definitely-invalid-payload"
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: saslContinue
              command:
                saslContinue: { $$exists: false }
                conversationId: { $$exists: false }
                payload: { $$exists: false }

  - description: "getnonce"
    runOnRequirements:
    - maxServerVersion: 6.1.99 # getnonce removed as of 6.2 via SERVER-71007
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: getnonce
          command:
            getnonce: 1
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: getnonce
              command: { getnonce: { $$exists: false } }
          - commandSucceededEvent:
              commandName: getnonce
              reply:
                ok: { $$exists: false }
                nonce: { $$exists: false }

  - description: "createUser"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: createUser
          command:
            createUser: "private"
            # Passing an object is prohibited and we want to trigger a command
            # failure
            pwd: {}
            roles: []
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: createUser
              command:
                createUser: { $$exists: false }
                pwd: { $$exists: false }
                roles: { $$exists: false }

  - description: "updateUser"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: updateUser
          command:
            updateUser: "private"
            pwd: {}
            roles: []
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: updateUser
              command:
                updateUser: { $$exists: false }
                pwd: { $$exists: false }
                roles: { $$exists: false }

  - description: "copydbgetnonce"
    runOnRequirements:
    - maxServerVersion: 3.6.99 # copydbgetnonce was removed as of 4.0 via SERVER-32276
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: copydbgetnonce
          command:
            copydbgetnonce: "private"
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: copydbgetnonce
              command: { copydbgetnonce: { $$exists: false } }

  - description: "copydbsaslstart"
    runOnRequirements:
    - maxServerVersion: 4.0.99 # copydbsaslstart was removed as of 4.2 via SERVER-36211
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: copydbsaslstart
          command:
            copydbsaslstart: "private"
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: copydbsaslstart
              command: { copydbsaslstart: { $$exists: false } }

  - description: "copydb"
    runOnRequirements:
    - maxServerVersion: 4.0.99 # copydb was removed as of 4.2 via SERVER-36257
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: copydb
          command:
            copydb: "private"
        expectError:
          isError: true
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: copydb
              command: { copydb: { $$exists: false } }

  - description: "hello with speculative authenticate"
    runOnRequirements:
      - minServerVersion: "4.9"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: hello
          command:
            hello: 1
            speculativeAuthenticate:
              saslStart: 1
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: hello
              command:
                hello: { $$exists: false }
                speculativeAuthenticate: { $$exists: false }
          - commandSucceededEvent:
              commandName: hello
              reply:
                # Even though authentication above fails and the reply does not
                # contain sensitive information, we're expecting the reply to be
                # redacted as well.
                isWritablePrimary: { $$exists: false }
                # This assertion will currently always hold true since we're
                # not expecting successful authentication, in which case this
                # field is missing anyways.
                speculativeAuthenticate: { $$exists: false }

  - description: "legacy hello with speculative authenticate"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: ismaster
          command:
            ismaster: 1
            speculativeAuthenticate:
              saslStart: 1
      - name: runCommand
        object: *database
        arguments:
          commandName: isMaster
          command:
            isMaster: 1
            speculativeAuthenticate:
              saslStart: 1
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: ismaster
              command:
                ismaster: { $$exists: false }
                speculativeAuthenticate: { $$exists: false }
          - commandSucceededEvent:
              commandName: ismaster
              reply:
                ismaster: { $$exists: false }
                speculativeAuthenticate: { $$exists: false }
          - commandStartedEvent:
              commandName: isMaster
              command:
                isMaster: { $$exists: false }
                speculativeAuthenticate: { $$exists: false }
          - commandSucceededEvent:
              commandName: isMaster
              reply:
                ismaster: { $$exists: false }
                speculativeAuthenticate: { $$exists: false }

  - description: "hello without speculative authenticate is not redacted"
    runOnRequirements:
      - minServerVersion: "4.9"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: hello
          command:
            hello: 1
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: hello
              command:
                hello: 1
          - commandSucceededEvent:
              commandName: hello
              reply:
                isWritablePrimary: { $$exists: true }

  - description: "legacy hello without speculative authenticate is not redacted"
    operations:
      - name: runCommand
        object: *database
        arguments:
          commandName: ismaster
          command:
            ismaster: 1
      - name: runCommand
        object: *database
        arguments:
          commandName: isMaster
          command:
            isMaster: 1
    expectEvents:
      - client: *client
        events:
          - commandStartedEvent:
              commandName: ismaster
              command:
                ismaster: 1
          - commandSucceededEvent:
              commandName: ismaster
              reply:
                ismaster: { $$exists: true }
          - commandStartedEvent:
              commandName: isMaster
              command:
                isMaster: 1
          - commandSucceededEvent:
              commandName: isMaster
              reply:
                ismaster: { $$exists: true }