Skip to content

Commit

Permalink
more cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Klemm committed Sep 20, 2023
1 parent 1d0acb2 commit 072f211
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 54 deletions.
39 changes: 21 additions & 18 deletions esp/services/esdl_svc_engine/esdl_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,9 @@ void EsdlServiceImpl::configureTargets(IPropertyTree *cfg, const char *service)
continue;
GatewaysCacheEntry& gce = m_methodGatewaysCache[method];
std::set<std::string> uniqueNames;
bool updateInlines = gateways->getPropBool("@updateInlineUrls");
bool updateInlines = gateways->getPropBool("@updateInline");
bool doLegacyTransform = !isEmptyString(gateways->queryProp("@legacyTransformTarget"));
Secrets secrets;
TransactionSecrets secrets;
Owned<IPTreeIterator> gwIt(gateways->getElements("Gateway"));
ForEach(*gwIt)
{
Expand All @@ -774,10 +774,11 @@ void EsdlServiceImpl::configureTargets(IPropertyTree *cfg, const char *service)
if (strncmp(url, gwLocalSecretPrefix, gwLocalSecretPrefixLength) == 0)
{
handler.setown(createLocalSecretGateway(gw, name, url));
gce.targetContext[key].set(handler.get());
// sanity check that a secret is identified; the updater is not to be retained
GatewayUpdaters updaters;
Owned<IGatewayUpdater> updater(handler->getUpdater(updaters, secrets));
updater.clear();
gce.targetContext[key].set(handler.get());
}
else if (hasHttpPrefix(url))
{
Expand Down Expand Up @@ -1393,7 +1394,7 @@ EsdlServiceImpl::IUpdatableGateway* EsdlServiceImpl::createInlineGateway(const I
return new CLegacyUrlGateway(gw, gwName, gwUrl);
}

void EsdlServiceImpl::applyGatewayUpdates(IPTreeIterator& gwIt, const UpdatableGateways& updatables, GatewayUpdaters& updaters, Secrets& secrets) const
void EsdlServiceImpl::applyGatewayUpdates(IPTreeIterator& gwIt, const UpdatableGateways& updatables, GatewayUpdaters& updaters, TransactionSecrets& secrets) const
{
ForEach(gwIt)
{
Expand Down Expand Up @@ -1784,7 +1785,7 @@ void EsdlServiceImpl::prepareFinalRequest(IEspContext &context,
GatewaysCache::const_iterator mgcIt = m_methodGatewaysCache.find(mthName);
Owned<IPTreeIterator> gwIt;
GatewayUpdaters updaters;
Secrets secrets;
TransactionSecrets secrets;
if (tgtctx)
{
if (mgcIt != m_methodGatewaysCache.end() && !mgcIt->second.targetContext.empty())
Expand Down Expand Up @@ -1833,7 +1834,6 @@ void EsdlServiceImpl::prepareFinalRequest(IEspContext &context,
// Temporarily add the closing </soap:Envelope> tag so we have valid
// XML to transform the gateways
Owned<IPTree> soapTree = createPTreeFromXMLString(reqProcessed.append("</soap:Envelope>"), ipt_ordered);

xpath.replaceString("{$query}", tgtQueryName);
xpath.replaceString("{$method}", mthName);
xpath.replaceString("{$service}", srvdef.queryName());
Expand Down Expand Up @@ -1903,7 +1903,7 @@ EsdlServiceImpl::~EsdlServiceImpl()
}
}

IPTree* EsdlServiceImpl::Secrets::getVaultSecret(const char* category, const char* vaultId, const char* name)
IPTree* EsdlServiceImpl::TransactionSecrets::getVaultSecret(const char* category, const char* vaultId, const char* name)
{
Owned<IPTree> secret(lookup(category, vaultId, name));
if (!secret)
Expand All @@ -1915,7 +1915,7 @@ IPTree* EsdlServiceImpl::Secrets::getVaultSecret(const char* category, const cha
return secret.getClear();
}

IPTree* EsdlServiceImpl::Secrets::getSecret(const char* category, const char* name)
IPTree* EsdlServiceImpl::TransactionSecrets::getSecret(const char* category, const char* name)
{
Owned<IPTree> secret(lookup(category, "", name));
if (!secret)
Expand All @@ -1927,7 +1927,7 @@ IPTree* EsdlServiceImpl::Secrets::getSecret(const char* category, const char* na
return secret;
}

IPTree* EsdlServiceImpl::Secrets::lookup(const char* category, const char* vaultId, const char* name) const
IPTree* EsdlServiceImpl::TransactionSecrets::lookup(const char* category, const char* vaultId, const char* name) const
{
Key key = std::make_tuple<std::string, std::string, std::string>(category ? category : "", vaultId ? vaultId : "", name ? name : "");
Cache::const_iterator it = cache.find(key);
Expand All @@ -1936,13 +1936,13 @@ IPTree* EsdlServiceImpl::Secrets::lookup(const char* category, const char* vault
return nullptr;
}

void EsdlServiceImpl::Secrets::store(IPTree& secret, const char* category, const char* vaultId, const char* name)
void EsdlServiceImpl::TransactionSecrets::store(IPTree& secret, const char* category, const char* vaultId, const char* name)
{
Key key = std::make_tuple<std::string, std::string, std::string>(category ? category : "", vaultId ? vaultId : "", name ? name : "");
cache[key].set(&secret);
}

EsdlServiceImpl::IGatewayUpdater* EsdlServiceImpl::CUpdatableGateway::getUpdater(GatewayUpdaters& updaters, Secrets& secrets) const
EsdlServiceImpl::IGatewayUpdater* EsdlServiceImpl::CUpdatableGateway::getUpdater(GatewayUpdaters& updaters, TransactionSecrets& secrets) const
{
GatewayUpdaters::iterator it = updaters.find(updatersKey);
if (it != updaters.end())
Expand Down Expand Up @@ -1990,7 +1990,7 @@ bool EsdlServiceImpl::CUpdatableGateway::updateURLCredentials(StringBuffer& url,
return false;
}

EsdlServiceImpl::CLegacyUrlGateway* EsdlServiceImpl::CLegacyUrlGateway::getUpdater(Secrets&) const
EsdlServiceImpl::CLegacyUrlGateway* EsdlServiceImpl::CLegacyUrlGateway::getUpdater(TransactionSecrets&) const
{
return LINK(const_cast<CLegacyUrlGateway*>(this));
}
Expand Down Expand Up @@ -2024,7 +2024,7 @@ void EsdlServiceImpl::CLocalSecretGateway::CUpdater::updateGateway(IPTree& gw, c
entry->doUpdate(gw, *secret, requiredUsage);
}

EsdlServiceImpl::CLocalSecretGateway::CUpdater::CUpdater(const CLocalSecretGateway& _entry, Secrets& secrets)
EsdlServiceImpl::CLocalSecretGateway::CUpdater::CUpdater(const CLocalSecretGateway& _entry, TransactionSecrets& secrets)
{
entry.set(&_entry);
if (entry->vaultId.isEmpty())
Expand All @@ -2033,7 +2033,7 @@ EsdlServiceImpl::CLocalSecretGateway::CUpdater::CUpdater(const CLocalSecretGatew
secret.setown(secrets.getVaultSecret("esp", entry->vaultId.str(), entry->secretName));
}

EsdlServiceImpl::IGatewayUpdater* EsdlServiceImpl::CLocalSecretGateway::getUpdater(Secrets& secrets) const
EsdlServiceImpl::IGatewayUpdater* EsdlServiceImpl::CLocalSecretGateway::getUpdater(TransactionSecrets& secrets) const
{
return new CUpdater(*this, secrets);
}
Expand Down Expand Up @@ -2067,18 +2067,21 @@ EsdlServiceImpl::CLocalSecretGateway::CLocalSecretGateway(const IPTree& gw, cons
void EsdlServiceImpl::CLocalSecretGateway::doUpdate(IPTree& gw, const IPTree& secret, const char* requiredUsage) const
{
if (!isEmptyString(requiredUsage) && !secret.getPropBool(requiredUsage))
throw makeStringExceptionV(-1, "gateway %s: '%s' does not allow '%s' usage", updatersKey.c_str(), secretId.str(), requiredUsage);
throw makeStringExceptionV(-1, "gateway %s: secret '%s' does not allow '%s' usage", updatersKey.c_str(), secretId.str(), requiredUsage);
}

void EsdlServiceImpl::CHttpConnectGateway::doUpdate(IPTree& gw, const IPTree& secret, const char* requiredUsage) const
{
CLocalSecretGateway::doUpdate(gw, secret, requiredUsage);
StringBuffer url;
if (!secret.getProp("url", url.clear()) || url.isEmpty())
throw makeStringExceptionV(-1, "gateway %s: '%s' missing required 'url' property; credential-only secrets not supported", gw.queryProp("@name"), secretId.str());
throw makeStringExceptionV(-1, "gateway %s: secret '%s' missing required 'url' property; credential-only secrets not supported", gw.queryProp("@name"), secretId.str());
const char* username = secret.queryProp("username");
if (isEmptyString(username) && !secret.getPropBool("omitCredentials"))
throw makeStringExceptionV(-1, "gateway %s: '%s' missing expected 'username' property; set 'omitCredentials` property to 'true' if credentials are not required", gw.queryProp("@name"), secretId.str());
bool omitCredentials = secret.getPropBool("omitCredentials");
if (isEmptyString(username) && !omitCredentials)
throw makeStringExceptionV(-1, "gateway %s: secret '%s' missing expected 'username' property; set 'omitCredentials` property to 'true' if credentials are not required", gw.queryProp("@name"), secretId.str());
if (!isEmptyString(username) && omitCredentials)
throw makeStringExceptionV(-1, "gateway %s: secret '%s' contains 'username' and sets 'omitCredentials'", gw.queryProp("@name"), secretId.str());
const char* password = secret.queryProp("password");
if (isEmptyString(username) && password)
throw makeStringExceptionV(-1, "gateway %s: '%s' invalid use of password without username", gw.queryProp("@name"), secretId.str());
Expand Down
60 changes: 24 additions & 36 deletions esp/services/esdl_svc_engine/esdl_binding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* - Encapsulate non-jsecrets access to support non-standard secret sources, unless
* jsecrets is changed to provide this encapsulation.
*/
class Secrets
class TransactionSecrets
{
private:
using Key = std::tuple<std::string, std::string, std::string>;
Expand Down Expand Up @@ -142,7 +142,7 @@ class EsdlServiceImpl : public CInterface, implements IEspService
*/
interface IUpdatableGateway : public IInterface
{
virtual IGatewayUpdater* getUpdater(GatewayUpdaters& updaters, Secrets& secrets) const = 0;
virtual IGatewayUpdater* getUpdater(GatewayUpdaters& updaters, TransactionSecrets& secrets) const = 0;
};
using UpdatableGateways = std::map<std::string, Owned<IUpdatableGateway>>;

Expand All @@ -157,18 +157,18 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* - Insertion (or replacement) of user credentials in a URL string is available to any
* subclass that needs it..
*
* All extensions must implement `getUpdater(Secrets&)`. In some cases this may entail creation
* All extensions must implement `getUpdater(TransactionSecrets&)`. In some cases this may entail creation
* of a new updater instance. In other cases a single instance may be reused.
*/
class CUpdatableGateway : public CInterfaceOf<IUpdatableGateway>
{
public:
virtual IGatewayUpdater* getUpdater(GatewayUpdaters& updaters, Secrets& secrets) const override;
virtual IGatewayUpdater* getUpdater(GatewayUpdaters& updaters, TransactionSecrets& secrets) const override;
protected:
std::string updatersKey;
protected:
CUpdatableGateway(const char* gwName);
virtual IGatewayUpdater* getUpdater(Secrets& secrets) const = 0;
virtual IGatewayUpdater* getUpdater(TransactionSecrets& secrets) const = 0;
bool updateURLCredentials(StringBuffer& url, const char* username, const char* password) const;
};

Expand All @@ -181,11 +181,14 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* - If `Gateway/@username` is given, `Gateway/@password` may specify an exncrypted password
* value to be decrypted and embedded in an updated URL.
* - It is an error to specify `Gateway/@password` without `Gateway/@username`.
*
* Support is provided for backward compatibility. Use of these secrets is strongly discouraged
* and should be avoided whenever possible.
*/
class CLegacyUrlGateway : public CUpdatableGateway, public IGatewayUpdater
{
protected: // CUpdatableGateway
virtual CLegacyUrlGateway* getUpdater(Secrets&) const override;
virtual CLegacyUrlGateway* getUpdater(TransactionSecrets&) const override;
public: // IGatewayUpdater
virtual void updateGateway(IPTree& gw, const char*) override;
protected:
Expand All @@ -203,6 +206,9 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* - Defines a standard updater separating dynamically changing secrets from the configuration.
* - Enforces a requirement for a local secret to explicitly allow its data to be shared with
* a backend roxie service.
*
* Support is provided as an alternative to inline definitions when secret names cannot be
* passed to the target roxie for resolution. Use is discouraged unless it is unavoidable.
*/
class CLocalSecretGateway : public CUpdatableGateway
{
Expand All @@ -216,15 +222,15 @@ class EsdlServiceImpl : public CInterface, implements IEspService
Linked<const CLocalSecretGateway> entry;
Owned<IPTree> secret;
public:
CUpdater(const CLocalSecretGateway& _entry, Secrets& secrets);
CUpdater(const CLocalSecretGateway& _entry, TransactionSecrets& secrets);
};
protected: // CUpdatableGateway
virtual IGatewayUpdater* getUpdater(Secrets& secrets) const override;
virtual IGatewayUpdater* getUpdater(TransactionSecrets& secrets) const override;
protected:
StringBuffer secretId;
StringAttr vaultId;
StringBuffer secretName;
public:
protected:
CLocalSecretGateway(const IPTree& gw, const char* gwName, const char* gwUrl, const char* classPrefix);
protected:
virtual void doUpdate(IPTree& gw, const IPTree& secret, const char* requiredUsage) const;
Expand All @@ -241,6 +247,7 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* - A secret must define either a non-empty `username` property or set the `omitCredentials`
* property to true.
* - A secret may define a `password` property if `username` is also defined.
* - A secret must not define `username` and set `omitCredentials` to true.
* - A secret must not define a `password` property if `username` is not defined.
*/
class CHttpConnectGateway : public CLocalSecretGateway
Expand All @@ -257,12 +264,13 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* Gateway updates may occur in either or both of two locations within a backend
* service request. The storage layout must enable support for both locations.
*
* 1. The optional inclusion of a methods binding definition that does not exclude defined
* 1. The optional inclusion of a method's binding definition that does not exclude defined
* gateways, also known as the target context. Target context inclusion must update all
* gateways referring to local secrets. Target context inclusion must not, for backward
* compatibility, update any gateways referring to inline URLs.
* compatibility, update any inline gateways unless `Gateways/@updateInline` is true.
* 2. The optional request for "legacy gateway transformation". Legacy transformations must
* update all gateways referring to local secrets and inline URLs.
* update all local secret and inline gateways when `Gateways/@legacyTransformTarget` is
* not empty.
*/
struct GatewaysCacheEntry
{
Expand Down Expand Up @@ -409,29 +417,9 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* ESDL script entry point transforms, if any exist.
*
* Initial request construction of all backend requests wraps the given request content in a
* SOAP envelope and SOAP body. For published requests, where `isroxie` is true, special
* handling for gateways is provided:
*
* - For `Gateways/Gateway` elements found in `tgtctx`:
* - Elements with local secret references are updated to replace `@url` with secret-
* defined data.
* - Elements with inline URL data are updated to insert user credentials into the URL, but
* only if `Gateways/@updateInlineUrls` is true.
* - For `Gateways/Gateway1 elements found in `tgtctx` when `Gateways/@legacyTransformTarget`
* is not empty:
* - Elements with local secret references are updated to replace `@url` with secret-
* defined data.
* - Elements with inline URL data are updated to insert user credentials into the URL.
* - `<Gateways><Gateway name="foo" url="bar"/></Gateways>` becomes
* `<gateways><row ServiceName="foo" URL="bar"/></gateways>`, with `Gateways/@legacyRowName`
* allowing an alternate name for element `row`.
* - The new `gateways` element is placed in the request at the location referred to by
* `Gateways/@legacyTransformTarget`. This XPath supports multiple variable substitutions
* such as:
* - {$query} becomes the value of `Method/@queryname`
* - {$method} becomes the ESDL definition's method name
* - {$service} becomes the ESDL definition's service name
* - {$request} becomes the ESDL definition's method request type
* SOAP envelope and SOAP body. For published requests, where `isroxie` is true, updatable
* gateways are updated prior to inclusion with the `tgtctx` configuration and as part of
* legacy gateway transformations.
*
* Support for inline URLs in the target configuration, and context which is a subset of the
* configuration, is provided for backward compatibility. Use is strongly discouraged.
Expand Down Expand Up @@ -501,7 +489,7 @@ class EsdlServiceImpl : public CInterface, implements IEspService
* @param updaters cache of updaters used in the current transaction
* @param secrets cache of secrets used in the current transaction
*/
void applyGatewayUpdates(IPTreeIterator& gwIt, const UpdatableGateways& updatables, GatewayUpdaters& updaters, Secrets& secrets) const;
void applyGatewayUpdates(IPTreeIterator& gwIt, const UpdatableGateways& updatables, GatewayUpdaters& updaters, TransactionSecrets& secrets) const;

/**
* @brief Implementation of legacy gateway transformation invoked only during preparation of
Expand Down

0 comments on commit 072f211

Please sign in to comment.