Skip to content

Commit

Permalink
chore: refactor TD004 into multiple different plugins (#478)
Browse files Browse the repository at this point in the history
* chore: refactor TD004 into multiple different plugins. Now, we have
   * TD004 - Enabled + Enforce on SSLInfo
   * TD011 - IgnoreValidationErrors is not present or false
   * TD012 - exactly one SSLInfo element
   * TD013 - hygiene w.r.t. ClientAuthEnabled
   * TD014 - exactly one URL or LoadBalancer element
   * TD015 - check for MaxFailures when LoadBalancer is present

* add tests for all of the above plugins

* fixup EP002 test to account for new TD012 error
  • Loading branch information
DinoChiesa authored Oct 7, 2024
1 parent f77742d commit 4e64b92
Show file tree
Hide file tree
Showing 51 changed files with 1,936 additions and 784 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,18 @@ This is the current list:
|   |:white_check_mark:| TD001 | Mgmt Server as Target | Discourage calls to the Management Server from a Proxy via target. |
|   |:white_check_mark:| TD002 | Use Target Servers | Encourage the use of target servers. |
|   |:white_check_mark:| TD003 | TargetEndpoint name | TargetEndpoint name should match basename of filename. |
|   |:white_check_mark:| TD004 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection should enable TLS/SSL. |
|   |:white_check_mark:| TD004 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection should enable and Enforce TLS/SSL. |
|   |:white_check_mark:| TD005 | TargetEndpoint SSLInfo references | TargetEndpoint SSLInfo should use references for KeyStore and TrustStore. |
|   |:white_check_mark:| TD006 | TargetEndpoint SSLInfo | When using a LoadBalancer, the SSLInfo should not be configured under HTTPTargetConnection. |
|   |:white_check_mark:| TD007 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection SSLInfo should use TrustStore. |
|   |:white_check_mark:| TD008 | TargetEndpoint LoadBalancer Servers | LoadBalancer should not have multiple IsFallback Server entries. |
|   |:white_check_mark:| TD009 | TargetEndpoint LoadBalancer | TargetEndpoint HTTPTargetConnection should have at most one LoadBalancer. |
|   |:white_check_mark:| TD010 | TargetEndpoint LoadBalancer Servers | LoadBalancer should have at least one Server entry, and no duplicate Server entries. |
|   |:white_check_mark:| TD011 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection SSLInfo should not Ignore validation errors. |
|   |:white_check_mark:| TD012 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection should have exactly one SSLInfo. |
|   |:white_check_mark:| TD013 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection should correctly configure ClientAuthEnbled. |
|   |:white_check_mark:| TD014 | TargetEndpoint SSLInfo | TargetEndpoint HTTPTargetConnection should use exctly one of URL, LoadBalancer. |
|   |:white_check_mark:| TD015 | TargetEndpoint LoadBalancer | if TargetEndpoint HTTPTargetConnection uses a LoadBalancer, it should specify MaxFailures. |
| Flow |   |   |   |   |
|   |:white_check_mark:| FL001 | Unconditional Flows | Only one unconditional flow will get executed. Error if more than one was detected. |
| Step |   |   |   |   |
Expand Down
144 changes: 144 additions & 0 deletions lib/package/plugins/TD004-targetSslInfo-enabled-and-enforce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
Copyright 2019-2024 Google LLC
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
https://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.
*/

const ruleId = require("../myUtil.js").getRuleId();

const plugin = {
ruleId,
name: "TargetEndpoint HTTPTargetConnection SSLInfo should use Enabled and Enforce correctly",
message:
"TargetEndpoint HTTPTargetConnection SSLInfo should use Enabled and Enforce correctly.",
fatal: false,
severity: 1, // 1 = warn, 2 = error
nodeType: "Endpoint",
enabled: true
};

const path = require("path"),
util = require("util"),
debug = require("debug")("apigeelint:" + ruleId);

let bundleProfile = "apigee";
const onBundle = function (bundle, cb) {
if (bundle.profile) {
bundleProfile = bundle.profile;
}
if (typeof cb == "function") {
cb(null, false);
}
};

const onTargetEndpoint = function (endpoint, cb) {
const htc = endpoint.getHTTPTargetConnection(),
shortFilename = path.basename(endpoint.getFileName());
let flagged = false;

debug(`onTargetEndpoint shortfile(${shortFilename})`);
if (htc) {
try {
const loadBalancers = htc.select("LoadBalancer");
if (loadBalancers.length == 0) {
const messages = [];
const sslInfos = htc.select("SSLInfo");
if (sslInfos.length == 1) {
debug(`onTargetEndpoint sslInfos(${util.format(sslInfos)})`);
const urls = htc.select("URL");
if (urls.length >= 1) {
debug(`onTargetEndpoint url(${util.format(urls[0])})`);
const endpointUrl =
urls[0].childNodes &&
urls[0].childNodes[0] &&
urls[0].childNodes[0].nodeValue;
const isHttps = endpointUrl.startsWith("https://");
let elts = htc.select(`SSLInfo/Enabled`);
const enabled =
elts &&
elts[0] &&
elts[0].childNodes &&
elts[0].childNodes[0] &&
elts[0].childNodes[0].nodeValue == "true";
elts = htc.select(`SSLInfo/Enforce`);
const enforce =
elts &&
elts[0] &&
elts[0].childNodes &&
elts[0].childNodes[0] &&
elts[0].childNodes[0].nodeValue == "true";

if (isHttps) {
if (!enabled) {
messages.push(
"SSLInfo configuration does not use Enabled=true"
);
}

if (bundleProfile == "apigeex") {
if (!enforce) {
messages.push(
"SSLInfo configuration does not use Enforce=true"
);
}
} else {
if (enforce) {
messages.push(
"SSLInfo configuration must not use the Enforce element"
);
}
}
} else {
if (enabled) {
messages.push(
"SSLInfo configuration must not use the Enabled=true with insecure URL"
);
}
if (enforce) {
messages.push(
"SSLInfo configuration must not use the Enforce=true with insecure URL"
);
}
}
}
//debug(`onTargetEndpoint messages(${messages})`);
messages.forEach((message) => {
endpoint.addMessage({
plugin,
line: htc.getElement().lineNumber,
column: htc.getElement().columnNumber,
message
});
debug(`onTargetEndpoint set flagged`);
flagged = true;
});
}
}
} catch (exc1) {
console.error("exception: " + exc1);
debug(`onTargetEndpoint exc(${exc1})`);
debug(`${exc1.stack}`);
}
}

if (typeof cb == "function") {
debug(`onTargetEndpoint isFlagged(${flagged})`);
cb(null, flagged);
}
};

module.exports = {
plugin,
onBundle,
onTargetEndpoint
};
203 changes: 0 additions & 203 deletions lib/package/plugins/TD004-targetSslInfo.js

This file was deleted.

Loading

0 comments on commit 4e64b92

Please sign in to comment.