4655
+ − 1 local array = require "util.array" ;
+ − 2 local st = require "util.stanza" ;
+ − 3
+ − 4 local tos_version = assert ( module : get_option ( "tos_version" ), "tos_version must be set" )
+ − 5
+ − 6 local status_storage ;
+ − 7 if prosody . process_type == "prosody" or prosody . shutdown then
+ − 8 status_storage = module : open_store ( "tos_status" , "keyval" )
+ − 9 end
+ − 10
+ − 11 local documents = array {};
+ − 12
+ − 13 local function validate_doc ( doc )
+ − 14 if not doc . title or not doc . sources or # doc . sources < 1 then
+ − 15 return false , "document needs to have a title and at least one source"
+ − 16 end
+ − 17 for _ , source in ipairs ( doc . sources ) do
+ − 18 if not source . url or not source . type then
+ − 19 return false , "document " .. doc . title .. " has a source without url or type"
+ − 20 end
+ − 21 end
+ − 22 return true , doc
+ − 23 end
+ − 24
+ − 25 for _ , doc in ipairs ( assert ( module : get_option ( "tos_documents" ), "tos_documents option is required" )) do
+ − 26 local ok , doc_or_err = validate_doc ( doc )
+ − 27 if not ok then
+ − 28 error ( "invalid TOS document: " .. doc_or_err )
+ − 29 end
+ − 30 documents : push ( doc );
+ − 31 end
+ − 32
+ − 33 local function send_tos_push ( session )
+ − 34 local to = session . username .. "@" .. session . host .. "/" .. session . resource ;
+ − 35 local push = st . message ({
+ − 36 type = "headline" ,
+ − 37 to = to ,
+ − 38 }, "In order to continue to use the service, you have to accept the current version of the Terms of Service." );
+ − 39 local tos = push : tag ( "tos-push" , { xmlns = "urn:xmpp:tos:0" }): tag ( "tos" , { version = tos_version });
+ − 40 for _ , doc in ipairs ( documents ) do
+ − 41 local doc_tag = tos : tag ( "document" ): text_tag ( "title" , doc . title );
+ − 42 for _ , source in ipairs ( doc . sources ) do
+ − 43 doc_tag : tag ( "source" , { url = source . url , type = source . type }): up ();
+ − 44 end
+ − 45 doc_tag : up ();
+ − 46 end
+ − 47 tos : up (): up ();
+ − 48 module : send ( push );
+ − 49 end
+ − 50
+ − 51 local function check_tos ( event )
+ − 52 local user = event . origin . username
+ − 53 assert ( user )
+ − 54 local tos_status = status_storage : get ( user )
+ − 55 if tos_status and tos_status . version and tos_status . version == tos_version then
+ − 56 module : log ( "debug" , "user %s has signed the current tos" , user );
+ − 57 return
+ − 58 end
+ − 59 module : log ( "debug" , "user %s has not signed the current tos, sending tos push" , user );
+ − 60 send_tos_push ( event . origin )
+ − 61 end
+ − 62
+ − 63 local function handle_accept_tos_iq ( event )
+ − 64 local user = event . origin . username ;
+ − 65 assert ( user );
+ − 66 local accept = event . stanza . tags [ 1 ];
+ − 67 local version = accept . attr [ "version" ];
+ − 68 module : log ( "debug" , "user %s has accepted ToS version %s" , user , version );
+ − 69 if version ~= tos_version then
+ − 70 local reply = st . error_reply ( event . stanza , "modify" , "not-allowed" , "Only the most recent version of the ToS can be accepted" );
+ − 71 module : log ( "debug" , "%s is not the most recent version (%s), rejecting" , version , tos_version );
+ − 72 event . origin . send ( reply );
+ − 73 return true ;
+ − 74 end
+ − 75
+ − 76 status_storage : set ( user , { version = tos_version });
+ − 77 local reply = st . reply ( event . stanza );
+ − 78 event . origin . send ( reply );
+ − 79 return true ;
+ − 80 end
+ − 81
+ − 82 module : hook ( "presence/initial" , check_tos , - 100 );
+ − 83 module : hook ( "iq-set/bare/urn:xmpp:tos:0:accept" , handle_accept_tos_iq );