Conditional read in context of delete

I want to run the following query: Verification.firstWhere(.email == "john@doecom")!.delete()

It’s a read followed by a delete. The challenge is now, that Verification is a quite sensitive collection, as it stores also verification tokens, so I don’t want that a user can read it’s content (And as my current knowledge field permissions are not yet existing in Fauna). But I want to give the user the chance to delete a verification that is associated with his identity.
The catch: I would like to work with standard query syntax Verification.firstWhere(.email == "john@doe.com")!.delete() in combination with ABAC rather then continuously introducing custom functions. So my question is, can I achieve somehow a conditional read that is only allowed if it’s directly followed by a delete?

Current code snippet:

role role_user {
  // [...]

  // Only delete permission is not enough as the document needs to be first identified with `read` permissions to get deleted.
  privileges Verification {
    delete {
      predicate ((doc) => {
        Query.identity()!.activeVerifications.includes(doc.email)
      })
    }
  }

  membership User {
    predicate ( (doc) => isCalledWithAccessToken() )
  }
}

collection Verification {
    email: String
    otp: String // This is the high sensitive field that should not be exposed to the user via `read` permission.
    user: Ref<User>?

    // [...]
}

It is not possible to make one privilege contingent upon future operations. Privileges are required at the time an operation is performed. If you don’t have the required privilege, the whole transaction is short-circuited. Inversely, if you do have the privilege, the operation is accepted and the query moves on.

In a case as complex as this, creating a UDF is the appropriate solution.

I think it would be problematic to attempt build rules around the kind of contingency you are looking for. Do you have suggestions for how to manage the rules you are looking for?

For example, how should fauna know the difference between the following?

let v = Verification.firstWhere(.email == "john@doecom")
// do stuff with v
v!.delete()

or

let v = Verification.firstWhere(.email == "john@doecom")
v!.delete() // read before delete
v           // but then return the original document

or

Verification
  .map(v => { log(v); v }) // log the document value to the response summary
  .firstWhere(.email == "john@doecom")!.delete()

I want to say, too, that you did hit on per-field read permissions, which seems like it would help you here, and would likely be valuable in a lot of situations. This is something that we’ve talked about a lot and maybe one of the most viable things to add.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.