Пример #1
0
        private void EnsurePreviousValueMatchCurrentValue(PatchRequest patchCmd, RavenJToken property)
        {
            var prevVal = patchCmd.PrevVal;

            if (prevVal == null)
            {
                return;
            }
            switch (prevVal.Type)
            {
            case JTokenType.Undefined:
                if (property != null)
                {
                    throw new ConcurrencyException();
                }
                break;

            default:
                if (property == null)
                {
                    throw new ConcurrencyException();
                }
                var equalityComparer = new RavenJTokenEqualityComparer();
                if (equalityComparer.Equals(property, prevVal) == false)
                {
                    throw new ConcurrencyException();
                }
                break;
            }
        }
        /// <summary>
        /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value.
        /// </summary>
        public static void VerifyEncryptionKey(DocumentDatabase database, EncryptionSettings settings)
        {
            JsonDocument doc;

            try
            {
                doc = database.Documents.Get(Constants.InResourceKeyVerificationDocumentName, null);
            }
            catch (CryptographicException e)
            {
                throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones "
                                                       + "currently in the configuration file.", e);
            }

            if (doc != null)
            {
                var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
                if (!ravenJTokenEqualityComparer.Equals(doc.DataAsJson, Constants.InResourceKeyVerificationDocumentContents))
                {
                    throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones "
                                                           + "currently in the configuration file.");
                }
            }
            else
            {
                // This is the first time the database is loaded.
                if (EncryptedDocumentsExist(database))
                {
                    throw new InvalidOperationException("The database already has existing documents, you cannot start using encryption now.");
                }

                var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot();
                database.Documents.Put(Constants.InResourceKeyVerificationDocumentName, null, clonedDoc, new RavenJObject(), null);
            }
        }
Пример #3
0
        public override void OnPut(string key, Stream data, RavenJObject metadata)
        {
            using (Database.DisableAllTriggersForCurrentThread())
            {
                metadata.Remove(Constants.RavenReplicationConflict);                // you can't put conflicts

                var oldVersion = Database.Attachments.GetStatic(key);
                if (oldVersion == null)
                {
                    return;
                }
                if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
                {
                    return;
                }

                var history = new RavenJArray(ReplicationData.GetHistory(metadata));
                metadata[Constants.RavenReplicationHistory] = history;

                var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
                // this is a conflict document, holding document keys in the
                // values of the properties
                var conflictData = oldVersion.Data().ToJObject();
                var conflicts    = conflictData.Value <RavenJArray>("Conflicts");
                if (conflicts == null)
                {
                    return;
                }
                foreach (var prop in conflicts)
                {
                    var        id         = prop.Value <string>();
                    Attachment attachment = Database.Attachments.GetStatic(id);
                    if (attachment == null)
                    {
                        continue;
                    }
                    Database.Attachments.DeleteStatic(id, null);

                    // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
                    var conflictHistory = new RavenJArray(ReplicationData.GetHistory(attachment.Metadata));
                    conflictHistory.Add(new RavenJObject
                    {
                        { Constants.RavenReplicationVersion, attachment.Metadata[Constants.RavenReplicationVersion] },
                        { Constants.RavenReplicationSource, attachment.Metadata[Constants.RavenReplicationSource] }
                    });

                    foreach (var item in conflictHistory)
                    {
                        if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item)))
                        {
                            continue;
                        }
                        history.Add(item);
                    }
                }
            }
        }
        /// <summary>
        /// Determines if the entity have changed.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="documentMetadata">The document metadata.</param>
        /// <returns></returns>
        protected bool EntityChanged(object entity, DocumentMetadata documentMetadata)
        {
            if (documentMetadata == null)
            {
                return(true);
            }
            var newObj           = ConvertEntityToJson(entity, documentMetadata.Metadata);
            var equalityComparer = new RavenJTokenEqualityComparer();

            return(equalityComparer.Equals(newObj, documentMetadata.OriginalValue) == false ||
                   equalityComparer.Equals(documentMetadata.Metadata, documentMetadata.OriginalMetadata) == false);
        }
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            using (Database.DisableAllTriggersForCurrentThread())
            {
                metadata.Remove(Constants.RavenReplicationConflict);                // you can't put conflicts

                var oldVersion = Database.Get(key, transactionInformation);
                if (oldVersion == null)
                {
                    return;
                }
                if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
                {
                    return;
                }

                RavenJArray history = new RavenJArray(ReplicationData.GetHistory(metadata));
                metadata[Constants.RavenReplicationHistory] = history;

                var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
                // this is a conflict document, holding document keys in the
                // values of the properties
                var conflicts = oldVersion.DataAsJson.Value <RavenJArray>("Conflicts");
                if (conflicts == null)
                {
                    return;
                }
                foreach (var prop in conflicts)
                {
                    RavenJObject deletedMetadata;
                    Database.Delete(prop.Value <string>(), null, transactionInformation, out deletedMetadata);

                    // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
                    var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata));
                    conflictHistory.Add(new RavenJObject
                    {
                        { Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion] },
                        { Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource] }
                    });

                    foreach (var item in conflictHistory)
                    {
                        if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item)))
                        {
                            continue;
                        }
                        history.Add(item);
                    }
                }
            }
        }
		public override void OnPut(string key, Stream data, RavenJObject metadata)
		{
			using (Database.DisableAllTriggersForCurrentThread())
			{
				metadata.Remove(Constants.RavenReplicationConflict);// you can't put conflicts

				var oldVersion = Database.GetStatic(key);
				if (oldVersion == null)
					return;
				if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
					return;

				RavenJArray history = metadata.Value<RavenJArray>(Constants.RavenReplicationHistory) ?? new RavenJArray();
				metadata[Constants.RavenReplicationHistory] = history;

				var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
				// this is a conflict document, holding document keys in the 
				// values of the properties
				var conflictData = oldVersion.Data().ToJObject();
				var conflicts = conflictData.Value<RavenJArray>("Conflicts");
				if (conflicts == null)
					return;
				foreach (var prop in conflicts)
				{
					var id = prop.Value<string>();
					Attachment attachment = Database.GetStatic(id);
					if(attachment == null)
						continue;
					Database.DeleteStatic(id, null);

					// add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
					var conflictHistory = attachment.Metadata.Value<RavenJArray>(Constants.RavenReplicationHistory) ?? new RavenJArray();
					conflictHistory.Add(new RavenJObject
					{
						{Constants.RavenReplicationVersion, attachment.Metadata[Constants.RavenReplicationVersion]},
						{Constants.RavenReplicationSource, attachment.Metadata[Constants.RavenReplicationSource]}
					});

					foreach (var item in conflictHistory)
					{
						if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item)))
							continue;
						history.Add(item);
					}
				}
			}
		}
Пример #7
0
        private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, token);
            if (token == null)
            {
                token = new RavenJArray();
                document[propName] = token;
            }
            var array = GetArray(token, propName);

            var position = patchCmd.Position;
            var value    = patchCmd.Value;

            if (position == null && (value == null || value.Type == JTokenType.Null))
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
            }
            if (position != null && value != null && value.Type != JTokenType.Null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
            }
            if (position != null && (position.Value < 0 || position.Value >= array.Length))
            {
                throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
                                                   "' because position element is out of bound bounds");
            }

            if (value != null && value.Type != JTokenType.Null)
            {
                var equalityComparer = new RavenJTokenEqualityComparer();
                var singleOrDefault  = array.FirstOrDefault(x => equalityComparer.Equals(x, value));
                if (singleOrDefault == null)
                {
                    return;
                }
                array.Remove(singleOrDefault);
                return;
            }

            if (position != null)
            {
                array.RemoveAt(position.Value);
            }
        }
        /// <summary>
        /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value.
        /// </summary>
        public static void VerifyEncryptionKey(RavenFileSystem fileSystem, EncryptionSettings settings)
        {
            RavenJObject config = null;

            try
            {
                fileSystem.Storage.Batch(accessor =>
                {
                    try
                    {
                        config = accessor.GetConfig(Constants.InResourceKeyVerificationDocumentName);
                    }
                    catch (FileNotFoundException)
                    {
                    }
                });
            }
            catch (CryptographicException e)
            {
                throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones "
                                                       + "currently in the configuration file.", e);
            }

            if (config != null)
            {
                var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
                if (!ravenJTokenEqualityComparer.Equals(config, Constants.InResourceKeyVerificationDocumentContents))
                {
                    throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones is currently configured");
                }
            }
            else
            {
                // This is the first time the file system is loaded.
                if (EncryptedFileExist(fileSystem))
                {
                    throw new InvalidOperationException("The file system already has existing files, you cannot start using encryption now.");
                }

                var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot();
                fileSystem.Storage.Batch(accessor => accessor.SetConfig(Constants.InResourceKeyVerificationDocumentName, clonedDoc));
            }
        }
		public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
		{
			using (Database.DisableAllTriggersForCurrentThread())
			{
				metadata.Remove(ReplicationConstants.RavenReplicationConflict);// you can't put conflicts

				var oldVersion = Database.Get(key, transactionInformation);
				if (oldVersion == null)
					return;
				if (oldVersion.Metadata[ReplicationConstants.RavenReplicationConflict] == null)
					return;

				RavenJArray history = metadata.Value<RavenJArray>(ReplicationConstants.RavenReplicationHistory) ?? new RavenJArray();
				metadata[ReplicationConstants.RavenReplicationHistory] = history;

				var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
				// this is a conflict document, holding document keys in the 
				// values of the properties
				var conflicts = oldVersion.DataAsJson.Value<RavenJArray>("Conflicts");
				if (conflicts == null)
					return;
				foreach (var prop in conflicts)
				{
					RavenJObject deletedMetadata;
					Database.Delete(prop.Value<string>(), null, transactionInformation, out deletedMetadata);

					// add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
					var conflictHistory = deletedMetadata.Value<RavenJArray>(ReplicationConstants.RavenReplicationHistory) ?? new RavenJArray();
					conflictHistory.Add(new RavenJObject
					{
						{ReplicationConstants.RavenReplicationVersion, deletedMetadata[ReplicationConstants.RavenReplicationVersion]},
						{ReplicationConstants.RavenReplicationSource, deletedMetadata[ReplicationConstants.RavenReplicationSource]}
					});

					foreach (var item in conflictHistory)
					{
						if(history.Any(x=>ravenJTokenEqualityComparer.Equals(x, item)))
							continue;
						history.Add(item);
					}
				}
			}
		}
Пример #10
0
        /// <summary>
        /// Determines if the entity have changed.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="documentMetadata">The document metadata.</param>
        /// <returns></returns>
        protected bool EntityChanged(object entity, DocumentMetadata documentMetadata)
        {
            if (documentMetadata == null)
            {
                return(true);
            }
            // prevent saves of a modified read only entity
            if (documentMetadata.OriginalMetadata.ContainsKey(Constants.RavenReadOnly) &&
                documentMetadata.OriginalMetadata.Value <bool>(Constants.RavenReadOnly) &&
                documentMetadata.Metadata.ContainsKey(Constants.RavenReadOnly) &&
                documentMetadata.Metadata.Value <bool>(Constants.RavenReadOnly))
            {
                return(false);
            }
            var newObj           = ConvertEntityToJson(entity, documentMetadata.Metadata);
            var equalityComparer = new RavenJTokenEqualityComparer();

            return(equalityComparer.Equals(newObj, documentMetadata.OriginalValue) == false ||
                   equalityComparer.Equals(documentMetadata.Metadata, documentMetadata.OriginalMetadata) == false);
        }
		/// <summary>
		/// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value.
		/// </summary>
		public static void VerifyEncryptionKey(DocumentDatabase database, EncryptionSettings settings)
		{
			JsonDocument doc;
			try
			{
				doc = database.Documents.Get(Constants.InDatabaseKeyVerificationDocumentName, null);
			}
			catch (CryptographicException e)
			{
				throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones "
					+ "currently in the configuration file.", e);
			}

			if (doc != null)
			{
				var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
				if (!ravenJTokenEqualityComparer.Equals(doc.DataAsJson,Constants.InDatabaseKeyVerificationDocumentContents))
					throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones "
						+ "currently in the configuration file.");
			}
			else
			{
				// This is the first time the database is loaded.
				if (EncryptedDocumentsExist(database))
					throw new InvalidOperationException("The database already has existing documents, you cannot start using encryption now.");

				var clonedDoc = (RavenJObject)Constants.InDatabaseKeyVerificationDocumentContents.CreateSnapshot();
				database.Documents.Put(Constants.InDatabaseKeyVerificationDocumentName, null, clonedDoc, new RavenJObject(), null);
			}
		}
Пример #12
0
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            using (Database.DisableAllTriggersForCurrentThread())
            {
                metadata.Remove(Constants.RavenReplicationConflict);                // you can't put conflicts

                var oldVersion = Database.Get(key, transactionInformation);
                if (oldVersion == null)
                {
                    return;
                }
                if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
                {
                    return;
                }

                var history = new RavenJArray();
                metadata[Constants.RavenReplicationHistory] = history;

                var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
                // this is a conflict document, holding document keys in the
                // values of the properties
                var conflicts = oldVersion.DataAsJson.Value <RavenJArray>("Conflicts");
                if (conflicts == null)
                {
                    return;
                }

                var list = new List <RavenJArray>
                {
                    new RavenJArray(ReplicationData.GetHistory(metadata))             // first item to interleave
                };
                foreach (var prop in conflicts)
                {
                    RavenJObject deletedMetadata;
                    Database.Delete(prop.Value <string>(), null, transactionInformation, out deletedMetadata);

                    if (deletedMetadata != null)
                    {
                        var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata));
                        conflictHistory.Add(new RavenJObject
                        {
                            { Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion] },
                            { Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource] }
                        });
                        list.Add(conflictHistory);
                    }
                }


                int  index = 0;
                bool added = true;
                while (added) // interleave the history from all conflicts
                {
                    added = false;
                    foreach (var deletedMetadata in list)
                    {
                        // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
                        if (index < deletedMetadata.Length)
                        {
                            history.Add(deletedMetadata[index]);
                            added = true;
                        }
                    }
                    index++;
                }

                while (history.Length > Constants.ChangeHistoryLength)
                {
                    history.RemoveAt(0);
                }
            }
        }
Пример #13
0
		private void EnsurePreviousValueMatchCurrentValue(PatchRequest patchCmd, RavenJToken property)
		{
			var prevVal = patchCmd.PrevVal;
			if (prevVal == null)
				return;
			switch (prevVal.Type)
			{
				case JTokenType.Undefined:
					if (property != null)
						throw new ConcurrencyException();
					break;
				default:
					if (property == null)
						throw new ConcurrencyException();
					var equalityComparer = new RavenJTokenEqualityComparer();
					if (equalityComparer.Equals(property, prevVal) == false)
						throw new ConcurrencyException();
					break;
			}
		}
Пример #14
0
		private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token)
		{
			EnsurePreviousValueMatchCurrentValue(patchCmd, token);
			if (token == null)
			{
				token = new RavenJArray();
				document[propName] = token;
			}
			var array = GetArray(token, propName);

			var position = patchCmd.Position;
			var value = patchCmd.Value;
			if (position == null && value == null)
				throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
			if (position != null && value != null)
				throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
			if (position < 0 || position >= array.Length)
				throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
												   "' because position element is out of bound bounds");

			if (value != null)
			{
				var equalityComparer = new RavenJTokenEqualityComparer();
				var singleOrDefault = array.FirstOrDefault(x => equalityComparer.Equals(x, value));
				if (singleOrDefault == null)
					return;
				array.Remove(singleOrDefault);
				return;
			}
			array.RemoveAt(position.Value);
		}
Пример #15
0
		public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
		{
			using (Database.DisableAllTriggersForCurrentThread())
			{
				metadata.Remove(Constants.RavenReplicationConflict);// you can't put conflicts

				var oldVersion = Database.Get(key, transactionInformation);
				if (oldVersion == null)
					return;
				if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
					return;

				var history = new RavenJArray();
				metadata[Constants.RavenReplicationHistory] = history;

				var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
				// this is a conflict document, holding document keys in the 
				// values of the properties
				var conflicts = oldVersion.DataAsJson.Value<RavenJArray>("Conflicts");
				if(conflicts == null)
					return;

			    var list = new List<RavenJArray>
			    {
			        new RavenJArray(ReplicationData.GetHistory(metadata)) // first item to interleave
			    };
				foreach (var prop in conflicts)
				{
					RavenJObject deletedMetadata;
					Database.Delete(prop.Value<string>(), null, transactionInformation, out deletedMetadata);

				    if (deletedMetadata != null)
				    {
                        var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata));
                        conflictHistory.Add(new RavenJObject
				        {
				            {Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion]},
				            {Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource]}
				        });
				        list.Add(conflictHistory);
				    }
				}


			    int index = 0;
                bool added = true;
                while (added) // interleave the history from all conflicts
                {
                    added = false;
                    foreach (var deletedMetadata in list)
			        {
                        // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
			            if (index < deletedMetadata.Length)
			            {
			                history.Add(deletedMetadata[index]);
			                added = true;
			            }
			        }
			        index++;
			    }

                while (history.Length > Constants.ChangeHistoryLength)
                {
                    history.RemoveAt(0);
                }
			}
		}
		/// <summary>
		/// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value.
		/// </summary>
		public static void VerifyEncryptionKey(RavenFileSystem fileSystem, EncryptionSettings settings)
		{
			RavenJObject config = null;
			try
			{
				fileSystem.Storage.Batch(accessor =>
				{
					try
					{
						config = accessor.GetConfig(Constants.InResourceKeyVerificationDocumentName);
					}
					catch (FileNotFoundException)
					{
					}
				});
			}
			catch (CryptographicException e)
			{
				throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones "
					+ "currently in the configuration file.", e);
			}

			if (config != null)
			{
				var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer();
				if (!ravenJTokenEqualityComparer.Equals(config, Constants.InResourceKeyVerificationDocumentContents))
					throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones is currently configured");
			}
			else
			{
				// This is the first time the file system is loaded.
				if (EncryptedFileExist(fileSystem))
					throw new InvalidOperationException("The file system already has existing files, you cannot start using encryption now.");

				var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot();
				fileSystem.Storage.Batch(accessor => accessor.SetConfig(Constants.InResourceKeyVerificationDocumentName, clonedDoc));
			}
		}