Skip to content

Commit

Permalink
fix(mqtt): require userClient in topic for all scene messages (#670)
Browse files Browse the repository at this point in the history
* add userClient to auth and build

* add userClient to scene

* restore namespace to device topic
  • Loading branch information
mwfarb authored Nov 7, 2024
1 parent a25274e commit 2c4fc6f
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 37 deletions.
1 change: 1 addition & 0 deletions build/arena-account.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default class ARENAUserAccount {
static async refreshAuthToken(authType, mqttUsername, namespacedScene) {
let params = `username=${mqttUsername}`;
params += `&id_auth=${authType}`;
params += `&client=${'webBuild'}`;
params += `&realm=${ARENADefaults ? ARENADefaults.realm : 'realm'}`;
// only request single-scene specific perms when rendering scene
// pages /scenes and /build should have general permissions for the user's scene objects
Expand Down
11 changes: 7 additions & 4 deletions build/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ window.addEventListener('onauth', async (e) => {

const username = e.detail.mqtt_username;
const mqttToken = e.detail.mqtt_token;
const userClient = e.detail.ids.userclient;

// Divs/textareas on the page
const output = document.getElementById('output');
Expand Down Expand Up @@ -460,7 +461,7 @@ window.addEventListener('onauth', async (e) => {
updateLink();
localStorage.setItem('scene', sceneinput.value);
updateUrl();
updatePublishControlsByToken(namespaceinput.value, sceneinput.value, mqttToken);
updatePublishControlsByToken(namespaceinput.value, sceneinput.value, mqttToken, userClient);
}, 500); // refresh after a while, so that delete messages are processed
}
});
Expand Down Expand Up @@ -656,7 +657,7 @@ window.addEventListener('onauth', async (e) => {
updateLink();
localStorage.setItem('scene', sceneinput.value);
updateUrl();
updatePublishControlsByToken(namespaceinput.value, sceneinput.value, mqttToken);
updatePublishControlsByToken(namespaceinput.value, sceneinput.value, mqttToken, userClient);
});

// Focus listener for scene
Expand Down Expand Up @@ -949,6 +950,7 @@ window.addEventListener('onauth', async (e) => {
authState,
mqttUsername: username,
mqttToken,
userClient,
exportSceneButton,
});

Expand Down Expand Up @@ -1005,7 +1007,7 @@ window.addEventListener('onauth', async (e) => {
reload();
updateLink();
updateUrl();
updatePublishControlsByToken(ns, s, mqttToken);
updatePublishControlsByToken(ns, s, mqttToken, userClient);

Swal.close();
});
Expand Down Expand Up @@ -1036,10 +1038,11 @@ Swal.fire({
* @param {string} scenename
* @param {string} mqttToken
*/
function updatePublishControlsByToken(namespace, scenename, mqttToken) {
function updatePublishControlsByToken(namespace, scenename, mqttToken, userClient) {
const objectsTopic = TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace: namespace,
sceneName: scenename,
userClient,
objectId: '+',
});
const editor = ARENAAUTH.isUserSceneEditor(mqttToken, objectsTopic);
Expand Down
3 changes: 3 additions & 0 deletions build/persist-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export async function init(settings) {
authState: settings.authState,
mqttUsername: settings.mqttUsername,
mqttToken: settings.mqttToken,
userClient: settings.userClient,
exportSceneButton: settings.exportSceneButton,
};

Expand Down Expand Up @@ -611,6 +612,7 @@ export function performActionArgObjList(action, scene, objList, json = true) {
const topic = TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace: theNewScene.split('/')[0],
sceneName: theNewScene.split('/')[1],
userClient: persist.userClient,
objectId: obj.object_id,
});
console.info(`Publish [ ${topic}]: ${actionObj}`);
Expand Down Expand Up @@ -685,6 +687,7 @@ export async function addObject(obj, nameSpace, sceneName) {
const topic = TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace,
sceneName,
userClient: persist.userClient,
objectId: obj.object_id,
});
console.info(`Publish [ ${topic}]: ${objJson}`);
Expand Down
1 change: 1 addition & 0 deletions src/components/camera/arena-hand.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ AFRAME.registerComponent('arena-hand', {
this.topicBase = TOPICS.PUBLISH.SCENE_USER.formatStr({
nameSpace: ARENA.nameSpace,
sceneName: ARENA.sceneName,
userClient: ARENA.userClient,
});

el.addEventListener('controllerconnected', () => {
Expand Down
56 changes: 29 additions & 27 deletions src/constants/topics.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
* ARENA pubsub topic variables
* - nameSpace - namespace of the scene
* - sceneName - name of the scene
* - userName - name of the user per arena-auth (e.g. jdoe)
* - idTag - username prefixed with a uuid (e.g. 1448081341_jdoe)
* - userClient - name of the user client per arena-auth (e.g. jdoe_1448081341_web)
* - idTag - username prefixed with a uuid (e.g. jdoe_1448081341)
* - userObj - idTag prefixed with camera_ (e.g. camera_jdoe_1448081341)
*/

// TODO: handle this scriptImport somehow (which can't be done in parcel with a worker...)
Expand All @@ -32,8 +33,9 @@ const TOPICS = Object.freeze({
NAMESPACE: 2,
SCENENAME: 3,
SCENE_MSGTYPE: 4,
UUID: 5,
TO_UID: 6,
USER_CLIENT: 5,
UUID: 6,
TO_UID: 7,
},
SCENE_MSGTYPES: {
PRESENCE: 'x',
Expand All @@ -47,35 +49,35 @@ const TOPICS = Object.freeze({
},
SUBSCRIBE: {
NETWORK: '$NETWORK',
DEVICE: `${REALM}/d/{deviceName}/#`, // All client placeholder
DEVICE: `${REALM}/d/{nameSpace}/{deviceName}/#`, // All client placeholder
RT_RUNTIME: `${REALM}/g/{nameSpace}/p/{rtUuid}`,
RT_MODULES: `${REALM}/s/{nameSpace}/{sceneName}/p/+`,
SCENE_PUBLIC: `${REALM}/s/{nameSpace}/{sceneName}/+/+`,
SCENE_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/+/+/{idTag}/#`,
SCENE_RENDER_PUBLIC: `${REALM}/s/{nameSpace}/{sceneName}/r/-`, // TODO: consolidate
SCENE_RENDER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/r/-/{idTag}/#`, // TODO: consolidate
RT_MODULES: `${REALM}/s/{nameSpace}/{sceneName}/p/+/+`,
SCENE_PUBLIC: `${REALM}/s/{nameSpace}/{sceneName}/+/+/+`,
SCENE_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/+/+/+/{idTag}/#`,
SCENE_RENDER_PUBLIC: `${REALM}/s/{nameSpace}/{sceneName}/r/+/-`, // TODO: consolidate
SCENE_RENDER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/r/+/-/{idTag}/#`, // TODO: consolidate
},
PUBLISH: {
NETWORK_LATENCY: '$NETWORK/latency',
DEVICE: `${REALM}/d/{deviceName}/{idTag}`,
DEVICE: `${REALM}/d/{nameSpace}/{deviceName}/{idTag}`,
RT_RUNTIME: `${REALM}/g/{nameSpace}/p/{rtUuid}`,
RT_MODULES: `${REALM}/s/{nameSpace}/{sceneName}/p/{idTag}`,
RT_MODULES: `${REALM}/s/{nameSpace}/{sceneName}/p/{userClient}/{idTag}`,
PROC_DBG: `${REALM}/proc/debug/{uuid}`,
SCENE_PRESENCE: `${REALM}/s/{nameSpace}/{sceneName}/x/{idTag}`,
SCENE_PRESENCE_PRIVATE:`${REALM}/s/{nameSpace}/{sceneName}/x/{idTag}/{toUid}`,
SCENE_CHAT: `${REALM}/s/{nameSpace}/{sceneName}/c/{idTag}`,
SCENE_CHAT_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/c/{idTag}/{toUid}`,
SCENE_USER: `${REALM}/s/{nameSpace}/{sceneName}/u/{userObj}`,
SCENE_USER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/u/{userObj}/{toUid}`, // Need to add face_ privs
SCENE_OBJECTS: `${REALM}/s/{nameSpace}/{sceneName}/o/{objectId}`, // All client placeholder
SCENE_OBJECTS_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/o/{objectId}/{toUid}`,
SCENE_RENDER: `${REALM}/s/{nameSpace}/{sceneName}/r/{idTag}`,
SCENE_RENDER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/r/{idTag}/-`, // To avoid unpriv sub
SCENE_ENV: `${REALM}/s/{nameSpace}/{sceneName}/e/{idTag}`,
SCENE_ENV_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/e/{idTag}/-`, // To avoid unpriv sub
SCENE_PROGRAM: `${REALM}/s/{nameSpace}/{sceneName}/p/{idTag}`,
SCENE_PROGRAM_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/p/{idTag}/{toUid}`,
SCENE_DEBUG: `${REALM}/s/{nameSpace}/{sceneName}/d/{idTag}/-`, // To avoid unpriv sub
SCENE_PRESENCE: `${REALM}/s/{nameSpace}/{sceneName}/x/{userClient}/{idTag}`,
SCENE_PRESENCE_PRIVATE:`${REALM}/s/{nameSpace}/{sceneName}/x/{userClient}/{idTag}/{toUid}`,
SCENE_CHAT: `${REALM}/s/{nameSpace}/{sceneName}/c/{userClient}/{idTag}`,
SCENE_CHAT_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/c/{userClient}/{idTag}/{toUid}`,
SCENE_USER: `${REALM}/s/{nameSpace}/{sceneName}/u/{userClient}/{userObj}`,
SCENE_USER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/u/{userClient}/{userObj}/{toUid}`, // Need to add face_ privs
SCENE_OBJECTS: `${REALM}/s/{nameSpace}/{sceneName}/o/{userClient}/{objectId}`, // All client placeholder
SCENE_OBJECTS_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/o/{userClient}/{objectId}/{toUid}`,
SCENE_RENDER: `${REALM}/s/{nameSpace}/{sceneName}/r/{userClient}/{idTag}`,
SCENE_RENDER_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/r/{userClient}/{idTag}/-`, // To avoid unpriv sub
SCENE_ENV: `${REALM}/s/{nameSpace}/{sceneName}/e/{userClient}/{idTag}`,
SCENE_ENV_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/e/{userClient}/{idTag}/-`, // To avoid unpriv sub
SCENE_PROGRAM: `${REALM}/s/{nameSpace}/{sceneName}/p/{userClient}/{idTag}`,
SCENE_PROGRAM_PRIVATE: `${REALM}/s/{nameSpace}/{sceneName}/p/{userClient}/{idTag}/{toUid}`,
SCENE_DEBUG: `${REALM}/s/{nameSpace}/{sceneName}/d/{userClient}/{idTag}/-`, // To avoid unpriv sub
},
});

Expand Down
1 change: 1 addition & 0 deletions src/systems/build3d/build3d-mqtt-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ AFRAME.registerComponent('build3d-mqtt-object', {
TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace: ARENA.nameSpace,
sceneName: ARENA.sceneName,
userClient: ARENA.userClient,
object_id: msg.object_id,
}),
msg
Expand Down
1 change: 1 addition & 0 deletions src/systems/build3d/build3d-mqtt-scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function publishUploadedFile(newObj) {
TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace: ARENA.nameSpace,
sceneName: ARENA.sceneName,
userClient: ARENA.userClient,
object_id: newObj.object_id,
}),
newObj
Expand Down
8 changes: 7 additions & 1 deletion src/systems/core/arena.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ AFRAME.registerSystem('arena-scene', {

// id tag including name is set from authentication service
this.setIdTag(this.mqttToken.ids.userid);
this.userClient = this.mqttToken.ids.userclient;

// Reuse object for topic parameters
this.topicParams = {
nameSpace: this.nameSpace,
sceneName: this.sceneName,
userClient: this.userClient,
idTag: this.idTag,
userObj: this.idTag,
};
Expand Down Expand Up @@ -224,7 +226,8 @@ AFRAME.registerSystem('arena-scene', {
mqttToken: this.mqttToken.mqtt_token,
nameSpace: this.nameSpace,
sceneName: this.sceneName,
idTag: this.idTag,
idTag: this.idTag,
userClient: this.userClient,
});
this.RuntimeManager.init();
},
Expand Down Expand Up @@ -313,6 +316,7 @@ AFRAME.registerSystem('arena-scene', {
const usersTopic = TOPICS.PUBLISH.SCENE_PRESENCE.formatStr({
nameSpace: this.nameSpace,
sceneName: this.sceneName,
userClient: this.userClient,
idTag: this.idTag,
});
return ARENAAUTH.matchJWT(usersTopic, this.mqttToken.token_payload.publ);
Expand All @@ -330,6 +334,7 @@ AFRAME.registerSystem('arena-scene', {
const writeTopic = TOPICS.PUBLISH.SCENE_OBJECTS.formatStr({
nameSpace: this.nameSpace,
sceneName: this.sceneName,
userClient: this.userClient,
idTag: '+',
});
return ARENAAUTH.matchJWT(writeTopic, this.mqttToken.token_payload.publ);
Expand All @@ -348,6 +353,7 @@ AFRAME.registerSystem('arena-scene', {
const chatTopic = TOPICS.PUBLISH.SCENE_CHAT.formatStr({
nameSpace: this.nameSpace,
sceneName: this.sceneName,
userClient: this.userClient,
idTag: this.idTag,
});
return ARENAAUTH.matchJWT(chatTopic, this.mqttToken.token_payload.publ);
Expand Down
3 changes: 2 additions & 1 deletion src/systems/core/mqtt.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ AFRAME.registerSystem('arena-mqtt', {
this.MQTTWorker = await this.initWorker();

const mqttToken = ARENA.mqttToken.mqtt_token;
const { nameSpace, sceneName, idTag } = ARENA;
const { nameSpace, sceneName, userClient, idTag } = ARENA;
// Do not pass functions in mqttClientOptions
ARENA.Mqtt = this; // Restore old alias
this.connect(
Expand All @@ -60,6 +60,7 @@ AFRAME.registerSystem('arena-mqtt', {
TOPICS.PUBLISH.SCENE_PRESENCE.formatStr({
nameSpace,
sceneName,
userClient,
idTag,
})
);
Expand Down
8 changes: 5 additions & 3 deletions src/systems/core/runtime-mngr/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ export default class RuntimeMngr {
realm = TOPICS.REALM,
nameSpace = 'public',
sceneName = 'default',
idTag = `${Math.floor(Math.random() * 10000000000 + 1000000000)}-anonymous-User`,
idTag = 'MissingAuthIdTag',
userClient = 'MissingAuthUserCLient',
uuid = UUID.generate(),
name = `rt-${(Math.random() + 1).toString(36).substring(2)}`,
maxNmodules = 0, // TMP: cannot run any modules
Expand Down Expand Up @@ -120,13 +121,14 @@ export default class RuntimeMngr {
nameSpace,
rtUuid: uuid,
});
// {nameSpace}/{sceneName}/p/{idTag}
// {nameSpace}/{sceneName}/p/{userClient}/{idTag}
this.modulesTopicPub = TOPICS.PUBLISH.RT_MODULES.formatStr({
nameSpace,
sceneName,
userClient,
idTag,
});
// {nameSpace}/{sceneName}/p/+
// {nameSpace}/{sceneName}/p/+/+
this.modulesTopicSub = TOPICS.SUBSCRIBE.RT_MODULES.formatStr({
nameSpace,
sceneName,
Expand Down
1 change: 1 addition & 0 deletions src/systems/face-tracking/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ AFRAME.registerSystem('face-tracking', {
const faceTopic = TOPICS.PUBLISH.SCENE_USER.formatStr({
nameSpace: ARENA.nameSpace,
sceneName: ARENA.sceneName,
userClient: ARENA.userClient,
userObj: ARENA.faceName,
});

Expand Down
2 changes: 2 additions & 0 deletions src/systems/ui/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ AFRAME.registerSystem('arena-chat-ui', {
this.liveUsers = {};

this.userId = this.arena.idTag;
this.userClient = this.arena.userClient;
this.realm = ARENA.defaults.realm;
this.displayName = ARENA.getDisplayName();
this.nameSpace = this.arena.nameSpace;
Expand All @@ -98,6 +99,7 @@ AFRAME.registerSystem('arena-chat-ui', {
const topicVars = {
nameSpace: this.nameSpace,
sceneName: this.scene,
userClient: this.userClient,
idTag: this.userId,
};
this.publicChatTopic = TOPICS.PUBLISH.SCENE_CHAT.formatStr(topicVars);
Expand Down
2 changes: 1 addition & 1 deletion static/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ window.ARENAAUTH = {
const authParams = {
username: mqttUsername,
id_auth: authType,
client: 'web',
};
if (ARENA.params.realm) {
authParams.realm = ARENA.params.realm;
Expand All @@ -221,7 +222,6 @@ window.ARENAAUTH = {
if (ARENA.sceneName) {
authParams.scene = ARENA.namespacedScene;
}
authParams.userid = true;
authParams.camid = true;
authParams.handleftid = true;
authParams.handrightid = true;
Expand Down

0 comments on commit 2c4fc6f

Please sign in to comment.