public IEnumerable <Item> AllItems() { using (var context = new DbContext()) { var seller = _accountService.ValidateSellerSession(Request.Cookies, context); if (seller != null) { var items = context.Items .Where(x => !x.Hidden && x.SellerId == seller.Id) .Include(item => item.Seller) .OrderBy(x => x.Id) .ToList(); return(items); } if (_accountService.ValidateAdminSession(Request.Cookies, context)) { var items = context.Items .Where(x => !x.Hidden) .Include(item => item.Seller) .OrderBy(x => x.Id) .ToList(); return(items); } // If the user is not a seller or admin, there is nothing to give them. Response.StatusCode = 403; return(null); } }
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); } }
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 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, 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()); } }
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(); } }
public async Task <Order> CreatePaypalOrder() { var orderItems = new List <Item>(); decimal totalPrice = 0; using (var context = new DbContext()) { var customer = _accountService.ValidateCustomerSession(Request.Cookies, context, true); var itemsInCart = context.CartItems .Where(x => x.SessionId == customer.Account.SessionId) .Include(x => x.Item) .Where(x => !x.Item.Hidden) .Select(cartItem => cartItem.Item).Include(x => x.Seller) .ToList(); foreach (var item in itemsInCart) { totalPrice += item.Price; // Limit description and title size so that Paypal doesn't refuse it const int maxStrSize = 100; var itemDescription = "Sold by " + item.Seller.Name + ". " + item.Description; if (itemDescription.Length > maxStrSize) { itemDescription = itemDescription.Substring(0, maxStrSize); } var itemName = item.Name; if (itemName.Length > maxStrSize) { itemName = itemName.Substring(0, maxStrSize); } orderItems.Add(new Item { Name = itemName, Sku = item.Id.ToString(), Quantity = 1.ToString(), Category = "PHYSICAL_GOODS", Description = itemDescription, Tax = new Money { CurrencyCode = "AUD", Value = "0.00" }, UnitAmount = new Money { CurrencyCode = "AUD", Value = item.Price.ToString(CultureInfo.InvariantCulture) } }); } } // Create mostViewed for order var order = await _paypalService.CreateOrder(orderItems, totalPrice); return(order); }
public void RemoveAccount() { using (var context = new DbContext()) { var account = _accountService.ValidateAccountSession(Request.Cookies, context); context.Accounts.Remove(account); context.SaveChanges(); } }
public Session ValidateSession(string sessionId, string token, DbContext context) { try { return(ValidateSession(int.Parse(sessionId), token, context)); } catch { return(null); } }
public IEnumerable <Item> GetItemsBoughtTogether([FromQuery] int id) { using (var context = new DbContext()) { var items = context.ItemsBoughtTogether .Where(x => x.ItemAId == id && x.ItemA.Hidden == false && x.ItemB.Hidden == false) .OrderByDescending(x => x.Count) .Take(8) .Select(x => x.ItemB) .ToList(); return(items); } }
public IEnumerable <Item> TopSellingItems(int count) { using (var context = new DbContext()) { var items = context.Items .Where(x => !x.Hidden) .Include(item => item.Seller) .OrderByDescending(item => item.Purchases) .Take(count) .ToList(); return(items); } }
public Session ValidateSession(dynamic requestCookies, DbContext context) { try { var sessionId = int.Parse(requestCookies["sessionId"]); var token = requestCookies["token"].ToString(); return(ValidateSession(sessionId, token, context)); } catch { return(null); } }
public bool ValidateAdminSession(dynamic requestCookies, DbContext context) { try { var sessionId = int.Parse(requestCookies["sessionId"]); var accountId = int.Parse(requestCookies["accountId"]); var token = requestCookies["token"].ToString(); return(ValidateAdminSession(sessionId, accountId, token, context)); } catch { return(false); } }
public Seller ValidateSellerSession(dynamic requestCookies, DbContext context, bool includeAccountObject = false) { try { var sessionId = int.Parse(requestCookies["sessionId"]); var accountId = int.Parse(requestCookies["accountId"]); var token = requestCookies["token"].ToString(); return(ValidateSellerSession(sessionId, accountId, token, context, includeAccountObject)); } catch { return(null); } }
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); } }
public IEnumerable <Seller> GetAllSellers() { using (var context = new DbContext()) { if (!_accountService.ValidateAdminSession(Request.Cookies, context)) { Response.StatusCode = 403; return(null); } var sellers = context.Sellers .Include(seller => seller.Account) .ToList(); return(sellers); } }
public Account ValidateCredentials(string email, string password, DbContext context) { var accountToValidate = context.Accounts.FirstOrDefault(account => account.Email == email); if (accountToValidate == null) { return(null); } if (ValidatePassword(password, accountToValidate)) { return(accountToValidate); } return(null); }
public SearchItemResult SearchItems([FromQuery] string query) { // TODO: Pages // TODO: Separate the search phrase when adding in filters if (query == null) { query = ""; } var searchPhrase = query.ToLower().Trim(); // Allow for searching by id if input string is an integer var searchId = -1; if (int.TryParse(searchPhrase.Replace("id:", ""), out var result)) { searchId = result; } using (var context = new DbContext()) { var q = context.Items.Where(x => !x.Hidden); // Include seller data from start so it can be searched q = q.Include(item => item.Seller); var words = _searchService.GetWordsFromPhrase(searchPhrase); // This code just adds another "WHERE" query for each word in the search phrase. // Rider really wanted to turn this into a LINQ expression, so I just let it do that lol q = words.Select((t, i) => i) .Aggregate(q, (current, i) => current.Where(x => x.Name.Contains(words[i]) || x.Description.Contains(words[i]) || x.Seller.Name.Contains(words[i]) || x.Id == searchId ) // Prioritise name and id matches .OrderBy(x => (x.Name.Contains(words[i]) ? 0 : 5) + (x.Name.StartsWith(words[i]) ? 0 : 6) + (x.Id == searchId ? 0 : 8)) ); return(new SearchItemResult { Items = q.ToList() }); } }
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 Session ValidateSession(int sessionId, string token, DbContext context) { var session = context.Sessions.Find(sessionId); // If the session doesn't exist, return null. if (session == null) { return(null); } // If the session exists, but the provided token is wrong, return null. var isValid = token == session.Token; if (!isValid) { return(null); } // The session is valid, and the session object will be returned. return(session); }
public IEnumerable <TransactionItem> AllTransactions() { using (var context = new DbContext()) { // If user is a customer, get all their transactions. var customer = _accountService.ValidateCustomerSession(Request.Cookies, context); if (customer != null) { var items = context.TransactionItems .Include(x => x.CustomerTransaction) .Where(x => x.CustomerTransaction.CustomerId == customer.Id) .OrderByDescending(x => x.CustomerTransaction.Date) .ToList(); return(items); } // If user is a seller, get all their transactions. var seller = _accountService.ValidateSellerSession(Request.Cookies, context); if (seller != null) { var items = context.TransactionItems .Where(x => x.SellerSaleId == seller.Id) .Include(x => x.CustomerTransaction) .OrderByDescending(x => x.CustomerTransaction.Date) .ToList(); return(items); } // If user is an admin, get everything. if (_accountService.ValidateAdminSession(Request.Cookies, context)) { var items = context.TransactionItems .Include(x => x.CustomerTransaction) .OrderByDescending(x => x.CustomerTransaction.Date) .ToList(); return(items); } // If the user is not a seller, customer, or admin, there is nothing to give them. Response.StatusCode = 403; return(null); } }
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); } }
private static bool ValidateAdminSession(int sessionId, int accountId, string token, DbContext context) { var session = ValidateAccountSession(sessionId, accountId, token, context); // If account not valid or not authorised, return null. if (session == null) { return(false); } var account = session.Account; // If account is not an admin, return false. return(account.Type == 'a'); }
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); }
private static Session ValidateAccountSession(int sessionId, int accountId, string token, DbContext context) { var session = context.Sessions.Include(x => x.Account).FirstOrDefault(x => x.Id == sessionId); // If session is nonexistent, or not linked with an account, return null. if (session?.AccountId == null) { return(null); } // If token and account id provided do not match with the corresponding entries in the database, return null. var isValid = token == session.Token && session.AccountId == accountId; if (!isValid) { return(null); } return(session); }
// If authorised, this will return an object with information about the user. // If more information is needed, authenticate and get the user directly. public Dictionary <string, dynamic> ValidateUser(int sessionId, int accountId, string token, DbContext context) { var session = ValidateAccountSession(sessionId, accountId, token, context); if (session == null) { return(null); } // Return either a customer or seller object, depending on what type the user is. // Account objects need to be stripped out for two reasons: security, and to avoid loops in the JSON. if (session.Account.Type == 'c') { var obj = new Dictionary <string, dynamic>(); var customer = context.Customers.Find(accountId); obj["type"] = 'c'; obj["id"] = customer.Id; obj["firstName"] = customer.FirstName; obj["lastName"] = customer.LastName; return(obj); } if (session.Account.Type == 's') { var obj = new Dictionary <string, dynamic>(); var seller = context.Sellers.Find(accountId); obj["type"] = 's'; obj["id"] = seller.Id; obj["name"] = seller.Name; return(obj); } if (session.Account.Type == 'a') { var obj = new Dictionary <string, dynamic>(); var account = context.Accounts.Find(accountId); obj["type"] = 'a'; obj["id"] = account.Id; return(obj); } return(null); }
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 }); } }
private static Seller ValidateSellerSession(int sessionId, int accountId, string token, DbContext context, bool includeAccountObject = false) { var session = ValidateAccountSession(sessionId, accountId, token, context); // If account not valid or not authorised, return null. if (session == null) { return(null); } var account = session.Account; // If account is not a seller, return null. if (account.Type != 's') { return(null); } Seller seller; if (includeAccountObject) { seller = context.Sellers.Include(x => x.Account) .FirstOrDefault(x => x.Id == account.Id); } else { seller = context.Sellers.Find(account.Id); } return(seller); }
public Dictionary <string, string> StartChat([FromQuery] int?id) { var obj = new Dictionary <string, string> { ["error"] = "", ["otherId"] = "" }; using (var context = new DbContext()) { // Check if user is a customer or seller var customer = _accountService.ValidateCustomerSession(Request.Cookies, context, true); var seller = _accountService.ValidateSellerSession(Request.Cookies, context, true); string userId, userName, userEmail, userRole; if (customer != null) { userId = customer.Id.ToString(); userName = customer.FirstName + " " + customer.LastName; userEmail = customer.Account.Email; userRole = "customer"; } else if (seller != null) { userId = seller.Id.ToString(); userName = seller.Name; userEmail = seller.Account.Email; userRole = "seller"; } else { // User is not authenticated Response.StatusCode = 403; obj["error"] = "Only registered customers and sellers can send and receive messages."; return(obj); } obj["userId"] = userId; obj["userName"] = userName; obj["userEmail"] = userEmail; obj["userRole"] = userRole; // If an id parameter is specified, try to start a new chat // (customers are only be able to talk to sellers, and vice versa) if (id != null) { if (customer != null) { var other = context.Sellers.Include(x => x.Account) .FirstOrDefault(x => x.Id == id); if (other != null) { obj["otherId"] = other.Id.ToString(); obj["otherName"] = other.Name; } } else { var other = context.Customers.Include(x => x.Account) .FirstOrDefault(x => x.Id == id); if (other != null) { obj["otherId"] = other.Id.ToString(); obj["otherName"] = other.FirstName; } } } // Generate signature var keyByte = new ASCIIEncoding().GetBytes(_chatSecret); var userIdBytes = new ASCIIEncoding().GetBytes(userId); var hash = new HMACSHA256(keyByte).ComputeHash(userIdBytes); // Convert to HEX (Base 16) obj["signature"] = string.Concat(Array.ConvertAll(hash, x => x.ToString("x2"))); } return(obj); }
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); }