Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj, const StringData& cmdName, const std::string& dbname, CreateOrUpdateRoleArgs* parsedArgs) { unordered_set<std::string> validFieldNames; validFieldNames.insert(cmdName.toString()); validFieldNames.insert("privileges"); validFieldNames.insert("roles"); validFieldNames.insert("writeConcern"); Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames); if (!status.isOK()) { return status; } status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern); if (!status.isOK()) { return status; } std::string roleName; status = bsonExtractStringField(cmdObj, "createRole", &roleName); if (!status.isOK()) { return status; } parsedArgs->roleName = RoleName(roleName, dbname); // Parse privileges if (cmdObj.hasField("privileges")) { BSONElement privilegesElement; status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement); if (!status.isOK()) { return status; } status = parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), &parsedArgs->privileges); if (!status.isOK()) { return status; } parsedArgs->hasPrivileges = true; } // Parse roles if (cmdObj.hasField("roles")) { BSONElement rolesElement; status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement); if (!status.isOK()) { return status; } status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, "roles", &parsedArgs->roles); if (!status.isOK()) { return status; } parsedArgs->hasRoles = true; } return Status::OK(); }
TEST( Shard, EqualityRs ) { Shard a("foo", "bar/a,b", 0, false, BSONArray()); Shard b("foo", "bar/a,b", 0, false, BSONArray()); ASSERT_EQUALS( a, b ); b = Shard("foo", "bar/b,a", 0, false, BSONArray()); ASSERT_EQUALS( a, b ); }
TEST_F(DocumentSourceFacetTest, ShouldRejectEmptyPipelines) { auto ctx = getExpCtx(); auto spec = BSON("$facet" << BSON("a" << BSONArray())); ASSERT_THROWS(DocumentSourceFacet::createFromBson(spec.firstElement(), ctx), UserException); spec = BSON("$facet" << BSON("a" << BSON_ARRAY(BSON("$skip" << 4)) << "b" << BSONArray())); ASSERT_THROWS(DocumentSourceFacet::createFromBson(spec.firstElement(), ctx), UserException); }
Status V2UserDocumentParser::initializeAuthenticationRestrictionsFromUserDocument( const BSONObj& privDoc, User* user) const { RestrictionDocuments::sequence_type restrictionVector; // Restrictions on the user const auto authenticationRestrictions = privDoc[AUTHENTICATION_RESTRICTIONS_FIELD_NAME]; if (!authenticationRestrictions.eoo()) { if (authenticationRestrictions.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "'authenticationRestrictions' field must be an array"); } auto restrictions = parseAuthenticationRestriction(BSONArray(authenticationRestrictions.Obj())); if (!restrictions.isOK()) { return restrictions.getStatus(); } restrictionVector.push_back(restrictions.getValue()); } // Restrictions from roles const auto inherited = privDoc[INHERITED_AUTHENTICATION_RESTRICTIONS_FIELD_NAME]; if (!inherited.eoo()) { if (inherited.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "'inheritedAuthenticationRestrictions' field must be an array"); } for (const auto& roleRestriction : BSONArray(inherited.Obj())) { if (roleRestriction.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "'inheritedAuthenticationRestrictions' sub-fields must be arrays"); } auto roleRestrictionDoc = parseAuthenticationRestriction(BSONArray(roleRestriction.Obj())); if (!roleRestrictionDoc.isOK()) { return roleRestrictionDoc.getStatus(); } restrictionVector.push_back(roleRestrictionDoc.getValue()); } } if (user) { user->setRestrictions(RestrictionDocuments(restrictionVector)); } return Status::OK(); }
mongo::BSONArray MockRemoteDBServer::query(MockRemoteDBServer::InstanceID id, const string& ns, mongo::Query query, int nToReturn, int nToSkip, const BSONObj* fieldsToReturn, int queryOptions, int batchSize) { checkIfUp(id); if (_delayMilliSec > 0) { mongo::sleepmillis(_delayMilliSec); } checkIfUp(id); scoped_spinlock sLock(_lock); _queryCount++; const vector<BSONObj>& coll = _dataMgr[ns]; BSONArrayBuilder result; for (vector<BSONObj>::const_iterator iter = coll.begin(); iter != coll.end(); ++iter) { result.append(iter->copy()); } return BSONArray(result.obj()); }
Value DocumentSourceGeoNear::serialize(bool explain) const { MutableDocument result; if (coordsIsArray) { result.setField("near", Value(BSONArray(coords))); } else { result.setField("near", Value(coords)); } // not in buildGeoNearCmd result.setField("distanceField", Value(distanceField->getPath(false))); result.setField("limit", Value(limit)); if (maxDistance > 0) result.setField("maxDistance", Value(maxDistance)); result.setField("query", Value(query)); result.setField("spherical", Value(spherical)); result.setField("distanceMultiplier", Value(distanceMultiplier)); if (includeLocs) result.setField("includeLocs", Value(includeLocs->getPath(false))); result.setField("uniqueDocs", Value(uniqueDocs)); return Value(DOC(getSourceName() << result.freeze())); }
Status parseRolesInfoCommand(const BSONObj& cmdObj, const StringData& dbname, std::vector<RoleName>* parsedRoleNames) { unordered_set<std::string> validFieldNames; validFieldNames.insert("rolesInfo"); Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames); if (!status.isOK()) { return status; } if (cmdObj["rolesInfo"].type() == Array) { status = parseRoleNamesFromBSONArray(BSONArray(cmdObj["rolesInfo"].Obj()), dbname, parsedRoleNames); if (!status.isOK()) { return status; } } else { RoleName name; status = _parseNameFromBSONElement(cmdObj["rolesInfo"], dbname, AuthorizationManager::ROLE_NAME_FIELD_NAME, AuthorizationManager::ROLE_SOURCE_FIELD_NAME, &name); if (!status.isOK()) { return status; } parsedRoleNames->push_back(name); } return Status::OK(); }
virtual bool run(OperationContext* txn, const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { if (!check(errmsg, result)) return false; if (cmdObj.hasField("handshake")) { // we have received a handshake, not an update message // handshakes are done here to ensure the receiving end supports the update command return appendCommandStatus( result, getGlobalReplicationCoordinator()->processReplSetUpdatePositionHandshake( cmdObj["handshake"].embeddedObject(), &result)); } uassert(16888, "optimes field should be an array with an object for each secondary", cmdObj["optimes"].type() == Array); return appendCommandStatus( result, getGlobalReplicationCoordinator()->processReplSetUpdatePosition( BSONArray(cmdObj["optimes"].Obj()), &result)); }
StatusWith<Shard::QueryResponse> ShardLocal::_exhaustiveFindOnConfig( OperationContext* txn, const ReadPreferenceSetting& readPref, const repl::ReadConcernLevel& readConcernLevel, const NamespaceString& nss, const BSONObj& query, const BSONObj& sort, boost::optional<long long> limit) { auto replCoord = repl::ReplicationCoordinator::get(txn); if (readConcernLevel == repl::ReadConcernLevel::kMajorityReadConcern) { // Set up operation context with majority read snapshot so correct optime can be retrieved. Status status = txn->recoveryUnit()->setReadFromMajorityCommittedSnapshot(); // Wait for any writes performed by this ShardLocal instance to be committed and visible. Status readConcernStatus = replCoord->waitUntilOpTimeForRead( txn, repl::ReadConcernArgs{_getLastOpTime(), readConcernLevel}); if (!readConcernStatus.isOK()) { return readConcernStatus; } // Inform the storage engine to read from the committed snapshot for the rest of this // operation. status = txn->recoveryUnit()->setReadFromMajorityCommittedSnapshot(); if (!status.isOK()) { return status; } } else { invariant(readConcernLevel == repl::ReadConcernLevel::kLocalReadConcern); } DBDirectClient client(txn); Query fullQuery(query); if (!sort.isEmpty()) { fullQuery.sort(sort); } fullQuery.readPref(readPref.pref, BSONArray()); try { std::unique_ptr<DBClientCursor> cursor = client.query(nss.ns().c_str(), fullQuery, limit.get_value_or(0)); if (!cursor) { return {ErrorCodes::OperationFailed, str::stream() << "Failed to establish a cursor for reading " << nss.ns() << " from local storage"}; } std::vector<BSONObj> documentVector; while (cursor->more()) { BSONObj document = cursor->nextSafe().getOwned(); documentVector.push_back(std::move(document)); } return Shard::QueryResponse{std::move(documentVector), replCoord->getCurrentCommittedSnapshotOpTime()}; } catch (const DBException& ex) { return ex.toStatus(); } }
TEST( Shard, EqualitySingle ) { ASSERT_EQUALS(Shard("foo", "b.foo.com:123", 0, false, BSONArray()), Shard("foo", "b.foo.com:123", 0, false, BSONArray())); ASSERT_NOT_EQUALS(Shard("foo", "b.foo.com:123", 0, false, BSONArray()), Shard("foo", "a.foo.com:123", 0, false, BSONArray())); ASSERT_NOT_EQUALS(Shard("foo", "b.foo.com:123", 0, false, BSONArray()), Shard("foo", "b.foo.com:124", 0, false, BSONArray())); ASSERT_NOT_EQUALS(Shard("foo", "b.foo.com:123", 0, false, BSONArray()), Shard("foa", "b.foo.com:123", 0, false, BSONArray())); }
TEST( AllElemMatchOp, MatchesElement ) { BSONObj baseOperanda1 = BSON( "a" << 1 ); auto_ptr<ComparisonMatchExpression> eqa1( new ComparisonMatchExpression() ); ASSERT( eqa1->init( "a", ComparisonMatchExpression::EQ, baseOperanda1[ "a" ] ).isOK() ); BSONObj baseOperandb1 = BSON( "b" << 1 ); auto_ptr<ComparisonMatchExpression> eqb1( new ComparisonMatchExpression() ); ASSERT( eqb1->init( "b", ComparisonMatchExpression::EQ, baseOperandb1[ "b" ] ).isOK() ); auto_ptr<AndMatchExpression> and1( new AndMatchExpression() ); and1->add( eqa1.release() ); and1->add( eqb1.release() ); // and1 = { a : 1, b : 1 } auto_ptr<ElemMatchObjectMatchExpression> elemMatch1( new ElemMatchObjectMatchExpression() ); elemMatch1->init( "x", and1.release() ); // elemMatch1 = { x : { $elemMatch : { a : 1, b : 1 } } } BSONObj baseOperanda2 = BSON( "a" << 2 ); auto_ptr<ComparisonMatchExpression> eqa2( new ComparisonMatchExpression() ); ASSERT( eqa2->init( "a", ComparisonMatchExpression::EQ, baseOperanda2[ "a" ] ).isOK() ); BSONObj baseOperandb2 = BSON( "b" << 2 ); auto_ptr<ComparisonMatchExpression> eqb2( new ComparisonMatchExpression() ); ASSERT( eqb2->init( "b", ComparisonMatchExpression::EQ, baseOperandb2[ "b" ] ).isOK() ); auto_ptr<AndMatchExpression> and2( new AndMatchExpression() ); and2->add( eqa2.release() ); and2->add( eqb2.release() ); auto_ptr<ElemMatchObjectMatchExpression> elemMatch2( new ElemMatchObjectMatchExpression() ); elemMatch2->init( "x", and2.release() ); // elemMatch2 = { x : { $elemMatch : { a : 2, b : 2 } } } AllElemMatchOp op; op.init( "" ); op.add( elemMatch1.release() ); op.add( elemMatch2.release() ); BSONObj nonArray = BSON( "x" << 4 ); ASSERT( !op.matchesSingleElement( nonArray[ "x" ] ) ); BSONObj emptyArray = BSON( "x" << BSONArray() ); ASSERT( !op.matchesSingleElement( emptyArray[ "x" ] ) ); BSONObj nonObjArray = BSON( "x" << BSON_ARRAY( 4 ) ); ASSERT( !op.matchesSingleElement( nonObjArray[ "x" ] ) ); BSONObj singleObjMatch = BSON( "x" << BSON_ARRAY( BSON( "a" << 1 << "b" << 1 ) ) ); ASSERT( !op.matchesSingleElement( singleObjMatch[ "x" ] ) ); BSONObj otherObjMatch = BSON( "x" << BSON_ARRAY( BSON( "a" << 2 << "b" << 2 ) ) ); ASSERT( !op.matchesSingleElement( otherObjMatch[ "x" ] ) ); BSONObj bothObjMatch = BSON( "x" << BSON_ARRAY( BSON( "a" << 1 << "b" << 1 ) << BSON( "a" << 2 << "b" << 2 ) ) ); ASSERT( op.matchesSingleElement( bothObjMatch[ "x" ] ) ); BSONObj noObjMatch = BSON( "x" << BSON_ARRAY( BSON( "a" << 1 << "b" << 2 ) << BSON( "a" << 2 << "b" << 1 ) ) ); ASSERT( !op.matchesSingleElement( noObjMatch[ "x" ] ) ); }
BSONArray storageEngineList() { if (!hasGlobalServiceContext()) return BSONArray(); std::unique_ptr<StorageFactoriesIterator> sfi( getGlobalServiceContext()->makeStorageFactoriesIterator()); if (!sfi) return BSONArray(); BSONArrayBuilder engineArrayBuilder; while (sfi->more()) { engineArrayBuilder.append(sfi->next()->getCanonicalName()); } return engineArrayBuilder.arr(); }
TEST( ExpressionParserArrayTest, SizeAsString ) { BSONObj query = BSON( "x" << BSON( "$size" << "a" ) ); StatusWithExpression result = ExpressionParser::parse( query ); ASSERT_TRUE( result.isOK() ); ASSERT( !result.getValue()->matches( BSON( "x" << 1 ) ) ); ASSERT( !result.getValue()->matches( BSON( "x" << BSON_ARRAY( 1 << 2 ) ) ) ); ASSERT( result.getValue()->matches( BSON( "x" << BSONArray() ) ) ); ASSERT( !result.getValue()->matches( BSON( "x" << BSON_ARRAY( 1 ) ) ) ); }
StatusWith<Shard::QueryResponse> ShardLocal::_exhaustiveFindOnConfig( OperationContext* txn, const ReadPreferenceSetting& readPref, const NamespaceString& nss, const BSONObj& query, const BSONObj& sort, boost::optional<long long> limit) { // Set up operation context with majority read snapshot so correct optime can be retrieved. Status status = txn->recoveryUnit()->setReadFromMajorityCommittedSnapshot(); auto replCoord = repl::ReplicationCoordinator::get(txn); // Ensure timeout is set on the txn so we don't wait forever for the snapshot. // TODO (SERVER-18277): Remove this CurOp::get(txn)->ensureStarted(); // Wait until a snapshot is available. while (status == ErrorCodes::ReadConcernMajorityNotAvailableYet) { LOG(1) << "Waiting for ReadFromMajorityCommittedSnapshot to become available"; replCoord->waitUntilSnapshotCommitted(txn, SnapshotName::min()); status = txn->recoveryUnit()->setReadFromMajorityCommittedSnapshot(); } if (!status.isOK()) { return status; } DBDirectClient client(txn); Query fullQuery(query); if (!sort.isEmpty()) { fullQuery.sort(sort); } fullQuery.readPref(readPref.pref, BSONArray()); try { std::unique_ptr<DBClientCursor> cursor = client.query(nss.ns().c_str(), fullQuery, limit.get_value_or(0)); if (!cursor) { return {ErrorCodes::OperationFailed, str::stream() << "Failed to establish a cursor for reading " << nss.ns() << " from local storage"}; } std::vector<BSONObj> documentVector; while (cursor->more()) { BSONObj document = cursor->nextSafe().getOwned(); documentVector.push_back(std::move(document)); } return Shard::QueryResponse{std::move(documentVector), replCoord->getCurrentCommittedSnapshotOpTime()}; } catch (const DBException& ex) { return ex.toStatus(); } }
TEST( SizeMatchExpression, MatchesNonArray ) { // Non arrays do not match. BSONObj stringValue = BSON( "a" << "z" ); BSONObj numberValue = BSON( "a" << 0 ); BSONObj arrayValue = BSON( "a" << BSONArray() ); SizeMatchExpression size; ASSERT( size.init( "", 0 ).isOK() ); ASSERT( !size.matchesSingleElement( stringValue.firstElement() ) ); ASSERT( !size.matchesSingleElement( numberValue.firstElement() ) ); ASSERT( size.matchesSingleElement( arrayValue.firstElement() ) ); }
Status parseRolesInfoCommand(const BSONObj& cmdObj, const StringData& dbname, RolesInfoArgs* parsedArgs) { unordered_set<std::string> validFieldNames; validFieldNames.insert("rolesInfo"); validFieldNames.insert("showPrivileges"); validFieldNames.insert("showBuiltinRoles"); Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames); if (!status.isOK()) { return status; } if (cmdObj["rolesInfo"].numberInt() == 1) { parsedArgs->allForDB = true; } else if (cmdObj["rolesInfo"].type() == Array) { status = parseRoleNamesFromBSONArray(BSONArray(cmdObj["rolesInfo"].Obj()), dbname, &parsedArgs->roleNames); if (!status.isOK()) { return status; } } else { RoleName name; status = _parseNameFromBSONElement(cmdObj["rolesInfo"], dbname, AuthorizationManager::ROLE_NAME_FIELD_NAME, AuthorizationManager::ROLE_SOURCE_FIELD_NAME, &name); if (!status.isOK()) { return status; } parsedArgs->roleNames.push_back(name); } status = bsonExtractBooleanFieldWithDefault(cmdObj, "showPrivileges", false, &parsedArgs->showPrivileges); if (!status.isOK()) { return status; } status = bsonExtractBooleanFieldWithDefault(cmdObj, "showBuiltinRoles", false, &parsedArgs->showBuiltinRoles); if (!status.isOK()) { return status; } return Status::OK(); }
bool appendEmptyResultSet(OperationContext* opCtx, BSONObjBuilder& result, Status status, const std::string& ns) { invariant(!status.isOK()); CurOp::get(opCtx)->debug().nreturned = 0; CurOp::get(opCtx)->debug().nShards = 0; if (status == ErrorCodes::NamespaceNotFound) { // Old style reply result << "result" << BSONArray(); // New (command) style reply appendCursorResponseObject(0LL, ns, BSONArray(), &result); return true; } uassertStatusOK(status); return true; }
Status parseAndValidateRolePrivilegeManipulationCommands(const BSONObj& cmdObj, const StringData& cmdName, const std::string& dbname, RoleName* parsedRoleName, PrivilegeVector* parsedPrivileges, BSONObj* parsedWriteConcern) { unordered_set<std::string> validFieldNames; validFieldNames.insert(cmdName.toString()); validFieldNames.insert("privileges"); validFieldNames.insert("writeConcern"); Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames); if (!status.isOK()) { return status; } status = _extractWriteConcern(cmdObj, parsedWriteConcern); if (!status.isOK()) { return status; } BSONObjBuilder roleObjBuilder; // Parse role name std::string roleName; status = bsonExtractStringField(cmdObj, cmdName, &roleName); if (!status.isOK()) { return status; } *parsedRoleName = RoleName(roleName, dbname); // Parse privileges BSONElement privilegesElement; status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement); if (!status.isOK()) { return status; } status = parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), parsedPrivileges); if (!status.isOK()) { return status; } if (!parsedPrivileges->size()) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << cmdName << " command requires a non-empty " "\"privileges\" array"); } return Status::OK(); }
Status parseUserRoleManipulationCommand(const BSONObj& cmdObj, const StringData& cmdName, const std::string& dbname, AuthorizationManager* authzManager, UserName* parsedUserName, vector<RoleName>* parsedRoleNames, BSONObj* parsedWriteConcern) { unordered_set<std::string> validFieldNames; validFieldNames.insert(cmdName.toString()); validFieldNames.insert("roles"); validFieldNames.insert("writeConcern"); Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames); if (!status.isOK()) { return status; } status = _extractWriteConcern(cmdObj, parsedWriteConcern); if (!status.isOK()) { return status; } std::string userNameStr; status = bsonExtractStringField(cmdObj, cmdName, &userNameStr); if (!status.isOK()) { return status; } *parsedUserName = UserName(userNameStr, dbname); BSONElement rolesElement; status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement); if (!status.isOK()) { return status; } status = _extractRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, authzManager, parsedRoleNames); if (!status.isOK()) { return status; } if (!parsedRoleNames->size()) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << cmdName << " command requires a non-empty" << " roles array"); } return Status::OK(); }
Status AuthzManagerExternalStateMongos::query( const NamespaceString& collectionName, const BSONObj& queryDoc, const BSONObj& projection, const stdx::function<void(const BSONObj&)>& resultProcessor) { try { scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(collectionName)); Query query(queryDoc); query.readPref(ReadPreference_PrimaryPreferred, BSONArray()); conn->get()->query(resultProcessor, collectionName.ns(), query, &projection); return Status::OK(); } catch (const DBException& e) { return e.toStatus(); } }
TEST( AllMatchExpression, MatchesArrayAndNonArrayMultiValues ) { BSONObj operand = BSON_ARRAY( 1 << 2 << 3 << 4 ); AllMatchExpression all; all.init( "a.b" ); all.getArrayFilterEntries()->addEquality( operand[0] ); all.getArrayFilterEntries()->addEquality( operand[1] ); all.getArrayFilterEntries()->addEquality( operand[2] ); all.getArrayFilterEntries()->addEquality( operand[3] ); ASSERT( all.matches( BSON( "a" << BSON_ARRAY( BSON( "b" << BSON_ARRAY( 4 << 5 << 2 ) ) << BSON( "b" << 3 ) << BSON( "b" << BSONArray() ) << BSON( "b" << BSON_ARRAY( 1 ) ) ) ), NULL ) ); }
TEST( AllElemMatchOp, Matches ) { BSONObj baseOperandgt1 = BSON( "$gt" << 1 ); auto_ptr<ComparisonMatchExpression> gt1( new ComparisonMatchExpression() ); ASSERT( gt1->init( "", ComparisonMatchExpression::GT, baseOperandgt1[ "$gt" ] ).isOK() ); BSONObj baseOperandlt1 = BSON( "$lt" << 10 ); auto_ptr<ComparisonMatchExpression> lt1( new ComparisonMatchExpression() ); ASSERT( lt1->init( "", ComparisonMatchExpression::LT, baseOperandlt1[ "$lt" ] ).isOK() ); auto_ptr<ElemMatchValueMatchExpression> elemMatch1( new ElemMatchValueMatchExpression() ); elemMatch1->init( "x" ); elemMatch1->add( gt1.release() ); elemMatch1->add( lt1.release() ); BSONObj baseOperandgt2 = BSON( "$gt" << 101 ); auto_ptr<ComparisonMatchExpression> gt2( new ComparisonMatchExpression() ); ASSERT( gt2->init( "", ComparisonMatchExpression::GT, baseOperandgt2[ "$gt" ] ).isOK() ); BSONObj baseOperandlt2 = BSON( "$lt" << 110 ); auto_ptr<ComparisonMatchExpression> lt2( new ComparisonMatchExpression() ); ASSERT( lt2->init( "", ComparisonMatchExpression::LT, baseOperandlt2[ "$lt" ] ).isOK() ); auto_ptr<ElemMatchValueMatchExpression> elemMatch2( new ElemMatchValueMatchExpression() ); elemMatch2->init( "x" ); elemMatch2->add( gt2.release() ); elemMatch2->add( lt2.release() ); AllElemMatchOp op; op.init( "x" ); op.add( elemMatch1.release() ); op.add( elemMatch2.release() ); BSONObj nonArray = BSON( "x" << 4 ); ASSERT( !op.matches( nonArray, NULL ) ); BSONObj emptyArray = BSON( "x" << BSONArray() ); ASSERT( !op.matches( emptyArray, NULL ) ); BSONObj nonNumberArray = BSON( "x" << BSON_ARRAY( "q" ) ); ASSERT( !op.matches( nonNumberArray, NULL ) ); BSONObj singleMatch = BSON( "x" << BSON_ARRAY( 5 ) ); ASSERT( !op.matches( singleMatch, NULL ) ); BSONObj otherMatch = BSON( "x" << BSON_ARRAY( 105 ) ); ASSERT( !op.matches( otherMatch, NULL ) ); BSONObj bothMatch = BSON( "x" << BSON_ARRAY( 5 << 105 ) ); ASSERT( op.matches( bothMatch, NULL ) ); BSONObj neitherMatch = BSON( "x" << BSON_ARRAY( 0 << 200 ) ); ASSERT( !op.matches( neitherMatch, NULL ) ); }
Status parseRolePossessionManipulationCommands(const BSONObj& cmdObj, const StringData& cmdName, const StringData& rolesFieldName, const std::string& dbname, std::string* parsedName, vector<RoleName>* parsedRoleNames, BSONObj* parsedWriteConcern) { unordered_set<std::string> validFieldNames; validFieldNames.insert(cmdName.toString()); validFieldNames.insert(rolesFieldName.toString()); validFieldNames.insert("writeConcern"); Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames); if (!status.isOK()) { return status; } status = _extractWriteConcern(cmdObj, parsedWriteConcern); if (!status.isOK()) { return status; } status = bsonExtractStringField(cmdObj, cmdName, parsedName); if (!status.isOK()) { return status; } BSONElement rolesElement; status = bsonExtractTypedField(cmdObj, rolesFieldName, Array, &rolesElement); if (!status.isOK()) { return status; } status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, rolesFieldName, parsedRoleNames); if (!status.isOK()) { return status; } if (!parsedRoleNames->size()) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << cmdName << " command requires a non-empty \"" << rolesFieldName << "\" array"); } return Status::OK(); }
Status Database::createView(OperationContext* txn, StringData ns, const CollectionOptions& options) { invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X)); invariant(options.isView()); NamespaceString nss(ns); NamespaceString viewOnNss(nss.db(), options.viewOn); _checkCanCreateCollection(nss, options); audit::logCreateCollection(&cc(), ns); if (nss.isOplog()) return Status(ErrorCodes::InvalidNamespace, str::stream() << "invalid namespace name for a view: " + nss.toString()); return _views.createView(txn, nss, viewOnNss, BSONArray(options.pipeline), options.collation); }
StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromBSON(const BSONObj& readPrefObj) { std::string modeStr; auto modeExtractStatus = bsonExtractStringField(readPrefObj, kModeFieldName, &modeStr); if (!modeExtractStatus.isOK()) { return modeExtractStatus; } ReadPreference mode; auto swReadPrefMode = parseReadPreferenceMode(modeStr); if (!swReadPrefMode.isOK()) { return swReadPrefMode.getStatus(); } mode = std::move(swReadPrefMode.getValue()); TagSet tags; BSONElement tagsElem; auto tagExtractStatus = bsonExtractTypedField(readPrefObj, kTagsFieldName, mongo::Array, &tagsElem); if (tagExtractStatus.isOK()) { tags = TagSet{BSONArray(tagsElem.Obj().getOwned())}; // In accordance with the read preference spec, passing the default wildcard tagset // '[{}]' is the same as not passing a TagSet at all. Furthermore, passing an empty // TagSet with a non-primary ReadPreference is equivalent to passing the wildcard // ReadPreference. if (tags == TagSet() || tags == TagSet::primaryOnly()) { tags = defaultTagSetForMode(mode); } // If we are using a user supplied TagSet, check that it is compatible with // the readPreference mode. else if (ReadPreference::PrimaryOnly == mode && (tags != TagSet::primaryOnly())) { return Status(ErrorCodes::BadValue, "Only empty tags are allowed with primary read preference"); } } else if (ErrorCodes::NoSuchKey == tagExtractStatus) { tags = defaultTagSetForMode(mode); } else { return tagExtractStatus; } return ReadPreferenceSetting(mode, tags); }
Status AuthzManagerExternalStateMongos::findOne( const NamespaceString& collectionName, const BSONObj& queryDoc, BSONObj* result) { try { scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(collectionName)); Query query(queryDoc); query.readPref(ReadPreference_PrimaryPreferred, BSONArray()); *result = conn->get()->findOne(collectionName, query).getOwned(); conn->done(); if (result->isEmpty()) { return Status(ErrorCodes::NoMatchingDocument, mongoutils::str::stream() << "No document in " << collectionName.ns() << " matches " << queryDoc); } return Status::OK(); } catch (const DBException& e) { return e.toStatus(); } }
Status parseAndValidateCreateRoleCommand(const BSONObj& cmdObj, const std::string& dbname, AuthorizationManager* authzManager, BSONObj* parsedRoleObj, BSONObj* parsedWriteConcern) { unordered_set<std::string> validFieldNames; validFieldNames.insert("createRole"); validFieldNames.insert("privileges"); validFieldNames.insert("roles"); validFieldNames.insert("writeConcern"); Status status = _checkNoExtraFields(cmdObj, "createRole", validFieldNames); if (!status.isOK()) { return status; } status = _extractWriteConcern(cmdObj, parsedWriteConcern); if (!status.isOK()) { return status; } BSONObjBuilder roleObjBuilder; // Parse role name std::string roleName; status = bsonExtractStringField(cmdObj, "createRole", &roleName); if (!status.isOK()) { return status; } // Prevent creating roles in the local database if (dbname == "local") { return Status(ErrorCodes::BadValue, "Cannot create roles in the local database"); } roleObjBuilder.append("_id", dbname + "." + roleName); roleObjBuilder.append(AuthorizationManager::ROLE_NAME_FIELD_NAME, roleName); roleObjBuilder.append(AuthorizationManager::ROLE_SOURCE_FIELD_NAME, dbname); // Parse privileges BSONElement privilegesElement; status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement); if (!status.isOK()) { return status; } status = _parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), NULL); if (!status.isOK()) { return status; } roleObjBuilder.append(privilegesElement); // Parse roles BSONElement rolesElement; status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement); if (!status.isOK()) { return status; } BSONArray modifiedRolesArray; status = _validateAndModifyRolesArray(rolesElement, dbname, authzManager, false, &modifiedRolesArray); if (!status.isOK()) { return status; } roleObjBuilder.append("roles", modifiedRolesArray); *parsedRoleObj = roleObjBuilder.obj(); return Status::OK(); }
virtual BSONArray splitPoints() const { return BSONArray(); }
Status _parseAndValidateInput(BSONObj cmdObj, CreateUserArgs* parsedArgs) const { unordered_set<std::string> validFieldNames; validFieldNames.insert("createUser"); validFieldNames.insert("user"); validFieldNames.insert("pwd"); validFieldNames.insert("userSource"); validFieldNames.insert("roles"); validFieldNames.insert("readOnly"); validFieldNames.insert("otherDBRoles"); // Iterate through all fields in command object and make sure there are no unexpected // ones. for (BSONObjIterator iter(cmdObj); iter.more(); iter.next()) { StringData fieldName = (*iter).fieldNameStringData(); if (!validFieldNames.count(fieldName.toString())) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "\"" << fieldName << "\" is not " "a valid argument to createUser"); } } Status status = bsonExtractStringField(cmdObj, "user", &parsedArgs->userName); if (!status.isOK()) { return status; } if (cmdObj.hasField("pwd")) { parsedArgs->hasPassword = true; status = bsonExtractStringField(cmdObj, "pwd", &parsedArgs->clearTextPassword); if (!status.isOK()) { return status; } } if (cmdObj.hasField("userSource")) { parsedArgs->hasUserSource = true; status = bsonExtractStringField(cmdObj, "userSource", &parsedArgs->userSource); if (!status.isOK()) { return status; } } if (cmdObj.hasField("readOnly")) { parsedArgs->hasReadOnly = true; status = bsonExtractBooleanField(cmdObj, "readOnly", &parsedArgs->readOnly); if (!status.isOK()) { return status; } } if (cmdObj.hasField("extraData")) { parsedArgs->hasExtraData = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "extraData", Object, &element); if (!status.isOK()) { return status; } parsedArgs->extraData = element.Obj(); } if (cmdObj.hasField("roles")) { parsedArgs->hasRoles = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "roles", Array, &element); if (!status.isOK()) { return status; } parsedArgs->roles = BSONArray(element.Obj()); } if (cmdObj.hasField("otherDBRoles")) { parsedArgs->hasOtherDBRoles = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "otherDBRoles", Object, &element); if (!status.isOK()) { return status; } parsedArgs->otherDBRoles = element.Obj(); } if (parsedArgs->hasPassword && parsedArgs->hasUserSource) { return Status(ErrorCodes::BadValue, "User objects can't have both 'pwd' and 'userSource'"); } if (!parsedArgs->hasPassword && !parsedArgs->hasUserSource) { return Status(ErrorCodes::BadValue, "User objects must have one of 'pwd' and 'userSource'"); } if (parsedArgs->hasRoles && parsedArgs->hasReadOnly) { return Status(ErrorCodes::BadValue, "User objects can't have both 'roles' and 'readOnly'"); } return Status::OK(); }
TagSet TagSet::primaryOnly() { return TagSet{BSONArray()}; }