Exemplo n.º 1
0
        public Dictionary <string, dynamic> RemoveItemFromCart([FromBody] SimpleInt id)
        {
            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                var itemToRemove =
                    context.CartItems.FirstOrDefault(x => x.SessionId == session.Id && x.ItemId == id.Value);
                if (itemToRemove == null)
                {
                    // Item does not exist or has already been removed
                    Response.StatusCode = 404;
                    return(null);
                }

                context.CartItems.Remove(itemToRemove);
                context.SaveChanges();
                return(GetItemsInCart());
            }
        }
        public Dictionary <string, string> ChangeName([FromBody] Dictionary <string, string> request)
        {
            using (var context = new DbContext())
            {
                var obj      = new Dictionary <string, string>();
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context);
                var seller   = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (customer != null)
                {
                    customer.FirstName = request["firstName"];
                    customer.LastName  = request["lastName"];
                }
                else if (seller != null)
                {
                    seller.Name = request["name"];
                }
                else
                {
                    obj["error"] = "Invalid session. Please refresh the page, and try again.";
                    return(obj);
                }

                context.SaveChanges();
                return(obj);
            }
        }
Exemplo n.º 3
0
        public Dictionary <string, dynamic> AddItemToCart([FromBody] SimpleInt id)
        {
            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                // If item does not exist, don't add it.
                if (context.Items.FirstOrDefault(x => x.Id == id.Value && !x.Hidden) == null)
                {
                    Response.StatusCode = 404; // Not found
                    return(null);
                }

                context.CartItems.Add(new CartItem
                {
                    SessionId = session.Id,
                    ItemId    = id.Value
                });

                context.SaveChanges();

                return(GetItemsInCart());
            }
        }
Exemplo n.º 4
0
        public void RemoveItem([FromBody] SimpleInt simpleInt)
        {
            using (var context = new DbContext())
            {
                var item = context.Items.First(x => x.Id == simpleInt.Value);
                // Check if the user is a seller.
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                var admin  = _accountService.ValidateAdminSession(Request.Cookies, context);
                // If user is not a seller or admin, return.
                if (seller == null && admin == false)
                {
                    Response.StatusCode = 403;
                    return;
                }

                // Do not let a seller remove the item if they are not the owner of the item.
                if (!admin && item.SellerId != seller.Id)
                {
                    Response.StatusCode = 403;
                    return;
                }

                item.Hidden = true;
                context.SaveChanges();
            }
        }
Exemplo n.º 5
0
        public Item CreateItem([FromBody] NewItemForm form)
        {
            form.Price = form.Price.Replace("$", "");
            using (var context = new DbContext())
            {
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (seller == null)
                {
                    Response.StatusCode = 403;
                    return(null);
                }

                var item = context.Items.Add(new Item
                {
                    Description = form.Description,
                    Name        = form.Name,
                    Price       = decimal.Parse(form.Price),
                    SellerId    = seller.Id,
                    ImageURL    = form.ImageURL,
                    Hidden      = false,
                    Purchases   = 0
                });
                context.SaveChanges();

                return(item.Entity);
            }
        }
 public void RemoveAccount()
 {
     using (var context = new DbContext())
     {
         var account = _accountService.ValidateAccountSession(Request.Cookies, context);
         context.Accounts.Remove(account);
         context.SaveChanges();
     }
 }
Exemplo n.º 7
0
 public Item GetItem([FromQuery] int id)
 {
     using (var context = new DbContext())
     {
         var item = context.Items
                    .Include(x => x.Seller)
                    .First(x => x.Id == id && !x.Hidden);
         if (item.Views == null)
         {
             item.Views = 0;
         }
         item.Views++;
         context.SaveChanges();
         return(item);
     }
 }
Exemplo n.º 8
0
        public Dictionary <string, dynamic> GetItemsInCart()
        {
            var obj = new Dictionary <string, dynamic>();

            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                var cartItems = context.CartItems
                                .Where(x => x.SessionId == session.Id)
                                .Include(x => x.Item);

                // If there are any hidden mostViewed in the cart, remove them before returning the mostViewed.
                var itemsToRemove = cartItems.Where(x => x.Item.Hidden);
                if (!itemsToRemove.IsNullOrEmpty())
                {
                    context.CartItems.RemoveRange(itemsToRemove);
                    context.SaveChanges();
                    if (itemsToRemove.Count() == 1)
                    {
                        obj["warning"] = "An item in your cart has been removed, as it is no longer available.";
                    }
                    else
                    {
                        obj["warning"] =
                            "Some mostViewed in your cart have been removed, as they are no longer available.";
                    }
                }

                var items = cartItems
                            .Select(cartItem => cartItem.Item)
                            .Where(x => !x.Hidden)
                            .Include(x => x.Seller)
                            .ToList();

                obj["mostViewed"] = items;
                return(obj);
            }
        }
        public Dictionary <string, string> ChangeEmail([FromBody] Dictionary <string, string> request)
        {
            using (var context = new DbContext())
            {
                var obj = new Dictionary <string, string>();
                // Validate the user's old email and password
                var account = _accountService.ValidateCredentials(request["oldEmail"], request["password"], context);
                var session = _accountService.ValidateSession(Request.Cookies, context);

                if (account == null || account.Id != session.AccountId)
                {
                    obj["error"]        = "Invalid credentials.";
                    Response.StatusCode = 403;
                    return(obj);
                }

                var newEmail = request["newEmail"];
                if (!_accountService.IsEmailValid(newEmail))
                {
                    obj["error"]        = "Invalid email.";
                    Response.StatusCode = 403;
                    return(obj);
                }

                // Set the new email
                account.Email = newEmail;

                // Set the new password hash
                var newHash = _accountService.HashPassword(request["password"], account);
                account.PasswordHash = newHash;

                // Reset session token (log user out everywhere)
                context.Sessions.Find(account.SessionId).Token = _accountService.CreateSessionToken();
                context.SaveChanges();

                // Log the user out
                ClearCookies();
                return(obj);
            }
        }
Exemplo n.º 10
0
        public async Task <Dictionary <string, dynamic> > CapturePaypalOrder([FromQuery] string orderId)
        {
            using (var context = new DbContext())
            {
                // Refuse capture if customer is not properly authenticated
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context, true);
                if (customer == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                // Refuse capture if

                // Capture funds through Paypal
                var order = await _paypalService.CaptureOrder(orderId);

                // Create transaction object
                var transaction = context.CustomerTransactions.Add(new CustomerTransaction
                {
                    CustomerId          = customer.Id,
                    CustomerName        = customer.FirstName + " " + customer.LastName,
                    Date                = DateTime.UtcNow.AddHours(10), // Force Sydney timezone
                    PaypalTransactionId = order.Id,
                    Total               = decimal.Parse(order.PurchaseUnits[0].AmountWithBreakdown.Value)
                });
                // Create transaction item objects
                var items        = order.PurchaseUnits[0].Items;
                var lootBoxItems = new List <int>();

                var boughtTogetherRecordsAlreadyHandledA = new HashSet <int>();
                foreach (var item in items)
                {
                    var itemId = int.Parse(item.Sku);

                    var itemEntity = context.Items
                                     .Include(x => x.Seller)
                                     .First(x => x.Id == itemId);

                    context.TransactionItems.Add(new TransactionItem
                    {
                        CustomerTransaction = transaction.Entity,
                        ItemSaleId          = itemId,
                        ItemSalePrice       = decimal.Parse(item.UnitAmount.Value),
                        ItemSaleName        = item.Name,
                        SellerSaleId        = itemEntity.SellerId,
                        SellerSaleName      = itemEntity.Seller.Name
                    });

                    // Handle bought together records and purchase count
                    if (!boughtTogetherRecordsAlreadyHandledA.Contains(itemId))
                    {
                        boughtTogetherRecordsAlreadyHandledA.Add(itemId);
                        itemEntity.Purchases++;

                        var boughtTogetherRecordsAlreadyHandledB = new HashSet <int>();
                        foreach (var itemB in items)
                        {
                            var itemBId = int.Parse(itemB.Sku);
                            // Skip if item already handled or same (means duplicate mostViewed don't impact the count)
                            if (boughtTogetherRecordsAlreadyHandledB.Contains(itemBId) || itemBId == itemId)
                            {
                                continue;
                            }

                            boughtTogetherRecordsAlreadyHandledB.Add(itemBId);

                            // Get existing bought together record
                            var boughtTogetherRecord = context.ItemsBoughtTogether
                                                       .FirstOrDefault(x => x.ItemAId == itemId && x.ItemBId == itemBId);
                            // If record doesn't exist, create it.
                            if (boughtTogetherRecord == null)
                            {
                                boughtTogetherRecord = context.ItemsBoughtTogether.Add(new ItemsBoughtTogether
                                {
                                    ItemAId = itemId,
                                    ItemBId = itemBId,
                                    Count   = 0
                                }).Entity;
                            }

                            // Increment bought together count
                            boughtTogetherRecord.Count++;
                        }
                    }


                    // If item is a loot box, also add in a random item below its price.
                    if (itemEntity.Id == 86)
                    {
                        var eligibleItems = context.Items
                                            .Include(x => x.Seller)
                                            .Where(x => !x.Hidden && x.Price < itemEntity.Price);
                        var             skip       = (int)(new Random().NextDouble() * eligibleItems.Count());
                        var             chosenItem = eligibleItems.Skip(skip).Take(1).FirstOrDefault();
                        TransactionItem transactionItem;
                        if (chosenItem == null)
                        {
                            transactionItem = context.TransactionItems.Add(new TransactionItem
                            {
                                CustomerTransaction = transaction.Entity,
                                ItemSaleId          = -1,
                                ItemSalePrice       = 0,
                                ItemSaleName        = "Empty Cardboard Box",
                                SellerSaleId        = itemEntity.SellerId,
                                SellerSaleName      = itemEntity.Seller.Name
                            }).Entity;
                        }
                        else
                        {
                            transactionItem = context.TransactionItems.Add(new TransactionItem
                            {
                                CustomerTransaction = transaction.Entity,
                                ItemSaleId          = chosenItem.Id,
                                ItemSalePrice       = 0,
                                ItemSaleName        = chosenItem.Name + " (from Loot Box)",
                                SellerSaleId        = chosenItem.SellerId,
                                SellerSaleName      = chosenItem.Seller.Name
                            }).Entity;
                        }
                        Console.WriteLine("Loot box item unlocked: " + transactionItem.ItemSaleName);
                        lootBoxItems.Add(transactionItem.ItemSaleId);
                    }
                }

                // Clear user's shopping cart
                var itemsToRemove = context.CartItems.Where(x => x.SessionId == customer.Account.SessionId);
                context.CartItems.RemoveRange(itemsToRemove);
                context.SaveChanges();

                if (lootBoxItems.IsNullOrEmpty())
                {
                    lootBoxItems = null;
                }
                return(new Dictionary <string, dynamic>
                {
                    ["order"] = order,
                    ["lootBoxItems"] = lootBoxItems
                });
            }
        }
        public bool Login([FromBody] LoginForm form)
        {
            int    accountId, sessionId;
            string token;

            // Validate
            form.Email = form.Email.Trim().ToLower();

            if (form.Email.Length < 4)
            {
                return(false);
            }

            if (form.Password.Length < 8)
            {
                return(false);
            }

            using (var context = new DbContext())
            {
                var account = _accountService.ValidateCredentials(form.Email, form.Password, context);

                if (account == null)
                {
                    return(false);
                }

                accountId = account.Id;

                var session = context.Sessions.FirstOrDefault(x => x.Id == account.SessionId);
                // Generate new session and token if empty for whatever reason
                if (session == null || string.IsNullOrEmpty(session.Token))
                {
                    var newSession = context.Sessions.Add(new Session
                    {
                        Token = _accountService.CreateSessionToken()
                    });

                    // Link session to account, and account to session
                    newSession.Entity.Account = account;
                    account.Session           = newSession.Entity;

                    context.SaveChanges();
                }

                token     = account.Session.Token;
                sessionId = (int)account.SessionId;
            }

            // Clear login cookies
            ClearCookies();

            // Provide with token and id cookies
            Response.Cookies.Append("token", token, new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("accountId", accountId.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("sessionId", sessionId.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });

            // Account has successfully been logged into. Page should now refresh.
            return(true);
        }
        public dynamic CreateSession()
        {
            // Don't create a new session if token and session cookies already exist.
            // (if only one of these exists, something has gone wrong and a new session will be created anyway)
            // Instead, return the data logged in user. (null if not logged in)
            if (Request.Cookies.ContainsKey("token") && Request.Cookies.ContainsKey("sessionId"))
            {
                var sessionId = int.Parse(Request.Cookies["sessionId"]);
                var token     = Request.Cookies["token"];

                if (!Request.Cookies.ContainsKey("accountId"))
                {
                    return(false);
                }

                var accountId = int.Parse(Request.Cookies["accountId"]);

                // Return the data logged in user
                var user = _accountService.ValidateUser(sessionId, accountId, token, new DbContext());
                // If user is invalid, clear cookies.
                if (user == null)
                {
                    ClearCookies();
                }
                else
                {
                    return(user);
                }
            }

            // If someone with an account id does not already have a valid session, log them out. (this shouldn't happen)
            if (Request.Cookies.ContainsKey("accountId"))
            {
                // Clear login cookies
                ClearCookies();
                return(false);
            }

            Session session;

            using (var context = new DbContext())
            {
                var newSession = context.Sessions.Add(new Session
                {
                    Token = _accountService.CreateSessionToken()
                });
                context.SaveChanges();
                session = newSession.Entity;
            }

            // Provide with token and id cookies
            Response.Cookies.Append("token", session.Token, new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("sessionId", session.Id.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });

            return(true);
        }
        public Dictionary <string, dynamic> CreateCustomerAccount([FromBody] CustomerAccountForm form)
        {
            // Create response object to send back to client
            var obj = new Dictionary <string, dynamic>
            {
                ["error"] = null, ["success"] = false
            };

            // Clean up fields
            form.Email = form.Email.Trim().ToLower();

            // Verify that email and password are valid
            if (!_accountService.IsEmailValid(form.Email))
            {
                obj["error"] = "Please provide a valid email.";
                return(obj);
            }

            if (!_accountService.IsPasswordValid(form.Password, out var reason))
            {
                obj["error"] = reason;
                return(obj);
            }

            using (var context = new DbContext())
            {
                // Verify that the session is actually valid, and that the session is not already linked to an account.
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null || session.AccountId != null)
                {
                    ClearCookies();
                    Response.StatusCode = 403;
                    obj["error"]        =
                        "Invalid session. Please try again, refresh the page, or delete cookies for the site.";
                    return(obj);
                }

                // Verify that the provided email is not already in use.
                if (context.Accounts.Any(x => x.Email == form.Email))
                {
                    obj["error"] = "The email address provided is already in use.";
                    return(obj);
                }

                // Try actually creating the account.
                try
                {
                    // Create the Account object
                    var newAccount = context.Accounts.Add(new Account
                    {
                        Type         = 'c',
                        Email        = form.Email,
                        PasswordHash = null,             // Fill in password later when id is available to use as salt
                        SessionId    = session.Id        // Tie the session to the newly created account.
                    });
                    session.Account = newAccount.Entity; // Tie the new account to the existing session.

                    // Have to send this to the database before creating the customer entity,
                    // as we don't know what the id is yet until the database tells us.
                    context.SaveChanges();

                    // Create the Customer object
                    context.Customers.Add(new Customer
                    {
                        Id        = newAccount.Entity.Id,
                        FirstName = form.FirstName,
                        LastName  = form.LastName
                    });

                    // Set the password hash
                    newAccount.Entity.PasswordHash = _accountService.HashPassword(form.Password, newAccount.Entity);

                    context.SaveChanges();
                }
                catch
                {
                    obj["error"] = "An unknown database error occurred.";
                    return(obj);
                }

                // Log in with credentials provided
                var loginSuccessful = Login(new LoginForm {
                    Email = form.Email, Password = form.Password
                });
                if (loginSuccessful)
                {
                    obj["success"] = true;
                    return(obj);
                }

                obj["error"] = "An account was created but could not be logged into. Please try logging in manually.";
                return(obj);
            }
        }
        public Dictionary <string, dynamic> CreateAdminAccount([FromBody] AdminAccountForm form)
        {
            // Create response object to send back to client
            var obj = new Dictionary <string, dynamic>
            {
                ["error"] = null, ["success"] = false
            };

            // Clean up fields
            form.Email = form.Email.Trim().ToLower();

            // Verify that email and password are valid
            if (!_accountService.IsEmailValid(form.Email))
            {
                obj["error"] = "Please provide a valid email.";
                return(obj);
            }

            if (!_accountService.IsPasswordValid(form.Password, out var reason))
            {
                obj["error"] = reason;
                return(obj);
            }

            using (var context = new DbContext())
            {
                // Verify that the account is being created by an admin
                if (!_accountService.ValidateAdminSession(Request.Cookies, context))
                {
                    obj["error"] = "Only admins can create admin accounts.";
                    return(obj);
                }

                // Verify that the provided email is not already in use.
                if (context.Accounts.Any(x => x.Email == form.Email))
                {
                    obj["error"] = "The email address provided is already in use.";
                    return(obj);
                }

                // Try actually creating the account.
                try
                {
                    // Create the Account object
                    var newAccount = context.Accounts.Add(new Account
                    {
                        Type         = 'a',
                        Email        = form.Email,
                        PasswordHash = null // Fill in password later when id is available to use as salt
                    });

                    // Have to send this to  the database before creating the customer entity,
                    // as we don't know what the id is yet until the database tells us.
                    context.SaveChanges();


                    // Set the password hash
                    newAccount.Entity.PasswordHash = _accountService.HashPassword(form.Password, newAccount.Entity);

                    context.SaveChanges();
                }
                catch
                {
                    obj["error"] = "An unknown database error occurred.";
                    return(obj);
                }

                return(obj);
            }
        }