Exemplo n.º 1
0
        public CreateTerminal(Guid id, Guid presynapticNeuronId, Guid postsynapticNeuronId, NeurotransmitterEffect effect, float strength, string externalReferenceUrl, string userId)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                presynapticNeuronId,
                Messages.Exception.InvalidId,
                nameof(presynapticNeuronId)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                postsynapticNeuronId,
                Messages.Exception.InvalidId,
                nameof(postsynapticNeuronId)
                );
            AssertionConcern.AssertArgumentNotEmpty(
                userId,
                Messages.Exception.InvalidUserId,
                nameof(userId)
                );

            this.Id = id;
            this.PresynapticNeuronId  = presynapticNeuronId;
            this.PostsynapticNeuronId = postsynapticNeuronId;
            this.Effect               = effect;
            this.Strength             = strength;
            this.ExternalReferenceUrl = externalReferenceUrl;
            this.UserId               = userId;
        }
Exemplo n.º 2
0
        public DeactivateNeuron(Guid id, Guid authorId, int expectedVersion)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                authorId,
                Messages.Exception.InvalidId,
                nameof(authorId)
                );
            AssertionConcern.AssertArgumentValid(
                i => i >= 1,
                expectedVersion,
                Messages.Exception.InvalidExpectedVersion,
                nameof(expectedVersion)
                );

            this.Id              = id;
            this.AuthorId        = authorId;
            this.ExpectedVersion = expectedVersion;
        }
Exemplo n.º 3
0
        public ChangeAggregate(Guid id, string newAggregate, Guid authorId, int expectedVersion)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentNotNull(newAggregate, nameof(newAggregate));
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                authorId,
                Messages.Exception.InvalidId,
                nameof(authorId)
                );
            AssertionConcern.AssertArgumentValid(
                i => i >= 0,
                expectedVersion,
                Messages.Exception.InvalidExpectedVersion,
                nameof(expectedVersion)
                );

            this.Id              = id;
            this.NewAggregate    = newAggregate;
            this.AuthorId        = authorId;
            this.ExpectedVersion = expectedVersion;
        }
Exemplo n.º 4
0
        public async Task <ItemData> GetItemById(Guid id, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );

            // Using a random Guid for Author as we won't be saving anyway
            var eventSource = this.eventSourceFactory.Create(
                this.settingsService.EventSourcingInBaseUrl + "/",
                this.settingsService.EventSourcingOutBaseUrl + "/",
                Guid.NewGuid()
                );

            var item = await eventSource.Session.Get <Item>(id, cancellationToken : token);

            return(new ItemData()
            {
                Id = item.Id.ToString(),
                Tag = item.Tag,
                Version = item.Version
            });
        }
Exemplo n.º 5
0
        public CreateTerminal(Guid id, Guid presynapticNeuronId, Guid postsynapticNeuronId, NeurotransmitterEffect effect, float strength, Guid authorId)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                presynapticNeuronId,
                Messages.Exception.InvalidId,
                nameof(presynapticNeuronId)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                postsynapticNeuronId,
                Messages.Exception.InvalidId,
                nameof(postsynapticNeuronId)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                authorId,
                Messages.Exception.InvalidId,
                nameof(authorId)
                );

            this.Id = id;
            this.PresynapticNeuronId  = presynapticNeuronId;
            this.PostsynapticNeuronId = postsynapticNeuronId;
            this.Effect   = effect;
            this.Strength = strength;
            this.AuthorId = authorId;
        }
Exemplo n.º 6
0
        public ChangeNeuronTag(Guid id, string newTag, string userId, int expectedVersion)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentNotNull(newTag, nameof(newTag));
            AssertionConcern.AssertArgumentNotEmpty(
                userId,
                Messages.Exception.InvalidUserId,
                nameof(userId)
                );
            AssertionConcern.AssertArgumentValid(
                i => i >= 1,
                expectedVersion,
                Messages.Exception.InvalidExpectedVersion,
                nameof(expectedVersion)
                );

            this.Id              = id;
            this.NewTag          = newTag;
            this.UserId          = userId;
            this.ExpectedVersion = expectedVersion;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Constructs a Neuron.
        /// </summary>
        /// <param name="id"></param>
        public Neuron(Guid id)
        {
            AssertionConcern.AssertArgumentValid(i => i != Guid.Empty, id, Messages.Exception.IdEmpty, nameof(id));

            this.Id = id;
            this.ApplyChange(new NeuronCreated(id));
        }
Exemplo n.º 8
0
        public async Task <Author> GetAuthorBySubjectId(Guid subjectId, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(g => g != Guid.Empty, subjectId, Constants.Messages.Exception.InvalidId, nameof(subjectId));

            await this.userRepository.Initialize();

            User user = await this.userRepository.GetBySubjectId(subjectId);

            AssertionConcern.AssertStateTrue(user != null, Constants.Messages.Exception.UnauthorizedUserAccess);

            // TODO: check if null if neuron is inactive or deactivated, if so, should throw exception
            var userNeuron = (await this.neuronGraphQueryClient.GetNeuronById(
                                  this.settingsService.CortexGraphOutBaseUrl + "/",
                                  user.NeuronId.ToString(),
                                  token: token
                                  )).First();

            AssertionConcern.AssertStateTrue(userNeuron != null, Constants.Messages.Exception.NeuronNotFound);

            await this.regionPermitRepository.Initialize();

            var permits = await this.regionPermitRepository.GetAllByUserNeuronId(user.NeuronId);

            var author = new Author(
                user,
                permits
                );

            return(author);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Constructs an Item.
        /// </summary>
        /// <param name="id"></param>
        public Item(Guid id, string aggregate)
        {
            AssertionConcern.AssertArgumentValid(i => i != Guid.Empty, id, Messages.Exception.IdEmpty, nameof(id));
            AssertionConcern.AssertArgumentNotNull(aggregate, nameof(aggregate));

            this.Id = id;
            this.ApplyChange(new AggregateChanged(id, aggregate));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Constructs an Item.
        /// </summary>
        /// <param name="id"></param>
        public Item(Guid id, string tag)
        {
            AssertionConcern.AssertArgumentValid(i => i != Guid.Empty, id, Messages.Exception.IdEmpty, nameof(id));
            AssertionConcern.AssertArgumentNotNull(tag, nameof(tag));

            this.Id = id;
            this.ApplyChange(new TagChanged(id, tag));
        }
Exemplo n.º 11
0
        public async Task <ActionValidationResult> UpdateNeuron(Guid neuronId, string userId, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(g => g != Guid.Empty, neuronId, Constants.Messages.Exception.InvalidId, nameof(neuronId));
            AssertionConcern.AssertArgumentNotEmpty(userId, Constants.Messages.Exception.InvalidUserId, nameof(userId));

            var    actionErrors = new List <ErrorInfo>();
            var    neuronErrors = new List <ErrorInfo>();
            Author author       = null;

            // get reference to neuron being modified
            var neuron = (await this.neuronGraphQueryClient.GetNeuronById(
                              this.settingsService.CortexGraphOutBaseUrl + "/",
                              neuronId.ToString(),
                              new NeuronQuery()
            {
                NeuronActiveValues = ActiveValues.All
            },
                              token
                              )).Neurons.First();

            await this.authorRepository.Initialize();

            author = await this.authorRepository.GetByUserId(userId);

            if (author == null)
            {
                actionErrors.Add(new ErrorInfo(Constants.Messages.Exception.UnauthorizedUserAccess, ErrorType.Error));
            }
            else
            {
                var regionTag = neuron.Region.Id != null ? neuron.Region.Tag : "Base";
                // get write permit of author user for region
                var permit = author.Permits.SingleOrDefault(p =>
                                                            p.RegionNeuronId.EqualsString(neuron.Region.Id) &&
                                                            p.WriteLevel > 0
                                                            );

                // does author user have a write permit
                if (permit == null)
                {
                    neuronErrors.Add(new ErrorInfo(string.Format(Constants.Messages.Exception.UnauthorizedRegionWriteTemplate, regionTag), ErrorType.Error));
                }
                // does author user have an admin write access, or author user is the author of this neuron
                else if (!(permit.WriteLevel == 2 || neuron.Creation.Author.Id == author.User.NeuronId.ToString()))
                {
                    neuronErrors.Add(new ErrorInfo(string.Format(Constants.Messages.Exception.UnauthorizedNeuronWriteTemplate, neuron.Tag), ErrorType.Error));
                }
            }

            return(new ActionValidationResult(
                       author != null ? author.User.NeuronId : Guid.Empty,
                       actionErrors.ToArray(),
                       neuronErrors.Count > 0 ?
                       new NeuronValidationResult[] { new NeuronValidationResult(neuronId, neuronErrors.ToArray()) } :
                       new NeuronValidationResult[0]
                       ));
        }
Exemplo n.º 12
0
        public ItemCommandHandlers(IEventStore eventStore, ISession session)
        {
            AssertionConcern.AssertArgumentNotNull(eventStore, nameof(eventStore));
            AssertionConcern.AssertArgumentValid(
                es => es is IAuthoredEventStore,
                eventStore,
                "Specified 'eventStore' must be an IAuthoredEventStore implementation.",
                nameof(eventStore)
                );
            AssertionConcern.AssertArgumentNotNull(session, nameof(session));

            this.eventStore = (IAuthoredEventStore)eventStore;
            this.session    = session;
        }
Exemplo n.º 13
0
        public CreateNeuron(Guid id, string tag, Guid?regionId, string externalReferenceUrl, string userId)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentNotNull(tag, nameof(tag));

            this.Id                   = id;
            this.Tag                  = tag;
            this.RegionId             = regionId;
            this.ExternalReferenceUrl = externalReferenceUrl;
            this.UserId               = userId;
        }
Exemplo n.º 14
0
        public Terminal(Guid id, Neuron presynapticNeuron, Neuron postsynapticNeuron, NeurotransmitterEffect effect, float strength)
        {
            AssertionConcern.AssertArgumentValid(i => i != Guid.Empty, id, Messages.Exception.IdEmpty, nameof(id));
            AssertionConcern.AssertArgumentNotNull(presynapticNeuron, nameof(presynapticNeuron));
            AssertionConcern.AssertArgumentValid(n => n.Active, presynapticNeuron, Messages.Exception.NeuronInactive, nameof(presynapticNeuron));
            AssertionConcern.AssertArgumentNotNull(postsynapticNeuron, nameof(postsynapticNeuron));
            AssertionConcern.AssertArgumentValid(n => n.Active, postsynapticNeuron, Messages.Exception.NeuronInactive, nameof(postsynapticNeuron));
            AssertionConcern.AssertArgumentValid(e => e != NeurotransmitterEffect.NotSet, effect, Messages.Exception.ValidEffect, nameof(effect));
            AssertionConcern.AssertArgumentValid(s => s > 0 && s <= 1, strength, Messages.Exception.StrengthInvalid, nameof(strength));
            AssertionConcern.AssertArgumentValid(g => g != presynapticNeuron.Id, postsynapticNeuron.Id, Messages.Exception.PostCannotBeTheSameAsPre, nameof(postsynapticNeuron));
            AssertionConcern.AssertArgumentValid(g => g != presynapticNeuron.Id, id, Messages.Exception.InvalidTerminalIdCreation, nameof(id));
            AssertionConcern.AssertArgumentValid(g => g != postsynapticNeuron.Id, id, Messages.Exception.InvalidTerminalIdCreation, nameof(id));

            this.Id = id;
            this.ApplyChange(new TerminalCreated(id, presynapticNeuron.Id, postsynapticNeuron.Id, effect, strength));
        }
Exemplo n.º 15
0
        // TODO: Get User Subject Id to specify subject id in call to AuthorApplicationService
        internal static Guid GetUserSubjectId(NancyContext context)
        {
            Guid result = Guid.Empty;

            if (bool.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableKeys.RequireAuthentication), out bool value) && value)
            {
                AssertionConcern.AssertArgumentValid(c => c.CurrentUser != null, context, "Context User is null or not found.", nameof(context));
                result = Guid.Parse(context.CurrentUser.Claims.First(c => c.Type == "sub").Value);
            }
            else
            {
                result = Guid.Parse(Environment.GetEnvironmentVariable(EnvironmentVariableKeys.TestUserSubjectId));
            }

            return(result);
        }
Exemplo n.º 16
0
        // TODO: private async Task CloseConnection(SQLiteAsyncConnection connection)
        //{
        //    await connection.CloseAsync();
        //    connection = null;
        //    GC.Collect();
        //    GC.WaitForPendingFinalizers();
        //}

        public static async Task <NotificationLog> CreateNotificationLog(NotificationLogId notificationLogId, long notificationCount, IEnumerable <Notification> notificationList)
        {
            AssertionConcern.AssertArgumentValid(
                l => (l % EVENTS_PER_LOG) == 0,
                notificationLogId.High,
                $"LogId 'High' value must be divisible by '{EVENTS_PER_LOG}'",
                nameof(notificationLogId)
                );
            AssertionConcern.AssertArgumentValid(
                l => (notificationCount == 0 && l == 0) || ((l - 1 == 0) || ((l - 1) % EVENTS_PER_LOG) == 0),
                notificationLogId.Low,
                $"LogId 'Low' value must be equal to 1 or, 1 plus a number divisible by '{EVENTS_PER_LOG}'",
                nameof(notificationLogId)
                );

            return(await EventStore.CreateNotificationLog(new NotificationLogInfo(notificationLogId, notificationCount), notificationCount, notificationList));
        }
Exemplo n.º 17
0
        public async Task <ItemData> GetItemById(Guid id, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );

            var item = await this.session.Get <Item>(id, cancellationToken : token);

            return(new ItemData()
            {
                Id = item.Id.ToString(),
                Aggregate = item.Aggregate,
                Version = item.Version
            });
        }
Exemplo n.º 18
0
        public CreateNeuron(Guid id, Guid authorId)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                authorId,
                Messages.Exception.InvalidId,
                nameof(authorId)
                );

            this.Id       = id;
            this.AuthorId = authorId;
        }
        public async Task Handle(DeactivateTerminal message, CancellationToken token = default(CancellationToken))
        {
            AssertionConcern.AssertArgumentNotNull(message, nameof(message));

            var queryResult = await this.neuronGraphQueryClient.GetTerminalById(
                this.settingsService.CortexGraphOutBaseUrl + "/",
                message.Id.ToString(),
                new Graph.Common.NeuronQuery()
            {
                TerminalActiveValues = Graph.Common.ActiveValues.All
            },
                token
                );

            var terminal = queryResult.Neurons.FirstOrDefault()?.Terminal;

            AssertionConcern.AssertArgumentValid(t => t != null, terminal, "Specified terminal does not exist.", "Id");

            // validate
            var validationResult = await this.validationClient.UpdateNeuron(
                this.settingsService.IdentityAccessOutBaseUrl + "/",
                Guid.Parse(terminal.PresynapticNeuronId),
                message.UserId,
                token);

            if (!validationResult.HasErrors)
            {
                var txn = await Transaction.Begin(this.eventStore, this.inMemoryEventStore, message.Id, validationResult.UserNeuronId, message.ExpectedVersion);

                await txn.InvokeAdapter(
                    typeof(TerminalDeactivated).Assembly,
                    async (ev) => await this.terminalAdapter.DeactivateTerminal(
                        message.Id,
                        validationResult.UserNeuronId,
                        ev
                        ));

                await txn.Commit();
            }
        }
Exemplo n.º 20
0
        public DeactivateTerminal(Guid id, string userId, int expectedVersion)
        {
            AssertionConcern.AssertArgumentValid(
                g => g != Guid.Empty,
                id,
                Messages.Exception.InvalidId,
                nameof(id)
                );
            AssertionConcern.AssertArgumentNotEmpty(
                userId,
                Messages.Exception.InvalidUserId,
                nameof(userId)
                );
            AssertionConcern.AssertArgumentValid(
                i => i >= 1,
                expectedVersion,
                Messages.Exception.InvalidExpectedVersion,
                nameof(expectedVersion)
                );

            this.Id              = id;
            this.UserId          = userId;
            this.ExpectedVersion = expectedVersion;
        }
Exemplo n.º 21
0
        public async Task <ActionValidationResult> ReadNeurons(IEnumerable <Guid> neuronIds, string userId, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentNotNull(neuronIds, nameof(neuronIds));
            neuronIds.ToList().ForEach(g => AssertionConcern.AssertArgumentValid(
                                           guid => guid != Guid.Empty, g, Constants.Messages.Exception.InvalidId, nameof(neuronIds)
                                           ));
            AssertionConcern.AssertArgumentNotEmpty(userId, Constants.Messages.Exception.InvalidUserId, nameof(userId));

            var query = new NeuronQuery()
            {
                Id = neuronIds.Select(g => g.ToString()),
                NeuronActiveValues = ActiveValues.All,
                PageSize           = neuronIds.Count()
            };

            // get neurons which are also inactive
            var queryResult = await this.neuronGraphQueryClient.GetNeurons(
                this.settingsService.CortexGraphOutBaseUrl + "/",
                query,
                token
                );

            var actionErrors  = new List <ErrorInfo>();
            var neuronResults = new List <NeuronValidationResult>();

            await this.authorRepository.Initialize();

            Author author = await this.authorRepository.GetByUserId(userId);

            if (author == null)
            {
                actionErrors.Add(new ErrorInfo(Constants.Messages.Exception.UnauthorizedUserAccess, ErrorType.Error));
            }
            else if (queryResult.Neurons.Count() > 0)
            {
                // loop through each neuron
                foreach (var neuron in queryResult.Neurons)
                {
                    var regionTag = neuron.Region.Id != null ? neuron.Region.Tag : "Base";
                    // get region permit of author user for region
                    var permit = author.Permits.SingleOrDefault(p =>
                                                                p.RegionNeuronId.EqualsString(neuron.Region.Id) &&
                                                                p.ReadLevel > 0
                                                                );

                    // does author user have a read permit
                    if (permit == null)
                    {
                        neuronResults.Add(new NeuronValidationResult(Guid.Parse(neuron.Id), new ErrorInfo[]
                        {
                            new ErrorInfo(string.Format(Constants.Messages.Exception.UnauthorizedRegionReadTemplate, regionTag), ErrorType.Warning)
                        }));
                    }
                }
            }

            return(new ActionValidationResult(
                       author != null ? author.User.NeuronId : Guid.Empty,
                       actionErrors.ToArray(),
                       neuronResults.ToArray()
                       ));
        }
Exemplo n.º 22
0
        internal static string GetUserId(Request value)
        {
            AssertionConcern.AssertArgumentValid(k => k, (bool)value.Query["userid"].HasValue, "User Id was not found.", "userid");

            return(value.Query["userid"].ToString());
        }
Exemplo n.º 23
0
        public async Task <ActionValidationResult> CreateNeuron(Guid neuronId, Guid?neuronRegionId, string userId, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(g => g != Guid.Empty, neuronId, Constants.Messages.Exception.InvalidId, nameof(neuronId));

            var    actionErrors = new List <ErrorInfo>();
            var    neuronErrors = new List <ErrorInfo>();
            var    regionTag    = string.Empty;
            Author author       = null;
            Guid   userNeuronId = Guid.Empty;

            // if non-root region was specified, check if it exists
            if (neuronRegionId.HasValue)
            {
                // ensure that layer is a valid neuron
                var qs = (await this.neuronGraphQueryClient.GetNeuronById(
                              this.settingsService.CortexGraphOutBaseUrl + "/",
                              neuronRegionId.Value.ToString(),
                              new NeuronQuery()
                {
                    NeuronActiveValues = ActiveValues.All
                },
                              token: token
                              ));
                if (qs == null || qs.Neurons == null || qs.Neurons.Count() == 0)
                {
                    neuronErrors.Add(new ErrorInfo("Invalid region specified.", ErrorType.Error));
                }
                else
                {
                    regionTag = qs.Neurons.First().Tag;
                }
            }
            else
            {
                regionTag = "Base";
            }

            // Ensure that Neuron Id is equal to AuthorId if first Neuron is being created
            if ((await this.notificationClient.GetNotificationLog(
                     this.settingsService.EventSourcingOutBaseUrl + "/",
                     string.Empty
                     )).NotificationList.Count == 0)
            {
                AssertionConcern.AssertArgumentValid(g => g == string.Empty, userId, Constants.Messages.Exception.AnonymousUserExpected, nameof(userId));

                userNeuronId = neuronId;
            }
            // Ensure that Neuron Id is not equal to AuthorId if non-first Neuron is being created
            else
            {
                AssertionConcern.AssertArgumentNotEmpty(userId, Constants.Messages.Exception.InvalidUserId, nameof(userId));

                await this.authorRepository.Initialize();

                author = await this.authorRepository.GetByUserId(userId);

                if (author == null)
                {
                    actionErrors.Add(new ErrorInfo(Constants.Messages.Exception.UnauthorizedUserAccess, ErrorType.Error));
                }
                else
                {
                    userNeuronId = author.User.NeuronId;

                    // get write permit of author user for region
                    var permit = author.Permits.SingleOrDefault(p => p.RegionNeuronId == neuronRegionId && p.WriteLevel > 0);

                    // if author user doesn't have a write permit
                    if (permit == null)
                    {
                        neuronErrors.Add(new ErrorInfo(string.Format(Constants.Messages.Exception.UnauthorizedRegionWriteTemplate, regionTag), ErrorType.Error));
                    }
                }
            }

            return(new ActionValidationResult(
                       userNeuronId,
                       actionErrors.ToArray(),
                       neuronErrors.Count > 0 ?
                       new NeuronValidationResult[] { new NeuronValidationResult(neuronId, neuronErrors.ToArray()) } :
                       new NeuronValidationResult[0]
                       ));
        }
Exemplo n.º 24
0
        public async Task <ValidationResult> ValidateWrite(Guid neuronId, Guid regionId, Guid subjectId, CancellationToken token = default)
        {
            AssertionConcern.AssertArgumentValid(g => g != Guid.Empty, neuronId, Constants.Messages.Exception.InvalidId, nameof(neuronId));
            AssertionConcern.AssertArgumentValid(g => g != Guid.Empty, subjectId, Constants.Messages.Exception.InvalidId, nameof(subjectId));

            var cortexGraphOutUrl   = this.settingsService.CortexGraphOutBaseUrl + "/";
            var eventSourcingOutUrl = this.settingsService.EventSourcingOutBaseUrl + "/";
            var author = await this.GetAuthorBySubjectId(subjectId, token);

            // Ensure that Neuron Id is equal to AuthorId if first Neuron is being created
            if ((await this.notificationClient.GetNotificationLog(eventSourcingOutUrl, string.Empty)).NotificationList.Count == 0)
            {
                AssertionConcern.AssertArgumentValid(m => m == author.User.NeuronId, neuronId, "Author Neuron is expected.", nameof(neuronId));
            }
            // Ensure that Neuron Id is not equal to AuthorId if non-first Neuron is being created
            else
            {
                AssertionConcern.AssertArgumentValid(m => m != author.User.NeuronId, neuronId, "Author Neuron not expected .", nameof(neuronId));
            }

            // if region was specified, check if it exists
            if (regionId != Guid.Empty)
            {
                // ensure that layer is a valid neuron
                var region = await this.neuronGraphQueryClient.GetNeuronById(
                    cortexGraphOutUrl,
                    regionId.ToString(),
                    token : token
                    );

                AssertionConcern.AssertStateTrue(region != null, "Invalid region specified");
            }

            // get reference to neuron being modified
            var neuron = (await this.neuronGraphQueryClient.GetNeuronById(
                              cortexGraphOutUrl.ToString(),
                              neuronId.ToString(),
                              token: token
                              )).First();

            // get write permit of author user for region
            var permit = author.Permits.SingleOrDefault(l => l.RegionNeuronId == regionId && l.WriteLevel > 0);

            // does author user have a write permit
            AssertionConcern.AssertStateTrue(
                permit != null,
                string.Format(Messages.Exception.UnauthorizedLayerWriteTemplate, neuron.RegionTag)
                );

            // TODO: test
            // does neuron already exist
            if (neuron != null)
            {
                AssertionConcern.AssertArgumentValid(r => r.ToString() == neuron.RegionId, regionId, "Specified RegionId does not match RegionId of specified Neuron.", nameof(regionId));

                // does author user have an admin write access, or author user is the author of this neuron
                AssertionConcern.AssertStateTrue(
                    permit.WriteLevel == 2 || neuron.AuthorId == author.User.NeuronId.ToString(),
                    string.Format(Messages.Exception.UnauthorizedNeuronWriteTemplate, neuron.Tag)
                    );
            }

            return(new ValidationResult(new string[0], true));
        }