postfix_admin 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -4
  3. data/CHANGELOG.md +24 -14
  4. data/README.md +14 -0
  5. data/Rakefile +29 -0
  6. data/db/reset.rb +7 -0
  7. data/db/seeds.rb +26 -0
  8. data/docker-admin/config.local.php +3 -1
  9. data/docker-compose.yml +3 -8
  10. data/lib/postfix_admin/base.rb +11 -22
  11. data/lib/postfix_admin/cli.rb +140 -56
  12. data/lib/postfix_admin/doveadm.rb +31 -15
  13. data/lib/postfix_admin/{admin.rb → models/admin.rb} +21 -2
  14. data/lib/postfix_admin/models/alias.rb +63 -0
  15. data/lib/postfix_admin/{application_record.rb → models/application_record.rb} +2 -2
  16. data/lib/postfix_admin/{concerns → models/concerns}/existing_timestamp.rb +1 -2
  17. data/lib/postfix_admin/models/concerns/has_password.rb +16 -0
  18. data/lib/postfix_admin/{domain.rb → models/domain.rb} +66 -2
  19. data/lib/postfix_admin/models/domain_admin.rb +21 -0
  20. data/lib/postfix_admin/models/log.rb +22 -0
  21. data/lib/postfix_admin/models/mailbox.rb +143 -0
  22. data/lib/postfix_admin/models/quota2.rb +20 -0
  23. data/lib/postfix_admin/models.rb +8 -9
  24. data/lib/postfix_admin/runner.rb +68 -14
  25. data/lib/postfix_admin/version.rb +1 -1
  26. metadata +15 -14
  27. data/lib/postfix_admin/alias.rb +0 -46
  28. data/lib/postfix_admin/concerns/dovecot_cram_md5_password.rb +0 -29
  29. data/lib/postfix_admin/domain_admin.rb +0 -8
  30. data/lib/postfix_admin/log.rb +0 -5
  31. data/lib/postfix_admin/mail_domain.rb +0 -9
  32. data/lib/postfix_admin/mailbox.rb +0 -97
  33. data/lib/postfix_admin/quota.rb +0 -6
  34. /data/lib/postfix_admin/{concerns → models/concerns}/.keep +0 -0
@@ -1,5 +1,28 @@
1
+ require "postfix_admin/models/application_record"
2
+
1
3
  module PostfixAdmin
2
4
  class Domain < ApplicationRecord
5
+ # version: 1841
6
+ # > describe domain;
7
+ # +-------------+--------------+------+-----+---------------------+-------+
8
+ # | Field | Type | Null | Key | Default | Extra |
9
+ # +-------------+--------------+------+-----+---------------------+-------+
10
+ # | domain | varchar(255) | NO | PRI | NULL | |
11
+ # | description | varchar(255) | NO | | NULL | |
12
+ # | aliases | int(10) | NO | | 0 | |
13
+ # | mailboxes | int(10) | NO | | 0 | |
14
+ # | maxquota | bigint(20) | NO | | 0 | |
15
+ # | quota | bigint(20) | NO | | 0 | |
16
+ # | transport | varchar(255) | NO | | NULL | |
17
+ # | backupmx | tinyint(1) | NO | | 0 | |
18
+ # | created | datetime | NO | | 2000-01-01 00:00:00 | |
19
+ # | modified | datetime | NO | | 2000-01-01 00:00:00 | |
20
+ # | active | tinyint(1) | NO | | 1 | |
21
+ # +-------------+--------------+------+-----+---------------------+-------+
22
+
23
+ UNLIMITED = 0
24
+ DISABLED = -1
25
+
3
26
  self.table_name = :domain
4
27
  self.primary_key = :domain
5
28
 
@@ -31,6 +54,10 @@ module PostfixAdmin
31
54
  has_many :rel_aliases, class_name: "Alias", foreign_key: :domain,
32
55
  dependent: :destroy
33
56
 
57
+ # logs that belong to this domain
58
+ has_many :logs, class_name: "Log", foreign_key: :domain,
59
+ dependent: :destroy
60
+
34
61
  # It causes errors to set `dependent: :destroy` as other columns
35
62
  # because the domain_admins table doesn't have a single primary key.
36
63
  #
@@ -45,6 +72,7 @@ module PostfixAdmin
45
72
  # It works well with `dependent: :delete_all` instead.
46
73
  #
47
74
  # PostfixAdmin::DomainAdmin Destroy (0.4ms) DELETE FROM `domain_admins` WHERE `domain_admins`.`domain` = 'example.com'
75
+ # Domain <-> DomainAdmin <-> Admin
48
76
  has_many :domain_admins, foreign_key: :domain, dependent: :delete_all
49
77
 
50
78
  has_many :admins, through: :domain_admins
@@ -61,6 +89,22 @@ module PostfixAdmin
61
89
  rel_aliases.pure
62
90
  end
63
91
 
92
+ def mailbox_count
93
+ rel_mailboxes.count
94
+ end
95
+
96
+ def pure_alias_count
97
+ pure_aliases.count
98
+ end
99
+
100
+ def mailbox_usage_display_str
101
+ "%4d / %4s" % [mailbox_count, mailboxes_str]
102
+ end
103
+
104
+ def alias_usage_display_str
105
+ "%4d / %4s" % [pure_alias_count, aliases_str]
106
+ end
107
+
64
108
  def aliases_str
65
109
  max_num_str(aliases)
66
110
  end
@@ -73,13 +117,33 @@ module PostfixAdmin
73
117
  max_num_str(maxquota)
74
118
  end
75
119
 
120
+ def mailbox_unlimited?
121
+ mailboxes == UNLIMITED
122
+ end
123
+
124
+ def alias_unlimited?
125
+ aliases == UNLIMITED
126
+ end
127
+
128
+ def maxquota_unlimited?
129
+ maxquota.zero?
130
+ end
131
+
132
+ def mailbox_disabled?
133
+ mailboxes == DISABLED
134
+ end
135
+
136
+ def alias_disabled?
137
+ aliases == DISABLED
138
+ end
139
+
76
140
  private
77
141
 
78
142
  def max_num_str(num)
79
143
  case num
80
- when -1
144
+ when DISABLED
81
145
  "Disabled"
82
- when 0
146
+ when UNLIMITED
83
147
  "Unlimited"
84
148
  else
85
149
  num.to_s
@@ -0,0 +1,21 @@
1
+ require "postfix_admin/models/application_record"
2
+
3
+ module PostfixAdmin
4
+ class DomainAdmin < ApplicationRecord
5
+ # version: 1841
6
+ # > describe domain_admins;
7
+ # +----------+--------------+------+-----+---------------------+-------+
8
+ # | Field | Type | Null | Key | Default | Extra |
9
+ # +----------+--------------+------+-----+---------------------+-------+
10
+ # | username | varchar(255) | NO | MUL | NULL | |
11
+ # | domain | varchar(255) | NO | | NULL | |
12
+ # | created | datetime | NO | | 2000-01-01 00:00:00 | |
13
+ # | active | tinyint(1) | NO | | 1 | |
14
+ # +----------+--------------+------+-----+---------------------+-------+
15
+
16
+ self.table_name = :domain_admins
17
+
18
+ belongs_to :admin, primary_key: :username, foreign_key: :username
19
+ belongs_to :rel_domain, class_name: "Domain", foreign_key: :domain
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ require "postfix_admin/models/application_record"
2
+
3
+ module PostfixAdmin
4
+ class Log < ApplicationRecord
5
+ # version: 1841
6
+ # > describe log;
7
+ # +-----------+--------------+------+-----+---------------------+----------------+
8
+ # | Field | Type | Null | Key | Default | Extra |
9
+ # +-----------+--------------+------+-----+---------------------+----------------+
10
+ # | timestamp | datetime | NO | MUL | 2000-01-01 00:00:00 | |
11
+ # | username | varchar(255) | NO | | NULL | |
12
+ # | domain | varchar(255) | NO | MUL | NULL | |
13
+ # | action | varchar(255) | NO | | NULL | |
14
+ # | data | text | NO | | NULL | |
15
+ # | id | int(11) | NO | PRI | NULL | auto_increment |
16
+ # +-----------+--------------+------+-----+---------------------+----------------+
17
+
18
+ self.table_name = :log
19
+
20
+ belongs_to :rel_domain, class_name: "Domain", foreign_key: :domain
21
+ end
22
+ end
@@ -0,0 +1,143 @@
1
+ require "postfix_admin/models/application_record"
2
+ require "postfix_admin/models/concerns/has_password"
3
+
4
+ module PostfixAdmin
5
+ class Mailbox < ApplicationRecord
6
+ # version: 1841
7
+ # > describe mailbox;
8
+ # +----------------+--------------+------+-----+---------------------+-------+
9
+ # | Field | Type | Null | Key | Default | Extra |
10
+ # +----------------+--------------+------+-----+---------------------+-------+
11
+ # | username | varchar(255) | NO | PRI | NULL | |
12
+ # | password | varchar(255) | NO | | NULL | |
13
+ # | name | varchar(255) | NO | | NULL | |
14
+ # | maildir | varchar(255) | NO | | NULL | |
15
+ # | quota | bigint(20) | NO | | 0 | |
16
+ # | local_part | varchar(255) | NO | | NULL | |
17
+ # | domain | varchar(255) | NO | MUL | NULL | |
18
+ # | created | datetime | NO | | 2000-01-01 00:00:00 | |
19
+ # | modified | datetime | NO | | 2000-01-01 00:00:00 | |
20
+ # | active | tinyint(1) | NO | | 1 | |
21
+ # | phone | varchar(30) | NO | | | |
22
+ # | email_other | varchar(255) | NO | | | |
23
+ # | token | varchar(255) | NO | | | |
24
+ # | token_validity | datetime | NO | | 2000-01-01 00:00:00 | |
25
+ # +----------------+--------------+------+-----+---------------------+-------+
26
+
27
+ UNLIMITED_QUOTA = 0
28
+ DISABLED_QUOTA = -1
29
+
30
+ self.table_name = :mailbox
31
+ self.primary_key = :username
32
+
33
+ include HasPassword
34
+
35
+ validates :username, presence: true, uniqueness: { case_sensitive: false },
36
+ format: { with: RE_EMAIL_LIKE_WITH_ANCHORS,
37
+ message: "must be a valid email address" }
38
+ validates :maildir, presence: true, uniqueness: { case_sensitive: false }
39
+ validates :local_part, presence: true
40
+
41
+ # quota (KB)
42
+ validates :quota, presence: true,
43
+ numericality: { only_integer: true,
44
+ greater_than_or_equal_to: 0 }
45
+
46
+ belongs_to :rel_domain, class_name: "Domain", foreign_key: :domain
47
+ has_one :alias, foreign_key: :address, dependent: :destroy
48
+ has_one :quota_usage, class_name: "Quota2", foreign_key: :username,
49
+ dependent: :destroy
50
+
51
+ validate on: :create do |mailbox|
52
+ domain = mailbox.rel_domain
53
+
54
+ if domain.mailbox_unlimited?
55
+ # unlimited: do nothing
56
+ elsif domain.mailbox_disabled?
57
+ # disabled
58
+ mailbox.errors.add(:domain, "has a disabled status for mailboxes")
59
+ elsif domain.mailbox_count >= domain.mailboxes
60
+ # exceeding mailbox limit
61
+ message = "has already reached the maximum number of mailboxes " \
62
+ "(maximum: #{domain.mailboxes})"
63
+ mailbox.errors.add(:domain, message)
64
+ end
65
+ end
66
+
67
+ # just in case
68
+ validate on: :update do |mailbox|
69
+ mailbox.errors.add(:username, 'cannot be changed') if mailbox.username_changed?
70
+ mailbox.errors.add(:local_part, 'cannot be changed') if mailbox.local_part_changed?
71
+ end
72
+
73
+ validate do |mailbox|
74
+ next if mailbox.quota == DISABLED_QUOTA
75
+
76
+ domain = mailbox.rel_domain
77
+
78
+ next if domain.maxquota_unlimited?
79
+
80
+ # Quota limit
81
+ message = "must be less than or equal to #{domain.maxquota} MB"
82
+ if mailbox.quota_unlimited?
83
+ # trying to set quota to 0 (unlimited) even when domain's maxquota is not unlimited
84
+ mailbox.errors.add(:quota, "cannot be set to 0 (unlimited)")
85
+ mailbox.errors.add(:quota, message)
86
+ elsif mailbox.quota_mb > domain.maxquota
87
+ # trying to set quota to value greater than domain's maxquota
88
+ mailbox.errors.add(:quota, message)
89
+ end
90
+ end
91
+
92
+ before_validation do |mailbox|
93
+ mailbox.name = "" if mailbox.name.nil?
94
+ mailbox.username = "#{mailbox.local_part}@#{mailbox.domain}"
95
+ mailbox.maildir ||= "#{mailbox.domain}/#{mailbox.username}/"
96
+ mailbox.build_alias(address: mailbox.username, goto: mailbox.username,
97
+ domain: mailbox.domain)
98
+ end
99
+
100
+ def quota_unlimited?
101
+ quota.zero?
102
+ end
103
+
104
+ def quota_mb
105
+ raise Error, "quota is out of range: #{quota}" if quota < 0
106
+
107
+ quota / KB_TO_MB
108
+ end
109
+
110
+ def quota_mb=(value)
111
+ raise Error, "quota is out of range: #{value}" if value < 0
112
+
113
+ self.quota = value * KB_TO_MB
114
+ end
115
+
116
+ def quota_usage_str(format: "%6.1f")
117
+ usage_mb = if quota_usage
118
+ usage_mb = quota_usage.bytes / KB_TO_MB.to_f
119
+ else
120
+ 0.0
121
+ end
122
+
123
+ format % usage_mb
124
+ end
125
+
126
+ def quota_mb_str(format: "%6.1f")
127
+ case quota
128
+ when DISABLED_QUOTA
129
+ # It's not sure what 'disabled' means for quota.
130
+ "Disabled"
131
+ when UNLIMITED_QUOTA
132
+ "Unlimited"
133
+ else
134
+ quota_mb = quota / KB_TO_MB.to_f
135
+ format % quota_mb
136
+ end
137
+ end
138
+
139
+ def quota_display_str(format: "%6.1f")
140
+ "%s / %s" % [quota_usage_str(format: format), quota_mb_str(format: format)]
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,20 @@
1
+ require "postfix_admin/models/application_record"
2
+
3
+ module PostfixAdmin
4
+ class Quota2 < ApplicationRecord
5
+ # version: 1841
6
+ # > describe quota2;
7
+ # +----------+--------------+------+-----+---------+-------+
8
+ # | Field | Type | Null | Key | Default | Extra |
9
+ # +----------+--------------+------+-----+---------+-------+
10
+ # | username | varchar(100) | NO | PRI | NULL | |
11
+ # | bytes | bigint(20) | NO | | 0 | |
12
+ # | messages | int(11) | NO | | 0 | |
13
+ # +----------+--------------+------+-----+---------+-------+
14
+
15
+ self.table_name = :quota2
16
+ self.primary_key = :username
17
+
18
+ belongs_to :rel_mailbox, class_name: "Mailbox", foreign_key: :username
19
+ end
20
+ end
@@ -1,10 +1,9 @@
1
1
  require 'active_record'
2
- require 'postfix_admin/application_record'
3
- require 'postfix_admin/admin'
4
- require 'postfix_admin/domain'
5
- require 'postfix_admin/mailbox'
6
- require 'postfix_admin/alias'
7
- require 'postfix_admin/domain_admin'
8
- require 'postfix_admin/log'
9
- require 'postfix_admin/mail_domain'
10
- require 'postfix_admin/quota'
2
+ require 'postfix_admin/models/application_record'
3
+ require 'postfix_admin/models/admin'
4
+ require 'postfix_admin/models/domain'
5
+ require 'postfix_admin/models/mailbox'
6
+ require 'postfix_admin/models/alias'
7
+ require 'postfix_admin/models/domain_admin'
8
+ require 'postfix_admin/models/log'
9
+ require 'postfix_admin/models/quota2'
@@ -30,21 +30,70 @@ module PostfixAdmin
30
30
  runner { @cli.show(name) }
31
31
  end
32
32
 
33
- desc "setup example.com password", "Set up a domain"
33
+ desc "admins", "List all admin users"
34
+ def admins
35
+ runner { @cli.show_admins }
36
+ end
37
+
38
+ desc "domains", "List all domains"
39
+ def domains
40
+ runner { @cli.show_domains }
41
+ end
42
+
43
+ desc "accounts", "List all accounts"
44
+ def accounts
45
+ runner { @cli.show_accounts }
46
+ end
47
+
48
+ desc "aliases", "List all aliases"
49
+ def aliases
50
+ runner { @cli.show_aliases }
51
+ end
52
+
53
+ desc "forwards", "List all forwards"
54
+ def forwards
55
+ runner { @cli.show_forwards }
56
+ end
57
+
58
+ desc "setup example.com password",
59
+ "Set up a domain (add a domain and an admin user for it)"
60
+ method_option :description, type: :string, aliases: "-d", desc: "description"
61
+ method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
62
+ method_option :rounds, type: :string, aliases: "-r", desc: "encryption rounds for BLF-CRYPT, SHA256-CRYPT and SHA512-CRYPT schemes"
34
63
  def setup(domain_name, password)
35
- runner { @cli.setup_domain(domain_name, password) }
64
+ runner do
65
+ @cli.setup_domain(domain_name, password,
66
+ description: options[:description],
67
+ scheme: options[:scheme], rounds: options[:rounds])
68
+ end
69
+ end
70
+
71
+ desc "teardown example.com",
72
+ "Tear down a domain (delete a domain and an admin user for it)"
73
+ def teardown(domain_name)
74
+ runner { @cli.teardown_domain(domain_name) }
36
75
  end
37
76
 
38
77
  desc "admin_passwd admin@example.com new_password",
39
78
  "Change the password of an admin user"
79
+ method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
80
+ method_option :rounds, type: :string, aliases: "-r", desc: "encryption rounds for BLF-CRYPT, SHA256-CRYPT and SHA512-CRYPT schemes"
40
81
  def admin_passwd(user_name, password)
41
- runner { @cli.change_admin_password(user_name, password) }
82
+ runner do
83
+ @cli.change_admin_password(user_name, password,
84
+ scheme: options[:scheme], rounds: options[:rounds])
85
+ end
42
86
  end
43
87
 
44
88
  desc "account_passwd user@example.com new_password",
45
89
  "Change the password of an account"
90
+ method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
91
+ method_option :rounds, type: :string, aliases: "-r", desc: "encryption rounds for BLF-CRYPT, SHA256-CRYPT and SHA512-CRYPT schemes"
46
92
  def account_passwd(user_name, password)
47
- runner { @cli.change_account_password(user_name, password) }
93
+ runner do
94
+ @cli.change_account_password(user_name, password,
95
+ scheme: options[:scheme], rounds: options[:rounds])
96
+ end
48
97
  end
49
98
 
50
99
  desc "add_domain example.com", "Add a new domain"
@@ -54,11 +103,11 @@ module PostfixAdmin
54
103
  end
55
104
 
56
105
  desc "edit_domain example.com", "Edit a domain"
57
- method_option :aliases, type: :numeric, aliases: "-a", desc: "Edit aliases limitation"
58
- method_option :mailboxes, type: :numeric, aliases: "-m", desc: "Edit mailboxes limitation"
59
- method_option :maxquota, type: :numeric, aliases: "-q", desc: "Edit max quota limitation"
106
+ method_option :aliases, type: :numeric, aliases: "-a", desc: "Update aliase limit"
107
+ method_option :mailboxes, type: :numeric, aliases: "-m", desc: "Update mailboxe limit"
108
+ method_option :maxquota, type: :numeric, aliases: "-q", desc: "Update maximum quota limit (MB)"
60
109
  method_option :active, type: :boolean, desc: "Update active status"
61
- method_option :description, type: :string, aliases: "-d", desc: "Edit description"
110
+ method_option :description, type: :string, aliases: "-d", desc: "Update description"
62
111
  def edit_domain(domain_name)
63
112
  runner do
64
113
  if options.size == 0
@@ -86,8 +135,9 @@ module PostfixAdmin
86
135
  end
87
136
 
88
137
  desc "add_account user@example.com password", "Add a new account"
89
- method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
90
138
  method_option :name, type: :string, aliases: "-n", desc: "full name"
139
+ method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
140
+ method_option :rounds, type: :string, aliases: "-r", desc: "encryption rounds for BLF-CRYPT, SHA256-CRYPT and SHA512-CRYPT schemes"
91
141
  def add_account(address, password)
92
142
  runner do
93
143
  if options[:scheme] == 'scheme'
@@ -98,7 +148,8 @@ module PostfixAdmin
98
148
  warn "Specify name"
99
149
  help('add_account')
100
150
  else
101
- @cli.add_account(address, password, options[:scheme], options[:name])
151
+ @cli.add_account(address, password, name: options[:name],
152
+ scheme: options[:scheme], rounds: options[:rounds])
102
153
  end
103
154
  end
104
155
  end
@@ -106,11 +157,11 @@ module PostfixAdmin
106
157
 
107
158
  desc "edit_account user@example.com", "Edit an account"
108
159
  method_option :goto, type: :string, aliases: "-g",
109
- desc: "mailboxes, addresses e-mails are delivered to"
160
+ desc: "Update mailboxes, addresses emails are delivered to"
110
161
  method_option :quota, type: :numeric, aliases: "-q",
111
- desc: "quota limitation (MB)"
162
+ desc: "Update quota limit (MB)"
112
163
  method_option :name, type: :string, aliases: "-n",
113
- desc: "full name"
164
+ desc: "Update full name"
114
165
  method_option :active, type: :boolean,
115
166
  desc: "Update active status"
116
167
  def edit_account(address)
@@ -146,13 +197,16 @@ module PostfixAdmin
146
197
  desc "add_admin admin@example.com password", "Add a new admin user"
147
198
  method_option :super, type: :boolean, aliases: "-S", desc: "register as a super admin"
148
199
  method_option :scheme, type: :string, aliases: "-s", desc: "password scheme"
200
+ method_option :rounds, type: :string, aliases: "-r", desc: "encryption rounds for BLF-CRYPT, SHA256-CRYPT and SHA512-CRYPT schemes"
149
201
  def add_admin(user_name, password)
150
202
  runner do
151
203
  if options[:scheme] == 'scheme'
152
204
  warn "Specify password scheme"
153
205
  help('add_admin')
154
206
  else
155
- @cli.add_admin(user_name, password, options[:super], options[:scheme])
207
+ @cli.add_admin(user_name, password,
208
+ super_admin: options[:super], scheme: options[:scheme],
209
+ rounds: options[:rounds])
156
210
  end
157
211
  end
158
212
  end
@@ -1,3 +1,3 @@
1
1
  module PostfixAdmin
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postfix_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hitoshi Kurokawa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-15 00:00:00.000000000 Z
11
+ date: 2024-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -154,6 +154,8 @@ files:
154
154
  - Rakefile
155
155
  - Thorfile
156
156
  - bin/console
157
+ - db/reset.rb
158
+ - db/seeds.rb
157
159
  - docker-admin/Dockerfile
158
160
  - docker-admin/config.local.php
159
161
  - docker-app/Dockerfile
@@ -164,23 +166,22 @@ files:
164
166
  - docker-db/postfix.v740.sql
165
167
  - exe/postfix_admin
166
168
  - lib/postfix_admin.rb
167
- - lib/postfix_admin/admin.rb
168
- - lib/postfix_admin/alias.rb
169
- - lib/postfix_admin/application_record.rb
170
169
  - lib/postfix_admin/base.rb
171
170
  - lib/postfix_admin/cli.rb
172
- - lib/postfix_admin/concerns/.keep
173
- - lib/postfix_admin/concerns/dovecot_cram_md5_password.rb
174
- - lib/postfix_admin/concerns/existing_timestamp.rb
175
- - lib/postfix_admin/domain.rb
176
- - lib/postfix_admin/domain_admin.rb
177
171
  - lib/postfix_admin/doveadm.rb
178
172
  - lib/postfix_admin/error.rb
179
- - lib/postfix_admin/log.rb
180
- - lib/postfix_admin/mail_domain.rb
181
- - lib/postfix_admin/mailbox.rb
182
173
  - lib/postfix_admin/models.rb
183
- - lib/postfix_admin/quota.rb
174
+ - lib/postfix_admin/models/admin.rb
175
+ - lib/postfix_admin/models/alias.rb
176
+ - lib/postfix_admin/models/application_record.rb
177
+ - lib/postfix_admin/models/concerns/.keep
178
+ - lib/postfix_admin/models/concerns/existing_timestamp.rb
179
+ - lib/postfix_admin/models/concerns/has_password.rb
180
+ - lib/postfix_admin/models/domain.rb
181
+ - lib/postfix_admin/models/domain_admin.rb
182
+ - lib/postfix_admin/models/log.rb
183
+ - lib/postfix_admin/models/mailbox.rb
184
+ - lib/postfix_admin/models/quota2.rb
184
185
  - lib/postfix_admin/runner.rb
185
186
  - lib/postfix_admin/version.rb
186
187
  - postfix_admin.gemspec
@@ -1,46 +0,0 @@
1
- module PostfixAdmin
2
- class Alias < ApplicationRecord
3
- self.table_name = :alias
4
- self.primary_key = :address
5
-
6
- validate on: :create do |a|
7
- domain = a.rel_domain
8
- if domain.aliases.zero? || a.mailbox
9
- elsif domain.rel_aliases.pure.count >= domain.aliases
10
- message = "already has the maximum number of aliases " \
11
- "(maximum is #{domain.aliases} aliases)"
12
- a.errors.add(:domain, message)
13
- end
14
- end
15
-
16
- validates :address, presence: true, uniqueness: { case_sensitive: false },
17
- format: { with: RE_EMAIL_LIKE_WITH_ANCHORS,
18
- message: "must be a valid email address" }
19
- validates :goto, presence: true
20
-
21
- belongs_to :rel_domain, class_name: "Domain", foreign_key: :domain
22
- belongs_to :mailbox, foreign_key: :address, optional: true
23
-
24
- scope :pure, -> { joins("LEFT OUTER JOIN mailbox ON alias.address = mailbox.username").where("mailbox.username" => nil) }
25
-
26
- attribute :local_part, :string
27
-
28
- before_validation do |a|
29
- unless a.address
30
- a.address = "#{a.local_part}@#{a.domain}" unless a.local_part.empty?
31
- end
32
- end
33
-
34
- def mailbox?
35
- !!mailbox
36
- end
37
-
38
- def pure_alias?
39
- !mailbox
40
- end
41
-
42
- def gotos
43
- goto.split(",")
44
- end
45
- end
46
- end
@@ -1,29 +0,0 @@
1
- require 'active_support/concern'
2
-
3
- module DovecotCramMD5Password
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- validates :password_unencrypted, length: { minimum: 5 }, allow_blank: true
8
- validates_confirmation_of :password_unencrypted, allow_blank: true
9
-
10
- validate do |record|
11
- record.errors.add(:password_unencrypted, :blank) unless record.password.present?
12
- end
13
-
14
- attr_reader :password_unencrypted
15
- end
16
-
17
- def password_unencrypted=(unencrypted_password)
18
- if unencrypted_password.nil?
19
- self.password = nil
20
- elsif !unencrypted_password.empty?
21
- @password_unencrypted = unencrypted_password
22
- self.password = DovecotCrammd5.calc(unencrypted_password)
23
- end
24
- end
25
-
26
- def authenticate(unencrypted_password)
27
- password == DovecotCrammd5.calc(unencrypted_password) && self
28
- end
29
- end
@@ -1,8 +0,0 @@
1
- module PostfixAdmin
2
- class DomainAdmin < ApplicationRecord
3
- self.table_name = :domain_admins
4
-
5
- belongs_to :admin, primary_key: :username, foreign_key: :username
6
- belongs_to :rel_domain, class_name: "Domain", foreign_key: :domain
7
- end
8
- end
@@ -1,5 +0,0 @@
1
- module PostfixAdmin
2
- class Log < ApplicationRecord
3
- self.table_name = :log
4
- end
5
- end
@@ -1,9 +0,0 @@
1
- module PostfixAdmin
2
- class MailDomain < ApplicationRecord
3
- self.table_name = :domain
4
- self.primary_key = :domain
5
-
6
- has_many :addresses, class_name: "Mailbox", foreign_key: :domain,
7
- dependent: :destroy
8
- end
9
- end