/**
  * Updates roleGraph for an insert-type oplog operation on admin.system.roles.
  */
 Status handleOplogInsert(RoleGraph* roleGraph, const BSONObj& insertedObj) {
     RoleInfo role;
     Status status = parseRoleFromDocument(insertedObj, &role);
     if (!status.isOK())
         return status;
     status = roleGraph->replaceRole(role.name, role.roles, role.privileges);
     return status;
 }
Exemple #2
0
/**
 * Updates roleGraph for an update-type oplog operation on admin.system.roles.
 *
 * Treats all updates as upserts.
 */
Status handleOplogUpdate(OperationContext* opCtx,
                         RoleGraph* roleGraph,
                         const BSONObj& updatePattern,
                         const BSONObj& queryPattern) {
    RoleName roleToUpdate;
    Status status = getRoleNameFromIdField(queryPattern["_id"], &roleToUpdate);
    if (!status.isOK())
        return status;

    boost::intrusive_ptr<ExpressionContext> expCtx(new ExpressionContext(opCtx, nullptr));
    UpdateDriver driver(std::move(expCtx));
    driver.setFromOplogApplication(true);

    // Oplog updates do not have array filters.
    std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
    driver.parse(updatePattern, arrayFilters);

    mutablebson::Document roleDocument;
    status = RoleGraph::getBSONForRole(roleGraph, roleToUpdate, roleDocument.root());
    if (status == ErrorCodes::RoleNotFound) {
        // The query pattern will only contain _id, no other immutable fields are present
        const FieldRef idFieldRef("_id");
        FieldRefSet immutablePaths;
        invariant(immutablePaths.insert(&idFieldRef));
        status = driver.populateDocumentWithQueryFields(
            opCtx, queryPattern, immutablePaths, roleDocument);
    }
    if (!status.isOK())
        return status;

    const bool validateForStorage = false;
    const FieldRefSet emptyImmutablePaths;
    status = driver.update(StringData(), &roleDocument, validateForStorage, emptyImmutablePaths);
    if (!status.isOK())
        return status;

    // Now use the updated document to totally replace the role in the graph!
    RoleInfo role;
    status = parseRoleFromDocument(roleDocument.getObject(), &role);
    if (!status.isOK())
        return status;
    status = roleGraph->replaceRole(role.name, role.roles, role.privileges, role.restrictions);

    return status;
}
    /**
     * Updates roleGraph for an update-type oplog operation on admin.system.roles.
     *
     * Treats all updates as upserts.
     */
    Status handleOplogUpdate(RoleGraph* roleGraph,
                             const BSONObj& updatePattern,
                             const BSONObj& queryPattern) {
        RoleName roleToUpdate;
        Status status = getRoleNameFromIdField(queryPattern["_id"], &roleToUpdate);
        if (!status.isOK())
            return status;

        UpdateDriver::Options updateOptions;
        updateOptions.upsert = true;
        UpdateDriver driver(updateOptions);
        status = driver.parse(updatePattern);
        if (!status.isOK())
            return status;

        mutablebson::Document roleDocument;
        status = AuthorizationManager::getBSONForRole(
                roleGraph, roleToUpdate, roleDocument.root());
        if (status == ErrorCodes::RoleNotFound) {
            status = driver.populateDocumentWithQueryFields(queryPattern, roleDocument);
        }
        if (!status.isOK())
            return status;

        status = driver.update(StringData(), &roleDocument);
        if (!status.isOK())
            return status;

        // Now use the updated document to totally replace the role in the graph!
        RoleInfo role;
        status = parseRoleFromDocument(roleDocument.getObject(), &role);
        if (!status.isOK())
            return status;
        status = roleGraph->replaceRole(role.name, role.roles, role.privileges);

        return status;
    }