Skip to content

Commit e48ecbb

Browse files
committed
correct scene/device namespace split more for sanity
1 parent 2a6c059 commit e48ecbb

File tree

2 files changed

+40
-32
lines changed

2 files changed

+40
-32
lines changed

users/mqtt.py

+40-30
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def generate_arena_token(
6060
Returns:
6161
str: JWT or None
6262
"""
63+
# TODO: realm cannot contain any /
6364
config = settings.PUBSUB
6465
if not realm:
6566
realm = config["mqtt_realm"]
@@ -99,15 +100,24 @@ def generate_arena_token(
99100
roomname = re.sub(r"[!#$&'()*+,\/:;=?@[\]]", '_', ns_scene.lower())
100101
payload["room"] = roomname
101102

102-
pubs, subs = get_pubsub_topics_api_v1(
103-
user,
104-
username,
105-
realm,
106-
ns_scene,
107-
ns_device,
108-
ids,
109-
perm,
110-
)
103+
# ns_scene, ns_device can/must contain only one '/'
104+
namespace = scene = device = None
105+
if ns_scene:
106+
parts = ns_scene.split("/")
107+
if len(parts) != 2:
108+
return None
109+
namespace = parts[0]
110+
scene = parts[1]
111+
elif ns_device:
112+
parts = ns_device.split("/")
113+
if len(parts) != 2:
114+
return None
115+
namespace = parts[0]
116+
device = parts[1]
117+
118+
pubs, subs = pubsub_api_v1(
119+
user, username, realm, namespace, scene, device, ids, perm)
120+
111121
if len(subs) > 0:
112122
payload["subs"] = clean_topics(subs)
113123
if len(pubs) > 0:
@@ -116,12 +126,13 @@ def generate_arena_token(
116126
return jwt.encode(payload, private_key, algorithm="RS256", headers=headers)
117127

118128

119-
def get_pubsub_topics_api_v1(
129+
def pubsub_api_v1(
120130
user,
121131
username,
122132
realm,
123-
ns_scene,
124-
ns_device,
133+
namespace,
134+
scene,
135+
device,
125136
ids,
126137
perm,
127138
):
@@ -133,16 +144,16 @@ def get_pubsub_topics_api_v1(
133144
pubs = []
134145
subs = []
135146
# everyone should be able to read all public scenes
136-
if not ns_device: # scene token scenario
147+
if not device: # scene token scenario
137148
subs.append(f"{realm}/s/{PUBLIC_NAMESPACE}/#")
138149
# And transmit env data
139150
pubs.append(f"{realm}/env/{PUBLIC_NAMESPACE}/#")
140151
# user presence objects
141152
if user.is_authenticated:
142-
if ns_device: # device token scenario
153+
if device: # device token scenario
143154
# device owners have rights to their device objects only
144-
subs.append(f"{realm}/d/{ns_device}/#")
145-
pubs.append(f"{realm}/d/{ns_device}/#")
155+
subs.append(f"{realm}/d/{namespace}/{device}/#")
156+
pubs.append(f"{realm}/d/{namespace}/{device}/#")
146157
else: # scene token scenario
147158
# scene rights default by namespace
148159
if user.is_staff:
@@ -153,8 +164,8 @@ def get_pubsub_topics_api_v1(
153164
subs.append(f"{realm}/env/#")
154165
pubs.append(f"{realm}/env/#")
155166
# vio experiments, staff only
156-
if ns_scene:
157-
pubs.append(f"{realm}/vio/{ns_scene}/#")
167+
if scene:
168+
pubs.append(f"{realm}/vio/{namespace}/{scene}/#")
158169
else:
159170
# scene owners have rights to their scene objects only
160171
subs.append(f"{realm}/s/{username}/#")
@@ -165,7 +176,7 @@ def get_pubsub_topics_api_v1(
165176
# add scenes that have been granted by other owners
166177
u_scenes = Scene.objects.filter(editors=user)
167178
for u_scene in u_scenes:
168-
if not ns_scene or (ns_scene and u_scene.name == ns_scene):
179+
if not scene or (scene and u_scene.name == f"{namespace}/{scene}"):
169180
subs.append(f"{realm}/s/{u_scene.name}/#")
170181
pubs.append(f"{realm}/s/{u_scene.name}/#")
171182
subs.append(f"{realm}/env/{u_scene.name}/#")
@@ -180,25 +191,24 @@ def get_pubsub_topics_api_v1(
180191
subs.append(f"{realm}/d/{username}/#")
181192
pubs.append(f"{realm}/d/{username}/#")
182193
# anon/non-owners have rights to view scene objects only
183-
if ns_scene and not user.is_staff:
194+
if scene and not user.is_staff:
184195
# did the user set specific public read or public write?
185196
if not user.is_authenticated and not perm["anonymous_users"]:
186197
return None # anonymous not permitted
187198
if perm["public_read"]:
188-
subs.append(f"{realm}/s/{ns_scene}/#")
199+
subs.append(f"{realm}/s/{namespace}/{scene}/#")
189200
# Interactivity to extent of viewing objects is similar to publishing env
190-
pubs.append(f"{realm}/env/{ns_scene}/#")
201+
pubs.append(f"{realm}/env/{namespace}/{scene}/#")
191202
if perm["public_write"]:
192-
pubs.append(f"{realm}/s/{ns_scene}/#")
203+
pubs.append(f"{realm}/s/{namespace}/{scene}/#")
193204
# user presence objects
194205
if ids and perm["users"]: # probable web browser write
195-
pubs.append(f"{realm}/s/{ns_scene}/{ids['camid']}")
196-
pubs.append(f"{realm}/s/{ns_scene}/{ids['camid']}/#")
197-
pubs.append(f"{realm}/s/{ns_scene}/{ids['handleftid']}")
198-
pubs.append(f"{realm}/s/{ns_scene}/{ids['handrightid']}")
206+
pubs.append(f"{realm}/s/{namespace}/{scene}/{ids['camid']}")
207+
pubs.append(f"{realm}/s/{namespace}/{scene}/{ids['camid']}/#")
208+
pubs.append(f"{realm}/s/{namespace}/{scene}/{ids['handleftid']}")
209+
pubs.append(f"{realm}/s/{namespace}/{scene}/{ids['handrightid']}")
199210
# chat messages
200-
if ns_scene and ids and perm["users"]:
201-
namespace = ns_scene.split("/")[0]
211+
if scene and ids and perm["users"]:
202212
userhandle = ids["userid"] + \
203213
base64.b64encode(ids["userid"].encode()).decode()
204214
# receive private messages: Read
@@ -210,7 +220,7 @@ def get_pubsub_topics_api_v1(
210220
# private messages to user: Write
211221
pubs.append(f"{realm}/c/{namespace}/p/+/{userhandle}")
212222
# apriltags
213-
if ns_scene:
223+
if scene:
214224
subs.append(f"{realm}/g/a/#")
215225
pubs.append(f"{realm}/g/a/#")
216226
# arts runtime-mngr

users/views.py

-2
Original file line numberDiff line numberDiff line change
@@ -718,9 +718,7 @@ def arena_token(request):
718718
token = generate_arena_token(
719719
user=user,
720720
username=username,
721-
# TODO: realm cannot contain any /
722721
realm=request.POST.get("realm", None),
723-
# TODO: scene can/must contain one /
724722
ns_scene=request.POST.get("scene", None),
725723
ids=ids,
726724
duration=duration

0 commit comments

Comments
 (0)