use of org.exist.storage.DBBroker in project exist by eXist-db.
the class ActiveDirectoryRealm method authenticate.
/*
* (non-Javadoc)
*
* @see org.exist.security.Realm#authenticate(java.lang.String,
* java.lang.Object)
*/
@Override
public Subject authenticate(final String username, Object credentials) throws AuthenticationException {
String[] returnedAtts = { "sn", "givenName", "mail" };
String searchFilter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
// Create the search controls
SearchControls searchCtls = new SearchControls();
searchCtls.setReturningAttributes(returnedAtts);
// Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
LdapContext ctxGC = null;
boolean ldapUser = false;
try {
ctxGC = ensureContextFactory().getLdapContext(username, String.valueOf(credentials));
// Search objects in GC using filters
NamingEnumeration<SearchResult> answer = ctxGC.search(((ContextFactory) ensureContextFactory()).getSearchBase(), searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = answer.next();
Attributes attrs = sr.getAttributes();
Map<String, Object> amap = null;
if (attrs != null) {
amap = new HashMap<>();
NamingEnumeration<? extends Attribute> ne = attrs.getAll();
while (ne.hasMore()) {
Attribute attr = ne.next();
amap.put(attr.getID(), attr.get());
ldapUser = true;
}
ne.close();
}
}
} catch (NamingException e) {
e.printStackTrace();
throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, e.getMessage());
}
if (ldapUser) {
AbstractAccount account = (AbstractAccount) getAccount(username);
if (account == null) {
try (final DBBroker broker = getDatabase().get(Optional.of(getSecurityManager().getSystemSubject()))) {
// perform as SYSTEM user
account = (AbstractAccount) getSecurityManager().addAccount(new UserAider(ID, username));
} catch (Exception e) {
throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, e.getMessage(), e);
}
}
return new SubjectAccreditedImpl(account, ctxGC);
}
return null;
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class ConnectionIT method getConnectionCanBeExplicitlyClosed.
@Test
public void getConnectionCanBeExplicitlyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
final String query = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "let $conn := sql:get-connection(\"" + h2Database.getDriverClass().getName() + "\", \"" + h2Database.getUrl() + "\", \"" + h2Database.getUser() + "\", \"" + h2Database.getPassword() + "\")\n" + "return sql:close-connection($conn)";
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Source source = new StringSource(query);
try (final DBBroker broker = pool.getBroker();
final Txn transaction = pool.getTransactionManager().beginTransaction()) {
// execute query
final Tuple2<XQueryContext, Boolean> contextAndResult = withCompiledQuery(broker, source, compiledXQuery -> {
final Sequence result = executeQuery(broker, compiledXQuery);
return Tuple(compiledXQuery.getContext(), result.itemAt(0).toJavaObject(boolean.class));
});
// check that the handle for the sql connection was closed
assertTrue(contextAndResult._2);
// check the connections were closed
final int connectionsCount = ModuleUtils.readContextMap(contextAndResult._1, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
assertEquals(0, connectionsCount);
transaction.commit();
}
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class ImplicitConnectionCloseIT method getJndiConnectionIsAutomaticallyClosed.
@Test
public void getJndiConnectionIsAutomaticallyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
final String mainQuery = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "sql:get-jndi-connection(\"" + JNDI_DS_NAME + "\", \"" + STUB_JDBC_USER + "\", \"" + STUB_JDBC_PASSWORD + "\")";
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Source mainQuerySource = new StringSource(mainQuery);
try (final DBBroker broker = pool.getBroker();
final Txn transaction = pool.getTransactionManager().beginTransaction()) {
final XQueryContext escapedMainQueryContext = withCompiledQuery(broker, mainQuerySource, mainCompiledQuery -> {
final XQueryContext mainQueryContext = mainCompiledQuery.getContext();
// execute the query
final Sequence result = executeQuery(broker, mainCompiledQuery);
// check that the handle for the sql connection that was created was valid
assertEquals(1, result.getItemCount());
assertTrue(result.itemAt(0) instanceof IntegerValue);
assertEquals(Type.LONG, result.itemAt(0).getType());
final long connectionHandle = result.itemAt(0).toJavaObject(long.class);
assertFalse(connectionHandle == 0);
return mainQueryContext;
});
// check the connections map is empty
final int connectionsCount = ModuleUtils.readContextMap(escapedMainQueryContext, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
assertEquals(0, connectionsCount);
// check the connections from our StubDataSource, they should all be closed
final Deque<StubDataSource> createdDataSources = StubDataSourceFactory.CREATED_DATA_SOURCES;
assertEquals(1, createdDataSources.size());
final StubDataSource stubDataSource = createdDataSources.peek();
final Deque<StubConnection> createdConnections = stubDataSource.createdConnections;
assertEquals(1, createdConnections.size());
final StubConnection stubConnection = createdConnections.peek();
assertTrue(stubConnection.isClosed());
transaction.commit();
}
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class Deployment method checkUserSettings.
private void checkUserSettings(final DBBroker broker, final RequestedPerms requestedPerms) throws PackageException {
final org.exist.security.SecurityManager secman = broker.getBrokerPool().getSecurityManager();
try {
if (requestedPerms.group.filter(g -> !secman.hasGroup(g)).isPresent()) {
secman.addGroup(broker, new GroupAider(requestedPerms.group.get()));
}
if (!secman.hasAccount(requestedPerms.user)) {
final UserAider aider = new UserAider(requestedPerms.user);
aider.setPassword(requestedPerms.password);
requestedPerms.group.ifPresent(aider::addGroup);
secman.addAccount(broker, aider);
}
} catch (final PermissionDeniedException | EXistException e) {
throw new PackageException("Failed to create user: " + requestedPerms.user, e);
}
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class Deployment method deploy.
public Optional<String> deploy(final DBBroker broker, final Txn transaction, final String pkgName, final Optional<ExistRepository> repo, final String userTarget) throws PackageException, IOException {
final Optional<Path> maybePackageDir = getPackageDir(pkgName, repo);
if (!maybePackageDir.isPresent()) {
throw new PackageException("Package not found: " + pkgName);
}
final Path packageDir = maybePackageDir.get();
final DocumentImpl repoXML = getRepoXML(broker, packageDir);
if (repoXML == null) {
return Optional.empty();
}
try {
// if there's a <setup> element, run the query it points to
final Optional<ElementImpl> setup = findElement(repoXML, SETUP_ELEMENT);
final Optional<String> setupPath = setup.map(ElementImpl::getStringValue).filter(s -> !s.isEmpty());
if (setupPath.isPresent()) {
runQuery(broker, null, packageDir, setupPath.get(), pkgName, QueryPurpose.SETUP);
return Optional.empty();
} else {
// otherwise create the target collection
XmldbURI targetCollection = null;
if (userTarget != null) {
try {
targetCollection = XmldbURI.create(userTarget);
} catch (final IllegalArgumentException e) {
throw new PackageException("Bad collection URI: " + userTarget, e);
}
} else {
final Optional<ElementImpl> target = findElement(repoXML, TARGET_COLL_ELEMENT);
final Optional<String> targetPath = target.map(ElementImpl::getStringValue).filter(s -> !s.isEmpty());
if (targetPath.isPresent()) {
// determine target collection
try {
targetCollection = XmldbURI.create(getTargetCollection(broker, targetPath.get()));
} catch (final IllegalArgumentException e) {
throw new PackageException("Bad collection URI for <target> element: " + targetPath.get(), e);
}
} else {
LOG.warn("EXPath Package '{}' does not contain a <target> in its repo.xml, no files will be deployed to /apps", pkgName);
}
}
if (targetCollection == null) {
// no target means: package does not need to be deployed into database
// however, we need to preserve a copy for backup purposes
final Optional<Package> pkg = getPackage(pkgName, repo);
pkg.orElseThrow(() -> new XPathException("expath repository is not available so the package was not stored."));
final String pkgColl = pkg.get().getAbbrev() + "-" + pkg.get().getVersion();
targetCollection = XmldbURI.SYSTEM.append("repo/" + pkgColl);
}
// extract the permissions (if any)
final Optional<ElementImpl> permissions = findElement(repoXML, PERMISSIONS_ELEMENT);
final Optional<RequestedPerms> requestedPerms = permissions.flatMap(elem -> {
final Optional<Either<Integer, String>> perms = Optional.ofNullable(elem.getAttribute("mode")).flatMap(mode -> {
try {
return Optional.of(Either.Left(Integer.parseInt(mode, 8)));
} catch (final NumberFormatException e) {
if (mode.matches("^[rwx-]{9}")) {
return Optional.of(Either.Right(mode));
} else {
return Optional.empty();
}
}
});
return perms.map(p -> new RequestedPerms(elem.getAttribute("user"), elem.getAttribute("password"), Optional.ofNullable(elem.getAttribute("group")), p));
});
// check that if there were permissions then we were able to parse them, a failure would be related to the mode string
if (permissions.isPresent() && !requestedPerms.isPresent()) {
final String mode = permissions.map(elem -> elem.getAttribute("mode")).orElse(null);
throw new PackageException("Bad format for mode attribute in <permissions>: " + mode);
}
// run the pre-setup query if present
final Optional<ElementImpl> preSetup = findElement(repoXML, PRE_SETUP_ELEMENT);
final Optional<String> preSetupPath = preSetup.map(ElementImpl::getStringValue).filter(s -> !s.isEmpty());
if (preSetupPath.isPresent()) {
runQuery(broker, targetCollection, packageDir, preSetupPath.get(), pkgName, QueryPurpose.PREINSTALL);
}
// TODO: if the user already exists, check and ensure the user is assigned to the specified group
if (requestedPerms.isPresent()) {
checkUserSettings(broker, requestedPerms.get());
}
final InMemoryNodeSet resources = findElements(repoXML, RESOURCES_ELEMENT);
// store all package contents into database, using the user/group/mode in the permissions element. however:
// 1. repo.xml is excluded for now, since it may contain the default user's password in the clear
// 2. contents of directories identified in the path attribute of any <resource path=""/> element are stored as binary
final List<String> errors = scanDirectory(broker, transaction, packageDir, targetCollection, resources, true, false, requestedPerms);
// store repo.xml, filtering out the default user's password
storeRepoXML(broker, transaction, repoXML, targetCollection, requestedPerms);
// run the post-setup query if present
final Optional<ElementImpl> postSetup = findElement(repoXML, POST_SETUP_ELEMENT);
final Optional<String> postSetupPath = postSetup.map(ElementImpl::getStringValue).filter(s -> !s.isEmpty());
if (postSetupPath.isPresent()) {
runQuery(broker, targetCollection, packageDir, postSetupPath.get(), pkgName, QueryPurpose.POSTINSTALL);
}
if (!errors.isEmpty()) {
throw new PackageException("Deployment incomplete, " + errors.size() + " issues found: " + String.join("; ", errors));
}
return Optional.ofNullable(targetCollection.getCollectionPath());
}
} catch (final XPathException e) {
throw new PackageException("Error found while processing repo.xml: " + e.getMessage(), e);
}
}
Aggregations