diff --git a/appsec/src/extension/ddappsec.c b/appsec/src/extension/ddappsec.c index 2eee26928f..9d78e32ddf 100644 --- a/appsec/src/extension/ddappsec.c +++ b/appsec/src/extension/ddappsec.c @@ -456,6 +456,50 @@ static PHP_FUNCTION(datadog_appsec_testing_request_exec) RETURN_TRUE; } +static PHP_FUNCTION(datadog_appsec_push_address) +{ + UNUSED(return_value); + if (!DDAPPSEC_G(active)) { + mlog(dd_log_debug, "Trying to access to push_address " + "function while appsec is disabled"); + return; + } + + zend_string *key = NULL; + zval *value = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &key, &value) == FAILURE) { + RETURN_FALSE; + } + + zval parameters_zv; + zend_array *parameters_arr = zend_new_array(1); + ZVAL_ARR(¶meters_zv, parameters_arr); + zend_hash_add(Z_ARRVAL(parameters_zv), key, value); + Z_TRY_ADDREF_P(value); + + dd_conn *conn = dd_helper_mgr_cur_conn(); + if (conn == NULL) { + zval_ptr_dtor(¶meters_zv); + mlog_g(dd_log_debug, "No connection; skipping push_address"); + return; + } + + dd_result res = dd_request_exec(conn, ¶meters_zv); + zval_ptr_dtor(¶meters_zv); + + if (dd_req_is_user_req()) { + if (res == dd_should_block || res == dd_should_redirect) { + dd_req_call_blocking_function(res); + } + } else { + if (res == dd_should_block) { + dd_request_abort_static_page(); + } else if (res == dd_should_redirect) { + dd_request_abort_redirect(); + } + } +} + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX( void_ret_bool_arginfo, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -464,9 +508,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(request_exec_arginfo, 0, 1, _IS_BOOL, 0) ZEND_ARG_INFO(0, "data") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(push_address_arginfo, 0, 0, IS_VOID, 1) +ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + // clang-format off static const zend_function_entry functions[] = { ZEND_RAW_FENTRY(DD_APPSEC_NS "is_enabled", PHP_FN(datadog_appsec_is_enabled), void_ret_bool_arginfo, 0) + ZEND_RAW_FENTRY(DD_APPSEC_NS "push_address", PHP_FN(datadog_appsec_push_address), push_address_arginfo, 0) PHP_FE_END }; static const zend_function_entry testing_functions[] = { diff --git a/appsec/tests/extension/inc/mock_helper.php b/appsec/tests/extension/inc/mock_helper.php index 888fb521da..54bd7a3d9e 100644 --- a/appsec/tests/extension/inc/mock_helper.php +++ b/appsec/tests/extension/inc/mock_helper.php @@ -152,6 +152,16 @@ function print_commands($sort = true) { print_r($commands); } + function get_command($command) { + $commands = $this->get_commands(); + foreach($commands as $c) { + if ($c[0] == $command) { + return $c; + } + } + return []; + } + static function ksort_recurse(&$arr) { if (!is_array($arr)) { return; diff --git a/appsec/tests/extension/push_params_block.phpt b/appsec/tests/extension/push_params_block.phpt new file mode 100644 index 0000000000..99d97f02e2 --- /dev/null +++ b/appsec/tests/extension/push_params_block.phpt @@ -0,0 +1,29 @@ +--TEST-- +Push address gets blocked +--INI-- +extension=ddtrace.so +datadog.appsec.enabled=1 +--FILE-- + '404', 'type' => 'json'], ['{"found":"attack"}','{"another":"attack"}']])), +]); + +rinit(); +push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]); + +var_dump("THIS SHOULD NOT GET IN THE OUTPUT"); + +?> +--EXPECTHEADERS-- +Status: 404 Not Found +Content-type: application/json +--EXPECTF-- +{"errors": [{"title": "You've been blocked", "detail": "Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]} +Warning: datadog\appsec\push_address(): Datadog blocked the request and presented a static error page in %s on line %d diff --git a/appsec/tests/extension/push_params_ok_01.phpt b/appsec/tests/extension/push_params_ok_01.phpt new file mode 100644 index 0000000000..1c8054cd28 --- /dev/null +++ b/appsec/tests/extension/push_params_ok_01.phpt @@ -0,0 +1,45 @@ +--TEST-- +Push address are sent on request_exec - array +--INI-- +extension=ddtrace.so +datadog.appsec.enabled=1 +--FILE-- + "params", "more" => "parameters"]); +var_dump(rshutdown()); + +var_dump($helper->get_command("request_exec")); + +?> +--EXPECTF-- +bool(true) +bool(true) +array(2) { + [0]=> + string(12) "request_exec" + [1]=> + array(1) { + [0]=> + array(1) { + ["server.request.path_params"]=> + array(2) { + ["some"]=> + string(6) "params" + ["more"]=> + string(10) "parameters" + } + } + } +} diff --git a/appsec/tests/extension/push_params_ok_02.phpt b/appsec/tests/extension/push_params_ok_02.phpt new file mode 100644 index 0000000000..c10f1fd53f --- /dev/null +++ b/appsec/tests/extension/push_params_ok_02.phpt @@ -0,0 +1,40 @@ +--TEST-- +Push address are sent on request_exec - string +--INI-- +extension=ddtrace.so +datadog.appsec.enabled=1 +--FILE-- +get_command("request_exec")); + +?> +--EXPECTF-- +bool(true) +bool(true) +array(2) { + [0]=> + string(12) "request_exec" + [1]=> + array(1) { + [0]=> + array(1) { + ["server.request.path_params"]=> + string(11) "some string" + } + } +} diff --git a/appsec/tests/extension/push_params_ok_03.phpt b/appsec/tests/extension/push_params_ok_03.phpt new file mode 100644 index 0000000000..32031dc5d2 --- /dev/null +++ b/appsec/tests/extension/push_params_ok_03.phpt @@ -0,0 +1,40 @@ +--TEST-- +Push address are sent on request_exec - integer +--INI-- +extension=ddtrace.so +datadog.appsec.enabled=1 +--FILE-- +get_command("request_exec")); + +?> +--EXPECTF-- +bool(true) +bool(true) +array(2) { + [0]=> + string(12) "request_exec" + [1]=> + array(1) { + [0]=> + array(1) { + ["server.request.path_params"]=> + int(1234) + } + } +} diff --git a/appsec/tests/extension/push_params_redirect.phpt b/appsec/tests/extension/push_params_redirect.phpt new file mode 100644 index 0000000000..1550c4f1fc --- /dev/null +++ b/appsec/tests/extension/push_params_redirect.phpt @@ -0,0 +1,28 @@ +--TEST-- +Push address gets blocked +--INI-- +extension=ddtrace.so +datadog.appsec.enabled=1 +--FILE-- + '303', 'location' => 'https://datadoghq.com'], []])), +]); + +rinit(); +push_address("server.request.path_params", ["some" => "params", "more" => "parameters"]); + +var_dump("THIS SHOULD NOT GET IN THE OUTPUT"); + +?> +--EXPECTHEADERS-- +Status: 303 See Other +Content-type: text/html; charset=UTF-8 +--EXPECTF-- +Warning: datadog\appsec\push_address(): Datadog blocked the request and attempted a redirection to https://datadoghq.com in %s on line %d diff --git a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Laravel8xTests.groovy b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Laravel8xTests.groovy index 14bbfd5f07..381a0d793c 100644 --- a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Laravel8xTests.groovy +++ b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Laravel8xTests.groovy @@ -10,10 +10,12 @@ import org.junit.jupiter.api.condition.EnabledIf import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers +import java.net.http.HttpRequest import java.net.http.HttpResponse import static com.datadog.appsec.php.integration.TestParams.getPhpVersion import static com.datadog.appsec.php.integration.TestParams.getVariant +import static java.net.http.HttpResponse.BodyHandlers.ofString @Testcontainers @EnabledIf('isExpectedVersion') @@ -69,7 +71,6 @@ class Laravel8xTests { assert span.metrics._sampling_priority_v1 == 2.0d } - @Test void 'Sign up automated event'() { def trace = container.traceFromRequest( @@ -84,4 +85,20 @@ class Laravel8xTests { assert span.meta."appsec.events.users.signup.track" == "true" assert span.metrics._sampling_priority_v1 == 2.0d } + + @Test + void 'test path params'() { + // Set ip which is blocked + HttpRequest req = container.buildReq('/dynamic-path/someValue').GET().build() + def trace = container.traceFromRequest(req, ofString()) { HttpResponse re -> + assert re.statusCode() == 403 + assert re.body().contains('blocked') + } + + Span span = trace.first() + assert span.metrics."_dd.appsec.enabled" == 1.0d + assert span.metrics."_dd.appsec.waf.duration" > 0.0d + assert span.meta."_dd.appsec.event_rules.version" != '' + assert span.meta."appsec.blocked" == "true" + } } diff --git a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Symfony62Tests.groovy b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Symfony62Tests.groovy index c5ac1f6dca..27f77c8c72 100644 --- a/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Symfony62Tests.groovy +++ b/appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Symfony62Tests.groovy @@ -88,4 +88,19 @@ class Symfony62Tests { assert span.meta."appsec.events.users.signup.track" == "true" assert span.metrics._sampling_priority_v1 == 2.0d } + + @Test + void 'test path params'() { + HttpRequest req = container.buildReq('/dynamic-path/someValue').GET().build() + def trace = container.traceFromRequest(req, ofString()) { HttpResponse re -> + assert re.statusCode() == 403 + assert re.body().contains('blocked') + } + + Span span = trace.first() + assert span.metrics."_dd.appsec.enabled" == 1.0d + assert span.metrics."_dd.appsec.waf.duration" > 0.0d + assert span.meta."_dd.appsec.event_rules.version" != '' + assert span.meta."appsec.blocked" == "true" + } } diff --git a/appsec/tests/integration/src/test/waf/recommended.json b/appsec/tests/integration/src/test/waf/recommended.json index d7d96b1f06..e4ff0748ce 100644 --- a/appsec/tests/integration/src/test/waf/recommended.json +++ b/appsec/tests/integration/src/test/waf/recommended.json @@ -3849,6 +3849,35 @@ ], "transformers": [] }, + { + "id": "path-params-tests", + "name": "Rule for testing path params", + "tags": { + "type": "block_params", + "category": "security_response" + }, + "conditions": [ + { + "parameters": { + "inputs": [ + { + "address": "server.request.path_params" + } + ], + "list": [ + "param01" + ] + }, + "operator": "phrase_match" + } + ], + "transformers": [ + "keys_only" + ], + "on_match": [ + "block" + ] + }, { "id": "crs-942-290", "name": "Finds basic MongoDB SQL injection attempts", diff --git a/appsec/tests/integration/src/test/www/laravel8x/app/Http/Controllers/MiscController.php b/appsec/tests/integration/src/test/www/laravel8x/app/Http/Controllers/MiscController.php new file mode 100644 index 0000000000..8dd1831efa --- /dev/null +++ b/appsec/tests/integration/src/test/www/laravel8x/app/Http/Controllers/MiscController.php @@ -0,0 +1,13 @@ +meta[Tag::HTTP_ROUTE] = $route->uri(); } + if (\method_exists($route, 'parameters') && function_exists('\datadog\appsec\push_address')) { + $parameters = $route->parameters(); + if (count($parameters) > 0) { + \datadog\appsec\push_address("server.request.path_params", $parameters); + } + } $rootSpan->meta[Tag::HTTP_METHOD] = $request->method(); $rootSpan->meta[Tag::SPAN_KIND] = 'server'; } diff --git a/src/Integrations/Integrations/Symfony/SymfonyIntegration.php b/src/Integrations/Integrations/Symfony/SymfonyIntegration.php index 9743f75589..05a3902532 100644 --- a/src/Integrations/Integrations/Symfony/SymfonyIntegration.php +++ b/src/Integrations/Integrations/Symfony/SymfonyIntegration.php @@ -393,6 +393,13 @@ function (SpanData $span, $args, $response) use ($integration) { $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $response->getStatusCode(); } + $parameters = $request->get('_route_params'); + if (!empty($parameters) && + is_array($parameters) && + function_exists('\datadog\appsec\push_address')) { + \datadog\appsec\push_address("server.request.path_params", $parameters); + } + $route = $request->get('_route'); if (null !== $route && null !== $request) { if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { diff --git a/src/Integrations/Integrations/WordPress/WordPressIntegration.php b/src/Integrations/Integrations/WordPress/WordPressIntegration.php index 2acc974f00..910a90ead0 100644 --- a/src/Integrations/Integrations/WordPress/WordPressIntegration.php +++ b/src/Integrations/Integrations/WordPress/WordPressIntegration.php @@ -70,6 +70,19 @@ public function init() return true; }); + \DDTrace\hook_method('WP', 'main', null, function ($This, $scope, $args) { + if (\property_exists($This, 'did_permalink') && $This->did_permalink === true) { + if (function_exists('\datadog\appsec\push_address') && + \property_exists($This, 'query_vars') && + function_exists('is_404') && is_404() === false) { + $parameters = $This->query_vars; + if (count($parameters) > 0) { + \datadog\appsec\push_address("server.request.path_params", $parameters); + } + } + } + }); + \DDTrace\hook_function( 'wp_authenticate', null, diff --git a/tests/Appsec/Mock.php b/tests/Appsec/Mock.php index 43483fb56b..a9c30dbfb1 100644 --- a/tests/Appsec/Mock.php +++ b/tests/Appsec/Mock.php @@ -24,6 +24,16 @@ protected function getDbPdo() return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); } + /** + * Not all test are interested on events but frameworks are instrumented so this check is to avoid errors + */ + private function initiated() + { + return $this->getDbPdo() + ->query("SELECT * FROM information_schema.tables WHERE table_name = 'appsec_events'") + ->rowCount() > 0; + } + public function init() { $this->getDbPdo()->exec("CREATE TABLE IF NOT EXISTS appsec_events (event varchar(1000))"); @@ -37,12 +47,18 @@ public function destroy() public function setDefaults() { + if (!$this->initiated()) { + return; + } $this->getDbPdo()->exec("DELETE FROM appsec_events"); - } public function addEvent(array $event, $eventName) { + if (!$this->initiated()) { + return; + } + $event['eventName'] = $eventName; $this->getDbPdo()->exec(sprintf("INSERT INTO appsec_events VALUES ('%s')", json_encode($event))); } @@ -51,6 +67,10 @@ public function getEvents() { $result = []; + if (!$this->initiated()) { + return $result; + } + $events = $this->getDbPdo()->query("SELECT * FROM appsec_events")->fetchAll(); foreach ($events as $event) { @@ -62,11 +82,20 @@ public function getEvents() } } +if (!function_exists('datadog\appsec\appsecMockEnabled')) { + function appsecMockEnabled() { + return getenv('APPSEC_MOCK_ENABLED') === "true"; + } +} + if (!function_exists('datadog\appsec\track_user_login_success_event')) { /** * This function is exposed by appsec but here we are mocking it for tests */ function track_user_login_success_event($userId, $metadata, $automated) { + if(!appsecMockEnabled()) { + return; + } $event = [ 'userId' => $userId, 'metadata' => $metadata, @@ -82,6 +111,9 @@ function track_user_login_success_event($userId, $metadata, $automated) { * This function is exposed by appsec but here we are mocking it for tests */ function track_user_login_failure_event($userId, $exists, $metadata, $automated) { + if(!appsecMockEnabled()) { + return; + } $event = [ 'userId' => $userId, 'exists' => $exists, @@ -98,6 +130,9 @@ function track_user_login_failure_event($userId, $exists, $metadata, $automated) * This function is exposed by appsec but here we are mocking it for tests */ function track_user_signup_event($userId, $metadata, $automated) { + if(!appsecMockEnabled()) { + return; + } $event = [ 'userId' => $userId, 'metadata' => $metadata, @@ -107,3 +142,16 @@ function track_user_signup_event($userId, $metadata, $automated) { AppsecStatus::getInstance()->addEvent($event, 'track_user_signup_event'); } } + +if (!function_exists('datadog\appsec\push_address')) { + /** + * This function is exposed by appsec but here we are mocking it for tests + * @param array $params + */ + function push_address($key, $value) { + if(!appsecMockEnabled()) { + return; + } + AppsecStatus::getInstance()->addEvent([$key => $value], 'push_address'); + } +} \ No newline at end of file diff --git a/tests/Common/AppsecTestCase.php b/tests/Common/AppsecTestCase.php new file mode 100644 index 0000000000..fb9074c5dc --- /dev/null +++ b/tests/Common/AppsecTestCase.php @@ -0,0 +1,52 @@ + true + ]); + } + + protected function connection() + { + return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); + } + + protected function databaseDump() + { + return ""; + } + + protected function ddSetUp() + { + parent::ddSetUp(); + $dump = $this->databaseDump(); + if (!empty($dump)) { + $this->connection()->exec($dump); + } + AppsecStatus::getInstance()->setDefaults(); + } + + public static function ddSetUpBeforeClass() + { + parent::ddSetUpBeforeClass(); + AppsecStatus::getInstance()->init(); + } + + public static function ddTearDownAfterClass() + { + AppsecStatus::getInstance()->destroy(); + parent::ddTearDownAfterClass(); + } + +} diff --git a/tests/Frameworks/Symfony/Version_3_3/src/AppBundle/Controller/CommonScenariosController.php b/tests/Frameworks/Symfony/Version_3_3/src/AppBundle/Controller/CommonScenariosController.php index 010a3535fe..5e0e071b19 100644 --- a/tests/Frameworks/Symfony/Version_3_3/src/AppBundle/Controller/CommonScenariosController.php +++ b/tests/Frameworks/Symfony/Version_3_3/src/AppBundle/Controller/CommonScenariosController.php @@ -31,6 +31,16 @@ public function simpleViewAction(Request $request) ]); } + /** + * @Route("/dynamic_route/{param01}/{param02}", name="dynamic route with optionals") + */ + public function dynamicWithOptionalsAction($param01, $param02) + { + return new Response( + 'Hi!' + ); + } + /** * @Route("/error", name="error") * @throws \Exception diff --git a/tests/Frameworks/Symfony/Version_4_4/src/Controller/CommonScenariosController.php b/tests/Frameworks/Symfony/Version_4_4/src/Controller/CommonScenariosController.php index deaa784d41..2003e5f9b3 100644 --- a/tests/Frameworks/Symfony/Version_4_4/src/Controller/CommonScenariosController.php +++ b/tests/Frameworks/Symfony/Version_4_4/src/Controller/CommonScenariosController.php @@ -31,6 +31,16 @@ public function simpleViewAction(Request $request) ]); } + /** + * @Route("/dynamic_route/{param01}/{param02?}", name="dynamic route with optionals") + */ + public function dynamicWithOptionalsAction($param01, $param02) + { + return new Response( + 'Hi!' + ); + } + /** * @Route("/error", name="error") * @throws \Exception diff --git a/tests/Frameworks/Symfony/Version_5_2/src/Controller/CommonScenariosController.php b/tests/Frameworks/Symfony/Version_5_2/src/Controller/CommonScenariosController.php index b922e2bdba..ec2777c2e4 100644 --- a/tests/Frameworks/Symfony/Version_5_2/src/Controller/CommonScenariosController.php +++ b/tests/Frameworks/Symfony/Version_5_2/src/Controller/CommonScenariosController.php @@ -32,6 +32,16 @@ public function simpleViewAction(Request $request) ]); } + /** + * @Route("/dynamic_route/{param01}/{param02?}", name="dynamic route with optionals") + */ + public function dynamicWithOptionalsAction($param01, $param02) + { + return new Response( + 'Hi!' + ); + } + /** * @Route("/error", name="error") * @throws \Exception diff --git a/tests/Frameworks/Symfony/Version_6_2/src/Controller/CommonScenariosController.php b/tests/Frameworks/Symfony/Version_6_2/src/Controller/CommonScenariosController.php index b922e2bdba..ec2777c2e4 100644 --- a/tests/Frameworks/Symfony/Version_6_2/src/Controller/CommonScenariosController.php +++ b/tests/Frameworks/Symfony/Version_6_2/src/Controller/CommonScenariosController.php @@ -32,6 +32,16 @@ public function simpleViewAction(Request $request) ]); } + /** + * @Route("/dynamic_route/{param01}/{param02?}", name="dynamic route with optionals") + */ + public function dynamicWithOptionalsAction($param01, $param02) + { + return new Response( + 'Hi!' + ); + } + /** * @Route("/error", name="error") * @throws \Exception diff --git a/tests/Frameworks/WordPress/Version_4_8/wp-config.php b/tests/Frameworks/WordPress/Version_4_8/wp-config.php index c46c830008..b8f0eed437 100644 --- a/tests/Frameworks/WordPress/Version_4_8/wp-config.php +++ b/tests/Frameworks/WordPress/Version_4_8/wp-config.php @@ -89,5 +89,8 @@ if ( !defined('ABSPATH') ) define('ABSPATH', dirname(__FILE__) . '/'); +//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec + require __DIR__.'/../../../Appsec/Mock.php'; + /** Sets up WordPress vars and included files. */ require_once(ABSPATH . 'wp-settings.php'); diff --git a/tests/Frameworks/WordPress/Version_4_8/wp-login.php b/tests/Frameworks/WordPress/Version_4_8/wp-login.php index 4e9fd8f45c..38db325473 100644 --- a/tests/Frameworks/WordPress/Version_4_8/wp-login.php +++ b/tests/Frameworks/WordPress/Version_4_8/wp-login.php @@ -11,9 +11,6 @@ /** Make sure that the WordPress bootstrap has run before continuing. */ require( dirname(__FILE__) . '/wp-load.php' ); -//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec - require __DIR__.'/../../../Appsec/Mock.php'; - // Redirect to https login if forced to use SSL if ( force_ssl_admin() && ! is_ssl() ) { if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { diff --git a/tests/Frameworks/WordPress/Version_5_5/wp-config.php b/tests/Frameworks/WordPress/Version_5_5/wp-config.php index 752728c7e1..dd44e66a6d 100644 --- a/tests/Frameworks/WordPress/Version_5_5/wp-config.php +++ b/tests/Frameworks/WordPress/Version_5_5/wp-config.php @@ -88,5 +88,8 @@ define( 'ABSPATH', __DIR__ . '/' ); } +//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec + require __DIR__.'/../../../Appsec/Mock.php'; + /** Sets up WordPress vars and included files. */ require_once ABSPATH . 'wp-settings.php'; diff --git a/tests/Frameworks/WordPress/Version_5_5/wp-login.php b/tests/Frameworks/WordPress/Version_5_5/wp-login.php index f20df3f1dd..320ea909b5 100644 --- a/tests/Frameworks/WordPress/Version_5_5/wp-login.php +++ b/tests/Frameworks/WordPress/Version_5_5/wp-login.php @@ -11,9 +11,6 @@ /** Make sure that the WordPress bootstrap has run before continuing. */ require __DIR__ . '/wp-load.php'; -//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec - require __DIR__.'/../../../Appsec/Mock.php'; - // Redirect to HTTPS login if forced to use SSL. if ( force_ssl_admin() && ! is_ssl() ) { if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { diff --git a/tests/Frameworks/WordPress/Version_5_9/wp-config.php b/tests/Frameworks/WordPress/Version_5_9/wp-config.php index aa80508145..caaa747600 100644 --- a/tests/Frameworks/WordPress/Version_5_9/wp-config.php +++ b/tests/Frameworks/WordPress/Version_5_9/wp-config.php @@ -94,5 +94,8 @@ define( 'ABSPATH', __DIR__ . '/' ); } +//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec +require __DIR__.'/../../../Appsec/Mock.php'; + /** Sets up WordPress vars and included files. */ require_once ABSPATH . 'wp-settings.php'; diff --git a/tests/Frameworks/WordPress/Version_5_9/wp-login.php b/tests/Frameworks/WordPress/Version_5_9/wp-login.php index db228def12..d05df01692 100644 --- a/tests/Frameworks/WordPress/Version_5_9/wp-login.php +++ b/tests/Frameworks/WordPress/Version_5_9/wp-login.php @@ -11,9 +11,6 @@ /** Make sure that the WordPress bootstrap has run before continuing. */ require __DIR__ . '/wp-load.php'; -//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec - require __DIR__.'/../../../Appsec/Mock.php'; - // Redirect to HTTPS login if forced to use SSL. if ( force_ssl_admin() && ! is_ssl() ) { if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { diff --git a/tests/Frameworks/WordPress/Version_6_1/wp-config.php b/tests/Frameworks/WordPress/Version_6_1/wp-config.php index 10f33b918f..75772b2dbd 100644 --- a/tests/Frameworks/WordPress/Version_6_1/wp-config.php +++ b/tests/Frameworks/WordPress/Version_6_1/wp-config.php @@ -96,3 +96,6 @@ /** Sets up WordPress vars and included files. */ require_once ABSPATH . 'wp-settings.php'; + +//Appsec mock. This wont be needed on customer apps since this functions will be exposed by appsec +require __DIR__.'/../../../Appsec/Mock.php'; diff --git a/tests/Integrations/Laravel/V4/AutomatedLoginEventsTest.php b/tests/Integrations/Laravel/V4/AutomatedLoginEventsTest.php index e187a4b5cf..23a172bacf 100644 --- a/tests/Integrations/Laravel/V4/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Laravel/V4/AutomatedLoginEventsTest.php @@ -2,28 +2,20 @@ namespace DDTrace\Tests\Integrations\Laravel\V4; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Laravel/Version_4_2/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -31,12 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - protected function login($email) { $this->call( diff --git a/tests/Integrations/Laravel/V4/PathParamsTest.php b/tests/Integrations/Laravel/V4/PathParamsTest.php new file mode 100644 index 0000000000..a523775db4 --- /dev/null +++ b/tests/Integrations/Laravel/V4/PathParamsTest.php @@ -0,0 +1,54 @@ +call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static/$param02") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalParametersNotGiven() + { + $param01 = 'first_param'; + $this->call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertCount(1, $events[0]["server.request.path_params"]); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testStaticRouteDoesNotGenerateEvent() + { + $this->call( + GetSpec::create('Call to static route', "/simple") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Laravel/V5_7/AutomatedLoginEventsTest.php b/tests/Integrations/Laravel/V5_7/AutomatedLoginEventsTest.php index 1d53b95204..4db962f96a 100644 --- a/tests/Integrations/Laravel/V5_7/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Laravel/V5_7/AutomatedLoginEventsTest.php @@ -2,28 +2,20 @@ namespace DDTrace\Tests\Integrations\Laravel\V5_7; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Laravel/Version_5_7/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -31,12 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - protected function login($email) { $this->call( diff --git a/tests/Integrations/Laravel/V5_7/PathParamsTest.php b/tests/Integrations/Laravel/V5_7/PathParamsTest.php new file mode 100644 index 0000000000..feeeb8e09f --- /dev/null +++ b/tests/Integrations/Laravel/V5_7/PathParamsTest.php @@ -0,0 +1,54 @@ +call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static/$param02") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalParametersNotGiven() + { + $param01 = 'first_param'; + $this->call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertCount(1, $events[0]["server.request.path_params"]); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testStaticRouteDoesNotGenerateEvent() + { + $this->call( + GetSpec::create('Call to static route', "/simple") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Laravel/V5_8/AutomatedLoginEventsTest.php b/tests/Integrations/Laravel/V5_8/AutomatedLoginEventsTest.php index 8b5c3c4662..b3ebeca782 100644 --- a/tests/Integrations/Laravel/V5_8/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Laravel/V5_8/AutomatedLoginEventsTest.php @@ -2,28 +2,20 @@ namespace DDTrace\Tests\Integrations\Laravel\V5_8; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Laravel/Version_5_8/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -31,12 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - protected function login($email) { $this->call( diff --git a/tests/Integrations/Laravel/V5_8/PathParamsTest.php b/tests/Integrations/Laravel/V5_8/PathParamsTest.php new file mode 100644 index 0000000000..b9ff545ff9 --- /dev/null +++ b/tests/Integrations/Laravel/V5_8/PathParamsTest.php @@ -0,0 +1,54 @@ +call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static/$param02") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalParametersNotGiven() + { + $param01 = 'first_param'; + $this->call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertCount(1, $events[0]["server.request.path_params"]); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testStaticRouteDoesNotGenerateEvent() + { + $this->call( + GetSpec::create('Call to static route', "/simple") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Laravel/V8_x/AutomatedLoginEventsTest.php b/tests/Integrations/Laravel/V8_x/AutomatedLoginEventsTest.php index e87be3a6b1..28fcaae345 100644 --- a/tests/Integrations/Laravel/V8_x/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Laravel/V8_x/AutomatedLoginEventsTest.php @@ -2,28 +2,20 @@ namespace DDTrace\Tests\Integrations\Laravel\V8_x; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Laravel/Version_8_x/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -31,12 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - protected function login($email) { $this->call( diff --git a/tests/Integrations/Laravel/V8_x/PathParamsTest.php b/tests/Integrations/Laravel/V8_x/PathParamsTest.php new file mode 100644 index 0000000000..97f2f4131b --- /dev/null +++ b/tests/Integrations/Laravel/V8_x/PathParamsTest.php @@ -0,0 +1,54 @@ +call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static/$param02") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalParametersNotGiven() + { + $param01 = 'first_param'; + $this->call( + GetSpec::create('Call to dynamic route', "/dynamic_route/$param01/static") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertCount(1, $events[0]["server.request.path_params"]); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testStaticRouteDoesNotGenerateEvent() + { + $this->call( + GetSpec::create('Call to static route', "/simple") + ); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Symfony/V3_3/AutomatedLoginEventsTest.php b/tests/Integrations/Symfony/V3_3/AutomatedLoginEventsTest.php index 0938700f3b..205a674648 100644 --- a/tests/Integrations/Symfony/V3_3/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Symfony/V3_3/AutomatedLoginEventsTest.php @@ -1,23 +1,21 @@ setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/Symfony/V3_3/PathParamsTest.php b/tests/Integrations/Symfony/V3_3/PathParamsTest.php new file mode 100644 index 0000000000..5fcf7de3f8 --- /dev/null +++ b/tests/Integrations/Symfony/V3_3/PathParamsTest.php @@ -0,0 +1,38 @@ +call(GetSpec::create('dynamic', "/dynamic_route/$param01/$param02")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testStaticRoute() + { + $this->call(GetSpec::create('static', "/simple")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Symfony/V4_4/AutomatedLoginEventsTest.php b/tests/Integrations/Symfony/V4_4/AutomatedLoginEventsTest.php index a02a4ba5aa..3bf17998c9 100644 --- a/tests/Integrations/Symfony/V4_4/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Symfony/V4_4/AutomatedLoginEventsTest.php @@ -2,22 +2,20 @@ namespace DDTrace\Tests\Integrations\Symfony\V4_4; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Symfony/Version_4_4/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -25,18 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/Symfony/V4_4/PathParamsTest.php b/tests/Integrations/Symfony/V4_4/PathParamsTest.php new file mode 100644 index 0000000000..107f6e26a2 --- /dev/null +++ b/tests/Integrations/Symfony/V4_4/PathParamsTest.php @@ -0,0 +1,50 @@ +call(GetSpec::create('dynamic', "/dynamic_route/$param01/$param02")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalsNotFilled() + { + $param01 = 'first_param'; + $this->call(GetSpec::create('dynamic', "/dynamic_route/$param01")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEmpty($events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + + public function testStaticRoute() + { + $this->call(GetSpec::create('static', "/simple")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Symfony/V5_2/AutomatedLoginEventsTest.php b/tests/Integrations/Symfony/V5_2/AutomatedLoginEventsTest.php index 63da83d017..b965ff0ff2 100644 --- a/tests/Integrations/Symfony/V5_2/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Symfony/V5_2/AutomatedLoginEventsTest.php @@ -2,22 +2,20 @@ namespace DDTrace\Tests\Integrations\Symfony\V5_2; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Symfony/Version_5_2/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -25,18 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/Symfony/V5_2/PathParamsTest.php b/tests/Integrations/Symfony/V5_2/PathParamsTest.php new file mode 100644 index 0000000000..9a0cd73720 --- /dev/null +++ b/tests/Integrations/Symfony/V5_2/PathParamsTest.php @@ -0,0 +1,50 @@ +call(GetSpec::create('dynamic', "/dynamic_route/$param01/$param02")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalsNotFilled() + { + $param01 = 'first_param'; + $this->call(GetSpec::create('dynamic', "/dynamic_route/$param01")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEmpty($events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + + public function testStaticRoute() + { + $this->call(GetSpec::create('static', "/simple")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/Symfony/V6_2/AutomatedLoginEventsTest.php b/tests/Integrations/Symfony/V6_2/AutomatedLoginEventsTest.php index 8e3ff840b0..a029bd0bc7 100644 --- a/tests/Integrations/Symfony/V6_2/AutomatedLoginEventsTest.php +++ b/tests/Integrations/Symfony/V6_2/AutomatedLoginEventsTest.php @@ -2,22 +2,20 @@ namespace DDTrace\Tests\Integrations\Symfony\V6_2; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase +/** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/Symfony/Version_6_2/public/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); - } - protected function ddSetUp() { parent::ddSetUp(); @@ -25,18 +23,6 @@ protected function ddSetUp() AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/Symfony/V6_2/PathParamsTest.php b/tests/Integrations/Symfony/V6_2/PathParamsTest.php new file mode 100644 index 0000000000..6c14597c4a --- /dev/null +++ b/tests/Integrations/Symfony/V6_2/PathParamsTest.php @@ -0,0 +1,50 @@ +call(GetSpec::create('dynamic', "/dynamic_route/$param01/$param02")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEquals($param02, $events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testDynamicRouteWithOptionalsNotFilled() + { + $param01 = 'first_param'; + $this->call(GetSpec::create('dynamic', "/dynamic_route/$param01")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals($param01, $events[0]["server.request.path_params"]['param01']); + $this->assertEmpty($events[0]["server.request.path_params"]['param02']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + + public function testStaticRoute() + { + $this->call(GetSpec::create('static', "/simple")); + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/WordPress/V4_8/AutomatedLoginEventsTest.php b/tests/Integrations/WordPress/V4_8/AutomatedLoginEventsTest.php index 3321a392d2..d2dfe24c67 100644 --- a/tests/Integrations/WordPress/V4_8/AutomatedLoginEventsTest.php +++ b/tests/Integrations/WordPress/V4_8/AutomatedLoginEventsTest.php @@ -2,42 +2,31 @@ namespace DDTrace\Tests\Integrations\WordPress\V4_8; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase + /** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/WordPress/Version_4_8/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); + protected function databaseDump() { + return file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_4_8/wp_2019-10-01.sql'); } protected function ddSetUp() { parent::ddSetUp(); - $this->connection()->exec(file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_4_8/wp_2019-10-01.sql')); $this->connection()->exec("DELETE from users where email LIKE 'test-user%'"); AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/WordPress/V4_8/PathParamsTest.php b/tests/Integrations/WordPress/V4_8/PathParamsTest.php new file mode 100644 index 0000000000..64b9a4205d --- /dev/null +++ b/tests/Integrations/WordPress/V4_8/PathParamsTest.php @@ -0,0 +1,77 @@ +call( + GetSpec::create( + 'Post example', + '/hello-world' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('hello-world', $events[0]["server.request.path_params"]['name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testCategory() + { + $this->call( + GetSpec::create( + 'Category', + '/category/uncategorized' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('uncategorized', $events[0]["server.request.path_params"]['category_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testAuthor() + { + $this->call( + GetSpec::create( + 'Author', + '/author/SammyK' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('SammyK', $events[0]["server.request.path_params"]['author_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testNonExistingPost() + { + $this->call( + GetSpec::create( + 'Not existing post', + '/non-existing-post' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/WordPress/V5_5/AutomatedLoginEventsTest.php b/tests/Integrations/WordPress/V5_5/AutomatedLoginEventsTest.php index 4862bd278f..e5f1a8b6f0 100644 --- a/tests/Integrations/WordPress/V5_5/AutomatedLoginEventsTest.php +++ b/tests/Integrations/WordPress/V5_5/AutomatedLoginEventsTest.php @@ -2,42 +2,31 @@ namespace DDTrace\Tests\Integrations\WordPress\V5_5; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase + /** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/WordPress/Version_5_5/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); + protected function databaseDump() { + return file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_5_5/wp_2020-10-21.sql'); } protected function ddSetUp() { parent::ddSetUp(); - $this->connection()->exec(file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_5_5/wp_2020-10-21.sql')); $this->connection()->exec("DELETE from users where email LIKE 'test-user%'"); AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/WordPress/V5_5/PathParamsTest.php b/tests/Integrations/WordPress/V5_5/PathParamsTest.php new file mode 100644 index 0000000000..45befad9c1 --- /dev/null +++ b/tests/Integrations/WordPress/V5_5/PathParamsTest.php @@ -0,0 +1,97 @@ +connection()->exec(file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_5_5/wp_2020-10-21.sql')); + AppsecStatus::getInstance()->setDefaults(); + } + + public static function ddSetUpBeforeClass() + { + parent::ddSetUpBeforeClass(); + AppsecStatus::getInstance()->init(); + } + + public static function ddTearDownAfterClass() + { + AppsecStatus::getInstance()->destroy(); + parent::ddTearDownAfterClass(); + } + + public function testPost() + { + $this->call( + GetSpec::create( + 'Post example', + '/hello-world' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('hello-world', $events[0]["server.request.path_params"]['name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testCategory() + { + $this->call( + GetSpec::create( + 'Category', + '/category/uncategorized' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('uncategorized', $events[0]["server.request.path_params"]['category_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testAuthor() + { + $this->call( + GetSpec::create( + 'Author', + '/author/test' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('test', $events[0]["server.request.path_params"]['author_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testNonExistingPost() + { + $this->call( + GetSpec::create( + 'Not existing post', + '/non-existing-post' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/WordPress/V5_9/AutomatedLoginEventsTest.php b/tests/Integrations/WordPress/V5_9/AutomatedLoginEventsTest.php index 389209a96b..1df849d497 100644 --- a/tests/Integrations/WordPress/V5_9/AutomatedLoginEventsTest.php +++ b/tests/Integrations/WordPress/V5_9/AutomatedLoginEventsTest.php @@ -2,42 +2,32 @@ namespace DDTrace\Tests\Integrations\WordPress\V5_8; -use DDTrace\Tests\Common\WebFrameworkTestCase; +use DDTrace\Tests\Common\AppsecTestCase; use DDTrace\Tests\Frameworks\Util\Request\PostSpec; +use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use datadog\appsec\AppsecStatus; -class AutomatedLoginEventsTest extends WebFrameworkTestCase + /** + * @group appsec + */ +class AutomatedLoginEventsTest extends AppsecTestCase { protected static function getAppIndexScript() { return __DIR__ . '/../../../Frameworks/WordPress/Version_5_9/index.php'; } - protected function connection() - { - return new \PDO('mysql:host=mysql_integration;dbname=test', 'test', 'test'); + protected function databaseDump() { + return file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_5_5/wp_2020-10-21.sql'); } protected function ddSetUp() { parent::ddSetUp(); - $this->connection()->exec(file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_5_5/wp_2020-10-21.sql')); $this->connection()->exec("DELETE from users where email LIKE 'test-user%'"); AppsecStatus::getInstance()->setDefaults(); } - public static function ddSetUpBeforeClass() - { - parent::ddSetUpBeforeClass(); - AppsecStatus::getInstance()->init(); - } - - public static function ddTearDownAfterClass() - { - AppsecStatus::getInstance()->destroy(); - parent::ddTearDownAfterClass(); - } - public function testUserLoginSuccessEvent() { $email = 'test-user@email.com'; diff --git a/tests/Integrations/WordPress/V5_9/PathParamsTest.php b/tests/Integrations/WordPress/V5_9/PathParamsTest.php new file mode 100644 index 0000000000..ac09f0d32f --- /dev/null +++ b/tests/Integrations/WordPress/V5_9/PathParamsTest.php @@ -0,0 +1,77 @@ +call( + GetSpec::create( + 'Post example', + '/hello-world' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('hello-world', $events[0]["server.request.path_params"]['name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testCategory() + { + $this->call( + GetSpec::create( + 'Category', + '/category/uncategorized' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('uncategorized', $events[0]["server.request.path_params"]['category_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testAuthor() + { + $this->call( + GetSpec::create( + 'Author', + '/author/test' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('test', $events[0]["server.request.path_params"]['author_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testNonExistingPost() + { + $this->call( + GetSpec::create( + 'Not existing post', + '/non-existing-post' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +} diff --git a/tests/Integrations/WordPress/V6_1/PathParamsTest.php b/tests/Integrations/WordPress/V6_1/PathParamsTest.php new file mode 100644 index 0000000000..3abe7275d4 --- /dev/null +++ b/tests/Integrations/WordPress/V6_1/PathParamsTest.php @@ -0,0 +1,81 @@ +exec(file_get_contents(__DIR__ . '/../../../Frameworks/WordPress/Version_6_1/scripts/wp_initdb.sql')); + AppsecStatus::getInstance()->setDefaults(); + } + + public function testPost() + { + $this->call( + GetSpec::create( + 'Post example', + '/hello-world' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('hello-world', $events[0]["server.request.path_params"]['name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testCategory() + { + $this->call( + GetSpec::create( + 'Category', + '/category/uncategorized' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('uncategorized', $events[0]["server.request.path_params"]['category_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testAuthor() + { + $this->call( + GetSpec::create( + 'Author', + '/author/test' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(1, count($events)); + $this->assertEquals('test', $events[0]["server.request.path_params"]['author_name']); + $this->assertEquals('push_address', $events[0]['eventName']); + } + + public function testNonExistingPost() + { + $this->call( + GetSpec::create( + 'Not existing post', + '/non-existing-post' + ) + ); + + $events = AppsecStatus::getInstance()->getEvents(); + $this->assertEquals(0, count($events)); + } +}