1{ pkgs, lib, ... }:
2{
3 name = "filesender";
4 meta = {
5 maintainers = with lib.maintainers; [ nhnn ];
6 broken = pkgs.stdenv.hostPlatform.isAarch64; # selenium.common.exceptions.WebDriverException: Message: Unsupported platform/architecture combination: linux/aarch64
7 };
8
9 nodes.filesender =
10 { ... }:
11 let
12 format = pkgs.formats.php { };
13 in
14 {
15 networking.firewall.allowedTCPPorts = [ 80 ];
16
17 services.filesender.enable = true;
18 services.filesender.localDomain = "filesender";
19 services.filesender.settings = {
20 auth_sp_saml_authentication_source = "default";
21 auth_sp_saml_uid_attribute = "uid";
22 storage_filesystem_path = "/tmp";
23 site_url = "http://filesender";
24 force_ssl = false;
25 admin = "";
26 admin_email = "admin@localhost";
27 email_reply_to = "noreply@localhost";
28 };
29 services.simplesamlphp.filesender = {
30 settings = {
31 baseurlpath = "http://filesender/saml";
32 "module.enable".exampleauth = true;
33 };
34 authSources = {
35 admin = [ "core:AdminPassword" ];
36 default = format.lib.mkMixedArray [ "exampleauth:UserPass" ] {
37 "user:password" = {
38 uid = [ "user" ];
39 cn = [ "user" ];
40 mail = [ "user@nixos.org" ];
41 };
42 };
43 };
44 };
45 };
46
47 nodes.client =
48 {
49 pkgs,
50 nodes,
51 ...
52 }:
53 let
54 filesenderIP = (builtins.head (nodes.filesender.networking.interfaces.eth1.ipv4.addresses)).address;
55 in
56 {
57 networking.hosts.${filesenderIP} = [ "filesender" ];
58
59 environment.systemPackages =
60 let
61 username = "user";
62 password = "password";
63 browser-test =
64 pkgs.writers.writePython3Bin "browser-test"
65 {
66 libraries = [ pkgs.python3Packages.selenium ];
67 flakeIgnore = [
68 "E124"
69 "E501"
70 ];
71 }
72 ''
73 from selenium.webdriver.common.by import By
74 from selenium.webdriver import Firefox
75 from selenium.webdriver.firefox.options import Options
76 from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
77 from selenium.webdriver.firefox.service import Service
78 from selenium.webdriver.support.ui import WebDriverWait
79 from selenium.webdriver.support import expected_conditions as EC
80 from subprocess import STDOUT
81 import string
82 import random
83 import logging
84 import time
85 selenium_logger = logging.getLogger("selenium")
86 selenium_logger.setLevel(logging.DEBUG)
87 selenium_logger.addHandler(logging.StreamHandler())
88 profile = FirefoxProfile()
89 profile.set_preference("browser.download.folderList", 2)
90 profile.set_preference("browser.download.manager.showWhenStarting", False)
91 profile.set_preference("browser.download.dir", "/tmp/firefox")
92 profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/plain;text/txt")
93 options = Options()
94 options.profile = profile
95 options.add_argument('--headless')
96 service = Service(log_output=STDOUT)
97 driver = Firefox(options=options)
98 driver.set_window_size(1024, 768)
99 driver.implicitly_wait(30)
100 driver.get('http://filesender/')
101 wait = WebDriverWait(driver, 20)
102 wait.until(EC.title_contains("FileSender"))
103 driver.find_element(By.ID, "btn_logon").click()
104 wait.until(EC.title_contains("Enter your username and password"))
105 driver.find_element(By.ID, 'username').send_keys(
106 '${username}'
107 )
108 driver.find_element(By.ID, 'password').send_keys(
109 '${password}'
110 )
111 driver.find_element(By.ID, "submit_button").click()
112 wait.until(EC.title_contains("FileSender"))
113 wait.until(EC.presence_of_element_located((By.ID, "topmenu_logoff")))
114 test_string = "".join(random.choices(string.ascii_uppercase + string.digits, k=20))
115 with open("/tmp/test_file.txt", "w") as file:
116 file.write(test_string)
117 driver.find_element(By.ID, "files").send_keys("/tmp/test_file.txt")
118 time.sleep(2)
119 driver.find_element(By.CSS_SELECTOR, '.start').click()
120 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".download_link")))
121 download_link = driver.find_element(By.CSS_SELECTOR, '.download_link > textarea').get_attribute('value').strip()
122 driver.get(download_link)
123 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".download")))
124 driver.find_element(By.CSS_SELECTOR, '.download').click()
125 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".ui-dialog-buttonset > button:nth-child(2)")))
126 driver.find_element(By.CSS_SELECTOR, ".ui-dialog-buttonset > button:nth-child(2)").click()
127 driver.close()
128 driver.quit()
129 '';
130 in
131 [
132 pkgs.firefox-unwrapped
133 pkgs.geckodriver
134 browser-test
135 ];
136 };
137
138 testScript = ''
139 start_all()
140 filesender.wait_for_file("/run/phpfpm/filesender.sock")
141 filesender.wait_for_open_port(80)
142 if "If you have received an invitation to access this site as a guest" not in client.wait_until_succeeds("curl -sS -f http://filesender"):
143 raise Exception("filesender returned invalid html")
144 client.succeed("browser-test")
145 '';
146}