Beispiel #1
0
def put(bag):
    data = {"type": bag["type"]}
    del bag["type"]
    if '_created' in bag:
        del bag["_created"]
    if '_deleted' in bag:
        del bag["_deleted"]

    table_name = data["type"]
    table = getattr(db, table_name)

    if table is None or not issubclass(table, (db.Base, db.CouchSync)):
        raise CbsException(TABLE_NOT_FOUND)

    for key in bag:
        data[key] = bag[key]
    # del_columns(data)

    for column in table.metadata.tables.get(table_name.lower()).columns._data:
        nullable = table.metadata.tables.get(
            table_name.lower()).columns._data[column].nullable
        if not nullable and not column.startswith(
                "_") and not column == "entry_user_id" and column not in data:
            raise CbsException(KEY_ERROR,
                               MESSAGE.get(KEY_ERROR).format(column))
        elif not column.startswith(
                "_") and not column == "entry_user_id" and column not in data:
            data[column] = None

    pg_db = PostgresDatabase()
    _id, _rev = pg_db.store(data, new_edits=True)
    return {"ok": True, "id": _id, "rev": _rev}
Beispiel #2
0
def delete(bag):
    if 'company_id' in g.session and not is_admin():
        bag['company_id'] = g.session['company_id']

    # if not is_admin() and "company_id" not in bag:
    #     raise CbsException(USER_NO_ACCESS)

    table_name = bag["type"]
    table = getattr(db, table_name)

    if table is None or not issubclass(table, (db.Base, db.CouchSync)):
        raise CbsException(TABLE_NOT_FOUND)

    if not is_admin():
        item_query = g.tran.query(table).filter_by(_deleted="infinity",
                                                   _id=bag["_id"])
        if table == db.Companies:
            item_query = item_query.filter(table._id == bag["company_id"],
                                           table.user_id == g.user.id)
            if issubclass(table, db.CompanySync):
                item_query = item_query.filter(
                    table.company_id == bag["company_id"])
        elif table == db.Companyemployees:
            item_query = item_query.filter(table.user_id == bag["user_id"])
            if issubclass(table, db.CompanySync):
                item_query = item_query.filter(
                    table.company_id == bag["company_id"])
        else:
            item_query = item_query.first()
            if item_query is None:
                raise CbsException(USER_NO_ACCESS)

    pg_db = PostgresDatabase()
    _id, _rev = pg_db.remove(bag["_id"], bag["_rev"])
    return {"ok": True, "id": _id, "rev": _rev}
Beispiel #3
0
    def saveapproval(self, bag):
        if '_created' in bag:
            del bag["_created"]
        if '_deleted' in bag:
            del bag["_deleted"]
        if 'date' not in bag['data']:
            bag["data"]['date'] = str(datetime.now())

        if '_id' in bag:
            query = g.tran.query(db.Document).filter_by(_id=bag['_id']) \
                .filter(db.Document.document_status != 'committed')
            document = query.first()
            if document is None:
                raise CbsException(USER_NO_ACCESS)

        pg_db = PostgresDatabase()
        bag['type'] = 'Document'
        bag['document_status'] = 'draft'
        if len(g.user.roles_id) > 0:
            bag['approval']['approval_roles'] = []
            for role_id in bag['approval']['roles_id']:
                bag['approval']['approval_roles'].append({
                    'role_id': role_id
                })
        _id, _rev = pg_db.store(bag, new_edits=True)
        return {"ok": True, "id": _id, "rev": _rev}
Beispiel #4
0
    def save(self, bag):
        if '_created' in bag:
            del bag["_created"]
        if '_deleted' in bag:
            del bag["_deleted"]
        if 'date' not in bag['data']:
            bag["data"]['date'] = str(datetime.now())

        if '_id' in bag:
            query = g.tran.query(db.Document).filter_by(_id=bag['_id']) \
                .filter(db.Document.data.contains(type_coerce({"user_id": g.user.id}, JSONB)),
                        db.Document.document_status != 'committed')
            document = query.first()
            if document is None:
                raise CbsException(USER_NO_ACCESS)
        if g.user.roles_id is None:
            raise CbsException(GENERIC_ERROR,
                               u'Вам необходимо получить права')
        else:
            pg_db = PostgresDatabase()
            bag['type'] = 'Document'
            bag['document_status'] = 'draft'
            bag['data']['user_id'] = g.user.id
            if len(g.user.roles_id) > 0:
                bag['approval']['approval_roles'] = []
                for role_id in bag['approval']['roles_id']:
                    bag['approval']['approval_roles'].append({
                        'role_id': role_id
                    })
            _id, _rev = pg_db.store(bag, new_edits=True)
        return {"ok": True, "id": _id, "rev": _rev}
Beispiel #5
0
def database_changes(dbname):
    args = flask.request.args
    heartbeat = args.get('heartbeat', 10000)
    since = json.loads(args.get('since', '0'))
    feed = args.get('feed', 'normal')
    style = args.get('style', 'all_docs')
    filter = args.get('filter', None)
    limit = args.get('limit', None)
    timeout = int(args.get('timeout', 25000))
    db = PostgresDatabase()
    changes, last_seq = db.changes(since, feed, style, filter, limit,
                                   timeout / 1000)
    return make_response(200, {'last_seq': last_seq, 'results': changes})
Beispiel #6
0
def remove(bag):
    table_name = bag["type"]
    table = getattr(db, table_name)

    if table is None or not issubclass(table, (db.Base, db.CouchSync)):
        raise CbsException(TABLE_NOT_FOUND)

    if not is_admin():
        item_query = g.tran.query(table).filter_by(_deleted="infinity",
                                                   _id=bag["_id"])
        item_query = item_query.first()
        if item_query is None:
            raise CbsException(USER_NO_ACCESS)

    pg_db = PostgresDatabase()
    _id, _rev = pg_db.remove(bag["_id"], bag["_rev"])
    return {"ok": True, "id": _id, "rev": _rev}
Beispiel #7
0
 def get():
     if appconf.DB != dbname:
         return flask.abort(404, '%s missed' % dbname)
     return make_response(200, PostgresDatabase().info())
Beispiel #8
0
def all_docs(dbname):
    args = {}
    for a in flask.request.args:
        args[a] = json.loads(flask.request.args[a])
    db = PostgresDatabase()
    return make_response(200, db.all_docs(**args))
Beispiel #9
0
def database_ensure_full_commit(dbname):
    db = PostgresDatabase()
    return make_response(201, db.ensure_full_commit())
Beispiel #10
0
def database_bulk_docs(dbname):
    db = PostgresDatabase()
    return make_response(201, db.bulk_docs(**flask.request.get_json()))
Beispiel #11
0
def database_revs_diff(dbname):
    db = PostgresDatabase()
    revs = db.revs_diff(flask.request.json)
    return make_response(200, revs)
Beispiel #12
0
def document(dbname, docid):
    def head():
        return get()

    def get():
        if flask.request.args.get('open_revs'):
            open_revs = json.loads(flask.request.args['open_revs'])
            ret = []
            for rev in open_revs:
                doc = db.load(docid,
                              rev=rev,
                              revs=flask.request.args.get('revs', False))
                ret.append(doc)
            return make_response(200, ret)
        else:
            doc = db.load(docid,
                          rev=flask.request.args.get('rev', None),
                          revs=flask.request.args.get('revs', False))
            return make_response(200, doc)

    def put():
        rev = flask.request.args.get('rev')
        new_edits = json.loads(flask.request.args.get('new_edits', 'true'))

        if flask.request.mimetype == 'application/json':
            doc = flask.request.get_json()

        elif flask.request.mimetype == 'multipart/related':
            parts = parse_multipart_data(
                flask.request.stream,
                flask.request.mimetype_params['boundary'])

            # CouchDB has an agreement, that document goes before attachments
            # which simplifies processing logic and reduces footprint
            headers, body = next(parts)
            assert headers['Content-Type'] == 'application/json'
            doc = json.loads(body.decode())
            # We have to inject revision into doc there to correct compute
            # revpos field for attachments
            doc.setdefault('_rev', rev)

            for headers, body in parts:
                params = werkzeug.http.parse_options_header(
                    headers['Content-Disposition'])[1]
                fname = params['filename']
                ctype = headers['Content-Type']
                db.add_attachment(doc, fname, body, ctype)

        else:
            # mimics to CouchDB response in case of unsupported mime-type
            return flask.abort(400)

        doc['_id'] = docid

        idx, rev = db.store(doc, rev, new_edits)
        return make_response(201, {'ok': True, 'id': idx, 'rev': rev})

    def delete():
        idx, rev = db.remove(docid, flask.request.args.get('rev', None))
        return make_response(201, {'ok': True, 'id': idx, 'rev': rev})

    db = PostgresDatabase()
    return locals()[flask.request.method.lower()]()
Beispiel #13
0
    def approve(self, bag, approve, comment):
        roles_filter = []
        for role_id in g.user.roles_id:
            roles_filter.append(db.Document.approval.contains(type_coerce({'approval_roles': [{"role_id": role_id}]}, JSONB)))
        query = g.tran.query(db.Document).filter_by(_id=bag[ID] if ID in bag else bag['_id'], _deleted='infinity') \
            .filter(or_(and_(db.Document.document_status == "approval", or_(*roles_filter)),
                        and_(db.Document.document_status == "approved",
                             db.Document.data.contains(type_coerce({'executor_id': g.user.id}, JSONB))),
                        and_(db.Document.document_status == 'draft',
                             db.Document.data.contains(type_coerce({'user_id': g.user.id}, JSONB)))))
        document = query.first()
        if document is None:
            raise CbsException(USER_NO_ACCESS)
        doc_data = orm_to_json(document)

        del doc_data["_created"]
        del doc_data["_deleted"]
        del doc_data["entry_user_id"]

        if bag['document_status'] == 'draft' and doc_data['document_status'] == 'draft':
            doc_data['document_status'] = 'approval'if \
                'required' in doc_data['approval'] and doc_data['approval']['required'] == True else 'approved'
            pg_db = PostgresDatabase()
            doc_data['type'] = 'Document'
            _id, _rev = pg_db.store(doc_data)
            return {"id": _id, "rev": _rev}
        elif bag['document_status'] == 'approval' and doc_data['document_status'] == 'approval':
            approval_position = 0
            for approval_role in doc_data['approval']["approval_roles"]:
                if g.user.roles_id.index(approval_role["role_id"]) >= 0 and "approved" not in approval_role:
                    if "approval_users" in approval_role:
                        for approval_users in approval_role["approval_users"]:
                            if approval_users["user_id"] == g.user.id:
                                raise CbsException(GENERIC_ERROR, u'Вы уже одобряли документ')
                        approval_role["approval_users"].append({
                            "user_id": g.user.id,
                            "approved": approve
                        })
                    else:
                        approval_role["approval_users"] = []
                        approval_role["approval_users"].append({
                            "user_id": g.user.id,
                            "approved": approve
                        })
                    if approve is True:
                        if doc_data['approval']["approval_type"] == 'all':
                            users_count = g.tran.query(db.User).filter_by(_deleted='infinity') \
                                .filter(db.User.roles_id.contains(type_coerce(approval_role["role_id"], JSONB)))
                            if users_count == len(approval_role["approval_users"]):
                                approval_role["approved"] = True
                                try:
                                    if approval_position == len(doc_data['approval']["approval_roles"]) - 1:
                                        doc_data['document_status'] = 'approved'
                                except IndexError:
                                    pass
                        else:
                            approval_role["approved"] = True
                            try:
                                if approval_position == len(doc_data['approval']["approval_roles"]) - 1:
                                    doc_data['document_status'] = 'approved'
                            except IndexError:
                                pass
                    else:
                        approval_role["approved"] = False
                        doc_data['document_status'] = 'rejected'
                    break
                approval_position += 1
            pg_db = PostgresDatabase()

            if comment:
                pg_db.store({
                    "type": "DocumentComments",
                    "document_id": doc_data['_id'],
                    "data": {
                        "comment_type": "approval" if approve is True else "rejection",
                        "comment": comment
                    }
                })

            doc_data['type'] = 'Document'
            _id, _rev = pg_db.store(doc_data)
            return {"id": _id, "rev": _rev}
        elif bag['document_status'] == 'approved' and doc_data['document_status'] == 'approved':
            pg_db = PostgresDatabase()

            if comment:
                pg_db.store({
                    "type": "DocumentComments",
                    "document_id": doc_data['_id'],
                    "data": {
                        "comment_type": "commit",
                        "comment": comment
                    }
                })

            if doc_data['data']["executor_id"] == g.user.id and \
                ('roles_id' not in doc_data['approval']):
                return self.commit(bag)
            elif doc_data['data']["executor_id"] == g.user.id:
                for role_id in doc_data['approval']['roles_id']:
                    doc_data['approval']['approval_roles'].append({
                        "role_id": role_id
                    })
                bag['type'] = 'Document'
                bag['document_status'] = 'approval'
                bag['approval'] = doc_data['approval']
                bag['data']['executor_id'] = doc_data['data']['executor_id']
                bag['data']['user_id'] = doc_data['data']['user_id']
                _id, _rev = pg_db.store(bag)
                return {"id": _id, "rev": _rev}

        raise CbsException(GENERIC_ERROR, u'Не подходящий статус документа')