代码之家  ›  专栏  ›  技术社区  ›  robotHamster

couchdb只读(无编辑)用户

  •  3
  • robotHamster  · 技术社区  · 7 年前

    工具链/框架

    我在用 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的 CreateView 在这种情况下,我现在正在做这个方法,只是在早期开发阶段。

    我脑子里有个问题,就是创建一个用户 myusername mypassword 具有以下权限:

    1. 编写新文档
    2. 阅读旧文档
    3. 不编辑 已创建文档

    我甚至可以只满足于1和3(并且只使用管理员阅读)。我花了点时间玩 福克斯顿 的接口,但我基本上只能创建 user 分配一个 role (甚至无法分配密码:/)

    澄清

    这个 Asset 不是一个 CouchDB 文档,这是一个普通的SQL模型,我只想将日志和post数据转储到 库奇德卜

    任何帮助/引导/文档指针都将非常感谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   lossleader    7 年前

    概述

    couchdb具有一个重写级别 administrator setup in configuration 而不是 setup in the _users 数据库并分配 _admin 防止被锁在外的许可。

    每个数据库都有一个粗略的级别 security policy 2个层次:

    1. 管理员
    2. 成员

    指定通过:

    1. 姓名
    2. 角色

    生成4个字段。

    这些级别对数据库可以包含的两种类型的文档的访问控制略有不同:

    1. 身份证件: _design/* -设计文档可以包含将在某些上下文中执行的函数
    2. 身份证件: other -普通文档只是普通数据

    两个级别的数据库访问都具有对数据库中所有文档的读取权限,但管理员具有对设计文档的写入权限。对普通文档的写访问权通常授予所有被授予对数据库的任何访问权的用户,但受以下限制: validate design documents .

    总结

    设置唯一安全策略的过程是:

    1. 在设置用户时,作为消费者体验提供的验证设计文档。
    2. 设置一个新的数据库及其基本安全性,使您的用户可以访问该数据库。
    3. 使用限制成员写入权限的验证函数向新数据库添加设计文档。

    1设置用户条目

    向用户添加角色

    作为管理员添加 role: ["logger"] 到用户的文档并保存它,请注意,由于默认用户设计文档的这一部分,必须由管理员完成:

            // 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的数据库 分配记录器A 安全策略 :

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

    三。新建 validate design document 在新数据库中

    作为管理员用户或 管理记录器 角色通过复制用户设计文档、删除版本并修改功能来创建新的验证设计文档:

    // 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中给予logger角色的用户只能在步骤2和3中配置的logger数据库中运行代码来编写新文档。