Пользователь CouchDB для записи / чтения (без редактирования)

Toolchain/ рамки

я использую django==2.1.3 а также python-cloudant==2.1.3 и работает CouchDB ver. 2.2.0и в значительной степени делает все мои настройки / конфигурации через Fauxton, Мне нравится думать, что я знаком с python / django в целом, и я тестирую этот подход в небольшом небольшом проекте, чтобы увидеть, как он работает

описание проблемы

Предположим, у меня есть довольно простое приложение CRUD только с одной моделью:

class Asset(models.Model):
    asset_id = models.CharField(max_length=32)
    asset_name = models.CharField(max_length=32)

и у меня есть вид, который я использую для создания актива

class CreateAssetView(views.View):
    def get(self, request, *args, **kwargs):
        #some code here


    def post(self, request, *args, **kwargs):
        #some code here|
        #log request data into database
        client = CouchDB('myusername', 'mypassword', url='http://127.0.0.1:5984', connect=True)
        db = client['assets']

        log_data = {'view_name': self.view_name, 'post_data': post_data,'user': request.user.username,
                    'time': str(timezone.now())}
        db.create_document(log_data)
        return render(...)

Я понимаю, что я должен делать часть регистрации с использованием промежуточного программного обеспечения (которое я планирую) и, вероятно, просто использовать django's CreateView в этом случае, я делаю этот подход сейчас только в начале разработки.

У меня проблема с тем, чтобы обернуть голову вокруг создания пользователя с myusername а также mypassword который имеет разрешения на:

  1. Написать новые документы
  2. Читать старые документы
  3. не редактировать уже созданные документы

Я мог даже согласиться только на 1 и 3 (и использовать только admin для чтения). Я провел немного времени, играя с Fauxtonинтерфейс для разрешений, но я могу только в основном создать user и назначить role (даже не смог назначить пароль:/)

осветление

Asset это не CouchDB документ, это нормальная модель SQL, я хочу только сбросить журналы с данными поста в CouchDB

Буду очень признателен за любую помощь / указатели / документацию

1 ответ

Решение

обзор

Couchdb имеет один основной уровень настройки администратора в конфигурации вместо _users базы данных и назначил _admin разрешение, чтобы предотвратить любую возможность быть заблокированным.

Каждая отдельная база данных имеет грубую политику безопасности на двух уровнях:

  1. админы
  2. члены

указывается через:

  1. имена
  2. роли

делая 4 поля.

Эти уровни управляют доступом немного по-разному для 2 типов документов, которые БД может содержать:

  1. Я бы: _design/* - Проектные документы могут содержать функции, которые будут выполняться в определенном контексте.
  2. Я бы: other - Нормальные документы - это просто нормальные данные

Оба уровня доступа к базе данных имеют доступ для чтения ко всем документам в базе данных, но администраторы имеют доступ для записи к _design документам. Доступ на запись к обычным документам обычно предоставляется всем пользователям, которым предоставлен какой-либо доступ к БД, но может быть ограничен проверкой проектных документов.

Подвести итоги

Процесс настройки уникальной политики безопасности:

  1. Испытайте предоставленный валидный проектный документ как потребитель при настройке _users.
  2. Настройте новую базу данных и ее базовую защиту, предоставляя пользователям доступ к файлам
  3. Добавьте документ разработки в новую базу данных с помощью функции проверки, которая ограничивает доступ членов к записи.

1 Настройка записей _users

Добавить роль пользователю

Как админ добавить role: ["logger"] к документу пользователя и сохраните его, обратите внимание, что это должно быть сделано администратором из-за этой части проектного документа _users по умолчанию:

        // DB: _users doc: _design/_auth
        function(newDoc, oldDoc, userCtx, secObj) {
        ..
        if (oldRoles.length !== newRoles.length) {
            throw({forbidden: 'Only _admin may edit roles'});
        }

Измените пароль для пользователя.

Либо администратор, либо пользователь могут изменить свой пароль, установив password:"mynewpassword" в их документе (который couchdb преобразует в хешированный / соленый пароль во время процесса сохранения). Это работает для пользователя, так как он может добавлять / изменять поля помимо своего имени и ролей, пока пользователь редактирует свой собственный документ:

        // DB: _users doc: _design/_auth
        function(newDoc, oldDoc, userCtx, secObj) {
        ..
        if (userCtx.name !== newDoc.name) {
            throw({
                forbidden: 'You may only update your own user document.'
            });
        }
        // then checks that they don't modify roles

Вы можете повторить этот процесс с пользователем, которому вы назначаете adminlogger роль для создания делегированного администратора, которому вы назначаете разрешения, может перенастроить базу данных или вы можете продолжать использовать администратора couchdb с его _admin роль для всей администрации.

2 Настройте новую базу данных и ее базовую безопасность

Создайте базу данных с именем logger, назначьте регистратору политику безопасности:

{
    "admins": {
        "names": [

        ],
        "roles": [
            "adminlogger"
        ]
    },
    "members": {
        "names": [

        ],
        "roles": [
            "logger"
        ]
    }
}

3. Создайте новый проверенный проектный документ в новом БД

В качестве пользователя _admin или пользователя с adminlogger Роль создать новый документ проверки дизайна путем копирования документа проекта _users, удаления _rev и изменения функции:

// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
     // Don't let non-admins write a pre-existing document:
     if (!is_server_or_database_admin()) {
          if (!!oldDoc) {
              throw({
                forbidden: 'You may not update existing documents.'
            });
          }
     }
     // Where the function to define admins can be copied verbatim from the doc:
     var is_server_or_database_admin = function(userCtx, secObj) {
        // see if the user is a server admin
        if(userCtx.roles.indexOf('_admin') !== -1) {
            return true; // a server admin
        }

        // see if the user a database admin specified by name
        if(secObj && secObj.admins && secObj.admins.names) {
            if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
                return true; // database admin
            }
        }

        // see if the user a database admin specified by role
        if(secObj && secObj.admins && secObj.admins.roles) {
            var db_roles = secObj.admins.roles;
            for(var idx = 0; idx < userCtx.roles.length; idx++) {
                var user_role = userCtx.roles[idx];
                if(db_roles.indexOf(user_role) !== -1) {
                    return true; // role matches!
                }
            }
        }

        return false; // default to no admin
    }
}    

Если вы выполнили эти шаги, то пользователь, которому вы дали роль регистратора на шаге 1, может запустить ваш код для записи новых документов только в базу данных регистратора, настроенную на шагах 2 и 3.

Другие вопросы по тегам