Esempio n. 1
0
 public async Task <User> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken)
 {
     using (var connection = new ConScope(_dataService))
     {
         return(await connection.Connection.SingleAsync <User>(x => x.EmailNormalized == normalizedEmail, cancellationToken));
     }
 }
Esempio n. 2
0
        public async Task <JobTask> DequeueJob()
        {
            JobV1 result;

            using (var connection = new ConScope(_dataService))
            {
                using (var transaction = await connection.BeginTransaction())
                {
                    result = await connection.Connection.SingleAsync(
                        connection.Connection.From <JobV1>()
                        .Where(x => x.Status == JobStatus.Queued)
                        .OrderBy(x => x.QueuedOn)
                        .Take(1));

                    if (result == null)
                    {
                        return(null);
                    }

                    result.Status = JobStatus.Processing;

                    await connection.Connection.UpdateAsync(result);

                    transaction.Commit();
                }
            }

            return(new JobTask
            {
                JobId = result.Id,
                Type = Type.GetType(result.JobType),
                Data = JsonConvert.DeserializeObject(result.JobData, Type.GetType(result.JobDataType), (JsonSerializerSettings)null)
            });
        }
Esempio n. 3
0
        public async Task <Account> GetOrCreateAccount(AccountIdentification id)
        {
            using (var con = new ConScope(_dataService))
                using (var trans = await con.BeginTransaction())
                {
                    var account = await GetAccount(id);

                    if (account == null)
                    {
                        if (!id.GlobalUserId.HasValue)
                        {
                            throw new Exception("Can only auto create account when using global user id.");
                        }

                        account = new Account
                        {
                            GlobalUserId = id.GlobalUserId.Value
                        };

                        await con.Connection.SaveAsync(account);

                        trans.Commit();

                        _logger.LogInformation("Created account {AccountId} for global user {GlobalUserId", account.Id, id.GlobalUserId);
                    }

                    return(account);
                }
        }
Esempio n. 4
0
 public async Task <User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
 {
     using (var connection = new ConScope(_dataService))
     {
         return(await connection.Connection.SingleAsync <User>(x => x.UserName.ToUpper() == normalizedUserName, cancellationToken));
     }
 }
Esempio n. 5
0
        public async Task MarkJobSucceeded(int jobId)
        {
            JobV1 job;

            using (var connection = new ConScope(_dataService))
            {
                using (var transaction = await connection.BeginTransaction())
                {
                    job = await connection.Connection.SingleByIdAsync <JobV1>(jobId);

                    if (job == null)
                    {
                        throw new Exception($"Invalid job id {jobId}");
                    }

                    if (job.Status != JobStatus.Processing)
                    {
                        throw new Exception($"Can't mark a job {jobId} as completed because it wasn't marked as processing.");
                    }

                    await connection.Connection.DeleteAsync(job);

                    transaction.Commit();
                }
            }

            await _jobSucceeded.Publish(this, new JobSucceededEvent(new JobTask
            {
                JobId = job.Id,
                Type = Type.GetType(job.JobType),
                Data = JsonConvert.DeserializeObject(job.JobData, Type.GetType(job.JobDataType))
            }));
        }
        public async Task SaveSetting <T>(Action <T> updateAction)
        {
            using (var connection = new ConScope(_dataService))
                using (var transaction = await connection.BeginTransaction())
                {
                    var name = GetSettingNameAttribute(typeof(T));

                    var existing = await GetSetting <T>();

                    updateAction(existing);

                    var settingValue = _settingsSerializer.Serialize(existing);

                    var setting = await connection.Connection.SingleAsync(connection.Connection.From <SettingV1>().Where(x => x.Name == name));

                    if (setting == null)
                    {
                        setting = new SettingV1 {
                            Name = name, Settings = settingValue
                        };
                        await connection.Connection.SaveAsync(setting);
                    }
                    else
                    {
                        setting.Settings = settingValue;
                        await connection.Connection.UpdateAsync(setting);
                    }

                    transaction.Commit();
                }
        }
Esempio n. 7
0
        public async Task Enqueue <T, TData>(TData data) where T : IJob where TData : new()
        {
            var job = new JobV1
            {
                QueuedOn    = DateTimeOffset.UtcNow,
                JobType     = typeof(T).AssemblyQualifiedName,
                JobDataType = typeof(TData).AssemblyQualifiedName,
                JobData     = JsonConvert.SerializeObject(data)
            };

            using (var connection = new ConScope(_dataService))
            {
                using (var transaction = await connection.BeginTransaction())
                {
                    await connection.Connection.SaveAsync(job);

                    transaction.Commit();
                }
            }

            await _jobEnqueued.Publish(this, new JobEnqueuedEvent(new JobTask
            {
                JobId = job.Id,
                Type = typeof(T),
                Data = data
            }));
        }
Esempio n. 8
0
        public async Task Can_update_settings()
        {
            var setting = new TestSetting
            {
                NameProperty = "lando",
                Value        = 5
            };
            await _settingsService.SaveSetting(setting);

            setting = new TestSetting
            {
                NameProperty = "landocalrissian",
                Value        = 10
            };
            await _settingsService.SaveSetting(setting);

            using (var conScope = new ConScope(GetDataService()))
            {
                (await conScope.Connection.CountAsync(conScope.Connection.From <SettingV1>().Where(x => x.Name == "dbname"))).Should().Be(1);
            }

            setting = await _settingsService.GetSetting <TestSetting>();

            setting.NameProperty.Should().Be("landocalrissian");
        }
Esempio n. 9
0
        public async Task <Transaction> AddTransaction(Guid accountId, decimal amount, string title, string metaData, Guid?payPalOrderId)
        {
            using (var con = new ConScope(_dataService))
                using (var trans = await con.BeginTransaction())
                {
                    // Let's update the total on the account object.
                    var runningTotal = await con.Connection.SingleAsync <decimal>(
                        con.Connection.From <Transaction>()
                        .Select(x => new {
                        Sum = Sql.Sum(x.Amount)
                    }));

                    runningTotal += amount;

                    var transaction = new Transaction
                    {
                        AccountId      = accountId,
                        Date           = DateTimeOffset.UtcNow,
                        Amount         = amount,
                        CurrentBalance = runningTotal,
                        Title          = title,
                        MetaData       = metaData,
                        PayPalOrderId  = payPalOrderId
                    };

                    await con.Connection.SaveAsync(transaction);

                    await con.Connection.UpdateOnlyAsync(() => new Account { CurrentBalance = runningTotal }, x => x.Id == accountId);

                    trans.Commit();

                    return(transaction);
                }
        }
Esempio n. 10
0
 public async Task <User> FindByIdAsync(string userId, CancellationToken cancellationToken)
 {
     using (var connection = new ConScope(_dataService))
     {
         return(await connection.Connection.SingleByIdAsync <User>(userId, cancellationToken));
     }
 }
Esempio n. 11
0
 public async Task ReQueueProcessingJobs()
 {
     using (var connection = new ConScope(_dataService))
     {
         using (var transaction = await connection.BeginTransaction())
         {
             connection.Connection.UpdateOnly(() => new JobV1 {
                 Status = JobStatus.Queued
             },
                                              x => x.Status == JobStatus.Processing);
             transaction.Commit();
         }
     }
 }
Esempio n. 12
0
        public async Task <List <JobTask> > GetAllJobs()
        {
            using (var connection = new ConScope(_dataService))
            {
                var jobs = await connection.Connection.SelectAsync(connection.Connection.From <JobV1>()
                                                                   .OrderBy(x => x.QueuedOn));

                return(jobs.Select(x => new JobTask
                {
                    JobId = x.Id,
                    Type = Type.GetType(x.JobType),
                    Data = JsonConvert.DeserializeObject(x.JobData, Type.GetType(x.JobDataType), (JsonSerializerSettings)null)
                }).ToList());
            }
        }
        public async Task <T> GetSetting <T>()
        {
            var name = GetSettingNameAttribute(typeof(T));

            using (var connection = new ConScope(_dataService))
            {
                var setting = await connection.Connection.SingleAsync(connection.Connection.From <SettingV1>().Where(x => x.Name == name));

                if (setting == null || string.IsNullOrEmpty(setting.Settings))
                {
                    return((T)Activator.CreateInstance(typeof(T)));
                }
                return(_settingsSerializer.Deserialize <T>(setting.Settings));
            }
        }
Esempio n. 14
0
        public int?GetCurrentVersion()
        {
            using (var conScope = new ConScope(_dataService))
            {
                var db = conScope.Connection;

                db.CreateTableIfNotExists <Migration>();
                var migrations = db.Select <Migration>().ToList();
                if (migrations.Count == 0)
                {
                    return(null);
                }
                return(migrations.OrderByDescending(x => x.Version).First().Version);
            }
        }
Esempio n. 15
0
        public async Task <Account> GetAccount(AccountIdentification id)
        {
            using (var con = new ConScope(_dataService))
            {
                if (id.Id.HasValue)
                {
                    return(await con.Connection.SingleAsync <Account>(id.Id));
                }

                if (id.GlobalUserId.HasValue)
                {
                    return(await con.Connection.SingleAsync <Account>(x => x.GlobalUserId == id.GlobalUserId));
                }

                throw new Exception("Invalid id");
            }
        }
Esempio n. 16
0
        public async Task CapturePendingOrder(string orderId, string payerId)
        {
            Order order;

            {
                var client  = _payPalClientProvider.BuildHttpClient();
                var request = new OrdersCaptureRequest(orderId);
                request.RequestBody(new OrderActionRequest());
                var response = await client.Execute(request);

                if (response.StatusCode != HttpStatusCode.Created)
                {
                    _logger.LogError("Invalid status code from PayPal order capture: status: {Status} response: {Response}", response.StatusCode, SerializePayPalType(response.Result <object>()));
                    throw new Exception("Invalid PayPal response");
                }

                order = response.Result <Order>();

                if (order.Status != "COMPLETED")
                {
                    _logger.LogError("The order from PayPal wasn't marked as COMPELTED: {Response}", SerializePayPalType(response.Result <object>()));
                    throw new Exception("The order from PayPal wasn't marked as COMPELTED");
                }
            }

            using (var con = new ConScope(_dataService))
                using (var trans = await con.BeginTransaction())
                {
                    var pendingOrder = con.Connection.Single <PayPalOrder>(x => x.PayPalOrderId == orderId);

                    if (pendingOrder.OrderStatus == PayPalOrderStatus.Completed)
                    {
                        throw new Exception($"Attempted to update order {orderId} as completed, but it is already marked as completed.");
                    }

                    pendingOrder.OrderStatus     = PayPalOrderStatus.Completed;
                    pendingOrder.PayPalPayerId   = payerId;
                    pendingOrder.PayPalOrderJson = SerializePayPalType(order);

                    await con.Connection.SaveAsync(pendingOrder);

                    await _transactionsService.AddTransaction(pendingOrder.AccountId, pendingOrder.Amount, "PayPal reload", pendingOrder.PayPalOrderJson, pendingOrder.Id);

                    trans.Commit();
                }
        }
Esempio n. 17
0
        public async Task <SeekedList <Transaction> > GetTransactions(Guid?accountId = null, int?skip = null, int?take = null)
        {
            using (var con = new ConScope(_dataService))
            {
                var query = con.Connection.From <Transaction>();

                if (accountId.HasValue)
                {
                    query.Where(x => x.AccountId == accountId);
                }

                long?count = null;
                if (!skip.HasValue && !take.HasValue)
                {
                    // We are returning all the items, not need to do additional DB query.
                }
                else
                {
                    count = await con.Connection.CountAsync(query);
                }

                query.OrderByDescending(x => x.Date);

                if (skip.HasValue)
                {
                    query.Skip(skip.Value);
                }

                if (take.HasValue)
                {
                    query.Take(take.Value);
                }

                var results = await con.Connection.SelectAsync(query);

                if (!count.HasValue)
                {
                    count = results.Count;
                }

                return(new SeekedList <Transaction>(results, skip, take, count.Value));
            }
        }
Esempio n. 18
0
        public async Task CancelPendingOrder(string orderId)
        {
            using (var con = new ConScope(_dataService))
                using (var trans = await con.BeginTransaction())
                {
                    var pendingOrder = await con.Connection.SingleAsync <PayPalOrder>(x => x.PayPalOrderId == orderId);

                    if (pendingOrder == null)
                    {
                        throw new Exception($"No pending paypal order to cancel with id {orderId}");
                    }

                    if (pendingOrder.OrderStatus == PayPalOrderStatus.Completed)
                    {
                        throw new Exception($"The order {orderId} was already completed.");
                    }

                    await con.Connection.DeleteByIdAsync <PayPalOrder>(pendingOrder.Id);

                    trans.Commit();
                }
        }
Esempio n. 19
0
        public async Task <IdentityResult> CreateAsync(User user, CancellationToken cancellationToken)
        {
            using (var connection = new ConScope(_dataService))
            {
                using (var transaction = await connection.BeginTransaction())
                {
                    var existing =
                        await connection.Connection.SingleAsync <User>(x => x.EmailNormalized == user.EmailNormalized,
                                                                       cancellationToken);

                    if (existing != null)
                    {
                        return(IdentityResult.Failed(new IdentityError
                        {
                            Description = "Email already in use."
                        }));
                    }

                    existing = await connection.Connection.SingleAsync <User>(
                        x => x.UserNameNormalized == user.UserNameNormalized, cancellationToken);

                    if (existing != null)
                    {
                        return(IdentityResult.Failed(new IdentityError
                        {
                            Description = "User name already in use."
                        }));
                    }

                    user.Id = Guid.NewGuid().ToString();
                    await connection.Connection.SaveAsync(user, token : cancellationToken);

                    transaction.Commit();

                    return(IdentityResult.Success);
                }
            }
        }
Esempio n. 20
0
        public async Task RemoveProblematicJobs()
        {
            using (var connection = new ConScope(_dataService))
            {
                using (var transaction = await connection.BeginTransaction())
                {
                    var jobs = await connection.Connection.SelectAsync(connection.Connection.From <JobV1>());

                    foreach (var job in jobs)
                    {
                        try
                        {
                            var jobType = Type.GetType(job.JobType);
                            if (jobType == null)
                            {
                                throw new Exception($"Invalid job type: {job.JobType}");
                            }

                            var jobDataType = Type.GetType(job.JobDataType);
                            if (jobDataType == null)
                            {
                                throw new Exception($"Invalid job type: {job.JobDataType}");
                            }

                            JsonConvert.DeserializeObject(job.JobData, Type.GetType(job.JobDataType),
                                                          (JsonSerializerSettings)null);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Detected problematic job, deleting");
                            await connection.Connection.DeleteByIdAsync <JobV1>(job.Id);
                        }
                    }

                    transaction.Commit();
                }
            }
        }
Esempio n. 21
0
        public async Task <PayPalOrder> CreatePendingOrder(Guid accountId, decimal amount)
        {
            // TODO: Make this range configurable.
            if (amount <= 0 || amount > 500)
            {
                throw new Exception("Invalid amount.");
            }

            _logger.LogInformation("Creating pending paypal order for {AccountId} for {Amount}", accountId, amount);

            var account = await _accountsService.GetAccount(AccountIdentification.ById(accountId));

            account.NotNull();

            var    potentialOrderId = Guid.NewGuid();
            string paypalOrderId;

            {
                var client  = _payPalClientProvider.BuildHttpClient();
                var request = new OrdersCreateRequest();
                request.Prefer("return=representation");
                request.RequestBody(new OrderRequest
                {
                    CheckoutPaymentIntent = "CAPTURE",
                    PurchaseUnits         = new List <PurchaseUnitRequest>
                    {
                        new PurchaseUnitRequest
                        {
                            ReferenceId         = potentialOrderId.ToString(),
                            AmountWithBreakdown = new AmountWithBreakdown
                            {
                                Value        = amount.ToString(CultureInfo.InvariantCulture),
                                CurrencyCode = "USD"
                            }
                        }
                    }
                });

                var response = await client.Execute(request);

                if (response.StatusCode != HttpStatusCode.Created)
                {
                    _logger.LogError("Invalid status code from PayPal order create: status: {Status} response: {Response}", response.StatusCode, SerializePayPalType(response.Result <object>()));
                    throw new Exception("Invalid PayPal response");
                }

                paypalOrderId = response.Result <Order>().Id;
            }

            // Great, we created a PayPal order, let's add the record into the database.
            using (var con = new ConScope(_dataService))
            {
                var pendingOrder = new PayPalOrder
                {
                    Id            = potentialOrderId,
                    OrderStatus   = PayPalOrderStatus.Pending,
                    PayPalOrderId = paypalOrderId,
                    AccountId     = account.Id,
                    Amount        = amount
                };

                await con.Connection.InsertAsync(pendingOrder);

                return(pendingOrder);
            }
        }