at 25.11-pre 8.0 kB view raw
1{ hostPkgs, lib, ... }: 2 3let 4 movim = { 5 domain = "movim.local"; 6 port = 8080; 7 info = "No ToS in tests"; 8 description = "NixOS testing server"; 9 }; 10 ejabberd = { 11 domain = "ejabberd.local"; 12 ports = { 13 c2s = 5222; 14 s2s = 5269; 15 http = 5280; 16 }; 17 spoolDir = "/var/lib/ejabberd"; 18 admin = rec { 19 JID = "${username}@${ejabberd.domain}"; 20 username = "romeo"; 21 password = "juliet"; 22 }; 23 }; 24 25 # START OF EJABBERD CONFIG ################################################## 26 # 27 # Ejabberd has sparse defaults as it is a generic XMPP server. As such this 28 # config might be longer than expected for a test. 29 # 30 # Movim suggests: https://github.com/movim/movim/wiki/Configure ejabberd 31 # 32 # In the future this may be the default setup 33 # See: https://github.com/NixOS/nixpkgs/pull/312316 34 ejabberd_config_file = 35 let 36 settingsFormat = hostPkgs.formats.yaml { }; 37 in 38 settingsFormat.generate "ejabberd.yml" { 39 loglevel = "info"; 40 hide_sensitive_log_data = false; 41 hosts = [ ejabberd.domain ]; 42 default_db = "mnesia"; 43 acme.auto = false; 44 s2s_access = "s2s"; 45 s2s_use_starttls = false; 46 new_sql_schema = true; 47 acl = { 48 admin = [ 49 { user = ejabberd.admin.JID; } 50 ]; 51 local.user_regexp = ""; 52 loopback.ip = [ 53 "127.0.0.1/8" 54 "::1/128" 55 ]; 56 }; 57 access_rules = { 58 c2s = { 59 deny = "blocked"; 60 allow = "all"; 61 }; 62 s2s = { 63 allow = "all"; 64 }; 65 local.allow = "local"; 66 announce.allow = "admin"; 67 configure.allow = "admin"; 68 pubsub_createnode.allow = "local"; 69 trusted_network.allow = "loopback"; 70 }; 71 api_permissions = { 72 "console commands" = { 73 from = [ "ejabberd_ctl" ]; 74 who = "all"; 75 what = "*"; 76 }; 77 }; 78 shaper = { 79 normal = { 80 rate = 3000; 81 burst_size = 20000; 82 }; 83 fast = 100000; 84 }; 85 modules = { 86 mod_caps = { }; 87 mod_disco = { }; 88 mod_mam = { }; 89 mod_http_upload = { 90 docroot = "${ejabberd.spoolDir}/uploads"; 91 dir_mode = "0755"; 92 file_mode = "0644"; 93 get_url = "http://@HOST@/upload"; 94 put_url = "http://@HOST@/upload"; 95 max_size = 65536; 96 custom_headers = { 97 Access-Control-Allow-Origin = "http://@HOST@,http://${movim.domain}"; 98 Access-Control-Allow-Methods = "GET,HEAD,PUT,OPTIONS"; 99 Access-Control-Allow-Headers = "Content-Type"; 100 }; 101 }; 102 # This PubSub block is required for Movim to work. 103 # 104 # See: https://github.com/movim/movim/wiki/Configure ejabberd#pubsub 105 mod_pubsub = { 106 hosts = [ "pubsub.@HOST@" ]; 107 access_createnode = "pubsub_createnode"; 108 ignore_pep_from_offline = false; 109 last_item_cache = false; 110 max_items_node = 2048; 111 default_node_config = { 112 max_items = 2048; 113 }; 114 plugins = [ 115 "flat" 116 "pep" 117 ]; 118 force_node_config = { 119 "storage:bookmarks".access_model = "whitelist"; 120 "eu.siacs.conversations.axolotl.*".access_model = "open"; 121 "urn:xmpp:bookmarks:0" = { 122 access_model = "whitelist"; 123 send_last_published_item = "never"; 124 max_items = "infinity"; 125 persist_items = true; 126 }; 127 "urn:xmpp:bookmarks:1" = { 128 access_model = "whitelist"; 129 send_last_published_item = "never"; 130 max_items = "infinity"; 131 persist_items = true; 132 }; 133 "urn:xmpp:pubsub:movim-public-subscription" = { 134 access_model = "whitelist"; 135 max_items = "infinity"; 136 persist_items = true; 137 }; 138 "urn:xmpp:microblog:0" = { 139 notify_retract = true; 140 max_items = "infinity"; 141 persist_items = true; 142 }; 143 "urn:xmpp:microblog:0:comments*" = { 144 access_model = "open"; 145 notify_retract = true; 146 max_items = "infinity"; 147 persist_items = true; 148 }; 149 }; 150 }; 151 mod_stream_mgmt = { }; 152 }; 153 listen = [ 154 { 155 module = "ejabberd_c2s"; 156 port = ejabberd.ports.c2s; 157 max_stanza_size = 262144; 158 access = "c2s"; 159 starttls_required = false; 160 } 161 { 162 module = "ejabberd_s2s_in"; 163 port = ejabberd.ports.s2s; 164 max_stanza_size = 524288; 165 shaper = "fast"; 166 } 167 { 168 module = "ejabberd_http"; 169 port = ejabberd.ports.http; 170 request_handlers = { 171 "/upload" = "mod_http_upload"; 172 }; 173 } 174 ]; 175 }; 176 # END OF EJABBERD CONFIG ################################################## 177in 178{ 179 name = "movim-ejabberd-h2o"; 180 181 meta = { 182 maintainers = with lib.maintainers; [ toastal ]; 183 }; 184 185 nodes = { 186 server = 187 { pkgs, ... }: 188 { 189 environment.systemPackages = [ 190 # For testing 191 pkgs.websocat 192 ]; 193 194 services.movim = { 195 inherit (movim) domain port; 196 enable = true; 197 verbose = true; 198 podConfig = { 199 inherit (movim) description info; 200 xmppdomain = ejabberd.domain; 201 }; 202 database = { 203 type = "postgresql"; 204 createLocally = true; 205 }; 206 h2o = { }; 207 }; 208 209 services.ejabberd = { 210 inherit (ejabberd) spoolDir; 211 enable = true; 212 configFile = ejabberd_config_file; 213 imagemagick = false; 214 }; 215 216 services.h2o.settings = { 217 compress = "ON"; 218 }; 219 220 systemd.services.ejabberd = { 221 serviceConfig = { 222 # Certain misconfigurations can cause RAM usage to swell before 223 # crashing; fail sooner with more-than-liberal memory limits 224 StartupMemoryMax = "1G"; 225 MemoryMax = "512M"; 226 }; 227 }; 228 229 networking = { 230 firewall.allowedTCPPorts = with ejabberd.ports; [ 231 c2s 232 s2s 233 ]; 234 extraHosts = '' 235 127.0.0.1 ${movim.domain} 236 127.0.0.1 ${ejabberd.domain} 237 ''; 238 }; 239 }; 240 }; 241 242 testScript = # python 243 '' 244 ejabberdctl = "su ejabberd -s $(which ejabberdctl) " 245 246 server.wait_for_unit("phpfpm-movim.service") 247 server.wait_for_unit("h2o.service") 248 server.wait_for_open_port(${builtins.toString movim.port}) 249 server.wait_for_open_port(80) 250 251 server.wait_for_unit("ejabberd.service") 252 ejabberd_status = server.succeed(ejabberdctl + "status") 253 assert "status: started" in ejabberd_status 254 server.succeed(ejabberdctl + "register ${ejabberd.admin.username} ${ejabberd.domain} ${ejabberd.admin.password}") 255 256 server.wait_for_unit("movim.service") 257 258 # Test unauthenticated 259 server.fail("curl -L --fail-with-body --max-redirs 0 http://${movim.domain}/chat") 260 261 # Test basic Websocket 262 server.succeed("echo | websocat --origin 'http://${movim.domain}' 'ws://${movim.domain}/ws/?path=login&offset=0'") 263 264 # Test login + create cookiejar 265 login_html = server.succeed("curl --fail-with-body -c /tmp/cookies http://${movim.domain}/login") 266 assert "${movim.description}" in login_html 267 assert "${movim.info}" in login_html 268 269 # Test authentication POST 270 server.succeed("curl --fail-with-body -b /tmp/cookies -X POST --data-urlencode 'username=${ejabberd.admin.JID}' --data-urlencode 'password=${ejabberd.admin.password}' http://${movim.domain}/login") 271 272 server.succeed("curl -L --fail-with-body --max-redirs 1 -b /tmp/cookies http://${movim.domain}/chat") 273 ''; 274}