public IActionResult User_AddAccount(int id, [FromBody] NewAccount accToAdd)
        {
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id, _keyAndIV))
            {
                ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                return(new UnauthorizedObjectResult(error));
            }

            // account limit is 50 for now
            if (_context.Users.Single(a => a.ID == id).Accounts.Count >= 50)
            {
                ErrorMessage error = new ErrorMessage("Failed to create new account", "User cannot have more than 50 passwords saved at once.");
                return(new BadRequestObjectResult(error));
            }

            // if this user does not own the folder we are adding to, then error
            if (accToAdd.FolderID != null && !_context.Users.Single(a => a.ID == id).Folders.Exists(b => b.ID == accToAdd.FolderID))
            {
                ErrorMessage error = new ErrorMessage("Failed to create new account", "User does not have a folder matching that ID.");
                return(new BadRequestObjectResult(error));
            }

            // create new account and save it
            Account new_account = new Account(accToAdd, id);

            new_account.LastModified = HelperMethods.EncryptStringToBytes_Aes(DateTime.Now.ToString(), HelperMethods.GetUserKeyAndIV(id));
            _context.Accounts.Add(new_account);
            _context.SaveChanges();

            // return the new object to easily update on frontend without making another api call
            return(new OkObjectResult(new ReturnableAccount(new_account)));
        }
        public IActionResult User_EditAccountDesc(int id, int account_id, [FromBody] string description)
        {
            // attempt to edit the description
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id, _keyAndIV))
            {
                ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                return(new UnauthorizedObjectResult(error));
            }

            // validate ownership of said account
            if (!_context.Users.Single(a => a.ID == id).Accounts.Exists(b => b.ID == account_id))
            {
                ErrorMessage error = new ErrorMessage("Invalid account", "User does not have an account matching that ID.");
                return(new BadRequestObjectResult(error));
            }

            // get account and modify
            Account accToEdit = _context.Users.Single(a => a.ID == id).Accounts.Single(b => b.ID == account_id);

            accToEdit.Description  = HelperMethods.EncryptStringToBytes_Aes(description, HelperMethods.GetUserKeyAndIV(id));;
            accToEdit.LastModified = HelperMethods.EncryptStringToBytes_Aes(DateTime.Now.ToString(), HelperMethods.GetUserKeyAndIV(id));
            _context.SaveChanges();

            return(Ok());
        }
        public IActionResult User_EditAccount(int id, int acc_id, [FromBody] NewAccount acc)
        {
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id, _keyAndIV))
            {
                ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                return(new UnauthorizedObjectResult(error));
            }

            // validate ownership of said account
            if (!_context.Users.Single(a => a.ID == id).Accounts.Exists(b => b.ID == acc_id))
            {
                ErrorMessage error = new ErrorMessage("Failed to delete account", "User does not have an account matching that ID.");
                return(new BadRequestObjectResult(error));
            }

            // get account and modify
            Account accToEdit = _context.Users.Single(a => a.ID == id).Accounts.Single(b => b.ID == acc_id);

            accToEdit.Title        = HelperMethods.EncryptStringToBytes_Aes(acc.Title, HelperMethods.GetUserKeyAndIV(id));
            accToEdit.Login        = HelperMethods.EncryptStringToBytes_Aes(acc.Login, HelperMethods.GetUserKeyAndIV(id));
            accToEdit.Password     = HelperMethods.EncryptStringToBytes_Aes(acc.Password, HelperMethods.GetUserKeyAndIV(id));
            accToEdit.Url          = HelperMethods.EncryptStringToBytes_Aes(acc.Url, HelperMethods.GetUserKeyAndIV(id));
            accToEdit.Description  = HelperMethods.EncryptStringToBytes_Aes(acc.Description, HelperMethods.GetUserKeyAndIV(id));
            accToEdit.LastModified = HelperMethods.EncryptStringToBytes_Aes(DateTime.Now.ToString(), HelperMethods.GetUserKeyAndIV(id));
            _context.SaveChanges();

            // return the new object to easily update on frontend without making another api call
            return(new OkObjectResult(new ReturnableAccount(accToEdit)));
        }
        public ActionResult User_Login([FromBody] Login login)
        {
            // get users saved password hash and salt
            User user = _context.Users.Single(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes(login.Email, _keyAndIV)));

            // check if the user has a verified email or not
            if (!user.EmailVerified)
            {
                ErrorMessage error = new ErrorMessage("Email unconfirmed.", "Please confirm email first.");
                return(new UnauthorizedObjectResult(error));
            }

            // successful login.. compare user hash to the hash generated from the inputted password and salt
            if (ValidatePassword(login.Password, user.Password))
            {
                string        tokenString = HelperMethods.GenerateJWTAccessToken(user.ID, _configuration.GetValue <string>("UserJwtTokenKey"));
                RefreshToken  refToken    = HelperMethods.GenerateRefreshToken(user, _context);
                LoginResponse rtrn        = new LoginResponse {
                    ID = user.ID, AccessToken = tokenString, RefreshToken = new ReturnableRefreshToken(refToken)
                };
                _context.SaveChanges(); // always last on db to make sure nothing breaks and db has new info

                // append cookies to response after login
                HelperMethods.SetCookies(Response, tokenString, refToken);
                return(new OkObjectResult(rtrn));
            }
            else
            {
                ErrorMessage error = new ErrorMessage("Invalid Credentials.", "Email or Password does not match.");
                return(new UnauthorizedObjectResult(error));
            }
        }
        public ActionResult User_ConfirmEmail(string token, string email)
        {
            byte[] encryptedEmail = HelperMethods.EncryptStringToBytes_Aes(email, _keyAndIV);
            User   userToConfirm  = _context.Users.Single(a => a.Email.SequenceEqual(encryptedEmail));

            // check if email is already verified
            if (userToConfirm.EmailVerified)
            {
                ErrorMessage error = new ErrorMessage("Failed to confirm email", "Email address is already confirmed.");
                return(new BadRequestObjectResult(error));
            }

            // verify that the email provided matches the email in the token.
            if (!encryptedEmail.SequenceEqual(HelperMethods.GetUserFromAccessToken(token, _context, _configuration.GetValue <string>("EmailConfirmationTokenKey")).Email))
            {
                ErrorMessage error = new ErrorMessage("Failed to confirm email", "Token is invalid.");
                return(new BadRequestObjectResult(error));
            }

            // ok now we save the users email as verified
            userToConfirm.EmailVerified = true;
            _context.Users.Update(userToConfirm);
            _context.SaveChanges();
            return(Ok());
        }
Exemple #6
0
        public IActionResult User_AddUser([FromBody] NewUser newUser)
        {
            newUser.Email = newUser.Email.ToLower(); // make all emails lowercase
            // attempt to create new user and add to the database.
            // if there is a user with this email already then we throw bad request error
            if (_context.Users.SingleOrDefault(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes(newUser.Email, _keyAndIV))) != null)
            {
                ErrorMessage error = new ErrorMessage("Failed to create new user", "Email already in use.");
                return(new BadRequestObjectResult(error));
            }

            User userToRegister = new User(newUser, _keyAndIV); // new user with no accounts and registered as user

            _context.Users.Add(userToRegister);
            _context.SaveChanges();

            try
            {
                // send the confirmation email
                SendConfirmationEmail(userToRegister);
            }
            catch (Exception ex)
            {
                // remove the user if we failed to send a confirmation email
                // this way they can retry signing up with the same email
                _context.Users.Remove(_context.Users.Single(a => a.ID == userToRegister.ID));
                _context.SaveChanges();
                throw;
            }

            return(Ok());
        }
        public IActionResult User_EditLastName(int id, [FromBody] string lastname)
        {
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id, _keyAndIV))
            {
                ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                return(new UnauthorizedObjectResult(error));
            }

            _context.Users.Where(a => a.ID == id).Single().Last_Name = HelperMethods.EncryptStringToBytes_Aes(lastname, _keyAndIV);;
            _context.SaveChanges();
            return(Ok());
        }
Exemple #8
0
        [HttpPost("{id:int}/accounts")]         // working
        public string User_AddAccount(int id, [FromBody] string accJson)
        {
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id))
            {
                Response.StatusCode = 401;
                return(JObject.FromObject(new ErrorMessage("Invalid User", "id accessed: " + id.ToString(), "Caller can only access their information.")).ToString());
            }

            JObject json = null;

            // might want Json verification as own function since all will do it.. we will see
            try { json = JObject.Parse(accJson); } catch (Exception ex) {
                Response.StatusCode = 400;
                ErrorMessage error = new ErrorMessage("Invalid Json", accJson, ex.Message);
                return(JObject.FromObject(error).ToString());
            }

            try {
                // if folder id is present, then use it, if not we use standard null for top parent
                int?folder_id;
                if (json["folder_id"] == null)
                {
                    folder_id = null;
                }
                else
                {
                    folder_id = _context.Users.Single(a => a.ID == id).Folders.Single(b => b.ID == int.Parse(json["folder_id"].ToString())).ID;                     // makes sure folder exists and is owned by user
                }

                // use token in header to to
                Account new_account = new Account {
                    UserID   = id,
                    FolderID = folder_id,
                    Title    = json["account_title"]?.ToString(),
                    Login    = json["account_login"]?.ToString(),
                    Password = json["account_password"] != null?HelperMethods.EncryptStringToBytes_Aes(json["account_password"].ToString(), HelperMethods.GetUserKeyAndIV(id)) : null,
                                   Description = json["account_description"]?.ToString()
                };
                _context.Accounts.Add(new_account);
                _context.SaveChanges();
            } catch (Exception ex) {
                Response.StatusCode = 500;
                return(JObject.FromObject(new ErrorMessage("Error creating new account.", accJson, ex.Message)).ToString());
            }

            return(SuccessMessage._result);
        }
        public IActionResult User_AddUser([FromBody] NewUser newUser)
        {
            // attempt to create new user and add to the database.
            // if there is a user with this email already then we throw bad request error
            if (_context.Users.SingleOrDefault(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes(newUser.Email, _keyAndIV))) != null)
            {
                ErrorMessage error = new ErrorMessage("Failed to create new user", "Email already in use.");
                return(new BadRequestObjectResult(error));
            }

            User userToRegister = new User(newUser, _keyAndIV); // new user with no accounts and registered as user

            _context.Users.Add(userToRegister);
            _context.SaveChanges();

            // after we save changes, we need to create unique key and iv, then send the confirmation email
            HelperMethods.CreateUserKeyandIV(userToRegister.ID);
            SendConfirmationEmail(userToRegister);
            return(Ok());
        }
Exemple #10
0
        [HttpPut("{id:int}/accounts/{account_id:int}/password")]         // in progress
        public string User_EditAccountPassword(int id, int account_id, [FromBody] string password)
        {
            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id))
            {
                Response.StatusCode = 401;
                return(JObject.FromObject(new ErrorMessage("Invalid User", "id accessed: " + id.ToString(), "Caller can only access their information.")).ToString());
            }

            try {
                Account acc = _context.Users.Single(a => a.ID == id).Accounts.Single(b => b.ID == account_id);
                acc.Password = HelperMethods.EncryptStringToBytes_Aes(password, HelperMethods.GetUserKeyAndIV(id));                 // this logic will need to be changed to use a unique key
                _context.Accounts.Update(acc);
                _context.SaveChanges();
            } catch (Exception ex) {
                Response.StatusCode = 500;
                return(JObject.FromObject(new ErrorMessage("Error editing password", "n/a", ex.Message)).ToString());
            }

            return(SuccessMessage._result);
        }
        public IActionResult User_EditFolderName(int id, int folder_id, [FromBody] string name)
        {
            // attempt to edit the title

            // verify that the user is either admin or is requesting their own data
            if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id, _keyAndIV))
            {
                ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                return(new UnauthorizedObjectResult(error));
            }

            // validate ownership of said folder
            if (!_context.Users.Single(a => a.ID == id).Folders.Exists(b => b.ID == folder_id))
            {
                ErrorMessage error = new ErrorMessage("Invalid Folder", "User does not have a folder matching that ID.");
                return(new BadRequestObjectResult(error));
            }

            // modify
            _context.Users.Single(a => a.ID == id).Folders.Single(b => b.ID == folder_id).FolderName = HelperMethods.EncryptStringToBytes_Aes(name, HelperMethods.GetUserKeyAndIV(id));
            _context.SaveChanges();
            return(Ok());
        }
        [HttpPut("{id:int}/accounts/{account_id:int}/password")] // in progress
        public IActionResult User_EditAccountPassword(int id, int account_id, [FromBody] string password)
        {
            try
            {
                // verify that the user is either admin or is requesting their own data
                if (!HelperMethods.ValidateIsUserOrAdmin(_httpContextAccessor, _context, id))
                {
                    ErrorMessage error = new ErrorMessage("Invalid User", "Caller can only access their information.");
                    return(new UnauthorizedObjectResult(error));
                }

                // validate ownership of said account
                if (!_context.Users.Single(a => a.ID == id).Accounts.Exists(b => b.ID == account_id))
                {
                    ErrorMessage error = new ErrorMessage("Invalid account", "User does not have an account matching that ID.");
                    return(new BadRequestObjectResult(error));
                }

                _context.Users.Single(a => a.ID == id).Accounts.Single(b => b.ID == account_id).Password = HelperMethods.EncryptStringToBytes_Aes(password, HelperMethods.GetUserKeyAndIV(id));
                _context.SaveChanges();
                return(Ok());
            }
            catch (Exception ex)
            {
                ErrorMessage error = new ErrorMessage("Error editing password", ex.Message);
                return(new InternalServerErrorResult(error));
            }
        }