Java tutorial
/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.couchdb.test.dialect.authenticated; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.HashMap; import java.util.Map; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.protocol.ClientContext; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.ogm.boot.OgmSessionFactoryBuilder; import org.hibernate.ogm.cfg.OgmProperties; import org.hibernate.ogm.util.configurationreader.spi.ConfigurationPropertyReader; import org.hibernate.ogm.utils.TestHelper; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.fasterxml.jackson.databind.ObjectMapper; /** * Tests the access of a CouchDB database which requires authentication. The test assumes a database in the default * configuration (i.e. without authentication enabled) and does the following preparation steps: * <ul> * <li>create a server admin user</li> * <li>create a test database</li> * <li>create an admin user for that database (db admin rights are required to create views)</li> * </ul> * The actual test is then run using the credentials of the db admin user, followed by removing the created users and * database. * * @author Gunnar Morling */ public class AuthenticatedAccessTest { private static String host; private static int port; private static String serverUri; private static String serverAdminUser = "alfred"; private static String serverAdminPassword = "secret"; private static String databaseUser = "cary"; private static String databaseUserPassword = "not_so_secret"; private static String database = "testdb_authenticated"; private static String databaseUserRevision; private static SessionFactory sessions; private static ResteasyClient client; @BeforeClass public static void createDatabaseAndSetUpAuthentication() throws Exception { StandardServiceRegistry serviceRegistry = getServiceRegistry(); ConfigurationPropertyReader propertyReader = new ConfigurationPropertyReader( serviceRegistry.getService(ConfigurationService.class).getSettings()); host = propertyReader.property(OgmProperties.HOST, String.class).withDefault("localhost").getValue(); port = propertyReader.property(OgmProperties.PORT, int.class).withDefault(5984).getValue(); serverUri = "http://" + host + ":" + port; client = getClientWithServerAdminCredentials(); createServerAdminUser(); createTestDatabase(); createDatabaseUser(); sessions = new MetadataSources(serviceRegistry).addAnnotatedClass(Flower.class).buildMetadata() .getSessionFactoryBuilder().unwrap(OgmSessionFactoryBuilder.class).build(); } @AfterClass public static void dropDatabaseAndDeleteAdminUser() throws Exception { closeSessionFactory(); deleteDatabaseUser(); dropTestDatabase(); deleteServerAdminUser(); } @Test public void databaseAccessWithCredentialsShouldSucceed() { Session session = sessions.openSession(); Transaction transaction = session.beginTransaction(); Flower flower = new Flower(); flower.setId("1"); flower.setName("Caltha palustris"); session.persist(flower); transaction.commit(); session.clear(); transaction = session.beginTransaction(); Flower loadedFlower = (Flower) session.get(Flower.class, flower.getId()); assertNotNull(loadedFlower); assertEquals(flower.getName(), loadedFlower.getName()); transaction.commit(); session.clear(); session.close(); } private static StandardServiceRegistry getServiceRegistry() { Map<String, Object> settings = new HashMap<>(); settings.put(OgmProperties.DATABASE, database); settings.put(OgmProperties.USERNAME, databaseUser); settings.put(OgmProperties.PASSWORD, databaseUserPassword); settings.put(OgmProperties.CREATE_DATABASE, Boolean.FALSE); return TestHelper.getDefaultTestStandardServiceRegistry(settings); } private static void createServerAdminUser() { Client client = ClientBuilder.newClient(); WebTarget target = client.target(serverUri + "/_config/admins/" + serverAdminUser); target.request().put(Entity.text("\"" + serverAdminPassword + "\"")).close(); } private static void createDatabaseUser() throws Exception { // 1.) create user WebTarget target = client.target(serverUri + "/_users/org.couchdb.user:" + databaseUser); Response response = target.request() .put(Entity.text("{ " + "\"_id\" : \"org.couchdb.user:" + databaseUser + "\", " + "\"type\" : \"user\", " + "\"name\" : \"" + databaseUser + "\", " + "\"roles\" : [], " + "\"password\" : \"" + databaseUserPassword + "\"" + " }")); String entity = response.readEntity(String.class); databaseUserRevision = (String) new ObjectMapper().readValue(entity, Map.class).get("rev"); response.close(); // 2.) make the user an admin of the database target = client.target(serverUri + "/" + database + "/_security"); response = target.request().put(Entity.text("{" + "\"admins\": {" + "\"names\":[\"" + databaseUser + "\"]," + " \"roles\":[]" + "}, " + "\"readers\": {" + "\"names\":[]," + "\"roles\":[]" + "}" + "}")); response.close(); } private static void createTestDatabase() { WebTarget target = client.target(serverUri + "/" + database); target.request().put(null).close(); } private static void deleteDatabaseUser() { WebTarget target = client .target(serverUri + "/_users/org.couchdb.user:" + databaseUser + "?rev=" + databaseUserRevision); target.request().delete().close(); } private static void dropTestDatabase() { WebTarget target = client.target(serverUri + "/" + database); target.request().delete().close(); } private static void deleteServerAdminUser() { WebTarget target = client.target(serverUri + "/_config/admins/" + serverAdminUser); target.request().delete().close(); } private static ResteasyClient getClientWithServerAdminCredentials() { DefaultHttpClient httpClient = new DefaultHttpClient(); httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(serverAdminUser, serverAdminPassword)); AuthCache authCache = new BasicAuthCache(); authCache.put(new HttpHost(host, port, "http"), new BasicScheme()); BasicHttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.AUTH_CACHE, authCache); return new ResteasyClientBuilder().httpEngine(new ApacheHttpClient4Engine(httpClient, localContext)) .build(); } private static void closeSessionFactory() { if (sessions != null) { sessions.close(); } } }