postfix_admin 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +20 -0
- data/CHANGELOG.md +19 -8
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +26 -20
- data/Rakefile +19 -1
- data/bin/console +6 -2
- data/docker-admin/Dockerfile +6 -0
- data/docker-admin/config.local.php +24 -0
- data/docker-app/Dockerfile +21 -0
- data/docker-app/my.cnf +5 -0
- data/docker-compose.yml +37 -11
- data/docker-db/postfix.v1841.sql +383 -0
- data/docker-db/postfix.v352.sql +223 -0
- data/docker-db/postfix.v740.sql +269 -0
- data/lib/postfix_admin/admin.rb +17 -2
- data/lib/postfix_admin/alias.rb +0 -19
- data/lib/postfix_admin/base.rb +120 -94
- data/lib/postfix_admin/cli.rb +184 -127
- data/lib/postfix_admin/concerns/dovecot_cram_md5_password.rb +0 -1
- data/lib/postfix_admin/domain.rb +35 -44
- data/lib/postfix_admin/doveadm.rb +11 -10
- data/lib/postfix_admin/mailbox.rb +14 -6
- data/lib/postfix_admin/runner.rb +35 -22
- data/lib/postfix_admin/version.rb +1 -1
- data/postfix_admin.gemspec +13 -9
- metadata +55 -21
- data/Dockerfile +0 -24
- data/docker-entrypoint.sh +0 -5
@@ -0,0 +1,269 @@
|
|
1
|
+
|
2
|
+
-- phpMyAdmin SQL Dump
|
3
|
+
-- version 3.5.7
|
4
|
+
-- http://www.phpmyadmin.net
|
5
|
+
--
|
6
|
+
-- ホスト: localhost
|
7
|
+
-- 生成日時: 2013 年 5 月 09 日 08:25
|
8
|
+
-- サーバのバージョン: 5.5.29
|
9
|
+
-- PHP のバージョン: 5.3.20
|
10
|
+
|
11
|
+
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
|
12
|
+
SET time_zone = "+00:00";
|
13
|
+
|
14
|
+
|
15
|
+
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
16
|
+
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
17
|
+
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
18
|
+
/*!40101 SET NAMES utf8 */;
|
19
|
+
|
20
|
+
--
|
21
|
+
-- データベース: `postfix`
|
22
|
+
--
|
23
|
+
|
24
|
+
-- --------------------------------------------------------
|
25
|
+
|
26
|
+
--
|
27
|
+
-- テーブルの構造 `admin`
|
28
|
+
--
|
29
|
+
|
30
|
+
CREATE TABLE IF NOT EXISTS `admin` (
|
31
|
+
`username` varchar(255) NOT NULL,
|
32
|
+
`password` varchar(255) NOT NULL,
|
33
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
34
|
+
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
35
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
36
|
+
PRIMARY KEY (`username`)
|
37
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Admins';
|
38
|
+
|
39
|
+
-- --------------------------------------------------------
|
40
|
+
|
41
|
+
--
|
42
|
+
-- テーブルの構造 `alias`
|
43
|
+
--
|
44
|
+
|
45
|
+
CREATE TABLE IF NOT EXISTS `alias` (
|
46
|
+
`address` varchar(255) NOT NULL,
|
47
|
+
`goto` text NOT NULL,
|
48
|
+
`domain` varchar(255) NOT NULL,
|
49
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
50
|
+
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
51
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
52
|
+
PRIMARY KEY (`address`),
|
53
|
+
KEY `domain` (`domain`)
|
54
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Aliases';
|
55
|
+
|
56
|
+
-- --------------------------------------------------------
|
57
|
+
|
58
|
+
--
|
59
|
+
-- テーブルの構造 `alias_domain`
|
60
|
+
--
|
61
|
+
|
62
|
+
CREATE TABLE IF NOT EXISTS `alias_domain` (
|
63
|
+
`alias_domain` varchar(255) NOT NULL,
|
64
|
+
`target_domain` varchar(255) NOT NULL,
|
65
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
66
|
+
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
67
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
68
|
+
PRIMARY KEY (`alias_domain`),
|
69
|
+
KEY `active` (`active`),
|
70
|
+
KEY `target_domain` (`target_domain`)
|
71
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Domain Aliases';
|
72
|
+
|
73
|
+
-- --------------------------------------------------------
|
74
|
+
|
75
|
+
--
|
76
|
+
-- テーブルの構造 `config`
|
77
|
+
--
|
78
|
+
|
79
|
+
CREATE TABLE IF NOT EXISTS `config` (
|
80
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
81
|
+
`name` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '',
|
82
|
+
`value` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '',
|
83
|
+
PRIMARY KEY (`id`),
|
84
|
+
UNIQUE KEY `name` (`name`)
|
85
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='PostfixAdmin settings' AUTO_INCREMENT=2 ;
|
86
|
+
|
87
|
+
--
|
88
|
+
-- テーブルのデータのダンプ `config`
|
89
|
+
--
|
90
|
+
|
91
|
+
INSERT INTO `config` (`id`, `name`, `value`) VALUES
|
92
|
+
(1, 'version', '740');
|
93
|
+
|
94
|
+
-- --------------------------------------------------------
|
95
|
+
|
96
|
+
--
|
97
|
+
-- テーブルの構造 `domain`
|
98
|
+
--
|
99
|
+
|
100
|
+
CREATE TABLE IF NOT EXISTS `domain` (
|
101
|
+
`domain` varchar(255) NOT NULL,
|
102
|
+
`description` varchar(255) CHARACTER SET utf8 NOT NULL,
|
103
|
+
`aliases` int(10) NOT NULL DEFAULT '0',
|
104
|
+
`mailboxes` int(10) NOT NULL DEFAULT '0',
|
105
|
+
`maxquota` bigint(20) NOT NULL DEFAULT '0',
|
106
|
+
`quota` bigint(20) NOT NULL DEFAULT '0',
|
107
|
+
`transport` varchar(255) NOT NULL,
|
108
|
+
`backupmx` tinyint(1) NOT NULL DEFAULT '0',
|
109
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
110
|
+
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
111
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
112
|
+
PRIMARY KEY (`domain`)
|
113
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Domains';
|
114
|
+
|
115
|
+
--
|
116
|
+
-- テーブルのデータのダンプ `domain`
|
117
|
+
--
|
118
|
+
|
119
|
+
INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`) VALUES
|
120
|
+
('ALL', '', 0, 0, 0, 0, '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1);
|
121
|
+
|
122
|
+
-- --------------------------------------------------------
|
123
|
+
|
124
|
+
--
|
125
|
+
-- テーブルの構造 `domain_admins`
|
126
|
+
--
|
127
|
+
|
128
|
+
CREATE TABLE IF NOT EXISTS `domain_admins` (
|
129
|
+
`username` varchar(255) NOT NULL,
|
130
|
+
`domain` varchar(255) NOT NULL,
|
131
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
132
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
133
|
+
KEY `username` (`username`)
|
134
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Domain Admins';
|
135
|
+
|
136
|
+
-- --------------------------------------------------------
|
137
|
+
|
138
|
+
--
|
139
|
+
-- テーブルの構造 `fetchmail`
|
140
|
+
--
|
141
|
+
|
142
|
+
CREATE TABLE IF NOT EXISTS `fetchmail` (
|
143
|
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
144
|
+
`mailbox` varchar(255) NOT NULL,
|
145
|
+
`src_server` varchar(255) NOT NULL,
|
146
|
+
`src_auth` enum('password','kerberos_v5','kerberos','kerberos_v4','gssapi','cram-md5','otp','ntlm','msn','ssh','any') CHARACTER SET utf8 DEFAULT NULL,
|
147
|
+
`src_user` varchar(255) NOT NULL,
|
148
|
+
`src_password` varchar(255) NOT NULL,
|
149
|
+
`src_folder` varchar(255) NOT NULL,
|
150
|
+
`poll_time` int(11) unsigned NOT NULL DEFAULT '10',
|
151
|
+
`fetchall` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
152
|
+
`keep` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
153
|
+
`protocol` enum('POP3','IMAP','POP2','ETRN','AUTO') CHARACTER SET utf8 DEFAULT NULL,
|
154
|
+
`usessl` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
155
|
+
`extra_options` text,
|
156
|
+
`returned_text` text,
|
157
|
+
`mda` varchar(255) NOT NULL,
|
158
|
+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
159
|
+
PRIMARY KEY (`id`)
|
160
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
|
161
|
+
|
162
|
+
-- --------------------------------------------------------
|
163
|
+
|
164
|
+
--
|
165
|
+
-- テーブルの構造 `log`
|
166
|
+
--
|
167
|
+
|
168
|
+
CREATE TABLE IF NOT EXISTS `log` (
|
169
|
+
`timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
170
|
+
`username` varchar(255) NOT NULL,
|
171
|
+
`domain` varchar(255) NOT NULL,
|
172
|
+
`action` varchar(255) NOT NULL,
|
173
|
+
`data` text NOT NULL,
|
174
|
+
KEY `timestamp` (`timestamp`)
|
175
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Log';
|
176
|
+
|
177
|
+
|
178
|
+
-- --------------------------------------------------------
|
179
|
+
|
180
|
+
--
|
181
|
+
-- テーブルの構造 `mailbox`
|
182
|
+
--
|
183
|
+
|
184
|
+
CREATE TABLE IF NOT EXISTS `mailbox` (
|
185
|
+
`username` varchar(255) NOT NULL,
|
186
|
+
`password` varchar(255) NOT NULL,
|
187
|
+
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
|
188
|
+
`maildir` varchar(255) NOT NULL,
|
189
|
+
`quota` bigint(20) NOT NULL DEFAULT '0',
|
190
|
+
`local_part` varchar(255) NOT NULL,
|
191
|
+
`domain` varchar(255) NOT NULL,
|
192
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
193
|
+
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
194
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
195
|
+
PRIMARY KEY (`username`),
|
196
|
+
KEY `domain` (`domain`)
|
197
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Mailboxes';
|
198
|
+
|
199
|
+
|
200
|
+
-- --------------------------------------------------------
|
201
|
+
|
202
|
+
--
|
203
|
+
-- テーブルの構造 `quota`
|
204
|
+
--
|
205
|
+
|
206
|
+
CREATE TABLE IF NOT EXISTS `quota` (
|
207
|
+
`username` varchar(255) CHARACTER SET utf8 NOT NULL,
|
208
|
+
`path` varchar(100) CHARACTER SET utf8 NOT NULL,
|
209
|
+
`current` bigint(20) DEFAULT NULL,
|
210
|
+
PRIMARY KEY (`username`,`path`)
|
211
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8;
|
212
|
+
|
213
|
+
-- --------------------------------------------------------
|
214
|
+
|
215
|
+
--
|
216
|
+
-- テーブルの構造 `quota2`
|
217
|
+
--
|
218
|
+
|
219
|
+
CREATE TABLE IF NOT EXISTS `quota2` (
|
220
|
+
`username` varchar(100) CHARACTER SET utf8 NOT NULL,
|
221
|
+
`bytes` bigint(20) NOT NULL DEFAULT '0',
|
222
|
+
`messages` int(11) NOT NULL DEFAULT '0',
|
223
|
+
PRIMARY KEY (`username`)
|
224
|
+
) ENGINE=INNODB DEFAULT CHARSET=utf8;
|
225
|
+
|
226
|
+
-- --------------------------------------------------------
|
227
|
+
|
228
|
+
--
|
229
|
+
-- テーブルの構造 `vacation`
|
230
|
+
--
|
231
|
+
|
232
|
+
CREATE TABLE IF NOT EXISTS `vacation` (
|
233
|
+
`email` varchar(255) NOT NULL,
|
234
|
+
`subject` varchar(255) CHARACTER SET utf8 NOT NULL,
|
235
|
+
`body` text CHARACTER SET utf8 NOT NULL,
|
236
|
+
`cache` text NOT NULL,
|
237
|
+
`domain` varchar(255) NOT NULL,
|
238
|
+
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
239
|
+
`active` tinyint(1) NOT NULL DEFAULT '1',
|
240
|
+
PRIMARY KEY (`email`),
|
241
|
+
KEY `email` (`email`)
|
242
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Vacation';
|
243
|
+
|
244
|
+
-- --------------------------------------------------------
|
245
|
+
|
246
|
+
--
|
247
|
+
-- テーブルの構造 `vacation_notification`
|
248
|
+
--
|
249
|
+
|
250
|
+
CREATE TABLE IF NOT EXISTS `vacation_notification` (
|
251
|
+
`on_vacation` varchar(150) CHARACTER SET utf8 NOT NULL,
|
252
|
+
`notified` varchar(150) NOT NULL,
|
253
|
+
`notified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
254
|
+
PRIMARY KEY (`on_vacation`,`notified`)
|
255
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Vacation Notifications';
|
256
|
+
|
257
|
+
--
|
258
|
+
-- ダンプしたテーブルの制約
|
259
|
+
--
|
260
|
+
|
261
|
+
--
|
262
|
+
-- テーブルの制約 `vacation_notification`
|
263
|
+
--
|
264
|
+
ALTER TABLE `vacation_notification`
|
265
|
+
ADD CONSTRAINT `vacation_notification_pkey` FOREIGN KEY (`on_vacation`) REFERENCES `vacation` (`email`) ON DELETE CASCADE;
|
266
|
+
|
267
|
+
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
268
|
+
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
269
|
+
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
data/lib/postfix_admin/admin.rb
CHANGED
@@ -22,9 +22,18 @@ module PostfixAdmin
|
|
22
22
|
admin.errors.add(:username, 'cannot be changed') if admin.username_changed?
|
23
23
|
end
|
24
24
|
|
25
|
+
def reload
|
26
|
+
@super_admin = nil
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
25
30
|
def super_admin?
|
26
31
|
if @super_admin.nil?
|
27
|
-
@super_admin =
|
32
|
+
@super_admin = if has_superadmin_column?
|
33
|
+
self.superadmin && rel_domains.exists?("ALL")
|
34
|
+
else
|
35
|
+
rel_domains.exists?("ALL")
|
36
|
+
end
|
28
37
|
else
|
29
38
|
@super_admin
|
30
39
|
end
|
@@ -35,10 +44,16 @@ module PostfixAdmin
|
|
35
44
|
domain_ids = self.rel_domain_ids.dup
|
36
45
|
domain_ids << "ALL"
|
37
46
|
self.rel_domain_ids = domain_ids
|
38
|
-
|
47
|
+
self.superadmin = true if has_superadmin_column?
|
39
48
|
else
|
40
49
|
domain_admins.where(domain: "ALL").delete_all
|
50
|
+
self.superadmin = false if has_superadmin_column?
|
41
51
|
end
|
52
|
+
save!
|
53
|
+
end
|
54
|
+
|
55
|
+
def has_superadmin_column?
|
56
|
+
has_attribute?(:superadmin)
|
42
57
|
end
|
43
58
|
|
44
59
|
def has_admin?(admin)
|
data/lib/postfix_admin/alias.rb
CHANGED
@@ -24,30 +24,11 @@ module PostfixAdmin
|
|
24
24
|
scope :pure, -> { joins("LEFT OUTER JOIN mailbox ON alias.address = mailbox.username").where("mailbox.username" => nil) }
|
25
25
|
|
26
26
|
attribute :local_part, :string
|
27
|
-
attr_writer :forward_addresses
|
28
|
-
|
29
|
-
def forward_addresses
|
30
|
-
if @forward_addresses.nil?
|
31
|
-
if goto.nil?
|
32
|
-
[nil]
|
33
|
-
else
|
34
|
-
goto.split(",") + [nil]
|
35
|
-
end
|
36
|
-
else
|
37
|
-
@forward_addresses
|
38
|
-
end
|
39
|
-
end
|
40
27
|
|
41
28
|
before_validation do |a|
|
42
29
|
unless a.address
|
43
30
|
a.address = "#{a.local_part}@#{a.domain}" unless a.local_part.empty?
|
44
31
|
end
|
45
|
-
|
46
|
-
unless a.forward_addresses.empty?
|
47
|
-
forward_addresses = a.forward_addresses.dup
|
48
|
-
forward_addresses.delete_if { |f| f.blank? }
|
49
|
-
a.goto = forward_addresses.join(",")
|
50
|
-
end
|
51
32
|
end
|
52
33
|
|
53
34
|
def mailbox?
|
data/lib/postfix_admin/base.rb
CHANGED
@@ -8,40 +8,41 @@ module PostfixAdmin
|
|
8
8
|
attr_reader :config
|
9
9
|
|
10
10
|
DEFAULT_CONFIG = {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
"database" => "mysql2://postfix:password@localhost/postfix",
|
12
|
+
"aliases" => 30,
|
13
|
+
"mailboxes" => 30,
|
14
|
+
"maxquota" => 100,
|
15
|
+
"scheme" => "CRAM-MD5",
|
16
|
+
"passwordhash_prefix" => true
|
17
|
+
}.freeze
|
17
18
|
|
18
19
|
def initialize(config)
|
19
20
|
@config = {}
|
20
|
-
@config[:database] = config[
|
21
|
-
@config[:aliases] = config[
|
22
|
-
@config[:mailboxes] = config[
|
23
|
-
@config[:maxquota] = config[
|
24
|
-
@config[:scheme] = config[
|
21
|
+
@config[:database] = config["database"]
|
22
|
+
@config[:aliases] = config["aliases"] || DEFAULT_CONFIG["aliases"]
|
23
|
+
@config[:mailboxes] = config["mailboxes"] || DEFAULT_CONFIG["mailboxes"]
|
24
|
+
@config[:maxquota] = config["maxquota"] || DEFAULT_CONFIG["maxquota"]
|
25
|
+
@config[:scheme] = config["scheme"] || DEFAULT_CONFIG["scheme"]
|
26
|
+
@config[:passwordhash_prefix] = if config.has_key?("passwordhash_prefix")
|
27
|
+
config["passwordhash_prefix"]
|
28
|
+
else
|
29
|
+
DEFAULT_CONFIG["passwordhash_prefix"]
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
def db_setup
|
28
|
-
|
34
|
+
database = ENV.fetch("DATABASE_URL") { @config[:database] }
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
if uri.scheme == "mysql"
|
33
|
-
uri.scheme = "mysql2"
|
34
|
-
warn("Deprecation Warning: Use 'mysql2' as a DB adopter instead of 'mysql' in '#{CLI.config_file}'")
|
36
|
+
unless database
|
37
|
+
raise_error "'database' parameter is required in '#{CLI.config_file}' or specify 'DATABASE_URL' environment variable"
|
35
38
|
end
|
36
39
|
|
37
|
-
|
38
|
-
raise "'#{uri.scheme}' is not supported as a DB adopter. Use 'mysql2' instead in '#{CLI.config_file}'."
|
39
|
-
end
|
40
|
+
uri = URI.parse(database)
|
40
41
|
|
41
42
|
ActiveRecord::Base.establish_connection(uri.to_s)
|
42
43
|
|
43
44
|
rescue LoadError => e
|
44
|
-
|
45
|
+
raise_error e.message
|
45
46
|
end
|
46
47
|
|
47
48
|
def add_admin_domain(user_name, domain_name)
|
@@ -51,11 +52,11 @@ module PostfixAdmin
|
|
51
52
|
domain = Domain.find(domain_name)
|
52
53
|
|
53
54
|
if admin.has_domain?(domain)
|
54
|
-
|
55
|
+
raise_error "Admin '#{user_name}' has already been registered for Domain '#{domain_name}'"
|
55
56
|
end
|
56
57
|
|
57
58
|
admin.rel_domains << domain
|
58
|
-
admin.save
|
59
|
+
admin.save || raise_error("Relation Error: Domain of Admin")
|
59
60
|
end
|
60
61
|
|
61
62
|
def delete_admin_domain(user_name, domain_name)
|
@@ -65,135 +66,116 @@ module PostfixAdmin
|
|
65
66
|
domain_admin_query = admin.domain_admins.where(domain: domain_name)
|
66
67
|
|
67
68
|
unless domain_admin_query.take
|
68
|
-
|
69
|
+
raise_error "#{user_name} is not registered as admin of #{domain_name}."
|
69
70
|
end
|
70
71
|
|
71
72
|
domain_admin_query.delete_all
|
72
73
|
end
|
73
74
|
|
74
75
|
def add_admin(username, password)
|
75
|
-
|
76
|
+
validate_password(password)
|
76
77
|
|
77
78
|
if Admin.exists?(username)
|
78
|
-
|
79
|
+
raise_error "Admin has already been registered: #{username}"
|
79
80
|
end
|
81
|
+
|
80
82
|
admin = Admin.new
|
81
83
|
admin.attributes = {
|
82
84
|
username: username,
|
83
|
-
password: password
|
85
|
+
password: password
|
84
86
|
}
|
85
|
-
unless admin.save
|
86
|
-
raise "Could not save Admin #{admin.errors.map(&:to_s).join}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def add_account(address, password, in_name = nil)
|
91
|
-
name = in_name || ''
|
92
|
-
password_check(password)
|
93
|
-
|
94
|
-
if address !~ /.+\@.+\..+/
|
95
|
-
raise Error, "Invalid mail address #{address}"
|
96
|
-
end
|
97
|
-
user, domain_name = address_split(address)
|
98
|
-
path = "#{domain_name}/#{address}/"
|
99
87
|
|
100
|
-
unless
|
101
|
-
|
102
|
-
end
|
88
|
+
raise_save_error(admin) unless admin.save
|
89
|
+
end
|
103
90
|
|
104
|
-
|
105
|
-
|
106
|
-
|
91
|
+
# Adds an email account that consists of a Mailbox and an Alias.
|
92
|
+
def add_account(address, password, name: "")
|
93
|
+
validate_account(address, password)
|
107
94
|
|
108
|
-
|
95
|
+
local_part, domain_name = address_split(address)
|
96
|
+
domain_must_exist!(domain_name)
|
109
97
|
|
110
98
|
attributes = {
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
quota_mb: @config[:maxquota]
|
99
|
+
local_part: local_part,
|
100
|
+
domain: domain_name,
|
101
|
+
password: password,
|
102
|
+
name: name,
|
103
|
+
quota_mb: @config[:maxquota]
|
117
104
|
}
|
118
105
|
|
106
|
+
# An Alias also will be added when a Mailbox is saved.
|
119
107
|
mailbox = Mailbox.new(attributes)
|
120
108
|
|
121
|
-
|
122
|
-
|
123
|
-
unless domain.save
|
124
|
-
raise "Could not save Mailbox and Domain #{mailbox.errors.map(&:to_s).join} #{domain.errors.map(&:to_s).join}"
|
125
|
-
end
|
109
|
+
raise_save_error(mailbox) unless mailbox.save
|
126
110
|
end
|
127
111
|
|
128
112
|
def add_alias(address, goto)
|
129
113
|
if Mailbox.exists?(address)
|
130
|
-
|
131
|
-
end
|
132
|
-
if Alias.exists?(address)
|
133
|
-
raise Error, "alias #{address} is already registered!"
|
114
|
+
raise_error "Mailbox has already been registered: #{address}"
|
134
115
|
end
|
135
116
|
|
136
|
-
|
117
|
+
alias_must_not_exist!(address)
|
137
118
|
|
138
|
-
|
139
|
-
raise Error, "Invalid domain! #{domain_name}"
|
140
|
-
end
|
119
|
+
local_part, domain_name = address_split(address)
|
141
120
|
|
142
|
-
domain =
|
121
|
+
domain = find_domain(domain_name)
|
143
122
|
|
144
123
|
attributes = {
|
145
124
|
local_part: local_part,
|
146
125
|
goto: goto
|
147
126
|
}
|
127
|
+
|
148
128
|
domain.rel_aliases << Alias.new(attributes)
|
149
|
-
|
129
|
+
|
130
|
+
raise_save_error(domain) unless domain.save
|
150
131
|
end
|
151
132
|
|
152
133
|
def delete_alias(address)
|
153
134
|
if Mailbox.exists?(address)
|
154
|
-
|
135
|
+
raise_error "Can not delete mailbox by delete_alias. Use delete_account"
|
155
136
|
end
|
156
137
|
|
157
138
|
unless Alias.exists?(address)
|
158
|
-
|
139
|
+
raise_error "#{address} is not found!"
|
159
140
|
end
|
160
141
|
|
161
142
|
Alias.where(address: address).delete_all
|
162
143
|
end
|
163
144
|
|
164
|
-
def add_domain(domain_name)
|
145
|
+
def add_domain(domain_name, description: nil)
|
165
146
|
domain_name = domain_name.downcase
|
166
|
-
|
167
|
-
|
147
|
+
|
148
|
+
unless valid_domain_name?(domain_name)
|
149
|
+
raise_error "Invalid domain name: #{domain_name}"
|
168
150
|
end
|
151
|
+
|
169
152
|
if Domain.exists?(domain_name)
|
170
|
-
|
153
|
+
raise_error "Domain has already been registered: #{domain_name}"
|
171
154
|
end
|
155
|
+
|
156
|
+
new_description = description || domain_name
|
157
|
+
|
172
158
|
domain = Domain.new
|
173
159
|
domain.attributes = {
|
174
160
|
domain: domain_name,
|
175
|
-
description:
|
161
|
+
description: new_description,
|
176
162
|
aliases: @config[:aliases],
|
177
163
|
mailboxes: @config[:mailboxes],
|
178
|
-
maxquota: @config[:maxquota]
|
164
|
+
maxquota: @config[:maxquota]
|
179
165
|
}
|
180
166
|
domain.save!
|
181
167
|
end
|
182
168
|
|
183
169
|
def delete_domain(domain_name)
|
184
170
|
domain_name = domain_name.downcase
|
185
|
-
unless Domain.exists?(domain_name)
|
186
|
-
raise Error, "Could not find domain #{domain_name}"
|
187
|
-
end
|
188
171
|
|
189
|
-
domain =
|
190
|
-
domain.rel_mailboxes.delete_all
|
191
|
-
domain.rel_aliases.delete_all
|
172
|
+
domain = find_domain(domain_name)
|
192
173
|
|
193
174
|
admin_names = domain.admins.map(&:username)
|
194
175
|
|
195
|
-
domain.
|
176
|
+
domain.destroy!
|
196
177
|
|
178
|
+
# Remove admins who had the deleted domain only
|
197
179
|
admin_names.each do |name|
|
198
180
|
next unless Admin.exists?(name)
|
199
181
|
|
@@ -201,16 +183,14 @@ module PostfixAdmin
|
|
201
183
|
|
202
184
|
# check if the admin is needed or not
|
203
185
|
if admin.rel_domains.empty?
|
204
|
-
admin.destroy
|
186
|
+
admin.destroy!
|
205
187
|
end
|
206
188
|
end
|
207
|
-
|
208
|
-
domain.destroy
|
209
189
|
end
|
210
190
|
|
211
191
|
def delete_admin(user_name)
|
212
192
|
unless Admin.exists?(user_name)
|
213
|
-
|
193
|
+
raise_error "Could not find admin #{user_name}"
|
214
194
|
end
|
215
195
|
|
216
196
|
admin = Admin.find(user_name)
|
@@ -220,26 +200,72 @@ module PostfixAdmin
|
|
220
200
|
|
221
201
|
def delete_account(address)
|
222
202
|
unless Alias.exists?(address) && Mailbox.exists?(address)
|
223
|
-
|
203
|
+
raise_error "Could not find account: #{address}"
|
224
204
|
end
|
225
205
|
|
226
206
|
Mailbox.where(username: address).delete_all
|
227
207
|
Alias.where(address: address).delete_all
|
228
208
|
end
|
229
209
|
|
210
|
+
private
|
211
|
+
|
212
|
+
def find_domain(domain_name)
|
213
|
+
domain_must_exist!(domain_name)
|
214
|
+
Domain.find(domain_name)
|
215
|
+
end
|
216
|
+
|
217
|
+
def raise_error(message)
|
218
|
+
raise PostfixAdmin::Error, message
|
219
|
+
end
|
220
|
+
|
221
|
+
def raise_save_error(obj)
|
222
|
+
raise_error "Failed to save #{obj.class}: #{obj.errors.full_messages.join(', ')}"
|
223
|
+
end
|
224
|
+
|
230
225
|
def address_split(address)
|
231
226
|
address.split('@')
|
232
227
|
end
|
233
228
|
|
234
|
-
|
229
|
+
def valid_domain_name?(domain_name)
|
230
|
+
/.+\..+/.match?(domain_name)
|
231
|
+
end
|
232
|
+
|
233
|
+
def valid_email_address?(address)
|
234
|
+
/.+@.+\..+/.match?(address)
|
235
|
+
end
|
236
|
+
|
237
|
+
def domain_must_exist!(domain_name)
|
238
|
+
unless Domain.exists?(domain_name)
|
239
|
+
raise_error "Could not find domain: #{domain_name}"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def alias_must_not_exist!(address)
|
244
|
+
if Alias.exists?(address)
|
245
|
+
raise_error "Alias has already been registered: #{address}"
|
246
|
+
end
|
247
|
+
end
|
235
248
|
|
236
249
|
def admin_domain_check(user_name, domain_name)
|
237
|
-
|
238
|
-
|
250
|
+
unless Admin.exists?(user_name)
|
251
|
+
raise_error "#{user_name} is not registered as admin."
|
252
|
+
end
|
253
|
+
|
254
|
+
domain_must_exist!(domain_name)
|
255
|
+
end
|
256
|
+
|
257
|
+
def validate_password(password)
|
258
|
+
raise_error "Empty password" if password.nil? || password.empty?
|
239
259
|
end
|
240
260
|
|
241
|
-
def
|
242
|
-
|
261
|
+
def validate_account(address, password)
|
262
|
+
validate_password(password)
|
263
|
+
|
264
|
+
unless valid_email_address?(address)
|
265
|
+
raise_error "Invalid email address: #{address}"
|
266
|
+
end
|
267
|
+
|
268
|
+
alias_must_not_exist!(address)
|
243
269
|
end
|
244
270
|
end
|
245
271
|
end
|