public async Task <Paged <StoryDto> > HandleAsync(BrowseStories query) { var now = (query.Now.HasValue ? query.Now.Value : _clock.Current()).ToUnixTimeMilliseconds(); var documents = _database.GetCollection <StoryDocument>($"{Schema}.stories") .AsQueryable() .Where(x => x.From <= now && x.To >= now); var input = query.Query; if (!string.IsNullOrWhiteSpace(input)) { documents = documents.Where(x => x.Title.Contains(input) || x.Author.Name.Contains(input) || x.Tags.Contains(input)); } var result = await documents.OrderByDescending(x => x.CreatedAt).PaginateAsync(query); var storyIds = result.Items.Select(x => x.Id); var rates = await _database.GetCollection <StoryRatingDocument>($"{Schema}.ratings") .AsQueryable() .Where(x => storyIds.Contains(x.StoryId)) .ToListAsync(); var pagedResult = Paged <StoryDto> .From(result, result.Items.Select(x => x.ToDto(rates))); return(new Paged <StoryDto> { CurrentPage = pagedResult.CurrentPage, TotalPages = pagedResult.TotalPages, ResultsPerPage = pagedResult.ResultsPerPage, TotalResults = pagedResult.TotalResults, Items = pagedResult.Items }); }
public async Task <StoryDetailsDto> HandleAsync(GetStory query) { var story = await _database.GetCollection <StoryDocument>($"{Schema}.stories") .AsQueryable() .SingleOrDefaultAsync(x => x.Id == query.StoryId); if (story is null) { return(null); } var now = _clock.Current().ToUnixTimeMilliseconds(); if (story.From > now || story.To < now) { return(null); } var rates = await _database.GetCollection <StoryRatingDocument>($"{Schema}.ratings") .AsQueryable() .Where(x => x.StoryId == query.StoryId) .ToListAsync(); return(story.ToDetailsDto(rates, query.UserId)); }
public async Task HandleAsync(SendStory command) { var user = await _userRepository.GetAsync(command.UserId); if (user is null) { throw new UserNotFoundException(command.UserId); } if (!_storyAuthorPolicy.CanCreate(user)) { throw new CannotCreateStoryException(user.Id); } var author = Author.Create(user); var text = _storyTextFactory.Create(command.Text); var now = _clock.Current(); var visibility = command.VisibleFrom.HasValue && command.VisibleTo.HasValue ? new Visibility(command.VisibleFrom.Value, command.VisibleTo.Value, command.Highlighted) : Visibility.Default(now); var storyId = command.StoryId <= 0 ? _idGenerator.Generate() : command.StoryId; var story = Story.Create(storyId, author, command.Title, text, command.Tags, now, visibility); await _storyRepository.AddAsync(story); var domainEvents = story.Events.ToArray(); await _domainEventDispatcher.DispatchAsync(domainEvents); var integrationEvents = _eventMapper.Map(domainEvents).ToArray(); _storyRequestStorage.SetStoryId(command.Id, story.Id); await _messageBroker.PublishAsync(integrationEvents); }
public async Task <Paged <Story> > GetTimelineAsync(Guid userId, DateTime?from = null, DateTime?to = null) { var now = _clock.Current(); var minScore = GetScore(from ?? now.AddDays(-7)); var maxScore = GetScore(to ?? now); var storyIds = await _database.SortedSetRangeByScoreAsync(GetTimelineKey(userId), minScore, maxScore); var storyKeys = storyIds.Select(x => (RedisKey)GetStoryKey((long)x)).ToArray(); var storyEntries = await _database.StringGetAsync(storyKeys); var stories = new List <Story>(); foreach (var entry in storyEntries) { if (!entry.HasValue) { continue; } var story = JsonSerializer.Deserialize <Story>(entry); if (story.Visibility.From <= now && story.Visibility.To >= now) { stories.Add(story); } } return(new Paged <Story> { Items = stories, CurrentPage = 1, TotalPages = 1, TotalResults = stories.Count, ResultsPerPage = stories.Count }); }
public JsonWebToken CreateToken(string userId, string role = null, string audience = null, IDictionary <string, IEnumerable <string> > claims = null) { if (string.IsNullOrWhiteSpace(userId)) { throw new ArgumentException("User ID claim (subject) cannot be empty.", nameof(userId)); } var now = _clock.Current(); var jwtClaims = new List <Claim> { new Claim(JwtRegisteredClaimNames.Sub, userId), new Claim(JwtRegisteredClaimNames.UniqueName, userId), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToUnixTimeMilliseconds().ToString()) }; if (!string.IsNullOrWhiteSpace(role)) { jwtClaims.Add(new Claim(ClaimTypes.Role, role)); } if (!string.IsNullOrWhiteSpace(audience)) { jwtClaims.Add(new Claim(JwtRegisteredClaimNames.Aud, audience)); } if (claims?.Any() is true) { var customClaims = new List <Claim>(); foreach (var(claim, values) in claims) { customClaims.AddRange(values.Select(value => new Claim(claim, value))); } jwtClaims.AddRange(customClaims); } var expires = now.AddMilliseconds(_options.Expiry.TotalMilliseconds); var jwt = new JwtSecurityToken( _issuer, claims: jwtClaims, notBefore: now, expires: expires, signingCredentials: _signingCredentials ); var token = new JwtSecurityTokenHandler().WriteToken(jwt); return(new JsonWebToken { AccessToken = token, RefreshToken = string.Empty, Expires = expires.ToUnixTimeMilliseconds(), Id = userId, Role = role ?? string.Empty, Claims = claims ?? EmptyClaims }); }
private async Task <string> CreateRefreshTokenAsync(Guid userId) { var token = _rng.Generate(30, true); var refreshToken = new RefreshToken(new AggregateId(), userId, token, _clock.Current()); await _refreshTokenRepository.AddAsync(refreshToken); return(token); }
public async Task HandleAsync(CreateAd command) { var ad = new Ad(command.AdId, command.UserId, command.Header, command.Content, command.Tags, AdState.New, command.From, command.To, _clock.Current()); await _adRepository.AddAsync(ad); await _messageBroker.PublishAsync(new AdCreated(command.AdId)); }
public async Task HandleAsync(IMessage message, Func <Task> handler, string module) { if (!Enabled) { _logger.LogWarning("Inbox is disabled, incoming messages won't be processed."); return; } if (message.Id == Guid.Empty) { // A synchronous request await handler(); return; } var collection = _database.GetCollection <InboxMessage>($"{module}-module.{_collectionName}"); _logger.LogTrace($"Received a message with ID: '{message.Id}' to be processed."); if (await collection.AsQueryable().AnyAsync(x => x.Id == message.Id)) { _logger.LogWarning($"Message with ID: '{message.Id}' was already processed."); return; } IClientSessionHandle session = null; if (_transactionsEnabled) { session = await _sessionFactory.CreateAsync(); session.StartTransaction(); } try { _logger.LogTrace($"Handling a message with ID: '{message.Id}'..."); await handler(); await collection.InsertOneAsync(new InboxMessage { Id = message.Id, CorrelationId = message.CorrelationId, Name = message.GetType().Name.Underscore(), Module = message.GetModuleName(), Timestamp = _clock.Current().ToUnixTimeMilliseconds() }); if (session is {}) { await session.CommitTransactionAsync(); } _logger.LogTrace($"Handled a message with ID: '{message.Id}'."); }
public async Task HandleAsync(PublishAd command) { var ad = await _adRepository.GetAsync(command.AdId); if (ad is null) { throw new AdNotFoundException(command.AdId); } ad.Publish(_clock.Current()); var storyId = await _storyApiClient.SendStoryAsync(new SendStory(default, ad.UserId,
public async Task HandleAsync(RevokeRefreshToken command) { var token = await _refreshTokenRepository.GetAsync(command.RefreshToken); if (token is null) { throw new InvalidRefreshTokenException(); } token.Revoke(_clock.Current()); await _refreshTokenRepository.UpdateAsync(token); }
public async Task HandleAsync(ApproveAd command) { var ad = await _adRepository.GetAsync(command.AdId); if (ad is null) { throw new AdNotFoundException(command.AdId); } ad.Approve(_clock.Current()); await _adRepository.UpdateAsync(ad); await _messageBroker.PublishAsync(new AdApproved(ad.Id)); }
public async Task HandleAsync(PayAd command) { var ad = await _adRepository.GetAsync(command.AdId); if (ad is null) { throw new AdNotFoundException(command.AdId); } ad.Pay(_clock.Current()); var fundsCharged = await _usersApiClient.ChargeFundsAsync(ad.UserId, ad.Amount); if (!fundsCharged) { throw new CannotPayAdException(ad.Id); } await _adRepository.UpdateAsync(ad); await _messageBroker.PublishAsync(new AdPaid(ad.Id)); }
public async Task HandleAsync(UserCreated @event) { var user = new User(@event.UserId, @event.Name, _clock.Current()); await _userRepository.AddAsync(user); }