Exemple #1
0
        public async Task POST_SignOut_Should_Return_Expired_Set_Cookie_Headers()
        {
            /*
             * HttpPost("users/logout")
             * Signout and check that we got 4 empty and expired set cookie headers
             */

            using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, _client.BaseAddress + "users/logout"))
            {
                // generate access code and set header
                string accessToken = HelperMethods.GenerateJWTAccessToken(_testUser.ID, _config["UserJwtTokenKey"]);
                ReturnableRefreshToken refToken = new ReturnableRefreshToken(HelperMethods.GenerateRefreshToken(_testUser, _context));
                string cookie = "AccessToken=" + accessToken + "; AccessTokenSameSite=" + accessToken + "; RefreshToken=" + refToken.Token + "; RefreshTokenSameSite=" + refToken.Token;
                requestMessage.Headers.Add("Cookie", cookie);

                // make request and validate status code
                var response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                // make sure cookies exist, and then make sure all are expired and empty
                Dictionary <string, string> cookiesToDelete = TestingHelpingMethods.CheckForCookies(response);
                foreach (string delete_cookie in response.Headers.GetValues("Set-Cookie").ToList())
                {
                    string   date         = delete_cookie.Split(';')[1].Split('=')[1];
                    DateTime expiringDate = DateTime.Parse(date);
                    Assert.True(DateTime.Now > expiringDate);                                     // make sure expired
                    Assert.Equal("", cookiesToDelete[delete_cookie.Split(';')[0].Split('=')[0]]); // make sure each is empty
                }
            }
        }
Exemple #2
0
        public async Task PUT_EditAccount()
        {
            /*
             * HttpPut("users/{id}/accounts/{acc_id}")
             * Edits one of the users saved accounts in the database
             */

            int accId = 4; // user John Doe always has an account with id of 4 from the db initializer

            using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, _client.BaseAddress + "users/" + _testUser.ID.ToString() + "/accounts/" + accId.ToString()))
            {
                // construct body with an encrypted account edit..
                // so we send an encrypted account and receive an encrypted account
                NewAccount accToEdit = new NewAccount
                {
                    Title       = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("changed", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Login       = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("changed", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Password    = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("changed", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Url         = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("https://changed.com", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Description = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("changed...", _uniqueUserEncryptionKeyAndIv)).Replace("-", "")
                };
                requestMessage.Content = new StringContent(JsonConvert.SerializeObject(accToEdit), Encoding.UTF8, "application/json");

                // Add cookie, make request and validate status code
                requestMessage.Headers.Add("AccessToken", _accessToken);
                HttpResponseMessage response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                // parse account from response, and also request the data from the database directly for comparison
                ReturnableAccount returnedAcc   = JsonConvert.DeserializeObject <ReturnableAccount>(response.Content.ReadAsStringAsync().Result);
                ReturnableAccount accInDatabase = new ReturnableAccount(_context.Accounts.SingleOrDefault(acc => acc.ID == returnedAcc.ID));
                TestingHelpingMethods.IntegrationTest_CompareAccounts(accToEdit, returnedAcc, accInDatabase); // make sure all are equal
            }
        }
Exemple #3
0
        public async Task POST_AddNewAccount()
        {
            /*
             * HttpPost("users/{id}/accounts")
             * Add a new saved password account to the users data collection.
             */

            using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, _client.BaseAddress + "users/" + _testUser.ID.ToString() + "/accounts"))
            {
                // construct body with a new account to add.. using same techniques as client side encryption
                // so we send an encrypted account and receive an encrypted account
                NewAccount accToAdd = new NewAccount
                {
                    Title       = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("Discord", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Login       = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("username", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Password    = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("useless", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Url         = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("https://discord.com", _uniqueUserEncryptionKeyAndIv)).Replace("-", ""),
                    Description = BitConverter.ToString(HelperMethods.EncryptStringToBytes_Aes("description...", _uniqueUserEncryptionKeyAndIv)).Replace("-", "")
                };
                requestMessage.Content = new StringContent(JsonConvert.SerializeObject(accToAdd), Encoding.UTF8, "application/json");

                // Add cookie, make request and validate status code
                requestMessage.Headers.Add("AccessToken", _accessToken);
                HttpResponseMessage response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                // parse account from response, and also request the data from the database directly for comparison
                ReturnableAccount returnedAcc   = JsonConvert.DeserializeObject <ReturnableAccount>(response.Content.ReadAsStringAsync().Result);
                ReturnableAccount accInDatabase = new ReturnableAccount(_context.Accounts.SingleOrDefault(acc => acc.ID == returnedAcc.ID));
                TestingHelpingMethods.IntegrationTest_CompareAccounts(accToAdd, returnedAcc, accInDatabase); // make sure all are equal
                Assert.Null(returnedAcc.FolderID);                                                           // check for null folderid indicating no parent
            }
        }
Exemple #4
0
        public async Task POST_Should_Login_And_Return_Valid_Access_And_Refresh_Tokens()
        {
            /*
             * HttpPost("users/login")
             * Login and use the newly recieved tokens to make api call and refresh.
             * Similar to refresh accept in the method we get our tokens. In refresh we generate
             * our first tokens through code and strictly test the refresh endpoint, then validate the tokens recieved from refresh.
             * Here, we get our tokens from the login endpoint and make sure they work as expected.
             *
             */

            // variable for managing our responses
            HttpResponseMessage response;

            // make a login request and validate response code
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, _client.BaseAddress + "users/login"))
            {
                Login login = new Login {
                    Email = _retTestUser.Email, Password = "******"
                };                                                                                                                 // the original user
                requestMessage.Content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json"); // set content
                response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }

            // valid cookies presence, retrieve, and create a cookie header string
            Dictionary <string, string> new_cookies = TestingHelpingMethods.CheckForCookies(response);
            string cookie = "AccessTokenSameSite=" + new_cookies.Single(a => a.Key == "AccessTokenSameSite").Value
                            + "; RefreshTokenSameSite=" + new_cookies.Single(a => a.Key == "RefreshTokenSameSite").Value;

            // check that we recieved a valid login response
            JObject responseBody = await TestingHelpingMethods.CheckForLoginResponse(response);

            // make a call to the api to make sure we recieved a valid access token
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, _client.BaseAddress + "users/" + responseBody["id"].ToString()))
            {
                requestMessage.Headers.Add("Cookie", cookie); // set new access and refresh tokens in cookies
                response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }

            // make a call to refresh and check for 200 status code.. we dont need to validate refesh in anyway here
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, _client.BaseAddress + "users/" + responseBody["id"].ToString()))
            {
                requestMessage.Headers.Add("Cookie", cookie); // set new access and refresh tokens in cookies
                response = await _client.SendAsync(requestMessage);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }
        }
        public async Task POST_Should_Return_New_Valid_Cookies()
        {
            /*
             * HttpPost("refresh")
             * For this test we need a valid refresh token, and an access token that is expired or not.
             * Then make a call to refresh and use the received tokens to see if we can make a valid call to the api.
             * And finally we make a call to validateRefreshToken to make sure the newly generated refresh was stored in the DB
             */

            // get reference to app settings and local db
            var config = new ConfigurationBuilder().AddJsonFile("appsettings.Development.json").Build();
            DbContextOptions <APIContext> options = new DbContextOptions <APIContext>();
            APIContext context = new APIContext(options, config);

            // generate an access token and valid refresh token
            string[] keyAndIV               = { config.GetValue <string>("UserEncryptionKey"), config.GetValue <string>("UserEncryptionIV") }; // for user encryption there is a single key
            User     user                   = context.Users.Single(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes("*****@*****.**", keyAndIV)));
            string   accessToken            = HelperMethods.GenerateJWTAccessToken(user.ID, config["UserJwtTokenKey"]);
            ReturnableRefreshToken refToken = new ReturnableRefreshToken(HelperMethods.GenerateRefreshToken(user, context));

            // set cookies in header
            string cookie = "AccessToken=" + accessToken + "; RefreshToken=" + refToken.Token;

            _client.DefaultRequestHeaders.Add("Cookie", cookie);

            // send request to refresh and assert request is ok and new cookies are present
            var response = await _client.PostAsync("refresh", null);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            // valid cookies presence and retrieve
            Dictionary <string, string> new_cookies = TestingHelpingMethods.CheckForCookies(response);

            // check that we recieved a valid login response
            JObject responseBody = await TestingHelpingMethods.CheckForLoginResponse(response);

            // set new access token in cookies
            _client.DefaultRequestHeaders.Remove("Cookie");
            cookie = "AccessTokenSameSite=" + new_cookies.Single(a => a.Key == "AccessTokenSameSite").Value;
            _client.DefaultRequestHeaders.Add("Cookie", cookie);

            // make a call to the api to make sure we recieved a valid access token
            response = await _client.GetAsync("users/" + responseBody["id"].ToString());

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            // and the last thing we need is to validate that the refresh token was stored in the DB
            context.Dispose();                                                                                                                                 // close old connection
            user = new APIContext(options, config).Users.Single(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes("*****@*****.**", keyAndIV))); // get fresh handle of user from the DB
            Assert.True(HelperMethods.ValidateRefreshToken(user, new_cookies.Single(a => a.Key == "RefreshTokenSameSite").Value));
        }