1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.crowd;
8
9 pkg = cfg.package.override {
10 home = cfg.home;
11 port = cfg.listenPort;
12 openidPassword = cfg.openidPassword;
13 } // (optionalAttrs cfg.proxy.enable {
14 proxyUrl = "${cfg.proxy.scheme}://${cfg.proxy.name}:${toString cfg.proxy.port}";
15 });
16
17 crowdPropertiesFile = pkgs.writeText "crowd.properties" ''
18 application.name crowd-openid-server
19 application.password @NIXOS_CROWD_OPENID_PW@
20 application.base.url http://localhost:${toString cfg.listenPort}/openidserver
21 application.login.url http://localhost:${toString cfg.listenPort}/openidserver
22 application.login.url.template http://localhost:${toString cfg.listenPort}/openidserver?returnToUrl=''${RETURN_TO_URL}
23
24 crowd.server.url http://localhost:${toString cfg.listenPort}/crowd/services/
25
26 session.isauthenticated session.isauthenticated
27 session.tokenkey session.tokenkey
28 session.validationinterval 0
29 session.lastvalidation session.lastvalidation
30 '';
31
32in
33
34{
35 options = {
36 services.crowd = {
37 enable = mkEnableOption (lib.mdDoc "Atlassian Crowd service");
38
39 user = mkOption {
40 type = types.str;
41 default = "crowd";
42 description = lib.mdDoc "User which runs Crowd.";
43 };
44
45 group = mkOption {
46 type = types.str;
47 default = "crowd";
48 description = lib.mdDoc "Group which runs Crowd.";
49 };
50
51 home = mkOption {
52 type = types.str;
53 default = "/var/lib/crowd";
54 description = lib.mdDoc "Home directory of the Crowd instance.";
55 };
56
57 listenAddress = mkOption {
58 type = types.str;
59 default = "127.0.0.1";
60 description = lib.mdDoc "Address to listen on.";
61 };
62
63 listenPort = mkOption {
64 type = types.port;
65 default = 8092;
66 description = lib.mdDoc "Port to listen on.";
67 };
68
69 openidPassword = mkOption {
70 type = types.str;
71 default = "WILL_NEVER_BE_SET";
72 description = lib.mdDoc "Application password for OpenID server.";
73 };
74
75 openidPasswordFile = mkOption {
76 type = types.nullOr types.str;
77 default = null;
78 description = lib.mdDoc "Path to the file containing the application password for OpenID server.";
79 };
80
81 catalinaOptions = mkOption {
82 type = types.listOf types.str;
83 default = [];
84 example = [ "-Xms1024m" "-Xmx2048m" ];
85 description = lib.mdDoc "Java options to pass to catalina/tomcat.";
86 };
87
88 proxy = {
89 enable = mkEnableOption (lib.mdDoc "reverse proxy support");
90
91 name = mkOption {
92 type = types.str;
93 example = "crowd.example.com";
94 description = lib.mdDoc "Virtual hostname at the proxy";
95 };
96
97 port = mkOption {
98 type = types.port;
99 default = 443;
100 example = 80;
101 description = lib.mdDoc "Port used at the proxy";
102 };
103
104 scheme = mkOption {
105 type = types.str;
106 default = "https";
107 example = "http";
108 description = lib.mdDoc "Protocol used at the proxy.";
109 };
110
111 secure = mkOption {
112 type = types.bool;
113 default = true;
114 description = lib.mdDoc "Whether the connections to the proxy should be considered secure.";
115 };
116 };
117
118 package = mkOption {
119 type = types.package;
120 default = pkgs.atlassian-crowd;
121 defaultText = literalExpression "pkgs.atlassian-crowd";
122 description = lib.mdDoc "Atlassian Crowd package to use.";
123 };
124
125 jrePackage = mkOption {
126 type = types.package;
127 default = pkgs.oraclejre8;
128 defaultText = literalExpression "pkgs.oraclejre8";
129 description = lib.mdDoc "Note that Atlassian only support the Oracle JRE (JRASERVER-46152).";
130 };
131 };
132 };
133
134 config = mkIf cfg.enable {
135 users.users.${cfg.user} = {
136 isSystemUser = true;
137 group = cfg.group;
138 };
139
140 users.groups.${cfg.group} = {};
141
142 systemd.tmpfiles.rules = [
143 "d '${cfg.home}' - ${cfg.user} ${cfg.group} - -"
144 "d /run/atlassian-crowd - - - - -"
145
146 "L+ /run/atlassian-crowd/database - - - - ${cfg.home}/database"
147 "L+ /run/atlassian-crowd/logs - - - - ${cfg.home}/logs"
148 "L+ /run/atlassian-crowd/work - - - - ${cfg.home}/work"
149 "L+ /run/atlassian-crowd/server.xml - - - - ${cfg.home}/server.xml"
150 ];
151
152 systemd.services.atlassian-crowd = {
153 description = "Atlassian Crowd";
154
155 wantedBy = [ "multi-user.target" ];
156 requires = [ "postgresql.service" ];
157 after = [ "postgresql.service" ];
158
159 path = [ cfg.jrePackage ];
160
161 environment = {
162 JAVA_HOME = "${cfg.jrePackage}";
163 CATALINA_OPTS = concatStringsSep " " cfg.catalinaOptions;
164 CATALINA_TMPDIR = "/tmp";
165 JAVA_OPTS = mkIf (cfg.openidPasswordFile != null) "-Dcrowd.properties=${cfg.home}/crowd.properties";
166 };
167
168 preStart = ''
169 rm -rf ${cfg.home}/work
170 mkdir -p ${cfg.home}/{logs,database,work}
171
172 sed -e 's,port="8095",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \
173 '' + (lib.optionalString cfg.proxy.enable ''
174 -e 's,compression="on",compression="off" protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${boolToString cfg.proxy.secure}",' \
175 '') + ''
176 ${pkg}/apache-tomcat/conf/server.xml.dist > ${cfg.home}/server.xml
177
178 ${optionalString (cfg.openidPasswordFile != null) ''
179 install -m660 ${crowdPropertiesFile} ${cfg.home}/crowd.properties
180 ${pkgs.replace-secret}/bin/replace-secret \
181 '@NIXOS_CROWD_OPENID_PW@' \
182 ${cfg.openidPasswordFile} \
183 ${cfg.home}/crowd.properties
184 ''}
185 '';
186
187 serviceConfig = {
188 User = cfg.user;
189 Group = cfg.group;
190 PrivateTmp = true;
191 Restart = "on-failure";
192 RestartSec = "10";
193 ExecStart = "${pkg}/start_crowd.sh -fg";
194 };
195 };
196 };
197}