Skip to content

Commit 358d7ab

Browse files
committed
Add events page and fix up users
1 parent c92e84b commit 358d7ab

File tree

5 files changed

+197
-61
lines changed

5 files changed

+197
-61
lines changed

python-flask-directory-sync-example/app.py

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
from flask_socketio import SocketIO, emit
77
import json
88
from flask_lucide import Lucide
9+
import workos.directory_sync
10+
import workos.resources
11+
import workos.resources.directory_sync
12+
import workos.typing
13+
import workos.utils
14+
import workos.utils.connection_types
915

1016

1117
DEBUG = False
@@ -37,9 +43,9 @@ def home():
3743
before = request.args.get("before")
3844
after = request.args.get("after")
3945
directories = workos.client.directory_sync.list_directories(
40-
before=before, after=after, limit=5, order=None
46+
before=before, after=after, limit=5
4147
)
42-
directories.list_method
48+
4349
before = directories.list_metadata.before
4450
after = directories.list_metadata.after
4551
return render_template(
@@ -53,14 +59,16 @@ def directory():
5359
if not directory_id:
5460
return "No directory ID provided", 400
5561
directory = workos.client.directory_sync.get_directory(directory_id)
56-
return render_template("directory.html", directory=directory.model_dump(), id=directory.id)
62+
63+
return render_template(
64+
"directory.html", directory=directory.model_dump(), id=directory.id
65+
)
5766

5867

5968
@app.route("/users")
6069
def directory_users():
6170
directory_id = request.args.get("id")
62-
users = workos.client.directory_sync.list_users(
63-
directory=directory_id, limit=100)
71+
users = workos.client.directory_sync.list_users(directory=directory_id, limit=100)
6472
return render_template("users.html", users=users)
6573

6674

@@ -69,17 +77,15 @@ def directory_user():
6977
user_id = request.args.get("id")
7078
if not user_id:
7179
return "No user ID provided", 400
72-
user = workos.client.directory_sync.get_user(
73-
user=user_id)
80+
user = workos.client.directory_sync.get_user(user=user_id)
7481

7582
return render_template("user.html", user=user.model_dump(), id=user_id)
7683

7784

7885
@app.route("/groups")
7986
def directory_groups():
8087
directory_id = request.args.get("id")
81-
groups = workos_client.directory_sync.list_groups(
82-
directory=directory_id, limit=100)
88+
groups = workos_client.directory_sync.list_groups(directory=directory_id, limit=100)
8389

8490
return render_template("groups.html", groups=groups)
8591

@@ -90,24 +96,50 @@ def directory_group():
9096
if not group_id:
9197
return "No user ID provided", 400
9298

93-
group = workos_client.directory_sync.get_group(
94-
group=group_id)
99+
group = workos_client.directory_sync.get_group(group=group_id)
95100

96101
return render_template("group.html", group=group.model_dump(), id=group_id)
97102

98103

104+
@app.route("/events")
105+
def events():
106+
after = request.args.get("after")
107+
events = workos.client.events.list_events(
108+
events=[
109+
"dsync.activated",
110+
"dsync.deleted",
111+
"dsync.group.created",
112+
"dsync.group.deleted",
113+
"dsync.group.updated",
114+
"dsync.user.created",
115+
"dsync.user.deleted",
116+
"dsync.user.updated",
117+
"dsync.group.user_added",
118+
"dsync.group.user_removed",
119+
],
120+
after=after,
121+
limit=20,
122+
)
123+
124+
after = events.list_metadata.after
125+
events_data = list(map(lambda event: event.model_dump(), events.data))
126+
return render_template("events.html", events=events_data, after=after)
127+
128+
99129
@app.route("/webhooks", methods=["GET", "POST"])
100130
def webhooks():
131+
signing_secret = os.getenv("WEBHOOKS_SECRET")
101132
if request.data:
102-
payload = request.get_data()
103-
sig_header = request.headers["WorkOS-Signature"]
104-
response = workos_client.webhooks.verify_event(
105-
payload=payload, sig_header=sig_header, secret=os.getenv(
106-
"WEBHOOKS_SECRET")
107-
)
108-
109-
message = json.dumps(response)
110-
socketio.emit("webhook_received", message)
133+
if signing_secret:
134+
payload = request.get_data()
135+
sig_header = request.headers["WorkOS-Signature"]
136+
response = workos_client.webhooks.verify_event(
137+
payload=payload, sig_header=sig_header, secret=signing_secret
138+
)
139+
message = json.dumps(response.dict())
140+
socketio.emit("webhook_received", message)
141+
else:
142+
print("No signing secret configured")
111143

112144
# Return a 200 to prevent retries based on validation
113145
return render_template("webhooks.html")

python-flask-directory-sync-example/static/home.css

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ h1 {
133133
bottom: 20%;
134134
}
135135

136+
.event_bodies {
137+
position: inherit !important;
138+
}
139+
136140
.logged_in_div_left h1 {
137141
color: #111111;
138142
font-size: 75px;
@@ -143,14 +147,12 @@ h1 {
143147
}
144148

145149
.home-hero-gradient {
146-
background-image: linear-gradient(
147-
45deg,
148-
#a163f1,
149-
#6363f1 22%,
150-
#3498ea 40%,
151-
#40dfa3 67%,
152-
rgba(64, 223, 163, 0)
153-
);
150+
background-image: linear-gradient(45deg,
151+
#a163f1,
152+
#6363f1 22%,
153+
#3498ea 40%,
154+
#40dfa3 67%,
155+
rgba(64, 223, 163, 0));
154156
background-size: 150% 100%;
155157
background-repeat: no-repeat;
156158
-webkit-background-clip: text;
@@ -192,14 +194,11 @@ div.text_box {
192194
overflow: scroll;
193195
border-width: 3px;
194196
border-style: solid;
195-
border-image: linear-gradient(
196-
#a163f1,
197+
border-image: linear-gradient(#a163f1,
197198
#6363f1 22%,
198199
#3498ea 40%,
199200
#40dfa3 67%,
200-
rgba(64, 223, 163, 0)
201-
)
202-
0 100%;
201+
rgba(64, 223, 163, 0)) 0 100%;
203202
}
204203

205204
.logged_in_nav {
@@ -245,6 +244,10 @@ pre.prettyprint {
245244
border: none !important;
246245
}
247246

247+
pre.overflow_scroll {
248+
overflow: scroll;
249+
}
250+
248251
.text_input {
249252
border: 1px solid #555555;
250253
border-radius: 10px;
@@ -354,6 +357,15 @@ th {
354357
padding: 15px 40px;
355358
}
356359

360+
tr.event_summary {
361+
text-align: left;
362+
}
363+
364+
tr.selected_event {
365+
font-weight: bold;
366+
background-color: #ebebf2;
367+
}
368+
357369
.width-75 {
358370
width: 75%;
359371
}
@@ -418,6 +430,6 @@ th {
418430
border: none;
419431
}
420432

421-
#noborder > :first-child {
433+
.prettyprinted> :first-child {
422434
display: none;
423-
}
435+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<html>
2+
3+
<head>
4+
<link rel="stylesheet" href="{{ url_for('static', filename='home.css')}}">
5+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter">
6+
</head>
7+
8+
<body class="container_success">
9+
<div class="logged_in_nav">
10+
<div class="flex">
11+
<div>
12+
<img src="../static/images/workos-logo-with-text.png" alt="workos logo">
13+
</div>
14+
</div>
15+
<div>
16+
<a href="https://workos.com/docs" target="_blank"><button class='button nav-item'>Documentation</button></a>
17+
<a href="https://workos.com/docs/reference" target="_blank"><button class='button nav-item'>API
18+
Reference</button></a>
19+
<a href="https://workos.com/blog" target="_blank"><button
20+
class='button nav-item blog-nav-button'>Blog</button></a>
21+
<a href="https://workos.com/" target="_blank"><button class='button button-outline'>WorkOS</button></a>
22+
</div>
23+
</div>
24+
<div class="flex">
25+
<div class="logged_in_div_left">
26+
<div class='flex_column'>
27+
<table>
28+
<thead>
29+
<tr>
30+
<th>Event</th>
31+
<th>Time</th>
32+
</tr>
33+
</thead>
34+
<tbody>
35+
{% for event in events %}
36+
<tr class="event_summary" data-clickable=true data-event-id="{{ event['id'] }}"
37+
onclick="displayEvent(this)">
38+
<td class="event_type">{{ event['event'] }}</td>
39+
<td>{{ event['created_at'] }}</td>
40+
</tr>
41+
{% endfor %}
42+
</tbody>
43+
</table>
44+
<div class="flex-end">
45+
{% if after %}
46+
<div>
47+
<a href="/events?after={{after}}"><button class="button page-title">Next</button></a>
48+
</div>
49+
{% endif %}
50+
</div>
51+
</div>
52+
</div>
53+
<div class='logged_in_div_right event_bodies flex_column width-40vw'>
54+
{% for event in events %}
55+
<pre id="{{ event['id'] }}" class="prettyprint overflow_scroll height-70vh" hidden>
56+
{{event|tojson_pretty}}
57+
</pre>
58+
{% endfor %}
59+
</div>
60+
</div>
61+
<script type="text/javascript" charset="utf-8">
62+
function deselectEvent(element) {
63+
if (!element) {
64+
return;
65+
}
66+
element.classList.remove('selected_event');
67+
const eventId = element.getAttribute('data-event-id');
68+
const eventBody = document.getElementById(eventId);
69+
eventBody.hidden = true;
70+
}
71+
72+
function selectEvent(element) {
73+
if (!element) {
74+
return;
75+
}
76+
element.classList.add('selected_event');
77+
const eventId = element.getAttribute('data-event-id');
78+
const eventBody = document.getElementById(eventId);
79+
eventBody.hidden = false;
80+
}
81+
function displayEvent(element) {
82+
const previousSelectedEvent = selectedEvent;
83+
deselectEvent(previousSelectedEvent);
84+
selectedEvent = element;
85+
selectEvent(selectedEvent);
86+
}
87+
88+
let selectedEvent = document.getElementsByClassName('event_summary')[0];
89+
displayEvent(selectedEvent);
90+
</script>
91+
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
92+
</body>
93+
94+
</html>

python-flask-directory-sync-example/templates/home.html

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter">
66
</head>
77

8-
<body >
8+
<body>
99
<div class="logged_in_nav">
1010
<div class="flex">
1111
<div>
@@ -30,36 +30,37 @@ <h2>Select a Directory</h2>
3030
<a href="/webhooks" class="button button-outline">Test Webhooks</a>
3131
</div>
3232
</div>
33-
34-
<div class='flex_column card width-65vw'>
33+
34+
<div class='flex_column card width-65vw'>
3535
<div>
3636
<table class="width-65vw">
3737
<tr>
38-
<th>Organization</th>
39-
<th>ID</th>
40-
<th>View Settings</th>
38+
<th>Organization</th>
39+
<th>ID</th>
40+
<th>View Settings</th>
4141
</tr>
42-
{% for i in directories %}
43-
<tr>
42+
{% for i in directories %}
43+
<tr>
4444
<td>{{ i['name'] }}</td>
45-
<td>{{ i['id'] }}</td>
46-
<td><a class="button button-outline" href="/directory?id={{i['id']}}">{{ lucide.icon('settings-2', stroke_width=1) }}</a></td>
47-
</tr>
48-
{% endfor %}
49-
</table>
50-
</div>
45+
<td>{{ i['id'] }}</td>
46+
<td><a class="button button-outline" href="/directory?id={{i['id']}}">{{
47+
lucide.icon('settings-2', stroke_width=1) }}</a></td>
48+
</tr>
49+
{% endfor %}
50+
</table>
51+
</div>
5152
<div class="flex flex-end width-65vw">
5253
{% if after %}
5354
<div>
5455
<a href="/?after={{after}}"><button class="button page-title">Previous</button></a>
55-
</div>
56+
</div>
5657
{% endif %}
5758
{% if before %}
5859
<div>
5960
<a href="/?before={{before}}"><button class="button page-title">Next</button></a>
60-
</div>
61-
{% endif %}
62-
</div>
61+
</div>
62+
{% endif %}
63+
</div>
6364
</div>
6465
</div>
6566
</body>

python-flask-directory-sync-example/templates/user.html

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@
2121
</div>
2222
</div>
2323
<div class='flex'>
24-
25-
<div class="logged_in_div_right">
26-
<div class="flex_column">
27-
<h2>User Details</h2>
28-
<div>
29-
<pre id="noborder" class="prettyprint noborder">
24+
<div class="flex_column">
25+
<h2>User Details</h2>
26+
<div>
27+
<pre id="noborder" class="prettyprint noborder height-70vh overflow_scroll">
3028
{{user|tojson_pretty}}
31-
</pre>
32-
</div>
29+
</pre>
3330
</div>
3431
</div>
3532
</div>

0 commit comments

Comments
 (0)