public IUser Add(UserWithPasswordsDto dto) { var credentials = dto.RepositoryCredentials; this.EncryptCredentials(credentials); var model = new User { Id = dto.Id, Email = dto.Email, Name = dto.Name, RepositoryCredentials = credentials?.Select(c => c.ToCredentials()) }; var document = dto.ToBsonDocument(); this.collection.InsertOne(document); return(model); }
public void Update(string id, UserWithPasswordsDto dto) { var filter = Builders <BsonDocument> .Filter.Eq("_id", id); var update = Builders <BsonDocument> .Update.Set("Name", dto.Name); update = update.Set("Email", dto.Email); var result = this.collection.UpdateOne(filter, update); // update passwords var changedPasswords = dto.RepositoryCredentials.Where(c => !string.IsNullOrEmpty(c.Password)).ToArray(); if (result.ModifiedCount == 0 && !changedPasswords.Any()) { throw new InvalidOperationException("Have not updated any document. Filter: " + filter.ToJson()); } this.EncryptCredentials(dto.RepositoryCredentials); foreach (var cp in changedPasswords) { // perform atomic FindOneAndUpdate operation var users = this.database.GetCollection <UserWithPasswordsDto>("users"); var x = users.FindOneAndUpdate( c => c.Id == dto.Id && c.RepositoryCredentials.Any( s => s.Login == cp.Login && s.RepositoryType == cp.RepositoryType), // find this match Builders <UserWithPasswordsDto> .Update.Set("RepositoryCredentials.$.Password", cp.Password)); // -1 means update first matching array element if (x == null) { throw new InvalidOperationException($"Have not updated password for user {cp.Login}"); } } }