Skip to content

Commit f0c4e93

Browse files
kmazariegosKarla Mazariegos
andauthored
PHP audit logs example app - first commit (#24)
* PHP audit logs example app - first commit * audit logs- adding more to example app * audit logs- adding more to get events section * audit logs- adding more to get events section * audit logs- adding more to example app * audit logs- adding to readme * audit logs- fixing errors Co-authored-by: Karla Mazariegos <[email protected]>
1 parent 0bd6275 commit f0c4e93

File tree

12 files changed

+936
-0
lines changed

12 files changed

+936
-0
lines changed

php-audit-logs-example/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
vendor/
3+
.env

php-audit-logs-example/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 WorkOS
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

php-audit-logs-example/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# php-audit-logs-example
2+
3+
An example PHP application demonstrating how to use the [WorkOS PHP SDK](https://github.com/workos/workos-php) to send and retrieve Audit Log events. This example is not meant to show a real-world example of an Audit Logs implementation, but rather to show concrete examples of how events can be sent using the PHP SDK.
4+
5+
Note: PHP 8 or higher is required to use this example application
6+
7+
## Dependencies
8+
9+
Composer - [Link](https://getcomposer.org/)
10+
11+
## Setup
12+
13+
1. Clone the repo and install the dependencies by running the following:
14+
15+
```bash
16+
git clone [email protected]:workos/php-example-applications/php-audit-logs-example
17+
cd php-example-applications/php-audit-logs-example
18+
composer i
19+
```
20+
21+
2. Create a new file called `.env` and enter your API Key and Client ID from the WorkOS Dashboard.
22+
23+
```
24+
WORKOS_API_KEY="your_api_key"
25+
WORKOS_CLIENT_ID="your_client_id"
26+
```
27+
28+
## Running the app
29+
30+
Use the following command to run the app:
31+
32+
```bash
33+
php -S localhost:8000 router.php
34+
```
35+
36+
Once running, navigate to the following URL for a demonstration on the SSO workflow: http://localhost:8000.
37+
38+
39+
## Audit Logs Setup with WorkOS
40+
41+
3. Follow the [Audit Logs configuration steps](https://workos.com/docs/audit-logs/emit-an-audit-log-event/sign-in-to-your-workos-dashboard-account-and-configure-audit-log-event-schemas) to set up the following 5 events that are sent with this example:
42+
43+
Action title: "user.signed_in" | Target type: "team"
44+
Action title: "user.logged_out" | Target type: "team"
45+
Action title: "user.organization_set" | Target type: "team"
46+
Action title: "user.organization_deleted" | Target type: "team"
47+
Action title: "user.connection_deleted" | Target type: "team"
48+
49+
4. Next, take note of the Organization ID for the Org which you will be sending the Audit Log events for. This ID gets entered into the splash page of the example application.
50+
51+
5. Once you enter the Organization ID and submit it, you will be brought to the page where you'll be able to send the audit log events that were just configured. You'll also notice that the action of setting the Organization triggered an Audit Log already. Click the buttons to send the respective events.
52+
53+
6. To obtain a CSV of the Audit Log events that were sent for the last 30 days, click the "Export Events" button. This will bring you to a new page where you can download the events. Downloading the events is a 2 step process. First you need to create the report by clicking the "Generate CSV" button. Then click the "Access CSV" button to download a CSV of the Audit Log events for the selected Organization for the past 30 days.
54+
55+
## Need help?
56+
57+
If you get stuck and aren't able to resolve the issue by reading our API reference or tutorials, you can reach out to us at [email protected] and we'll lend a hand.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
$user_signed_in = [
4+
"action" => "user.signed_in",
5+
"occurred_at" => date("c"),
6+
"version" => 1,
7+
"actor" => [
8+
"id" => "user_01GBNJC3MX9ZZJW1FSTF4C5938",
9+
"type" => "user",
10+
],
11+
"targets" => [
12+
[
13+
"id" => "team_01GBNJD4MKHVKJGEWK42JNMBGS",
14+
"type" => "team",
15+
],
16+
],
17+
"context" => [
18+
"location" => "123.123.123.123",
19+
"user_agent" => "Chrome/104.0.0.0",
20+
],
21+
];
22+
23+
$user_logged_out = [
24+
"action" => "user.logged_out",
25+
"occurred_at" => date("c"),
26+
"actor" => [
27+
"id" => "user_01GBNJC3MX9ZZJW1FSTF4C5938",
28+
"type" => "user",
29+
],
30+
"targets" => [
31+
[
32+
"id" => "team_01GBNJD4MKHVKJGEWK42JNMBGS",
33+
"type" => "team",
34+
],
35+
],
36+
"context" => [
37+
"location" => "123.123.123.123",
38+
"user_agent" => "Chrome/104.0.0.0",
39+
],
40+
];
41+
42+
$user_organization_set = [
43+
"action" => "user.organization_set",
44+
"occurred_at" => date("c"),
45+
"actor" => [
46+
"id" => "user_01GBNJC3MX9ZZJW1FSTF4C5938",
47+
"type" => "user",
48+
],
49+
"targets" => [
50+
[
51+
"id" => "team_01GBNJD4MKHVKJGEWK42JNMBGS",
52+
"type" => "team",
53+
],
54+
],
55+
"context" => [
56+
"location" => "123.123.123.123",
57+
"user_agent" => "Chrome/104.0.0.0",
58+
],
59+
];
60+
61+
$user_organization_deleted = [
62+
"action" => "user.organization_deleted",
63+
"occurred_at" => date("c"),
64+
"actor" => [
65+
"id" => "user_01GBNJC3MX9ZZJW1FSTF4C5938",
66+
"type" => "user",
67+
],
68+
"targets" => [
69+
[
70+
"id" => "team_01GBNJD4MKHVKJGEWK42JNMBGS",
71+
"type" => "team",
72+
],
73+
],
74+
"context" => [
75+
"location" => "123.123.123.123",
76+
"user_agent" => "Chrome/104.0.0.0",
77+
],
78+
];
79+
80+
$user_connection_deleted = [
81+
"action" => "user.connection_deleted",
82+
"occurred_at" => date("c"),
83+
"actor" => [
84+
"id" => "user_01GBNJC3MX9ZZJW1FSTF4C5938",
85+
"type" => "user",
86+
],
87+
"targets" => [
88+
[
89+
"id" => "team_01GBNJD4MKHVKJGEWK42JNMBGS",
90+
"type" => "team",
91+
],
92+
],
93+
"context" => [
94+
"location" => "123.123.123.123",
95+
"user_agent" => "Chrome/104.0.0.0",
96+
],
97+
];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "workos-inc/php-sso-example",
3+
"description": "An example PHP application demonstrating how to use the WorkOS PHP SDK",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "WorkOS",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {
12+
"workos/workos-php": "^1.12.0",
13+
"twig/twig": "^3.0",
14+
"vlucas/phpdotenv": "^5.4.1"
15+
}
16+
}

php-audit-logs-example/router.php

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
3+
require __DIR__ . "/vendor/autoload.php";
4+
include './auditLogEvents.php';
5+
6+
use Twig\Environment;
7+
use Twig\Loader\FilesystemLoader;
8+
9+
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
10+
$dotenv->load();
11+
12+
//Set API Key, ClientID, and Connection
13+
$WORKOS_API_KEY = $_ENV['WORKOS_API_KEY'];
14+
$WORKOS_CLIENT_ID = $_ENV['WORKOS_CLIENT_ID'];
15+
16+
// Setup html templating library
17+
$loader = new FilesystemLoader(__DIR__ . '/templates');
18+
$twig = new Environment($loader);
19+
20+
// Configure WorkOS with API Key and Client ID
21+
\WorkOS\WorkOS::setApiKey($WORKOS_API_KEY);
22+
\WorkOS\WorkOS::setClientId($WORKOS_CLIENT_ID);
23+
24+
// Convenient function for throwing a 404
25+
function httpNotFound()
26+
{
27+
header($_SERVER["SERVER_PROTOCOL"] . " 404");
28+
return true;
29+
}
30+
31+
// Convenient function to transform an object to an associative array
32+
function objectToArray($d)
33+
{
34+
if (is_object($d)) {
35+
// Gets the properties of the given object
36+
// with get_object_vars function
37+
$d = get_object_vars($d);
38+
}
39+
40+
if (is_array($d)) {
41+
/*
42+
* Return array converted to object
43+
* Using __FUNCTION__ (Magic constant)
44+
* for recursive call
45+
*/
46+
return array_map(__FUNCTION__, $d);
47+
} else {
48+
// Return array
49+
return $d;
50+
}
51+
}
52+
53+
//Routing
54+
switch (strtok($_SERVER["REQUEST_URI"], "?")) {
55+
case (preg_match("/\.css$/", $_SERVER["REQUEST_URI"]) ? true : false):
56+
$path = __DIR__ . "/static/css" .$_SERVER["REQUEST_URI"];
57+
if (is_file($path)) {
58+
header("Content-Type: text/css");
59+
readfile($path);
60+
return true;
61+
}
62+
return httpNotFound();
63+
64+
case (preg_match("/\.png$/", $_SERVER["REQUEST_URI"]) ? true : false):
65+
$path = __DIR__ . "/static/images" .$_SERVER["REQUEST_URI"];
66+
if (is_file($path)) {
67+
header("Content-Type: image/png");
68+
readfile($path);
69+
return true;
70+
}
71+
return httpNotFound();
72+
73+
74+
//set_org route is what will set organization
75+
case ("/"):
76+
case ("/login"):
77+
case ("/logout"):
78+
echo $twig->render("login.html.twig");
79+
return true;
80+
81+
case ("/set_org"):
82+
$organizationId = $_POST["org"] ?? "";
83+
$organization = (new \WorkOS\Organizations()) -> getOrganization($organizationId);
84+
$orgPayloadArray = objectToArray($organization);
85+
$orgPayloadArrayRawData = $orgPayloadArray['raw'];
86+
$finalOrgId = $orgPayloadArrayRawData["id"] ?? "";
87+
$orgName = $orgPayloadArrayRawData["name"] ?? "";
88+
session_start();
89+
$_SESSION['id'] = $finalOrgId;
90+
$_SESSION['name'] = $orgName;
91+
echo $twig->render("send_events.html.twig", ['org_id' => $_SESSION['id'], 'org_name' => $orgName]);
92+
return true;
93+
94+
//send_event
95+
case ("/send_event"):
96+
session_start();
97+
$payload = file_get_contents("php://input");
98+
$eventId = $payload[6];
99+
$event;
100+
if($eventId === '0'){
101+
$event = $user_signed_in;
102+
} else if($eventId === '1'){
103+
$event = $user_logged_out;
104+
} else if($eventId === '2'){
105+
$event = $user_organization_deleted;
106+
} else if($eventId === '3'){
107+
$event = $user_connection_deleted;
108+
}
109+
110+
$orgId = $_SESSION['id'];
111+
$orgName = $_SESSION['name'];
112+
113+
$auditLogsEvent = (new \WorkOS\AuditLogs()) -> createEvent(
114+
organizationId: $orgId,
115+
event: $event
116+
);
117+
118+
echo $twig->render("send_events.html.twig", ['org_id' => $_SESSION['id'], 'org_name' => $_SESSION['name']]);
119+
return true;
120+
121+
//export_events
122+
case ("/export_events"):
123+
session_start();
124+
$payload = file_get_contents("php://input");
125+
$orgId = $_SESSION['id'];
126+
$orgName = $_SESSION['name'];
127+
echo $twig->render("export_events.html.twig", ['org_id' => $orgId, 'org_name' => $orgName]);
128+
return true;
129+
130+
//generate_csv
131+
case ("/get_events"):
132+
session_start();
133+
$payload = file_get_contents("php://input");
134+
$orgId = $_SESSION['id'];
135+
$orgName = $_SESSION['name'];
136+
$event = $_POST["event"] ?? "";
137+
$dateNow = (new \DateTime('now',new \DateTimeZone("UTC")))->format(\DateTime::ATOM);
138+
$dateMonth = (new \DateTime('-1 month',new \DateTimeZone("UTC")))->format(\DateTime::ATOM);
139+
$auditId;
140+
141+
if($event === "generate_csv"){
142+
$createExport = (new \WorkOS\AuditLogs()) -> createExport(
143+
organizationId: $orgId,
144+
rangeStart: $dateMonth,
145+
rangeEnd: $dateNow
146+
);
147+
$orgPayloadArray = objectToArray($createExport);
148+
$orgPayloadArrayRawData = $orgPayloadArray['raw'];
149+
$auditId = $orgPayloadArrayRawData["id"] ?? "";
150+
$_SESSION['Auditid'] = $auditId;
151+
}
152+
153+
if($event === "access_csv"){
154+
$fetchExport = (new \WorkOS\AuditLogs()) -> getExport(
155+
$_SESSION['Auditid']
156+
);
157+
$orgPayloadArray = objectToArray($fetchExport);
158+
$orgPayloadArrayRawData = $orgPayloadArray['raw'];
159+
$url = $orgPayloadArrayRawData["url"] ?? "";
160+
$source = file_get_contents($url);
161+
file_put_contents('/[YOUR PATH HERE]/auditlogs.csv', $source);
162+
}
163+
164+
echo $twig->render("export_events.html.twig", ['org_id' => $orgId, 'org_name' => $orgName]);
165+
return true;
166+
167+
168+
169+
170+
default:
171+
return httpNotFound();
172+
173+
}
174+
175+
?>

0 commit comments

Comments
 (0)