1{ lib, ... }:
2{
3 name = "paretosecurity";
4 meta.maintainers = [ lib.maintainers.zupo ];
5
6 nodes.terminal =
7 { pkgs, ... }:
8 {
9 imports = [ ./common/user-account.nix ];
10
11 networking.firewall.enable = true;
12 services.paretosecurity = {
13 enable = true;
14
15 # Create a patched version of the package that points to the local dashboard
16 # for easier testing
17 package = pkgs.paretosecurity.overrideAttrs (oldAttrs: {
18 postPatch =
19 oldAttrs.postPatch or ""
20 + ''
21 substituteInPlace team/report.go \
22 --replace-warn 'const reportURL = "https://dash.paretosecurity.com"' \
23 'const reportURL = "http://dashboard"'
24 '';
25 });
26 };
27
28 };
29
30 nodes.dashboard = {
31 networking.firewall.allowedTCPPorts = [ 80 ];
32
33 services.nginx = {
34 enable = true;
35 virtualHosts."dashboard" = {
36 locations."/api/v1/team/".extraConfig = ''
37 add_header Content-Type application/json;
38 return 200 '{"message": "Linked device."}';
39 '';
40 };
41 };
42 };
43
44 nodes.xfce =
45 { pkgs, ... }:
46 {
47 imports = [ ./common/user-account.nix ];
48
49 services.paretosecurity.enable = true;
50
51 services.xserver.enable = true;
52 services.xserver.displayManager.lightdm.enable = true;
53 services.xserver.desktopManager.xfce.enable = true;
54
55 services.displayManager.autoLogin = {
56 enable = true;
57 user = "alice";
58
59 };
60
61 virtualisation.resolution = {
62 x = 640;
63 y = 480;
64 };
65
66 environment.systemPackages = [ pkgs.xdotool ];
67 environment.variables.XAUTHORITY = "/home/alice/.Xauthority";
68 };
69
70 enableOCR = true;
71
72 testScript = ''
73 # Test setup
74 terminal.succeed("su - alice -c 'mkdir -p /home/alice/.config'")
75 for m in [terminal, dashboard]:
76 m.systemctl("start network-online.target")
77 m.wait_for_unit("network-online.target")
78
79 # Test 1: Test the systemd socket is installed & enabled
80 terminal.succeed('systemctl is-enabled paretosecurity.socket')
81
82 # Test 2: Test running checks
83 terminal.succeed(
84 "su - alice -c 'paretosecurity check"
85 # Disable some checks that need intricate test setup so that this test
86 # remains simple and fast. Tests for all checks and edge cases available
87 # at https://github.com/ParetoSecurity/agent/tree/main/test/integration
88 + " --skip c96524f2-850b-4bb9-abc7-517051b6c14e" # SecureBoot
89 + " --skip 37dee029-605b-4aab-96b9-5438e5aa44d8" # Screen lock
90 + " --skip 21830a4e-84f1-48fe-9c5b-beab436b2cdb" # Disk encryption
91 + " --skip 44e4754a-0b42-4964-9cc2-b88b2023cb1e" # Pareto Security is up to date
92 + " --skip f962c423-fdf5-428a-a57a-827abc9b253e" # Password manager installed
93 + "'"
94 )
95
96 # Test 3: Test linking
97 terminal.succeed("su - alice -c 'paretosecurity link"
98 + " paretosecurity://enrollTeam/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
99 + "eyJ0b2tlbiI6ImR1bW15LXRva2VuIiwidGVhbUlEIjoiZHVtbXktdGVhbS1pZCIsImlhdCI6"
100 + "MTcwMDAwMDAwMCwiZXhwIjoxOTAwMDAwMDAwfQ.WgnL6_S0EBJHwF1wEVUG8GtIcoVvK5IjWbZpUeZr4Qw'")
101
102 config = terminal.succeed("cat /home/alice/.config/pareto.toml")
103 assert 'AuthToken = "dummy-token"' in config
104 assert 'TeamID = "dummy-team-id"' in config
105
106 # Test 4: Test the tray icon
107 xfce.wait_for_x()
108 for unit in [
109 'paretosecurity-trayicon',
110 'paretosecurity-user',
111 'paretosecurity-user.timer'
112 ]:
113 status, out = xfce.systemctl("is-enabled " + unit, "alice")
114 assert status == 0, f"Unit {unit} is not enabled (status: {status}): {out}"
115 xfce.succeed("xdotool mousemove 460 10")
116 xfce.wait_for_text("Pareto Security")
117 xfce.succeed("xdotool click 1")
118 xfce.wait_for_text("Run Checks")
119
120 # Test 5: Desktop entry
121 xfce.succeed("xdotool mousemove 10 10")
122 xfce.succeed("xdotool click 1") # hide the tray icon window
123 xfce.succeed("xdotool click 1") # show the Applications menu
124 xfce.succeed("xdotool mousemove 10 200")
125 xfce.succeed("xdotool click 1")
126 xfce.wait_for_text("Pareto Security")
127
128 # Test 6: paretosecurity:// URL handler is registered
129 xfce.execute("su - alice -c 'xdg-open paretosecurity://foo >/dev/null &'")
130 xfce.wait_for_text("Failed to add device")
131
132 '';
133}