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 static void SetCookies(HttpResponse Response, string tokenString, RefreshToken refToken) { ReturnableRefreshToken retToken = new ReturnableRefreshToken(refToken); // decrypt the token // append cookies after login Response.Cookies.Append("AccessToken", tokenString, HelperMethods.GetCookieOptions(false)); Response.Cookies.Append("RefreshToken", retToken.Token, HelperMethods.GetCookieOptions(false)); Response.Cookies.Append("AccessTokenSameSite", tokenString, HelperMethods.GetCookieOptions(true)); Response.Cookies.Append("RefreshTokenSameSite", retToken.Token, HelperMethods.GetCookieOptions(true)); }
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)); }
} // encryption key and iv used for all users base data,, this key cannot unluck user stored passwords/accounts public UserControllerIntegrationTest(WebApplicationFactory <SafeAccountsAPI.Startup> fixture) { _client = fixture.CreateClient(); // get reference to app settings and local db _config = new ConfigurationBuilder().AddJsonFile("appsettings.Development.json").Build(); DbContextOptions <APIContext> options = new DbContextOptions <APIContext>(); _context = new APIContext(options, _config); // set default header for our api_key... Development key only, doesnt work with online api _client.DefaultRequestHeaders.Add("ApiKey", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYXBpX2tleSIsImV4cCI6MTY2Mjk4NzA4MywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNjYiLCJhdWQiOiJodHRwczovL2xvY2FsaG9zdDo0NDM2NiJ9.NUf-fL3g72Z8XqihXJIuaG_z8_NEHmSwckb94VgVK3Q"); // set reference to our user for testing _keyAndIv = new string[] { _config.GetValue <string>("UserEncryptionKey"), _config.GetValue <string>("UserEncryptionIV") }; // for user encryption there is a single key _testUser = _context.Users.Single(a => a.Email.SequenceEqual(HelperMethods.EncryptStringToBytes_Aes("*****@*****.**", _keyAndIv))); // encrypted user _retTestUser = new ReturnableUser(_testUser, _keyAndIv); // decrypted user // generate access code and refresh token for use with endpoints that need to be logged in _accessToken = HelperMethods.GenerateJWTAccessToken(_testUser.ID, _config["UserJwtTokenKey"], _config.GetValue <string>("ApiUrl")); _refreshToken = new ReturnableRefreshToken(HelperMethods.GenerateRefreshToken(_testUser, _context, _keyAndIv), _keyAndIv).Token; }