Skip to content

Commit 22b29fe

Browse files
committed
Add user event to Laravel 8
1 parent d2d9d2f commit 22b29fe

File tree

6 files changed

+99
-6
lines changed

6 files changed

+99
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ docker-compose.override.yml
5252
tests/Sapi/Roadrunner/rr-*
5353
github-actions-helpers/_build.csproj.DotSettings
5454
.nuke
55+
cookies.txt

src/Integrations/Integrations/Laravel/LaravelIntegration.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,33 @@ function ($This, $scope, $args) use ($integration) {
461461
}
462462
);
463463

464+
\DDTrace\hook_method(
465+
'Illuminate\Auth\Events\Authenticated',
466+
'__construct',
467+
null,
468+
function ($This, $scope, $args) use ($integration) {
469+
$authClass = 'Illuminate\Contracts\Auth\Authenticatable';
470+
if (
471+
!isset($args[1]) ||
472+
!$args[1] ||
473+
!($args[1] instanceof $authClass)
474+
) {
475+
return;
476+
}
477+
478+
$meta = [];
479+
$user = $args[1];
480+
if (isset($user->name)) {
481+
$meta['name'] = $user->name;
482+
}
483+
if (isset($user->email)) {
484+
$meta['email'] = $user->email;
485+
}
486+
487+
\DDTrace\set_user($user->getAuthIdentifier(), $meta);
488+
}
489+
);
490+
464491
return Integration::LOADED;
465492
}
466493

tests/Common/WebFrameworkTestCase.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,25 @@ abstract class WebFrameworkTestCase extends IntegrationTestCase
2121
const PORT = 9999;
2222

2323
const ERROR_LOG_NAME = 'phpunit_error.log';
24+
const COOKIE_JAR = 'cookies.txt';
2425

2526
/**
2627
* @var WebServer|null
2728
*/
2829
private static $appServer;
2930
protected $checkWebserverErrors = true;
31+
protected $cookiesFile;
32+
33+
protected function ddSetUp()
34+
{
35+
parent::ddSetUp();
36+
$this->cookiesFile = realpath(dirname(static::getAppIndexScript()) . '/' . static::COOKIE_JAR);
37+
$f = @fopen($this->cookiesFile, "r+");
38+
if ($f !== false) {
39+
ftruncate($f, 0);
40+
fclose($f);
41+
}
42+
}
3043

3144
public static function ddSetUpBeforeClass()
3245
{
@@ -192,6 +205,10 @@ protected function sendRequest($method, $url, $headers = [], $body = [], $change
192205
curl_setopt($ch, CURLOPT_RETURNTRANSFER, $options[CURLOPT_RETURNTRANSFER]);
193206
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
194207
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $options[CURLOPT_FOLLOWLOCATION]);
208+
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiesFile);
209+
curl_setopt ($ch, CURLOPT_COOKIEFILE, $this->cookiesFile);
210+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
211+
curl_setopt($ch, CURLOPT_HEADER, 1);
195212
if ($method === 'POST') {
196213
curl_setopt($ch, CURLOPT_POST, true);
197214
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($body) ? json_encode($body) : $body);

tests/Frameworks/Laravel/Version_8_x/app/Http/Controllers/LoginTestController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,9 @@ public function register(Request $request): RedirectResponse
5050

5151
return redirect(RouteServiceProvider::HOME);
5252
}
53+
54+
public function behind_auth()
55+
{
56+
return "page behind auth";
57+
}
5358
}

tests/Frameworks/Laravel/Version_8_x/routes/web.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
Route::get('queue/workOn', [QueueTestController::class, 'workOn']);
4040
Route::get('login/auth', [LoginTestController::class, 'auth']);
4141
Route::get('login/signup', [LoginTestController::class, 'register']);
42+
Route::get('/behind_auth', [LoginTestController::class, 'behind_auth'])->name('behind_auth')->middleware('auth');
4243

4344
// This route has to remain unnamed so we test both route cached and not cached.
4445
Route::get('/unnamed-route', [RouteCachingController::class, 'unnamed']);

tests/Integrations/Laravel/V8_x/AutomatedLoginEventsTest.php renamed to tests/Integrations/Laravel/V8_x/LoginEventsTest.php

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use DDTrace\Tests\Frameworks\Util\Request\GetSpec;
77
use datadog\appsec\AppsecStatus;
88

9-
class AutomatedLoginEventsTest extends WebFrameworkTestCase
9+
class LoginEventsTest extends WebFrameworkTestCase
1010
{
1111
protected static function getAppIndexScript()
1212
{
@@ -39,18 +39,24 @@ public static function ddTearDownAfterClass()
3939

4040
protected function login($email)
4141
{
42-
$this->call(
43-
GetSpec::create('Login success event', '/login/auth?email='.$email)
44-
);
42+
return $this->tracesFromWebRequest(function () use ($email) {
43+
$this->call(
44+
GetSpec::create('Login success event', '/login/auth?email='.$email)
45+
);
46+
});
47+
}
48+
49+
protected function createUser($id, $name, $email) {
50+
//Password is password
51+
$this->connection()->exec("insert into users (id, name, email, password) VALUES (".$id.", '".$name."', '".$email."', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi')");
4552
}
4653

4754
public function testUserLoginSuccessEvent()
4855
{
4956
$id = 1234;
5057
$name = 'someName';
5158
$email = '[email protected]';
52-
//Password is password
53-
$this->connection()->exec("insert into users (id, name, email, password) VALUES (".$id.", '".$name."', '".$email."', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi')");
59+
$this->createUser($id, $name, $email);
5460

5561
$this->login($email);
5662

@@ -63,6 +69,42 @@ public function testUserLoginSuccessEvent()
6369
$this->assertEquals('track_user_login_success_event', $events[0]['eventName']);
6470
}
6571

72+
public function testLoggedInCalls()
73+
{
74+
$id = 1234;
75+
$name = 'someName';
76+
$email = '[email protected]';
77+
$this->createUser($id, $name, $email);
78+
79+
//First log in
80+
$traces = $this->login($email);
81+
82+
$meta = $traces[0][0]['meta'];
83+
$this->assertEquals($id, $meta['usr.id']);
84+
$this->assertEquals($name, $meta['usr.name']);
85+
$this->assertEquals($email, $meta['usr.email']);
86+
87+
$events = AppsecStatus::getInstance()->getEvents();
88+
$this->assertEquals(1, count($events));
89+
$this->assertEquals($id, $events[0]['userId']);
90+
$this->assertEquals($name, $events[0]['metadata']['name']);
91+
$this->assertEquals($email, $events[0]['metadata']['email']);
92+
$this->assertTrue($events[0]['automated']);
93+
$this->assertEquals('track_user_login_success_event', $events[0]['eventName']);
94+
95+
//Now we are logged in lets do another call
96+
AppsecStatus::getInstance()->setDefaults(); //Remove all events
97+
$traces = $this->tracesFromWebRequest(function () {
98+
$this->call(GetSpec::create('Behind auth', '/behind_auth'));
99+
});
100+
101+
$meta = $traces[0][0]['meta'];
102+
$this->assertEquals(0, count($events)); //Auth does not generate appsec events
103+
$this->assertEquals($id, $meta['usr.id']);
104+
$this->assertEquals($name, $meta['usr.name']);
105+
$this->assertEquals($email, $meta['usr.email']);
106+
}
107+
66108
public function testUserLoginFailureEvent()
67109
{
68110
$email = '[email protected]';

0 commit comments

Comments
 (0)