// /*
//  * Copyright 2016 Red Hat, Inc. and/or its affiliates
//  * and other contributors as indicated by the @author tags.
//  *
//  * Licensed under the Apache License, Version 2.0 (the "License");
//  * you may not use this file except in compliance with the License.
//  * You may obtain a copy of the License at
//  *
//  * http://www.apache.org/licenses/LICENSE-2.0
//  *
//  * Unless required by applicable law or agreed to in writing, software
//  * distributed under the License is distributed on an "AS IS" BASIS,
//  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  * See the License for the specific language governing permissions and
//  * limitations under the License.
//  */
// package org.keycloak.testsuite.federation.storage;

// import org.junit.After;
// import org.junit.Assert;
// import org.junit.ClassRule;
// import org.junit.Rule;
// import org.junit.Test;
// import org.keycloak.OAuth2Constants;
// import org.keycloak.common.util.Time;
// import org.keycloak.component.ComponentModel;
// import org.keycloak.credential.CredentialAuthentication;
// import org.keycloak.credential.UserCredentialStoreManager;
// import org.keycloak.models.GroupModel;
// import org.keycloak.models.KeycloakSession;
// import org.keycloak.models.RealmModel;
// import org.keycloak.models.RoleModel;
// import org.keycloak.models.UserCredentialModel;
// import org.keycloak.models.UserModel;
// import org.keycloak.models.cache.CachedUserModel;
// import org.keycloak.models.cache.infinispan.UserAdapter;
// import org.keycloak.services.managers.RealmManager;
// import org.keycloak.storage.StorageId;
// import org.keycloak.storage.UserStorageProviderModel;
// import org.keycloak.testsuite.OAuthClient;
// import org.keycloak.testsuite.pages.AppPage;
// import org.keycloak.testsuite.pages.LoginPage;
// import org.keycloak.testsuite.rule.KeycloakRule;
// import org.keycloak.testsuite.rule.WebResource;
// import org.keycloak.testsuite.rule.WebRule;
// import org.openqa.selenium.WebDriver;

// import java.util.Calendar;
// import java.util.HashSet;
// import java.util.List;
// import java.util.Set;

// /**
//  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
//  * @version $Revision: 1 $
//  */
// public class UserStorageTest {
//     public static ComponentModel memoryProvider = null;
//     public static ComponentModel writableProvider = null;
//     @ClassRule
//     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {

//         @Override
//         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
//             UserStorageProviderModel model = new UserStorageProviderModel();
//             model.setName("memory");
//             model.setPriority(0);
//             model.setProviderId(UserMapStorageFactory.PROVIDER_ID);
//             model.setParentId(appRealm.getId());
//             memoryProvider = appRealm.addComponentModel(model);

//             model = new UserStorageProviderModel();
//             model.setName("read-only-user-props");
//             model.setPriority(1);
//             model.setProviderId(UserPropertyFileStorageFactory.PROVIDER_ID);
//             model.setParentId(appRealm.getId());
//             model.getConfig().putSingle("propertyFile", "/storage-test/read-only-user-password.properties");
//             appRealm.addComponentModel(model);
//             createUserPropModel(appRealm);
//         }
//     });

//     private static void createUserPropModel(RealmModel appRealm) {
//         UserStorageProviderModel model;
//         model = new UserStorageProviderModel();
//         model.setName("user-props");
//         model.setPriority(2);
//         model.setParentId(appRealm.getId());
//         model.setProviderId(UserPropertyFileStorageFactory.PROVIDER_ID);
//         model.getConfig().putSingle("propertyFile", "/storage-test/user-password.properties");
//         model.getConfig().putSingle("federatedStorage", "true");
//         writableProvider = appRealm.addComponentModel(model);
//     }

//     @Rule
//     public WebRule webRule = new WebRule(this);

//     @WebResource
//     protected OAuthClient oauth;

//     @WebResource
//     protected WebDriver driver;

//     @WebResource
//     protected AppPage appPage;

//     @WebResource
//     protected LoginPage loginPage;

//     private void loginSuccessAndLogout(String username, String password) {
//         loginPage.open();
//         loginPage.login(username, password);
//         Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
//         Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
//         oauth.openLogout();
//     }

//     public void loginBadPassword(String username) {
//         loginPage.open();
//         loginPage.login("username", "badpassword");
//         Assert.assertEquals("Invalid username or password.", loginPage.getError());
//     }

//     @Test
//     public void testLoginSuccess() {
//         loginSuccessAndLogout("tbrady", "goat");
//         loginSuccessAndLogout("thor", "hammer");
//         loginBadPassword("tbrady");
//     }

//     @After
//     public void resetTimeoffset() {
//         Time.setOffset(0);

//     }

//     //@Test
//     public void testIDE() throws Exception {
//         Thread.sleep(100000000);
//     }

//     /**
//      * KEYCLOAK-4013
//      *
//      * @throws Exception
//      */
//     @Test
//     public void testCast() throws Exception {
//         KeycloakSession session = keycloakRule.startSession();
//         List<CredentialAuthentication> list = UserCredentialStoreManager.getCredentialProviders(session, null, CredentialAuthentication.class);
//         keycloakRule.stopSession(session, true);

//     }

//     @Test
//     public void testDailyEviction() {
//         Calendar cal = Calendar.getInstance();
//         cal.add(Calendar.HOUR, 1);
//         int hour = cal.get(Calendar.HOUR_OF_DAY);
//         int min = cal.get(Calendar.MINUTE);

//         UserStorageProviderModel model = new UserStorageProviderModel(writableProvider);
//         model.setCachePolicy(UserStorageProviderModel.CachePolicy.EVICT_DAILY);
//         model.setEvictionHour(cal.get(Calendar.HOUR_OF_DAY));
//         model.setEvictionMinute(cal.get(Calendar.MINUTE));

//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         CachedUserModel thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         long lastTimestamp = thor.getCacheTimestamp();
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         lastTimestamp = thor.getCacheTimestamp();
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);

//         // test is cached
//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         // thor should be evicted because we changed the model
//         Assert.assertTrue(thor.getCacheTimestamp() > lastTimestamp);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);


//         Time.setOffset(60 * 2 * 60); // 2 hours

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         UserModel thor2 = session.users().getUserByUsername("thor", realm);
//         // thor should be evicted because we put it 2 hours in the future
//         if (thor2 instanceof CachedUserModel) {
//             Assert.assertTrue(((CachedUserModel)thor2).getCacheTimestamp() > lastTimestamp);
//         }
//         model.getConfig().remove("cachePolicy");
//         model.getConfig().remove("evictionHour");
//         model.getConfig().remove("evictionMinute");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);
//     }

//     @Test
//     public void testWeeklyEviction() {
//         Calendar cal = Calendar.getInstance();

//         // sets day of the week to 4 days from now
//         cal.add(Calendar.HOUR, 4 * 24);

//         UserStorageProviderModel model = new UserStorageProviderModel(writableProvider);
//         model.setCachePolicy(UserStorageProviderModel.CachePolicy.EVICT_WEEKLY);
//         model.setEvictionDay(cal.get(Calendar.DAY_OF_WEEK));
//         model.setEvictionHour(cal.get(Calendar.HOUR_OF_DAY));
//         model.setEvictionMinute(cal.get(Calendar.MINUTE));

//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         CachedUserModel thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         long lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);

//         Time.setOffset(60 * 60 * 24 * 2); // 2 days in future, should be cached still

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         // test still
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         Assert.assertEquals(thor.getCacheTimestamp(), lastTimestamp);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);

//         Time.setOffset(Time.getOffset() + 60 * 60 * 24 * 3); // 3 days into future, cache will be invalidated

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         UserModel thor2 = session.users().getUserByUsername("thor", realm);
//         // thor should be evicted because we put it 2 hours in the future
//         if (thor2 instanceof CachedUserModel) {
//             Assert.assertTrue(((CachedUserModel)thor2).getCacheTimestamp() > lastTimestamp);
//         }
//         model.getConfig().remove("cachePolicy");
//         model.getConfig().remove("evictionHour");
//         model.getConfig().remove("evictionMinute");
//         model.getConfig().remove("evictionDay");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);
//     }

//     @Test
//     public void testMaxLifespanEviction() {
//         UserStorageProviderModel model = new UserStorageProviderModel(writableProvider);
//         model.setCachePolicy(UserStorageProviderModel.CachePolicy.MAX_LIFESPAN);
//         model.setMaxLifespan(600000); // Lifetime is 10 minutes

//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         CachedUserModel thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         long lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);


//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);


//         Time.setOffset(60 * 5); // 5 minutes in future, should be cached still
//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         Assert.assertEquals(thor.getCacheTimestamp(), lastTimestamp);
//         lastTimestamp = thor.getCacheTimestamp();
//         keycloakRule.stopSession(session, true);

//         Time.setOffset(60 * 20); // 20 minutes into future, cache will be invalidated

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         UserModel thor2 = session.users().getUserByUsername("thor", realm);
//         // thor should be evicted because we put it 2 hours in the future
//         if (thor2 instanceof CachedUserModel) {
//             Assert.assertTrue(((CachedUserModel)thor2).getCacheTimestamp() > lastTimestamp);
//         }
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         model.getConfig().remove("cachePolicy");
//         model.getConfig().remove("maxLifespan");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);
//     }

//     @Test
//     public void testNoCache() {
//         UserStorageProviderModel model = new UserStorageProviderModel(writableProvider);
//         model.setCachePolicy(UserStorageProviderModel.CachePolicy.NO_CACHE);
//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         CachedUserModel thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);


//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         // test still
//         UserModel thor2 = session.users().getUserByUsername("thor", realm);
//         Assert.assertFalse(thor2 instanceof CachedUserModel);
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor2 = session.users().getUserByUsername("thor", realm);
//         Assert.assertFalse(thor2 instanceof CachedUserModel);
//         model.getConfig().remove("cachePolicy");
//         model.getConfig().remove("evictionHour");
//         model.getConfig().remove("evictionMinute");
//         model.getConfig().remove("evictionDay");
//         realm.updateComponent(model);
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = (CachedUserModel)session.users().getUserByUsername("thor", realm);
//         keycloakRule.stopSession(session, true);

//     }

//     @Test
//     public void testUpdate() {
//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         UserModel thor = session.users().getUserByUsername("thor", realm);
//         thor.setFirstName("Stian");
//         thor.setLastName("Thorgersen");
//         thor.setEmailVerified(true);
//         long thorCreated = System.currentTimeMillis() - 100;
//         thor.setCreatedTimestamp(thorCreated);
//         thor.setEmail("thor@hammer.com");
//         thor.setSingleAttribute("test-attribute", "value");
//         RoleModel role = realm.addRole("foo-role");
//         thor.grantRole(role);
//         GroupModel group = realm.createGroup("my-group");
//         thor.joinGroup(group);
//         thor.addRequiredAction("POOP");
//         keycloakRule.stopSession(session, true);

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         thor = session.users().getUserByUsername("thor", realm);
//         Assert.assertEquals("Stian", thor.getFirstName());
//         Assert.assertEquals("Thorgersen", thor.getLastName());
//         Assert.assertEquals("thor@hammer.com", thor.getEmail());
//         Assert.assertEquals("value", thor.getFirstAttribute("test-attribute"));
//         Assert.assertTrue(thor.isEmailVerified());
//         Assert.assertTrue(thor instanceof UserAdapter);
//         Set<RoleModel> roles = thor.getRoleMappings();
//         System.out.println("num roles " + roles.size());
//         Assert.assertTrue(roles.size() > 1);
//         role = realm.getRole("foo-role");
//         Assert.assertTrue(thor.hasRole(role));

//         Set<GroupModel> groups = thor.getGroups();
//         boolean foundGroup = false;
//         for (GroupModel g : groups) {
//             if (g.getName().equals("my-group")) foundGroup = true;

//         }
//         Assert.assertTrue(foundGroup);
//         System.out.println("num groups " + groups.size());
//         Assert.assertTrue(thor.getRequiredActions().iterator().next().equals("POOP"));
//         thor.removeRequiredAction("POOP");
//         session.userCredentialManager().updateCredential(realm, thor, UserCredentialModel.password("lightning"));
//         keycloakRule.stopSession(session, true);
//         loginSuccessAndLogout("thor", "lightning");

//         // test removal of provider
//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         realm.removeComponent(writableProvider);
//         keycloakRule.stopSession(session, true);
//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         createUserPropModel(realm);
//         keycloakRule.stopSession(session, true);

//         loginSuccessAndLogout("thor", "hammer");

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");

//         thor = session.users().getUserByUsername("thor", realm);
//         Assert.assertNull(thor.getFirstName());
//         Assert.assertNull(thor.getLastName());
//         Assert.assertNull(thor.getEmail());
//         Assert.assertNull(thor.getFirstAttribute("test-attribute"));
//         Assert.assertFalse(thor.isEmailVerified());
//         role = realm.getRole("foo-role");
//         Assert.assertFalse(thor.hasRole(role));

//         groups = thor.getGroups();
//         foundGroup = false;
//         for (GroupModel g : groups) {
//             if (g.getName().equals("my-group")) foundGroup = true;

//         }
//         Assert.assertFalse(foundGroup);


//     }

//     @Test
//     public void testQuery() {
//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");

//         // Test paging
//         List<UserModel> localUsers = session.userLocalStorage().getUsers(realm, false);
//         Set<UserModel> queried = new HashSet<>();
//         // tests assumes that local storage is queried first
//         int first = localUsers.size();
//         while (queried.size() < 8) {
//             List<UserModel> results = session.users().getUsers(realm, first, 3);
//             if (results.size() == 0) break;
//             first += results.size();
//             queried.addAll(results);

//         }
//         Set<String> usernames = new HashSet<>();
//         for (UserModel user : queried) {
//             usernames.add(user.getUsername());
//             System.out.println(user.getUsername());

//         }
//         Assert.assertEquals(8, queried.size());
//         Assert.assertTrue(usernames.contains("thor"));
//         Assert.assertTrue(usernames.contains("zeus"));
//         Assert.assertTrue(usernames.contains("apollo"));
//         Assert.assertTrue(usernames.contains("perseus"));
//         Assert.assertTrue(usernames.contains("tbrady"));
//         Assert.assertTrue(usernames.contains("rob"));
//         Assert.assertTrue(usernames.contains("jules"));
//         Assert.assertTrue(usernames.contains("danny"));

//         // test searchForUser
//         List<UserModel> users = session.users().searchForUser("tbrady", realm);
//         Assert.assertTrue(users.size() == 1);
//         Assert.assertTrue(users.get(0).getUsername().equals("tbrady"));

//         // test getGroupMembers()
//         GroupModel gods = realm.createGroup("gods");
//         UserModel user = null;
//         user = session.users().getUserByUsername("apollo", realm);
//         user.joinGroup(gods);
//         user = session.users().getUserByUsername("zeus", realm);
//         user.joinGroup(gods);
//         user = session.users().getUserByUsername("thor", realm);
//         user.joinGroup(gods);
//         queried.clear();
//         usernames.clear();

//         first = 0;
//         while (queried.size() < 8) {
//             List<UserModel> results = session.users().getGroupMembers(realm, gods, first, 1);
//             if (results.size() == 0) break;
//             first += results.size();
//             queried.addAll(results);

//         }
//         for (UserModel u : queried) {
//             usernames.add(u.getUsername());
//             System.out.println(u.getUsername());

//         }
//         Assert.assertEquals(3, queried.size());
//         Assert.assertTrue(usernames.contains("apollo"));
//         Assert.assertTrue(usernames.contains("zeus"));
//         Assert.assertTrue(usernames.contains("thor"));

//         // search by single attribute
//         System.out.println("search by single attribute");
//         user = session.users().getUserByUsername("thor", realm);
//         user.setSingleAttribute("weapon", "hammer");

//         users = session.users().searchForUserByUserAttribute("weapon", "hammer", realm);
//         for (UserModel u : users) {
//             System.out.println(u.getUsername());

//         }
//         Assert.assertEquals(1, users.size());
//         Assert.assertEquals("thor", users.get(0).getUsername());


//         keycloakRule.stopSession(session, true);
//     }

//     @Test
//     public void testRegistration() {
//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         UserModel user = session.users().addUser(realm, "memuser");
//         session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password("password"));
//         keycloakRule.stopSession(session, true);
//         loginSuccessAndLogout("memuser", "password");
//         loginSuccessAndLogout("memuser", "password");
//         loginSuccessAndLogout("memuser", "password");

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         user = session.users().getUserByUsername("memuser", realm);
//         Assert.assertEquals(memoryProvider.getId(), StorageId.resolveProviderId(user));
//         session.users().removeUser(realm, user);
//         Assert.assertNull(session.users().getUserByUsername("memuser", realm));
//         keycloakRule.stopSession(session, true);

//     }

//     @Test
//     public void testLifecycle() {
//         UserMapStorage.allocations.set(0);
//         UserMapStorage.closings.set(0);
//         KeycloakSession session = keycloakRule.startSession();
//         RealmModel realm = session.realms().getRealmByName("test");
//         UserModel user = session.users().addUser(realm, "memuser");
//         Assert.assertNotNull(user);
//         user = session.users().getUserByUsername("nonexistent", realm);
//         Assert.assertNull(user);
//         keycloakRule.stopSession(session, true);
//         Assert.assertEquals(1, UserMapStorage.allocations.get());
//         Assert.assertEquals(1, UserMapStorage.closings.get());

//         session = keycloakRule.startSession();
//         realm = session.realms().getRealmByName("test");
//         user = session.users().getUserByUsername("memuser", realm);
//         session.users().removeUser(realm, user);
//         Assert.assertNull(session.users().getUserByUsername("memuser", realm));
//         keycloakRule.stopSession(session, true);

//     }

// }
