Me preguntaba cómo crear un sistema en el que los usuarios puedan enviar mensajes a otros usuarios. Por supuesto, todos deben poder acceder solo a su bandeja de entrada, por lo que necesitamos una infraestructura de base de datos por usuario para eso. Siguiendo el ejemplo de http://guide.couchdb.org/draft/notifications.html, vemos que los usuarios pueden simplemente poner los mensajes en la base de datos del destinatario. Simple y efectivo.CouchDB escenario de base de datos por usuario con sistema privado de mensajería
Pero, ¿qué ocurre si no queremos permitir que los usuarios sepan el nombre de la base de datos del destinatario? ¿Y si queremos un sistema que resuelva la base de datos del destinatario mirando en el campo a del documento de mensaje (que podría ser el nombre de usuario, sin relación alguna con su nombre de base de datos):
{
"to": "john.kowalski",
"from": "jake.podolski",
"subject": "hi",
"message": "..."
}
Parece como una tarea perfecta para nivel adicional, pero entonces no sería una diversión y no vale la pena una pregunta, así que vamos a tratar de resolver con la replicación:
- usuario pone documento de mensaje en la base de datos principal
- replicación tarea (tendríamos una tarea para cada usuario) obtiene esa doc que usa un filtro que filtra _cambios de feed por a campo. El nombre "john.kowalski" se pasará como parámetro para la función de filtro.
- El documento finaliza en la base de datos de destinatarios.
Sin embargo, esto crea un problema, porque la base de datos principal debería estar visible para todos los usuarios. Entonces ... ¿qué pasaría si pudiéramos agregar también la tarea de replicación principal del usuario, para que los mensajes sean recogidos de la base de datos del usuario transferida a la base de datos principal y luego colocados en la base de datos de los destinatarios (oh señor, se está complicando, podemos ya perder el tiempo tratando de resolverlo de esta manera, pero intentémoslo).
- usuario pone documento de mensaje en su base de datos
- tarea de duplicación obtiene que el doc, pero no puede utilizar la función de filtro de ningún tipo, ya que el filtro, en este caso es propiedad del usuario, y por lo tanto no se puede confiar.
- La base de datos principal valida el documento: comprueba si el campo del campo es el asociado a la base de datos de origen.
- La tarea de replicación utilizada en el enfoque anterior transfiere el documento al destinatario.
Hay un problema en el tercer paso aquí (sin ese paso, los usuarios podrán enviar mensajes haciéndose pasar por cualquier otro usuario rellenando información falsa en de campo) - ¿cómo somos capaces de pasar datos adicionales a la validación funciones, los únicos parámetros allí por lo que yo sé son:
- viejo doctor
- nuevo documento contexto
- usuario (nombre de usuario conectado, papeles, db a la que se está escribiendo documento)
- objeto de seguridad?
Al consultar la funcionalidad de la base de datos del replicador presentada en 1.1.0, podríamos pasar el contexto de user_ctx a la tarea de replicación. ¿Sería posible que este objeto contenga datos personalizados en lugar de información real del usuario?¿Cómo afectaría eso a la forma estándar en que CouchDB maneja el acceso a la base de datos?
Si eso fuera posible, la tarea de replicación simplemente tendría el nombre del destinatario lleno como parámetro en user_ctx, luego la función de validación usaría ese valor para compararlo con del campo. No habría forma de que el usuario "envíe" el mensaje como alguien más que él.
Para un registro, soy bastante consciente del hecho de que podría abusar de la replicación aquí, y alguna tarea de trabajo ejecutándose como administrador (para que pueda leer todas las bases de datos) podría mover documentos de una manera más robusta y simple. – Bartosz