예제 #1
0
        public async Task <TokenResponseModel> Authenticate([FromBody] TokenRequestModel request)
        {
            var user = await Store.PasswordVerifyAsync(request.Identifier, request.Password);

            if (user != null)
            {
                await EventSender.SendAsync(new UserAuthenticated
                {
                    UserIdentifierTopic = request.Identifier
                });

                SecurityContext.AssumeUser(user);

                return(new TokenResponseModel
                {
                    Token = JWT.CreateUserToken(user, request.ClientClaims),
                    User = user,
                    Organization = await OrganizationStore.GetOneAsync(request.Identifier)
                });
            }
            else
            {
                throw new SecurityException();
            }
        }
예제 #2
0
        public void SendRequiresEvents()
        {
            var transportSender = new ObservableTransportSenderMock();
            var sender          = new EventSender(transportSender, "dummy", new EventSenderOptions());

            Assert.That(async() => await sender.SendAsync(null, new EventBatchingOptions()), Throws.ArgumentNullException);
        }
예제 #3
0
        private static async Task SendAndReceiveEvents()
        {
            var eventBatch = new[]
            {
                new EventData(Encoding.UTF8.GetBytes("First event data")),
                new EventData(Encoding.UTF8.GetBytes("Second event data")),
                new EventData(Encoding.UTF8.GetBytes("Third event data"))
            };
            var index          = 0;
            var receivedEvents = new List <EventData>();

            //Before sending any event, start the receiver
            await receiver.ReceiveAsync(1, TimeSpan.Zero);

            Console.Write("Ready to send a batch of " + eventBatch.Count().ToString() + " events... ");
            await sender.SendAsync(eventBatch);

            Console.Write("Sent\n");

            Console.Write("Receiving events... ");
            while ((receivedEvents.Count < eventBatch.Length) && (++index < 3))
            {
                receivedEvents.AddRange(await receiver.ReceiveAsync(eventBatch.Length + 10, TimeSpan.FromMilliseconds(25)));
            }
            index = 0;

            //Check if at least one event was received in order to start validation
            if (receivedEvents.Count == 0)
            {
                throw new Exception(String.Format("Error, No events received."));
            }
            Console.Write(receivedEvents.Count() + " events received.\n");

            Console.WriteLine("Beginning validation...");
            foreach (var receivedEvent in receivedEvents)
            {
                var receivedEventMessage = Encoding.UTF8.GetString(receivedEvent.Body.ToArray());
                var sentEventMessage     = Encoding.UTF8.GetString(eventBatch[index].Body.ToArray());

                if (receivedEventMessage == sentEventMessage)
                {
                    Console.WriteLine("\tEvent '" + receivedEventMessage + "' correctly validated.");
                }
                else
                {
                    throw new Exception(String.Format("Error, Event: '" + receivedEventMessage + "' was not expected."));
                }
                index++;
            }

            if (index < eventBatch.Count())
            {
                throw new Exception(String.Format("Error, expecting " + eventBatch.Count().ToString() + " events, but only got " + index.ToString() + "."));
            }

            Console.WriteLine("done");
        }
        public async Task <UserNotification> Create(UserNotification notification)
        {
            notification.User ??= ContextProvider.GetRepository <IUserRepository>().GetByKey(UserId);

            var createdNotification = await ContextProvider.GetRepository <IUserNotificationRepository>().Create(notification);

            await EventSender.SendAsync($"OnUserNotification_{notification.User.Id}", createdNotification);

            return(createdNotification);
        }
예제 #5
0
        public void SendAllowsAPartitionHashKey()
        {
            var batchingOptions = new EventBatchingOptions {
                PartitionKey = "testKey"
            };
            var events          = new[] { new EventData(new byte[] { 0x44, 0x66, 0x88 }) };
            var transportSender = new ObservableTransportSenderMock();
            var sender          = new EventSender(transportSender, "dummy", new EventSenderOptions());

            Assert.That(async() => await sender.SendAsync(events, batchingOptions), Throws.Nothing);
        }
예제 #6
0
        public async Task SendWithoutOptionsInvokesTheTransportSender()
        {
            var events          = Mock.Of <IEnumerable <EventData> >();
            var transportSender = new ObservableTransportSenderMock();
            var sender          = new EventSender(transportSender, "dummy", new EventSenderOptions());

            await sender.SendAsync(events);

            (var calledWithEvents, var calledWithOptions) = transportSender.SendCalledWithParameters;

            Assert.That(calledWithEvents, Is.SameAs(events), "The events should be the same instance.");
            Assert.That(calledWithOptions, Is.Not.Null, "A default set of options should be used.");
        }
예제 #7
0
        public void SendForASpecificPartitionDoesNotAllowAPartitionHashKey()
        {
            var batchingOptions = new EventBatchingOptions {
                PartitionKey = "testKey"
            };
            var events          = new[] { new EventData(new byte[] { 0x44, 0x66, 0x88 }) };
            var transportSender = new ObservableTransportSenderMock();
            var sender          = new EventSender(transportSender, "dummy", new EventSenderOptions {
                PartitionId = "1"
            });

            Assert.That(async() => await sender.SendAsync(events, batchingOptions), Throws.InvalidOperationException);
        }
예제 #8
0
        public async Task Setup(Guid sessionId, long templateId, string templateVersionId, Language language, AuthorInfo authorInfo)
        {
            if (language == Language.Unspecified)
            {
                throw new SessionCannotBeCreatedException("Language must be explicitly specified.");
            }

            var templateDescriptor = await _templatesStorageReader.GetTemplateDescriptor(templateId, templateVersionId);

            var sessionDescriptor = new SessionDescriptor
            {
                TemplateId                 = templateDescriptor.Id,
                TemplateVersionId          = templateDescriptor.VersionId,
                Language                   = language,
                BinaryElementTemplateCodes = templateDescriptor.GetBinaryElementTemplateCodes()
            };
            var request = new PutObjectRequest
            {
                BucketName  = _filesBucketName,
                Key         = sessionId.AsS3ObjectKey(Tokens.SessionPostfix),
                CannedACL   = S3CannedACL.PublicRead,
                ContentType = ContentType.Json,
                ContentBody = JsonConvert.SerializeObject(sessionDescriptor, SerializerSettings.Default)
            };

            var expiresAt       = SessionDescriptor.CurrentTime().Add(_sessionExpiration);
            var metadataWrapper = MetadataCollectionWrapper.For(request.Metadata);

            metadataWrapper.Write(MetadataElement.ExpiresAt, expiresAt);
            metadataWrapper.Write(MetadataElement.Author, authorInfo.Author);
            metadataWrapper.Write(MetadataElement.AuthorLogin, authorInfo.AuthorLogin);
            metadataWrapper.Write(MetadataElement.AuthorName, authorInfo.AuthorName);

            await _eventSender.SendAsync(_sessionsTopicName, new SessionCreatingEvent(sessionId, expiresAt));

            await _cephS3Client.PutObjectAsync(request);

            _createdSessionsMetric.Inc();
        }
        private static async Task SendAndReceiveEvents()
        {
            var eventBatch = new[]
            {
                new EventData(Encoding.UTF8.GetBytes("First event data")),
                new EventData(Encoding.UTF8.GetBytes("Second event data")),
                new EventData(Encoding.UTF8.GetBytes("Third event data"))
            };
            var index          = 0;
            var receivedEvents = new List <EventData>();

            //Before sending any event, start the receiver
            await receiver.ReceiveAsync(1, TimeSpan.Zero);

            Console.Write("Ready to send a batch of " + eventBatch.Count().ToString() + " events... ");
            await sender.SendAsync(eventBatch);

            Console.Write("Sent\n");

            Console.Write("Receiving events... ");
            while ((receivedEvents.Count < eventBatch.Length) && (++index < 3))
            {
                receivedEvents.AddRange(await receiver.ReceiveAsync(eventBatch.Length + 10, TimeSpan.FromMilliseconds(25)));
            }

            if (receivedEvents.Count == 0)
            {
                throw new Exception(String.Format("Error, No events received."));
            }
            Console.Write(receivedEvents.Count() + " events received.\n");

            if (receivedEvents.Count() < eventBatch.Count())
            {
                throw new Exception(String.Format($"Error, expecting {eventBatch.Count()} events, but only got {receivedEvents.Count().ToString()}."));
            }

            Console.WriteLine("done");
        }
예제 #10
0
        public async Task <TokenResponseModel> Impersonate([FromBody] UserIdentifier userIdentifier)
        {
            if (userIdentifier == null)
            {
                throw new ArgumentNullException(nameof(userIdentifier));
            }

            var organizationModel = await OrganizationStore.GetOneAsync(userIdentifier);

            var userModel = await Store.GetOneAsync(userIdentifier);

            if (organizationModel == null || userModel == null)
            {
                throw new ObjectDoesNotExistException();
            }

            organizationModel.PrivilegeCheck("user:impersonate", SecurityContext);

            if (userModel != null)
            {
                await EventSender.SendAsync(new UserImpersonated
                {
                    UserIdentifierTopic = userIdentifier
                });

                return(new TokenResponseModel
                {
                    Token = JWT.CreateUserToken(userModel),
                    User = userModel,
                    Organization = organizationModel
                });
            }
            else
            {
                throw new SecurityException();
            }
        }
예제 #11
0
        private IDisposable ObjectVersionCreatedEventsProducing(CancellationToken cancellationToken)
        {
            async Task ProcessAsync(KafkaEvent <ObjectVersionCreatingEvent> @event)
            {
                var objectId  = @event.Source.ObjectId;
                var versionId = @event.Source.CurrentVersionId;

                IReadOnlyCollection <ObjectVersionRecord> versionRecords;

                if (string.IsNullOrEmpty(versionId))
                {
                    var policy = CreateGetObjectVersionsResiliencePolicy();
                    versionRecords = await policy.ExecuteAsync(() => _objectsStorageReader.GetObjectVersions(objectId, versionId));

                    if (versionRecords == null)
                    {
                        _logger.LogWarning(
                            "{taskName}: Got an event for the object with id = '{objectId}' that was not eventually created. The event will be skipped.",
                            nameof(ObjectVersionCreatedEventsProducing),
                            objectId);
                        return;
                    }
                }
                else
                {
                    versionRecords = await _objectsStorageReader.GetObjectVersions(objectId, versionId);
                }

                _logger.LogInformation(
                    "{taskName}: There are '{versionsCount}' new versions were created after the versionId = {versionId} for the object id = '{objectId}'.",
                    nameof(ObjectVersionCreatedEventsProducing),
                    versionRecords.Count,
                    versionId,
                    objectId);
                foreach (var record in versionRecords)
                {
                    var versionCreatedEvent = new ObjectVersionCreatedEvent(
                        record.Id,
                        record.VersionId,
                        record.VersionIndex,
                        record.Author,
                        record.Properties,
                        record.LastModified);
                    await _eventSender.SendAsync(_objectVersionsTopic, versionCreatedEvent);

                    _logger.LogInformation(
                        "{taskName}: Event for object id = '{objectId}' and versionId = {versionId} sent to {topic}.",
                        nameof(ObjectVersionCreatedEventsProducing),
                        record.Id,
                        record.VersionId,
                        _objectVersionsTopic);
                }

                await _versionEventReceiver.CommitAsync(@event);
            }

            var observable = _versionEventReceiver.Subscribe <ObjectVersionCreatingEvent>(cancellationToken);

            return(observable
                   .Do(@event =>
            {
                var retry = CreateRetryPolicy(_logger, nameof(ObjectVersionCreatedEventsProducing));
                retry.Execute(() => ProcessAsync(@event).GetAwaiter().GetResult());
            })
                   .Subscribe());
        }
예제 #12
0
        private async Task <string> PutObject(long id,
                                              string versionId,
                                              AuthorInfo authorInfo,
                                              IEnumerable <IObjectElementDescriptor> existingObjectElements,
                                              IObjectDescriptor objectDescriptor)
        {
            PreprocessObjectElements(objectDescriptor.Elements);
            await VerifyObjectElementsConsistency(id, objectDescriptor.Language, objectDescriptor.Elements);

            var metadataForBinaries = await RetrieveMetadataForBinaries(id, existingObjectElements, objectDescriptor.Elements);

            await _eventSender.SendAsync(_objectEventsTopic, new ObjectVersionCreatingEvent(id, versionId));

            var totalBinariesCount = 0;
            PutObjectRequest          putRequest;
            MetadataCollectionWrapper metadataWrapper;

            foreach (var elementDescriptor in objectDescriptor.Elements)
            {
                var(elementPersistenceValue, binariesCount) = ConvertToPersistenceValue(elementDescriptor.Value, metadataForBinaries);
                var elementPersistenceDescriptor = new ObjectElementPersistenceDescriptor(elementDescriptor, elementPersistenceValue);
                totalBinariesCount += binariesCount;
                putRequest          = new PutObjectRequest
                {
                    Key         = id.AsS3ObjectKey(elementDescriptor.Id),
                    BucketName  = _bucketName,
                    ContentType = ContentType.Json,
                    ContentBody = JsonConvert.SerializeObject(elementPersistenceDescriptor, SerializerSettings.Default),
                    CannedACL   = S3CannedACL.PublicRead
                };

                metadataWrapper = MetadataCollectionWrapper.For(putRequest.Metadata);
                metadataWrapper.Write(MetadataElement.Author, authorInfo.Author);
                metadataWrapper.Write(MetadataElement.AuthorLogin, authorInfo.AuthorLogin);
                metadataWrapper.Write(MetadataElement.AuthorName, authorInfo.AuthorName);

                await _s3Client.PutObjectAsync(putRequest);
            }

            var objectKey      = id.AsS3ObjectKey(Tokens.ObjectPostfix);
            var objectVersions = await _objectsStorageReader.GetObjectLatestVersions(id);

            var elementVersions             = objectVersions.Where(x => !x.Id.EndsWith(Tokens.ObjectPostfix)).ToList();
            var objectPersistenceDescriptor = new ObjectPersistenceDescriptor
            {
                TemplateId        = objectDescriptor.TemplateId,
                TemplateVersionId = objectDescriptor.TemplateVersionId,
                Language          = objectDescriptor.Language,
                Properties        = objectDescriptor.Properties,
                Elements          = elementVersions
            };

            putRequest = new PutObjectRequest
            {
                Key         = objectKey,
                BucketName  = _bucketName,
                ContentType = ContentType.Json,
                ContentBody = JsonConvert.SerializeObject(objectPersistenceDescriptor, SerializerSettings.Default),
                CannedACL   = S3CannedACL.PublicRead
            };

            metadataWrapper = MetadataCollectionWrapper.For(putRequest.Metadata);
            metadataWrapper.Write(MetadataElement.Author, authorInfo.Author);
            metadataWrapper.Write(MetadataElement.AuthorLogin, authorInfo.AuthorLogin);
            metadataWrapper.Write(MetadataElement.AuthorName, authorInfo.AuthorName);
            metadataWrapper.Write(
                MetadataElement.ModifiedElements,
                string.Join(Tokens.ModifiedElementsDelimiter.ToString(), objectDescriptor.Elements.Select(x => x.TemplateCode)));

            await _s3Client.PutObjectAsync(putRequest);

            _referencedBinariesMetric.Inc(totalBinariesCount);

            objectVersions = await _objectsStorageReader.GetObjectLatestVersions(id);

            return(objectVersions.Where(x => x.Id.EndsWith(Tokens.ObjectPostfix))
                   .Select(x => x.VersionId)
                   .Single());
        }