Browse Source

add jitsi-meet config to tracim config

Guénaël Muller 7 years ago
parent
commit
ddcbbe63c7

+ 10 - 0
tracim/development.ini.base View File

235
 # it's just an empty file use to prevent concurrent access to imap unseen mail
235
 # it's just an empty file use to prevent concurrent access to imap unseen mail
236
 email.reply.lockfile_path = %(here)s/email_fetcher.lock
236
 email.reply.lockfile_path = %(here)s/email_fetcher.lock
237
 
237
 
238
+## Jitsi_meet_integration
239
+jitsi_meet.activated = False
240
+jitsi_meet.domain = your_jitsi_meet_instance
241
+jitsi_meet.use_token = False
242
+jitsi_meet.token_generator = local
243
+jitsi_meet.token_generator.local.app_id = tracim
244
+jitsi_meet.token_generator.local.secret = my_secret
245
+jitsi_meet.token_generator.local.algo = HS256
246
+jitsi_meet.token_generator.local.duration = 60
247
+
238
 ## Radical (CalDav server) configuration
248
 ## Radical (CalDav server) configuration
239
 # radicale.server.host = 0.0.0.0
249
 # radicale.server.host = 0.0.0.0
240
 # radicale.server.port = 5232
250
 # radicale.server.port = 5232

+ 30 - 0
tracim/tracim/config/app_cfg.py View File

436
             # ContentType.Folder -- Folder is skipped
436
             # ContentType.Folder -- Folder is skipped
437
         ]
437
         ]
438
 
438
 
439
+        self.JITSI_MEET_ACTIVATED = asbool(tg.config.get(
440
+            'jitsi_meet.activated',
441
+            False,
442
+        ))
443
+        self.JITSI_MEET_DOMAIN = tg.config.get(
444
+            'jitsi_meet.domain'
445
+        )
446
+        self.JITSI_MEET_USE_TOKEN = asbool(tg.config.get(
447
+            'jitsi_meet.use_token',
448
+            False,
449
+        ))
450
+        self.JITSI_MEET_TOKEN_GENERATOR = tg.config.get(
451
+            'jitsi_meet.token_generator',
452
+            'local'
453
+        )
454
+        self.JITSI_MEET_TOKEN_GENERATOR_LOCAL_APP_ID = tg.config.get(
455
+            'jitsi_meet.token_generator.local.app_id'
456
+        )
457
+        self.JITSI_MEET_TOKEN_GENERATOR_LOCAL_SECRET = tg.config.get(
458
+            'jitsi_meet.token_generator.local.secret'
459
+        )
460
+        self.JITSI_MEET_TOKEN_GENERATOR_LOCAL_ALG = tg.config.get(
461
+            'jitsi_meet.token_generator.local.alg',
462
+            'HS256'
463
+        )
464
+        self.JITSI_MEET_TOKEN_GENERATOR_LOCAL_DURATION = int(tg.config.get(
465
+            'jitsi_meet.token_generator.local.duration',
466
+            60
467
+        ))
468
+
439
         self.RADICALE_SERVER_HOST = tg.config.get(
469
         self.RADICALE_SERVER_HOST = tg.config.get(
440
             'radicale.server.host',
470
             'radicale.server.host',
441
             '127.0.0.1',
471
             '127.0.0.1',

+ 28 - 7
tracim/tracim/controllers/root.py View File

8
 from tg import require
8
 from tg import require
9
 from tg import tmpl_context
9
 from tg import tmpl_context
10
 from tg import url
10
 from tg import url
11
+from tg import abort
11
 from tg.i18n import ugettext as _
12
 from tg.i18n import ugettext as _
12
 
13
 
13
 from tracim.controllers import StandardController
14
 from tracim.controllers import StandardController
33
 from tracim.model.serializers import CTX
34
 from tracim.model.serializers import CTX
34
 from tracim.model.serializers import DictLikeClass
35
 from tracim.model.serializers import DictLikeClass
35
 from tracim.lib.jitsi_meet.jitsi_meet import JitsiMeetRoom
36
 from tracim.lib.jitsi_meet.jitsi_meet import JitsiMeetRoom
36
-
37
+from tracim.lib.jitsi_meet.jitsi_meet import JitsiTokenConfig
38
+from tracim.config.app_cfg import CFG
37
 
39
 
38
 class RootController(StandardController):
40
 class RootController(StandardController):
39
     """
41
     """
183
     @require(predicates.not_anonymous())
185
     @require(predicates.not_anonymous())
184
     @expose('tracim.templates.videoconf')
186
     @expose('tracim.templates.videoconf')
185
     def videoconf(self):
187
     def videoconf(self):
188
+        cfg = CFG.get_instance()
189
+        if not cfg.JITSI_MEET_ACTIVATED:
190
+            abort(404)
186
         user = tmpl_context.current_user
191
         user = tmpl_context.current_user
187
         current_user_content = Context(CTX.CURRENT_USER).toDict(user)
192
         current_user_content = Context(CTX.CURRENT_USER).toDict(user)
188
-        fake_api = Context(CTX.CURRENT_USER).toDict({'current_user': current_user_content})
193
+        fake_api = Context(CTX.CURRENT_USER).toDict(
194
+            {'current_user': current_user_content}
195
+        )
196
+
189
         room = 'test'
197
         room = 'test'
190
-        token = JitsiMeetRoom.generate_token(room)
191
-        domain = JitsiMeetRoom.domain
198
+
199
+        token = None
200
+        if cfg.JITSI_MEET_USE_TOKEN:
201
+            if cfg.JITSI_MEET_TOKEN_GENERATOR == 'local':
202
+                token = JitsiTokenConfig(
203
+                    app_id=cfg.JITSI_MEET_TOKEN_GENERATOR_LOCAL_APP_ID,
204
+                    secret=cfg.JITSI_MEET_TOKEN_GENERATOR_LOCAL_SECRET,
205
+                    alg=cfg.JITSI_MEET_TOKEN_GENERATOR_LOCAL_ALG,
206
+                    duration=cfg.JITSI_MEET_TOKEN_GENERATOR_LOCAL_DURATION,
207
+                )
208
+            else:
209
+                abort(400)
210
+
211
+        jitsi_meet_room = JitsiMeetRoom(
212
+            room=room,
213
+            domain=cfg.JITSI_MEET_DOMAIN,
214
+            token_config=token)
192
 
215
 
193
         return DictLikeClass(fake_api=fake_api,
216
         return DictLikeClass(fake_api=fake_api,
194
-                             token=token,
195
-                             room=room,
196
-                             domain=domain)
217
+                             jitsi_meet_room=jitsi_meet_room)

+ 24 - 35
tracim/tracim/lib/jitsi_meet/jitsi_meet.py View File

3
 
3
 
4
 import jwt
4
 import jwt
5
 
5
 
6
-JITSI_DOMAIN = "prosody"
7
-JWT_APP_ID = "test"
8
-JWT_SECRET = "secret"
9
-JWT_ALG = 'HS256'
10
-JWT_DURATION = 60*1  # duration in second
11
-JITSI_USE_TOKEN = True
12
 
6
 
13
-
14
-class JitsiTokenConfig:
7
+class JitsiTokenConfig(object):
15
 
8
 
16
     def __init__(self,
9
     def __init__(self,
17
                  app_id: str,
10
                  app_id: str,
19
                  alg: str,
12
                  alg: str,
20
                  duration: int,
13
                  duration: int,
21
                  )-> None:
14
                  )-> None:
15
+        """
16
+        JWT token generator config for JitsiMeet,
17
+        :param app_id: application identifier
18
+        :param secret: secret share between token generator and XMPP server
19
+        :param alg: algorithm used
20
+        :param duration: duration of token
21
+        """
22
         self.app_id = app_id
22
         self.app_id = app_id
23
         self.secret = secret
23
         self.secret = secret
24
         self.alg = alg
24
         self.alg = alg
25
         self.duration = duration
25
         self.duration = duration
26
 
26
 
27
 
27
 
28
-class JitsiMeetRoomHandler:
28
+class JitsiMeetRoom(object):
29
 
29
 
30
     def __init__(self,
30
     def __init__(self,
31
                  domain: str,
31
                  domain: str,
32
+                 room: str,
32
                  token_config: typing.Optional[JitsiTokenConfig],
33
                  token_config: typing.Optional[JitsiTokenConfig],
33
                  ) -> None:
34
                  ) -> None:
35
+        """
36
+        JitsiMeet room Parameters
37
+        :param domain: jitsi-meet domain
38
+        :param room: room name
39
+        :param token_config: token config, None if token not used.
40
+        """
34
         self.domain = domain
41
         self.domain = domain
42
+        self.room = room
35
         self.token_config = token_config
43
         self.token_config = token_config
36
 
44
 
37
-    def generate_token(self, room: str)->str:
45
+    def generate_token(self) -> str:
38
         """
46
         """
39
         Create jwt token according to room name and config
47
         Create jwt token according to room name and config
40
-        :param room: room name
48
+        see https://github.com/jitsi/lib-jitsi-meet/blob/master/doc/tokens.md
41
         :return: jwt encoded token as string
49
         :return: jwt encoded token as string
42
         """
50
         """
43
         assert self.token_config
51
         assert self.token_config
45
         exp = now+datetime.timedelta(seconds=self.token_config.duration)
53
         exp = now+datetime.timedelta(seconds=self.token_config.duration)
46
         data = {
54
         data = {
47
             "iss": self.token_config.app_id,  # Issuer
55
             "iss": self.token_config.app_id,  # Issuer
48
-            "room": room,  # Custom-param for jitsi_meet
56
+            "room": self.room,  # Custom-param for jitsi_meet
49
             "aud": "*",  # TODO: Understood this param
57
             "aud": "*",  # TODO: Understood this param
50
             "exp": exp,  # Expiration date
58
             "exp": exp,  # Expiration date
51
             "nbf": now,  # NotBefore
59
             "nbf": now,  # NotBefore
56
                                algorithm=self.token_config.alg)
64
                                algorithm=self.token_config.alg)
57
         return jwt_token.decode("utf-8")
65
         return jwt_token.decode("utf-8")
58
 
66
 
59
-    def generate_url(self, room: str)->str:
67
+    def generate_url(self) -> str:
60
         """
68
         """
61
         Generate url with or without token
69
         Generate url with or without token
62
-        :param room: room name
63
         :return: url as string
70
         :return: url as string
64
         """
71
         """
65
         if self.token_config:
72
         if self.token_config:
66
-            token = self.generate_token(room)
73
+            token = self.generate_token()
67
             url = "{}/{}?jwt={}".format(self.domain,
74
             url = "{}/{}?jwt={}".format(self.domain,
68
-                                        room,
75
+                                        self.room,
69
                                         token,)
76
                                         token,)
70
         else:
77
         else:
71
             url = "{}/{}".format(self.domain,
78
             url = "{}/{}".format(self.domain,
72
-                                 room,)
79
+                                 self.room,)
73
         return "https://{}".format(url)
80
         return "https://{}".format(url)
74
-
75
-if JITSI_USE_TOKEN:
76
-    defaultTokenConfig = JitsiTokenConfig(
77
-        app_id=JWT_APP_ID,
78
-        secret=JWT_SECRET,
79
-        alg=JWT_ALG,
80
-        duration=JWT_DURATION,
81
-    )
82
-else:
83
-    defaultTokenConfig = None
84
-
85
-JitsiMeetRoom = JitsiMeetRoomHandler(
86
-    domain=JITSI_DOMAIN,
87
-    token_config= defaultTokenConfig
88
-)
89
-
90
-if __name__ == '__main__' :
91
-    print(JitsiMeetRoom.generate_url('test'))

+ 6 - 3
tracim/tracim/templates/videoconf.mak View File

40
         // It support alls jitsi-meet features.
40
         // It support alls jitsi-meet features.
41
         // About support for "private (1-to-1) text message into room", check this :
41
         // About support for "private (1-to-1) text message into room", check this :
42
         // https://github.com/jitsi/lib-jitsi-meet/pull/616
42
         // https://github.com/jitsi/lib-jitsi-meet/pull/616
43
-        var domain = '${domain}';
43
+        var domain = '${jitsi_meet_room.domain}';
44
         var options = {
44
         var options = {
45
 	    // jitsi-meet support now(10-2017) only one way to auto-auth, token,
45
 	    // jitsi-meet support now(10-2017) only one way to auto-auth, token,
46
 	    // which is anonymous BOSH auth with specific url (with token value in params of the url).
46
 	    // which is anonymous BOSH auth with specific url (with token value in params of the url).
47
-            jwt: '${token}',
48
-            roomName : '${room}',
47
+            %if jitsi_meet_room.token_config:
48
+                jwt: '${jitsi_meet_room.generate_token()}',
49
+            %endif
50
+            roomName : '${jitsi_meet_room.room}',
49
             parentNode: document.querySelector('#jitsi'),
51
             parentNode: document.querySelector('#jitsi'),
50
 	    // has external API use iframe, height is a problem
52
 	    // has external API use iframe, height is a problem
51
             height: 800,
53
             height: 800,
87
         // We can override also avatar.
89
         // We can override also avatar.
88
         api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647');
90
         api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647');
89
     </script>
91
     </script>
92
+    ${jitsi_meet_room.generate_url()}
90
 </div>
93
 </div>
91
 
94