Мне было интересно, как построить систему, в которой пользователи могли бы отправлять сообщения другим пользователям. Конечно, каждый должен иметь доступ только к своей папке входящих, поэтому для этого нам нужна инфраструктура базы данных для каждого пользователя. Следуя примеру из http://guide.couchdb.org/draft/notifications.html,, мы видим, что пользователи могут просто помещать сообщения в базу данных получателя. Просто и эффективно.
Но что, если мы не хотим, чтобы пользователи знали имя базы данных получателей? Что если нам нужна система, которая будет разрешать базу данных получателей, просматривая поле от до документа сообщения (это может быть имя пользователя, полностью не связанное с именем его базы данных):
{
"to": "john.kowalski",
"from": "jake.podolski",
"subject": "hi",
"message": "..."
}
Это кажется идеальной задачей для дополнительного уровня, но тогда это будет неинтересно и не стоит вопроса, поэтому мы попробуем решить его с репликацией:
- Пользователь помещает документ сообщения в основную базу данных
- Задача репликации (у нас была бы задача для каждого пользователя) выбирает этот документ, используя фильтр, который фильтрует _changes feed по полю в . Имя "john.kowalski" будет передано в качестве параметра для функции фильтра.
- Документ заканчивается в базе данных получателей.
Однако это создает проблему, потому что основная база данных должна быть видна всем пользователям! Итак ... что если мы сможем добавить задачу user-> main для репликации, так что сообщения будут взяты из базы данных пользователей, перенесены в основную базу данных и затем помещены в базу данных получателей (о боже, это становится сложным, мы можем уже тратить свое время, пытаясь решить это таким образом, но давайте попробуем).
- Пользователь помещает документ сообщения в свою базу данных
- Задача репликации извлекает этот документ, но не может использовать какую-либо функцию фильтра, поскольку фильтр в этом случае принадлежит пользователю и поэтому не может быть доверенным.
- Основная база данных проверяет документ - он проверяет, является ли поле из тем, которое связано с исходной базой данных.
- Задача репликации, используемая в предыдущем подходе, передает документ получателю.
Здесь есть проблема на третьем этапе (без этого этапа пользователи смогут отправлять сообщения, выдавая себя за других пользователей, заполняя поддельную информацию в из поля ) - как мы можем передавать дополнительные данные в функции проверки, насколько я знаю, там есть только параметры:
- старый документ
- новый документ
- пользовательский контекст (зарегистрированное имя пользователя, роли, база данных, в которую записывается документ)
- объект безопасности?
Путем отмены функциональности базы данных репликатора, представленной в 1.1.0, мы могли бы передать контекст user_ctx в задачу репликации. Возможно ли, чтобы этот объект содержал пользовательские данные, а не реальную информацию о пользователе? Как это повлияет на то, как CouchDB обрабатывает доступ к базе данных?
Если это будет возможно, задача репликации будет просто иметь имя получателя, заполненное как параметр в user_ctx, тогда функция проверки будет использовать это значение для сравнения с из поля . У пользователя не будет возможности «отправить» сообщение кому-либо, кроме него.