1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.mtprotoproxy;
8
9 configOpts = {
10 PORT = cfg.port;
11 USERS = cfg.users;
12 SECURE_ONLY = cfg.secureOnly;
13 } // lib.optionalAttrs (cfg.adTag != null) { AD_TAG = cfg.adTag; }
14 // cfg.extraConfig;
15
16 convertOption = opt:
17 if isString opt || isInt opt then
18 builtins.toJSON opt
19 else if isBool opt then
20 if opt then "True" else "False"
21 else if isList opt then
22 "[" + concatMapStringsSep "," convertOption opt + "]"
23 else if isAttrs opt then
24 "{" + concatStringsSep "," (mapAttrsToList (name: opt: "${builtins.toJSON name}: ${convertOption opt}") opt) + "}"
25 else
26 throw "Invalid option type";
27
28 configFile = pkgs.writeText "config.py" (concatStringsSep "\n" (mapAttrsToList (name: opt: "${name} = ${convertOption opt}") configOpts));
29
30in
31
32{
33
34 ###### interface
35
36 options = {
37
38 services.mtprotoproxy = {
39
40 enable = mkEnableOption (lib.mdDoc "mtprotoproxy");
41
42 port = mkOption {
43 type = types.port;
44 default = 3256;
45 description = lib.mdDoc ''
46 TCP port to accept mtproto connections on.
47 '';
48 };
49
50 users = mkOption {
51 type = types.attrsOf types.str;
52 example = {
53 tg = "00000000000000000000000000000000";
54 tg2 = "0123456789abcdef0123456789abcdef";
55 };
56 description = lib.mdDoc ''
57 Allowed users and their secrets. A secret is a 32 characters long hex string.
58 '';
59 };
60
61 secureOnly = mkOption {
62 type = types.bool;
63 default = true;
64 description = lib.mdDoc ''
65 Don't allow users to connect in non-secure mode (without random padding).
66 '';
67 };
68
69 adTag = mkOption {
70 type = types.nullOr types.str;
71 default = null;
72 # Taken from mtproxyproto's repo.
73 example = "3c09c680b76ee91a4c25ad51f742267d";
74 description = lib.mdDoc ''
75 Tag for advertising that can be obtained from @MTProxybot.
76 '';
77 };
78
79 extraConfig = mkOption {
80 type = types.attrs;
81 default = {};
82 example = {
83 STATS_PRINT_PERIOD = 600;
84 };
85 description = lib.mdDoc ''
86 Extra configuration options for mtprotoproxy.
87 '';
88 };
89
90 };
91
92 };
93
94
95 ###### implementation
96
97 config = mkIf cfg.enable {
98
99 systemd.services.mtprotoproxy = {
100 description = "MTProto Proxy Daemon";
101 wantedBy = [ "multi-user.target" ];
102 serviceConfig = {
103 ExecStart = "${pkgs.mtprotoproxy}/bin/mtprotoproxy ${configFile}";
104 DynamicUser = true;
105 };
106 };
107
108 };
109
110}