From ce93e5bbaaa87268fc10b1b7d949fe826299c1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 10:37:00 +0200 Subject: [PATCH 1/7] Fixing the way rights are sent to the admin (now sending organization/world/room) --- back/src/Model/RoomIdentifier.ts | 19 +++++++++++++++---- back/src/Services/AdminApi.ts | 3 +-- front/src/Connexion/Room.ts | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/back/src/Model/RoomIdentifier.ts b/back/src/Model/RoomIdentifier.ts index 2cba16fd..d1516264 100644 --- a/back/src/Model/RoomIdentifier.ts +++ b/back/src/Model/RoomIdentifier.ts @@ -1,14 +1,25 @@ export class RoomIdentifier { - public anonymous: boolean; - public id:string + public readonly anonymous: boolean; + public readonly id:string + public readonly organizationSlug: string|undefined; + public readonly worldSlug: string|undefined; + public readonly roomSlug: string|undefined; constructor(roomID: string) { if (roomID.startsWith('_/')) { this.anonymous = true; } else if(roomID.startsWith('@/')) { this.anonymous = false; + + const match = /@\/([^/]+)\/([^/]+)\/(.+)/.exec(roomID); + if (!match) { + throw new Error('Could not extract info from "'+roomID+'"'); + } + this.organizationSlug = match[1]; + this.worldSlug = match[2]; + this.roomSlug = match[3]; } else { throw new Error('Incorrect room ID: '+roomID); } - this.id = roomID; //todo: extract more data from the id (like room slug, organization name, etc); + this.id = roomID; } -} \ No newline at end of file +} diff --git a/back/src/Services/AdminApi.ts b/back/src/Services/AdminApi.ts index 9e64296c..0039dc9c 100644 --- a/back/src/Services/AdminApi.ts +++ b/back/src/Services/AdminApi.ts @@ -51,9 +51,8 @@ class AdminApi { return Promise.reject('No admin backoffice set!'); } try { - //todo: send more specialized data instead of the whole id const res = await Axios.get(ADMIN_API_URL+'/api/member/is-granted-access', - { headers: {"Authorization" : `${ADMIN_API_TOKEN}`}, params: {memberId, roomIdentifier: roomIdentifier.id} } + { headers: {"Authorization" : `${ADMIN_API_TOKEN}`}, params: {memberId, organizationSlug: roomIdentifier.organizationSlug, worldSlug: roomIdentifier.worldSlug, roomSlug: roomIdentifier.roomSlug} } ) return !!res.data; } catch (e) { diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index 01509aa3..308ea5a2 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -66,7 +66,7 @@ export class Room { this.instance = match[1]; return this.instance; } else { - const match = /_\/([^/]+)\/([^/]+)\/.+/.exec(this.id); + const match = /@\/([^/]+)\/([^/]+)\/.+/.exec(this.id); if (!match) throw new Error('Could not extract instance from "'+this.id+'"'); this.instance = match[1]+'/'+match[2]; return this.instance; From 98bda49d7e3bfeb6a8c544e9669dbd36cd020f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 11:07:34 +0200 Subject: [PATCH 2/7] Get tags from the admin And uses tag "admin" to choose whether to display the console or not --- back/src/Controller/IoSocketController.ts | 11 ++++++++--- back/src/Model/Websocket/ExSocketInterface.ts | 5 +++-- back/src/Services/AdminApi.ts | 14 +++++++++++--- front/src/Connexion/RoomConnection.ts | 6 ++++++ front/src/Phaser/Game/GameScene.ts | 7 ++++--- messages/messages.proto | 1 + 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index d2a697c9..6b112e9e 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -145,12 +145,14 @@ export class IoSocketController { const userUuid = await jwtTokenManager.getUserUuidFromToken(token); console.log('uuid', userUuid); + let memberTags: string[] = []; if (roomIdentifier.anonymous === false) { - const isGranted = await adminApi.memberIsGrantedAccessToRoom(userUuid, roomIdentifier); - if (!isGranted) { + const grants = await adminApi.memberIsGrantedAccessToRoom(userUuid, roomIdentifier); + if (!grants.granted) { console.log('access not granted for user '+userUuid+' and room '+roomId); throw new Error('Client cannot acces this ressource.') } else { + memberTags = grants.memberTags; console.log('access granted for user '+userUuid+' and room '+roomId); } } @@ -181,7 +183,8 @@ export class IoSocketController { right, bottom, left - } + }, + tags: memberTags }, /* Spell these correctly */ websocketKey, @@ -218,6 +221,7 @@ export class IoSocketController { client.name = ws.name; client.characterLayers = ws.characterLayers; client.roomId = ws.roomId; + client.tags = ws.tags; this.sockets.set(client.userId, client); @@ -353,6 +357,7 @@ export class IoSocketController { } roomJoinedMessage.setCurrentuserid(client.userId); + roomJoinedMessage.setTagList(client.tags); const serverToClientMessage = new ServerToClientMessage(); serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage); diff --git a/back/src/Model/Websocket/ExSocketInterface.ts b/back/src/Model/Websocket/ExSocketInterface.ts index d70205ef..a41d34bb 100644 --- a/back/src/Model/Websocket/ExSocketInterface.ts +++ b/back/src/Model/Websocket/ExSocketInterface.ts @@ -7,7 +7,7 @@ import {WebSocket} from "uWebSockets.js" export interface ExSocketInterface extends WebSocket, Identificable { token: string; roomId: string; - userId: number; // A temporary (autoincremented) identifier for this user + //userId: number; // A temporary (autoincremented) identifier for this user userUuid: string; // A unique identifier for this user name: string; characterLayers: string[]; @@ -19,5 +19,6 @@ export interface ExSocketInterface extends WebSocket, Identificable { emitInBatch: (payload: SubMessage) => void; batchedMessages: BatchMessage; batchTimeout: NodeJS.Timeout|null; - disconnecting: boolean + disconnecting: boolean, + tags: string[] } diff --git a/back/src/Services/AdminApi.ts b/back/src/Services/AdminApi.ts index 0039dc9c..605af738 100644 --- a/back/src/Services/AdminApi.ts +++ b/back/src/Services/AdminApi.ts @@ -10,6 +10,11 @@ export interface AdminApiData { userUuid: string } +export interface GrantedApiData { + granted: boolean, + memberTags: string[] +} + class AdminApi { async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise { @@ -46,7 +51,7 @@ class AdminApi { return res.data; } - async memberIsGrantedAccessToRoom(memberId: string, roomIdentifier: RoomIdentifier): Promise { + async memberIsGrantedAccessToRoom(memberId: string, roomIdentifier: RoomIdentifier): Promise { if (!ADMIN_API_URL) { return Promise.reject('No admin backoffice set!'); } @@ -54,10 +59,13 @@ class AdminApi { const res = await Axios.get(ADMIN_API_URL+'/api/member/is-granted-access', { headers: {"Authorization" : `${ADMIN_API_TOKEN}`}, params: {memberId, organizationSlug: roomIdentifier.organizationSlug, worldSlug: roomIdentifier.worldSlug, roomSlug: roomIdentifier.roomSlug} } ) - return !!res.data; + return res.data; } catch (e) { console.log(e.message) - return false; + return { + granted: false, + memberTags: [] + }; } } } diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 48f6f9f1..3f0bb84e 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -43,6 +43,7 @@ export class RoomConnection implements RoomConnection { private listeners: Map = new Map(); private static websocketFactory: null|((url: string)=>any) = null; // eslint-disable-line @typescript-eslint/no-explicit-any private closed: boolean = false; + private tags: string[] = []; public static setWebsocketFactory(websocketFactory: (url: string)=>any): void { // eslint-disable-line @typescript-eslint/no-explicit-any RoomConnection.websocketFactory = websocketFactory; @@ -124,6 +125,7 @@ export class RoomConnection implements RoomConnection { } this.userId = roomJoinedMessage.getCurrentuserid(); + this.tags = roomJoinedMessage.getTagList(); this.dispatch(EventMessage.START_ROOM, { users, @@ -478,4 +480,8 @@ export class RoomConnection implements RoomConnection { this.socket.send(clientToServerMessage.serializeBinary().buffer); } + + public hasTag(tag: string): boolean { + return this.tags.indexOf(tag) !== -1; + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 490284b4..4e209c42 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -397,9 +397,6 @@ export class GameScene extends ResizableScene implements CenterListener { //create input to move this.userInputManager = new UserInputManager(this); - //TODO check right of user - this.ConsoleGlobalMessageManager = new ConsoleGlobalMessageManager(this.connection, this.userInputManager); - //notify game manager can to create currentUser in map this.createCurrentPlayer(); @@ -530,6 +527,10 @@ export class GameScene extends ResizableScene implements CenterListener { connection.onStartRoom((roomJoinedMessage: RoomJoinedMessageInterface) => { this.initUsersPosition(roomJoinedMessage.users); this.connectionAnswerPromiseResolve(roomJoinedMessage); + // Analyze tags to find if we are admin. If yes, show console. + if (this.connection.hasTag('admin')) { + this.ConsoleGlobalMessageManager = new ConsoleGlobalMessageManager(this.connection, this.userInputManager); + } }); connection.onUserJoins((message: MessageUserJoined) => { diff --git a/messages/messages.proto b/messages/messages.proto index a5134b56..935e033b 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -139,6 +139,7 @@ message RoomJoinedMessage { repeated GroupUpdateMessage group = 2; repeated ItemStateMessage item = 3; int32 currentUserId = 4; + repeated string tag = 5; } message WebRtcStartMessage { From 731ccd8796c8481de8e442f7ed75fb5b759b48ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 11:48:34 +0200 Subject: [PATCH 3/7] Fix CI --- front/src/Connexion/RoomConnection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 3f0bb84e..e53bc2f8 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -482,6 +482,6 @@ export class RoomConnection implements RoomConnection { } public hasTag(tag: string): boolean { - return this.tags.indexOf(tag) !== -1; + return this.tags.includes(tag); } } From cf4c608360f0fa100e674c01a5a693c78fcdff1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 12:00:23 +0200 Subject: [PATCH 4/7] Adding ADMIN_API_TOKEN to deployment --- deeployer.libsonnet | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deeployer.libsonnet b/deeployer.libsonnet index 74606da4..df04399a 100644 --- a/deeployer.libsonnet +++ b/deeployer.libsonnet @@ -14,7 +14,9 @@ }, "ports": [8080], "env": { - "SECRET_KEY": "tempSecretKeyNeedsToChange" + "SECRET_KEY": "tempSecretKeyNeedsToChange", + "ADMIN_API_TOKEN": env.ADMIN_API_TOKEN, + "ADMIN_API_URL": "https://admin."+url } }, "front": { From ff37e0f9b9a6ef8d230a888f7971266b0d0bc378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 12:25:05 +0200 Subject: [PATCH 5/7] Adding ADMIN_API_TOKEN --- .github/workflows/build-and-deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 7e7c9014..25d2b0cd 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -120,6 +120,7 @@ jobs: uses: thecodingmachine/deeployer@master env: KUBE_CONFIG_FILE: ${{ secrets.KUBE_CONFIG_FILE }} + ADMIN_API_TOKEN: ${{ secrets.ADMIN_API_TOKEN }} with: namespace: workadventure-${{ env.GITHUB_REF_SLUG }} From b7340022de8c47efc53f96cf826ab0668531e26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 13:29:16 +0200 Subject: [PATCH 6/7] Fixing rewriterule with @ in prod --- front/dist/.htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/dist/.htaccess b/front/dist/.htaccess index 53979e53..cc97cd5a 100644 --- a/front/dist/.htaccess +++ b/front/dist/.htaccess @@ -20,4 +20,4 @@ RewriteBase / # We only want to let Apache serve files and not directories. # Rewrite all other queries starting with _ to index.ts. RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule "^_/" "/index.html" [L] +RewriteRule "^[_@]/" "/index.html" [L] From 807ccc49d4a86aa2003edeed7d5f9f3185c2ed23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 14 Oct 2020 13:52:02 +0200 Subject: [PATCH 7/7] Fixing rewriterule with register link in prod --- front/dist/.htaccess | 1 + 1 file changed, 1 insertion(+) diff --git a/front/dist/.htaccess b/front/dist/.htaccess index cc97cd5a..72c4d724 100644 --- a/front/dist/.htaccess +++ b/front/dist/.htaccess @@ -21,3 +21,4 @@ RewriteBase / # Rewrite all other queries starting with _ to index.ts. RewriteCond %{REQUEST_FILENAME} !-f RewriteRule "^[_@]/" "/index.html" [L] +RewriteRule "^register/" "/index.html" [L]