public bool DenyInviteToKitchen(long kitchenId, PantryPlannerUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (Context.KitchenExists(kitchenId) == false)
            {
                throw new KitchenNotFoundException(kitchenId);
            }

            if (Context.UserExists(user.Id) == false)
            {
                throw new UserNotFoundException(user.UserName);
            }

            KitchenUser inviteToDeny = user.KitchenUser.Where(k => k.KitchenId == kitchenId && k.UserId == user.Id && k.HasAcceptedInvite.Value == false).FirstOrDefault();

            if (inviteToDeny == null)
            {
                throw new InviteNotFoundException("No invite found for kitchen.");
            }

            Context.KitchenUser.Remove(inviteToDeny);
            Context.SaveChangesAsync();

            return(true);
        }
        public async Task DenyKitchenInvite_ValidKitchen_ReturnsOKAndInviteDenied()
        {
            List <long> myKitchenIds = _userManager.TestUser.KitchenUser.Select(u => u.KitchenId).ToList();
            Kitchen     notMyKitchen = _context.KitchenUser.Where(u => myKitchenIds.Contains(u.KitchenId) == false).FirstOrDefault()?.Kitchen;

            PantryPlannerUser userSendingInvite = notMyKitchen.KitchenUser
                                                  .Where(k => k.UserId != _userManager.TestUser.Id)
                                                  .FirstOrDefault()?
                                                  .User;

            if (userSendingInvite == null || notMyKitchen == null)
            {
                throw new Exception("user or kitchen is not setup for testing");
            }

            // send invite to test user
            KitchenUserService service = new KitchenUserService(_context);

            service.InviteUserToKitchenByUsername(_userManager.TestUser.UserName, notMyKitchen.KitchenId, userSendingInvite);

            // have test user accept invite
            ActionResult inviteResult = await _controller.DenyKitchenInvite(notMyKitchen.KitchenId);

            Assert.IsType <OkResult>(inviteResult);
            Assert.False(_context.KitchenUser.Any(k => k.KitchenId == notMyKitchen.KitchenId && k.UserId == _userManager.TestUser.Id));
        }
        /// <summary>
        /// Creates users and adds them to already existing kitchens.
        /// </summary>
        /// <param name="context"> create users using this DbContext and adds them Kitchens in it </param>
        /// <param name="numOfUsersToAddPerKitchen"> amount of users to add per Kitchen </param>
        internal static void AddNewRandomUsersToKitchens(PantryPlannerContext context, int numOfUsersToAddPerKitchen)
        {
            if (context.Kitchen.Count() == 0)
            {
                throw new Exception("Cannot add users because Kitchen is not populated");
            }


            Random randGenerator = new Random();

            foreach (Kitchen kitchen in context.Kitchen)
            {
                bool hasAccepted = true;  // this will guarantee that atleast one new user has accepted the Invite (i.e. HasAcceptedInvite = true)

                for (int i = 0; i < numOfUsersToAddPerKitchen; i++)
                {
                    PantryPlannerUser newUser = AddNewRandomUser(context);

                    KitchenUser newKitchenUser = new KitchenUser()
                    {
                        KitchenId         = kitchen.KitchenId,
                        UserId            = newUser.Id,
                        DateAdded         = DateTime.Now,
                        IsOwner           = false,
                        HasAcceptedInvite = hasAccepted
                    };

                    context.KitchenUser.Add(newKitchenUser);
                    context.SaveChanges();

                    hasAccepted = (randGenerator.Next(0, 2) == 0);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the PantryPlannerUser associated with the <paramref name="userClaimsPrincipal"/>.
        /// Determines user based on Cookies or checking the Claims that are set by Jwt for authorization.
        /// </summary>
        /// <exception cref="PermissionsException"> Thrown when user can not be found and is null </exception>
        /// <param name="userManager"> </param>
        /// <param name="userClaimsPrincipal"></param>
        /// <returns> A valid <see cref="PantryPlannerUser"/> </returns>
        public static async Task <PantryPlannerUser> GetUserFromCookieOrJwtAsync(this UserManager <PantryPlannerUser> userManager, ClaimsPrincipal userClaimsPrincipal)
        {
            // first attempt to get the user based on Cookies
            PantryPlannerUser user = await userManager.GetUserAsync(userClaimsPrincipal);

            if (user != null)
            {
                return(user);
            }


            // Second attempt to get the user based on Jwt claims (User Id is stored in Jwt)... reference: https://stackoverflow.com/questions/46112258/how-do-i-get-current-user-in-net-core-web-api-from-jwt-token
            IEnumerable <Claim> nameIdentifiers = userClaimsPrincipal.FindAll(ClaimTypes.NameIdentifier);

            foreach (var claim in nameIdentifiers) // looping over nameidentifier claims because it could be the email or Id in the token
            {
                user = await userManager.FindByIdAsync(claim.Value);

                if (user != null)
                {
                    break;
                }
            }


            if (user == null)
            {
                // no user could be determined from Cookies passed in or from the Jwt token so throw a unauthorized result
                throw new PermissionsException("Could not authenticate user.");
            }

            return(user);
        }
        public KitchenUser OwnerDeleteKitchenUserByKitchenUserId(long kitchenUserId, PantryPlannerUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var kitchenUser = Context.KitchenUser.Find(kitchenUserId);

            if (kitchenUser == null)
            {
                throw new KitchenUserNotFoundException();
            }

            // validate user has rights and owns the kitchen
            if (!Permissions.UserOwnsKitchen(user, kitchenUser.KitchenId))
            {
                throw new PermissionsException($"you must be kitchen owner to remove the user '{kitchenUser.User.UserName}'");
            }


            // validate user is not removing themselves since they own the kitchen
            if (kitchenUser.UserId == user.Id)
            {
                throw new InvalidOperationException("You can not remove yourself from the Kitchen because you own it. Transfer ownership or delete the kitchen instead.");
            }


            Context.KitchenUser.Remove(kitchenUser);
            Context.SaveChanges();

            return(kitchenUser);
        }
Ejemplo n.º 6
0
        public Kitchen GetKitchenById(long id, PantryPlannerUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (Context.KitchenExists(id) == false)
            {
                throw new KitchenNotFoundException(id);
            }

            if (Context.UserExists(user.Id) == false)
            {
                throw new UserNotFoundException(user.UserName);
            }

            Kitchen kitchen = Context.Kitchen.Find(id);

            if (!Permissions.UserHasRightsToKitchen(user, kitchen))
            {
                throw new PermissionsException();
            }

            return(kitchen);
        }
        public KitchenUserServiceUnitTest()
        {
            _testUser = InMemoryDataGenerator.TestUser;
            _context  = InMemoryDataGenerator.CreateAndInitializeInMemoryDatabaseContext(Guid.NewGuid().ToString(), _testUser, insertIngredientData: false);

            _kitchenUserService = new KitchenUserService(_context);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Validate <paramref name="idToken"/> is Google Id Token and then Login the user. An account will be auto-created if the google user does not have an account yet.
        /// Returns a Jwt Token for authorizing later requests.
        /// </summary>
        /// <param name="idToken"> Google Id Token provided by google when signing in with OAuth (e.g. from mobile app) </param>
        /// <returns> Jwt Token for authorizing later requests to API. </returns>
        /// <exception cref="AccountException"> Thrown when <paramref name="idToken"/> is not valid or user can not be created or login </exception>
        public async Task <string> LoginUsingGoogleIdToken(string idToken)
        {
            bool isValid = await IsGoogleTokenValidAsync(idToken).ConfigureAwait(false);

            if (!isValid)
            {
                throw new AccountException("Google Id token is invalid");
            }

            GoogleJsonWebSignature.Payload validPayload = await GoogleJsonWebSignature.ValidateAsync(idToken).ConfigureAwait(false);

            PantryPlannerUser appUser = _userManager.Users.SingleOrDefault(u => u.Email == validPayload.Email);


            if (appUser == null)
            {
                // user doesn't exist so we'll auto create them
                appUser = await AutoCreateAccountFromGoogleAsync(validPayload).ConfigureAwait(false);
            }


            if (appUser != null)
            {
                // sign the user in and return a Jwt Token
                await _signInManager.SignInAsync(appUser, false).ConfigureAwait(false);

                string token = GenerateJwtToken(appUser, _configuration);
                return(token);
            }

            // reached here then the user could not be created/found
            throw new AccountException($"Could not login with google user for email {validPayload.Email}");
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Login to API with username and password. Jwt Token returned on success that can be used to authorize later requests.
        /// </summary>
        /// <param name="model"> DTO with email and password to login with </param>
        /// <returns> Jwt Token for logged in user </returns>
        /// <exception cref="AccountException"> Thrown when failed to login (cant find user, user is locked out, or invalid username/password) </exception>
        internal async Task <string> LoginWithEmailAndPasswordAsync(LoginDto model)
        {
            SignInResult result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);

            if (result.Succeeded)
            {
                PantryPlannerUser appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);

                if (appUser == null)
                {
                    throw new AccountException("Could not look up user.");
                }

                string token = GenerateJwtToken(appUser, _configuration);
                return(token);
            }
            else if (result.IsLockedOut)
            {
                throw new AccountException("The user is locked out");
            }
            else if (result.IsNotAllowed)
            {
                throw new AccountException("The user is not allowed to login");
            }


            throw new AccountException("Failed to login.");
        }
        /// <summary>
        /// Adds an ingredient to the <see cref="Context"/> that was added by the <paramref name="user"/>.
        /// </summary>
        /// <param name="newIngredient"> ingredient to add </param>
        /// <param name="user"> user who is adding ingredient </param>
        public void AddIngredient(Ingredient newIngredient, PantryPlannerUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (newIngredient == null)
            {
                throw new ArgumentNullException(nameof(newIngredient));
            }

            if (Context.UserExists(user.Id) == false)
            {
                throw new UserNotFoundException(user.UserName);
            }

            // validate name passed in
            if (String.IsNullOrWhiteSpace(newIngredient.Name))
            {
                throw new InvalidOperationException("Ingredient Name is required");
            }

            // validate an ingredient with same name in the same category doesn't already exist
            if (Context.IngredientExistsForUser(newIngredient, user))
            {
                throw new InvalidOperationException($"An ingredient with the name {newIngredient.Name} already exists");
            }

            newIngredient.AddedByUserId = user.Id;
            newIngredient.DateAdded     = DateTime.Now;

            Context.Ingredient.Add(newIngredient);
            Context.SaveChanges();
        }
Ejemplo n.º 11
0
        public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            // Get the information about the user from the external login provider
            var info = await _signInManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                ErrorMessage = "Error loading external login information during confirmation.";
                return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
            }

            if (ModelState.IsValid)
            {
                var user = new PantryPlannerUser { UserName = Input.Email, Email = Input.Email };
                var result = await _userManager.CreateAsync(user);
                if (result.Succeeded)
                {
                    result = await _userManager.AddLoginAsync(user, info);
                    if (result.Succeeded)
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
                        return LocalRedirect(returnUrl);
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            LoginProvider = info.LoginProvider;
            ReturnUrl = returnUrl;
            return Page();
        }
 /// <summary>
 /// Adds test data to <paramref name="context"/> and initializes <paramref name="testUser"/> with relationships to the test data.
 /// </summary>
 public static void InitializeUsersAndKitchens(PantryPlannerContext context, PantryPlannerUser testUser)
 {
     InitializeUser(context, testUser);
     InitializeKitchen(context);
     InitializeKitchenAndKitchenUserForUser(context, testUser);
     InitializeRandomKitchenAndKitchenUser(context);
     AddNewRandomUsersToKitchens(context, numOfUsersToAddPerKitchen: 3);
 }
        public List <KitchenUser> GetAcceptedUsersForKitchen(Kitchen kitchen, PantryPlannerUser userAccessing)
        {
            if (kitchen == null)
            {
                throw new ArgumentNullException("kitchen is null");
            }

            return(GetAcceptedUsersForKitchenById(kitchen.KitchenId, userAccessing));
        }
        internal bool UserAddedIngredient(Ingredient ingredient, PantryPlannerUser user)
        {
            if (ingredient == null)
            {
                return(false);
            }

            return(UserAddedIngredient(ingredient.IngredientId, user));
        }
        internal bool UserHasRightsToKitchen(PantryPlannerUser user, Kitchen kitchen)
        {
            if (Context == null || user == null || kitchen == null || Context.KitchenUser == null)
            {
                return(false);
            }

            return(Context.KitchenUser.Any(x => x.KitchenId == kitchen.KitchenId && x.UserId == user.Id));
        }
        public bool DenyInviteToKitchen(Kitchen kitchen, PantryPlannerUser user)
        {
            if (kitchen == null)
            {
                throw new ArgumentNullException(nameof(kitchen));
            }

            return(DenyInviteToKitchen(kitchen.KitchenId, user));
        }
        public bool AcceptInviteToKitchen(Kitchen kitchenToJoin, PantryPlannerUser userAccepting)
        {
            if (kitchenToJoin == null)
            {
                throw new ArgumentNullException("kitchen is null");
            }

            return(AcceptInviteToKitchenByKitchenId(kitchenToJoin.KitchenId, userAccepting));
        }
        public List <KitchenUser> GetMyInvites(PantryPlannerUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            return(GetMyInvites(user.Id));
        }
        public List <KitchenUser> GetUsersThatHaveNotAcceptedInvite(Kitchen kitchen, PantryPlannerUser userAccessing)
        {
            if (kitchen == null)
            {
                throw new ArgumentNullException("kitchen is null");
            }

            return(GetUsersThatHaveNotAcceptedInviteByKitchenId(kitchen.KitchenId, userAccessing));
        }
        internal bool UserAddedIngredient(long ingredientId, PantryPlannerUser user)
        {
            if (user == null)
            {
                return(false);
            }

            return(UserAddedIngredient(ingredientId, user.Id));
        }
        internal bool UserOwnsKitchen(PantryPlannerUser user, Kitchen kitchen)
        {
            if (user == null || kitchen == null)
            {
                return(false);
            }

            return(Context.KitchenUser.Any(x => x.KitchenId == kitchen.KitchenId && x.UserId == user.Id && x.IsOwner));
        }
        /// <summary>
        /// Deletes ingredient if user has rights to it (i.e. added the ingredient)
        /// </summary>
        public Ingredient DeleteIngredient(Ingredient ingredient, PantryPlannerUser userDeleting)
        {
            if (ingredient == null)
            {
                throw new ArgumentNullException(nameof(ingredient));
            }

            return(DeleteIngredient(ingredient.IngredientId, userDeleting));
        }
        public void AcceptInviteToKitchen_InvalidKitchen_ThrowsKitchenNotFoundException()
        {
            // add random user to test against
            PantryPlannerUser newUser = InMemoryDataGenerator.AddNewRandomUser(_context);

            Assert.Throws <KitchenNotFoundException>(() =>
            {
                _kitchenUserService.AcceptInviteToKitchenByKitchenId(-5, newUser);
            });
        }
        public void InviteUserToKitchenByUsername_InvalidKitchenId_ThrowsKitchenNotFoundException()
        {
            // add random user to test against
            PantryPlannerUser newUser = InMemoryDataGenerator.AddNewRandomUser(_context);

            Assert.Throws <KitchenNotFoundException>(() =>
            {
                _kitchenUserService.InviteUserToKitchenByUsername(newUser.UserName, -5, _testUser);
            });
        }
        public void InviteUserToKitchenByUsername_NullKitchen_ThrowsArgumentNullException()
        {
            // add random user to test against
            PantryPlannerUser newUser = InMemoryDataGenerator.AddNewRandomUser(_context);

            Assert.Throws <ArgumentNullException>(() =>
            {
                _kitchenUserService.InviteUserToKitchenByUsername(newUser.UserName, null, _testUser);
            });
        }
        public KitchenUser DeleteKitchenUserFromKitchenByUsername(Kitchen kitchen, string usernameToDelete, PantryPlannerUser userDeleting)
        {
            if (Context.UserExists(usernameToDelete) == false)
            {
                throw new UserNotFoundException(usernameToDelete);
            }

            PantryPlannerUser userToDelete = Context.Users.Where(u => u.UserName == usernameToDelete).FirstOrDefault();

            return(DeleteKitchenUserFromKitchen(kitchen.KitchenId, userToDelete.Id, userDeleting));
        }
 public KitchenServiceUnitTest()
 {
     _testUser = new PantryPlannerUser()
     {
         Id       = "Constructor123",
         UserName = "******",
         Email    = "*****@*****.**"
     };
     _context        = InMemoryDataGenerator.CreateAndInitializeInMemoryDatabaseContext(Guid.NewGuid().ToString(), _testUser, insertIngredientData: false);
     _kitchenService = new KitchenService(_context);
 }
        public KitchenUser DeleteMyselfFromKitchen(long kitchenId, PantryPlannerUser user)
        {
            if (Context.KitchenExists(kitchenId) == false)
            {
                throw new KitchenNotFoundException(kitchenId);
            }

            Kitchen kitchen = Context.Kitchen.Find(kitchenId);

            return(DeleteMyselfFromKitchen(kitchen, user));
        }
        public async Task AutoCreateAccountFromGoogleAsync_Valid_UserReturnedAsync()
        {
            GoogleJsonWebSignature.Payload payload = new GoogleJsonWebSignature.Payload()
            {
                Email = "*****@*****.**"
            };

            PantryPlannerUser newUser = await _service.AutoCreateAccountFromGoogleAsync(payload);

            Assert.NotNull(newUser);
            Assert.Equal(payload.Email, newUser.Email);
        }
        public void AcceptInviteToKitchen_NoKitchenInvite_ThrowsInviteNotFoundException()
        {
            // add random user to test against
            PantryPlannerUser newUser = InMemoryDataGenerator.AddNewRandomUser(_context);

            // get valid kitchen from test user
            Kitchen kitchen = _testUser.KitchenUser.FirstOrDefault()?.Kitchen;

            Assert.Throws <InviteNotFoundException>(() =>
            {
                _kitchenUserService.AcceptInviteToKitchen(kitchen, newUser);
            });
        }