You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mod_token_verification.lua 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. -- Token authentication
  2. -- Copyright (C) 2015 Atlassian
  3. local log = module._log;
  4. local host = module.host;
  5. local st = require "util.stanza";
  6. local um_is_admin = require "core.usermanager".is_admin;
  7. local function is_admin(jid)
  8. return um_is_admin(jid, host);
  9. end
  10. local parentHostName = string.gmatch(tostring(host), "%w+.(%w.+)")();
  11. if parentHostName == nil then
  12. log("error", "Failed to start - unable to get parent hostname");
  13. return;
  14. end
  15. local parentCtx = module:context(parentHostName);
  16. if parentCtx == nil then
  17. log("error",
  18. "Failed to start - unable to get parent context for host: %s",
  19. tostring(parentHostName));
  20. return;
  21. end
  22. local token_util = module:require "token/util".new(parentCtx);
  23. -- no token configuration
  24. if token_util == nil then
  25. return;
  26. end
  27. log("debug",
  28. "%s - starting MUC token verifier app_id: %s app_secret: %s allow empty: %s",
  29. tostring(host), tostring(token_util.appId), tostring(token_util.appSecret),
  30. tostring(token_util.allowEmptyToken));
  31. -- option to disable room modification (sending muc config form) for guest that do not provide token
  32. local require_token_for_moderation;
  33. local function load_config()
  34. require_token_for_moderation = module:get_option_boolean("token_verification_require_token_for_moderation");
  35. end
  36. load_config();
  37. -- verify user and whether he is allowed to join a room based on the token information
  38. local function verify_user(session, stanza)
  39. log("debug", "Session token: %s, session room: %s",
  40. tostring(session.auth_token),
  41. tostring(session.jitsi_meet_room));
  42. -- token not required for admin users
  43. local user_jid = stanza.attr.from;
  44. if is_admin(user_jid) then
  45. log("debug", "Token not required from admin user: %s", user_jid);
  46. return true;
  47. end
  48. log("debug",
  49. "Will verify token for user: %s, room: %s ", user_jid, stanza.attr.to);
  50. if not token_util:verify_room(session, stanza.attr.to) then
  51. log("error", "Token %s not allowed to join: %s",
  52. tostring(session.auth_token), tostring(stanza.attr.to));
  53. session.send(
  54. st.error_reply(
  55. stanza, "cancel", "not-allowed", "Room and token mismatched"));
  56. return false; -- we need to just return non nil
  57. end
  58. log("debug",
  59. "allowed: %s to enter/create room: %s", user_jid, stanza.attr.to);
  60. return true;
  61. end
  62. module:hook("muc-room-pre-create", function(event)
  63. local origin, stanza = event.origin, event.stanza;
  64. log("debug", "pre create: %s %s", tostring(origin), tostring(stanza));
  65. if not verify_user(origin, stanza) then
  66. return true; -- Returning any value other than nil will halt processing of the event
  67. end
  68. end);
  69. module:hook("muc-occupant-pre-join", function(event)
  70. local origin, room, stanza = event.origin, event.room, event.stanza;
  71. log("debug", "pre join: %s %s", tostring(room), tostring(stanza));
  72. if not verify_user(origin, stanza) then
  73. return true; -- Returning any value other than nil will halt processing of the event
  74. end
  75. end);
  76. for event_name, method in pairs {
  77. -- Normal room interactions
  78. ["iq-set/bare/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_set_to_room" ;
  79. -- Host room
  80. ["iq-set/host/http://jabber.org/protocol/muc#owner:query"] = "handle_owner_query_set_to_room" ;
  81. } do
  82. module:hook(event_name, function (event)
  83. local session, stanza = event.origin, event.stanza;
  84. -- if we do not require token we pass it through(default behaviour)
  85. -- or the request is coming from admin (focus)
  86. if not require_token_for_moderation or is_admin(stanza.attr.from) then
  87. return;
  88. end
  89. -- jitsi_meet_room is set after the token had been verified
  90. if not session.auth_token or not session.jitsi_meet_room then
  91. session.send(
  92. st.error_reply(
  93. stanza, "cancel", "not-allowed", "Room modification disabled for guests"));
  94. return true;
  95. end
  96. end, -1); -- the default prosody hook is on -2
  97. end
  98. module:hook_global('config-reloaded', load_config);