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 } } }
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 } }
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 } }
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)); }