postfix_admin 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +7 -5
- data/Dockerfile +24 -0
- data/README.md +22 -15
- data/Rakefile +5 -0
- data/bin/console +18 -0
- data/docker-compose.yml +24 -0
- data/docker-entrypoint.sh +5 -0
- data/{bin → exe}/postfix_admin +1 -0
- data/lib/postfix_admin.rb +1 -1
- data/lib/postfix_admin/admin.rb +52 -0
- data/lib/postfix_admin/alias.rb +65 -0
- data/lib/postfix_admin/application_record.rb +44 -0
- data/lib/postfix_admin/base.rb +98 -88
- data/lib/postfix_admin/cli.rb +50 -46
- data/lib/postfix_admin/concerns/.keep +0 -0
- data/lib/postfix_admin/concerns/dovecot_cram_md5_password.rb +30 -0
- data/lib/postfix_admin/concerns/existing_timestamp.rb +18 -0
- data/lib/postfix_admin/domain.rb +98 -0
- data/lib/postfix_admin/domain_admin.rb +8 -0
- data/lib/postfix_admin/doveadm.rb +1 -1
- data/lib/postfix_admin/log.rb +5 -0
- data/lib/postfix_admin/mail_domain.rb +9 -0
- data/lib/postfix_admin/mailbox.rb +89 -0
- data/lib/postfix_admin/models.rb +10 -213
- data/lib/postfix_admin/quota.rb +6 -0
- data/lib/postfix_admin/runner.rb +39 -36
- data/lib/postfix_admin/version.rb +1 -1
- data/postfix_admin.gemspec +20 -13
- metadata +49 -50
- data/spec/base_spec.rb +0 -253
- data/spec/cli_spec.rb +0 -300
- data/spec/doveadm_spec.rb +0 -35
- data/spec/models_spec.rb +0 -195
- data/spec/postfix_admin.conf +0 -5
- data/spec/postfix_test.sql +0 -250
- data/spec/runner_spec.rb +0 -370
- data/spec/spec_helper.rb +0 -201
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a83f945f0f977fc80b8715b899af26d908b3d6b1169d27fae9cf92089bac5082
|
4
|
+
data.tar.gz: f8f63116ece1064079b99f986fc26778c4f4affc28ae8dbd3beca3496a595186
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22f7cc6d351d3a7e63ba95e653ac21f4b1eeebaebb5a717810477ab0d700dbb3199eeee042ca34909aee1c959bb7d27fe705d1c332895e7bb38ae0cc1f3e9120
|
7
|
+
data.tar.gz: 821bb8bac75277e3faf303f1db8292256cc9bbcf40cb2de6f63f9c3c38e40f84c5739849edc159ddec8bf262d9fa9e5ea8f9bac15e8dce37f2691f0a017e2772
|
data/.rubocop.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
## 0.2.0
|
2
|
+
* Switched its object-relational mapper from DataMapper to ActiveRecord
|
3
|
+
* Stored password hash includes scheme prefix: like `{CRAM-MD5}`, `{PLAIN}`
|
4
|
+
|
1
5
|
## 0.1.4
|
2
|
-
*
|
6
|
+
* Added "log" subcommand
|
3
7
|
|
4
8
|
## 0.1.3
|
5
9
|
* Support for activation and deactivation of domain, admin and account
|
6
|
-
*
|
10
|
+
* Added "edit_admin" subcommand
|
7
11
|
|
8
12
|
## 0.1.2
|
9
|
-
* Support password hash by doveadm (external
|
13
|
+
* Support password hash by doveadm (external subcommand)
|
10
14
|
* Show active status
|
11
15
|
* Don't show passwords using list format
|
12
16
|
|
13
17
|
## 0.1.1, release 2013-05-10
|
14
18
|
* Fixed string length of password
|
15
|
-
|
16
|
-
|
data/Dockerfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
FROM centos:8
|
2
|
+
|
3
|
+
RUN dnf -y module enable ruby:2.6 \
|
4
|
+
&& dnf -y install \
|
5
|
+
ruby ruby-devel mariadb-devel sqlite-devel gcc make redhat-rpm-config \
|
6
|
+
mariadb dovecot git \
|
7
|
+
&& dnf clean all
|
8
|
+
|
9
|
+
WORKDIR /app
|
10
|
+
|
11
|
+
COPY Gemfile postfix_admin.gemspec ./
|
12
|
+
COPY ./lib/postfix_admin/version.rb ./lib/postfix_admin/version.rb
|
13
|
+
|
14
|
+
RUN gem install bundler && bundle install
|
15
|
+
|
16
|
+
COPY spec/postfix_admin.conf /root/.postfix_admin.conf
|
17
|
+
|
18
|
+
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
19
|
+
RUN chmod +x /docker-entrypoint.sh
|
20
|
+
ENTRYPOINT ["/docker-entrypoint.sh"]
|
21
|
+
|
22
|
+
EXPOSE 80
|
23
|
+
|
24
|
+
CMD ["/sbin/init"]
|
data/README.md
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
[](https://rubygems.org/gems/postfix_admin)
|
2
2
|
|
3
|
-
#
|
3
|
+
# postfix_admin
|
4
4
|
|
5
|
-
Command Line Tools
|
5
|
+
Command Line Tools for Postfix Admin
|
6
6
|
|
7
7
|
## Description
|
8
8
|
|
9
|
-
Postfix Admin Web
|
9
|
+
* Postfix Admin (Original Web-based Application)
|
10
|
+
+ Web Site http://postfixadmin.sourceforge.net/
|
11
|
+
+ GitHub https://github.com/postfixadmin/postfixadmin
|
10
12
|
|
11
|
-
|
13
|
+
* Postfix Admin 3.2 is supported.
|
12
14
|
|
13
|
-
|
14
|
-
PostgreSQL is not supported.
|
15
|
+
* MySQL/MariaDB is supported.
|
15
16
|
|
16
|
-
|
17
|
+
* Other database engines are not supported.
|
17
18
|
|
18
19
|
## Installation
|
19
20
|
|
@@ -21,6 +22,18 @@ Install postfix_admin as:
|
|
21
22
|
|
22
23
|
$ gem install postfix_admin
|
23
24
|
|
25
|
+
Just execute `postfix_admin` command to generate your config file: `~/.postfix_admin.conf`
|
26
|
+
|
27
|
+
$ postfix_admin
|
28
|
+
|
29
|
+
Edit the file for your environment:
|
30
|
+
|
31
|
+
$ vi ~/.postfix_admin.conf
|
32
|
+
|
33
|
+
You can see domains on your host if the `database` parameter is set properly:
|
34
|
+
|
35
|
+
$ postfix_admin show
|
36
|
+
|
24
37
|
## Usage
|
25
38
|
|
26
39
|
List the postfix_admin subcommands as:
|
@@ -44,19 +57,13 @@ Commands:
|
|
44
57
|
postfix_admin dump # Dump all data
|
45
58
|
postfix_admin edit_account user@example.com # Edit an account
|
46
59
|
postfix_admin edit_admin admin@example.com # Edit an admin user
|
60
|
+
postfix_admin edit_alias alias@example.com # Edit an alias
|
47
61
|
postfix_admin edit_domain example.com # Edit a domain limitation
|
48
62
|
postfix_admin help [COMMAND] # Describe available commands or one specific command
|
63
|
+
postfix_admin log # Show action logs
|
49
64
|
postfix_admin schemes # List all supported password schemes
|
50
65
|
postfix_admin setup example.com password # Setup a domain
|
51
66
|
postfix_admin show [example.com | admin@example.com | user@example.com] # Show domains or admins or mailboxes
|
52
67
|
postfix_admin summary [example.com] # Summarize the usage of PostfixAdmin
|
53
68
|
postfix_admin version # Show postfix_admin version
|
54
69
|
```
|
55
|
-
|
56
|
-
## Contributing
|
57
|
-
|
58
|
-
1. Fork it
|
59
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
61
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
-
5. Create new Pull Request
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "postfix_admin"
|
5
|
+
require "postfix_admin/cli"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
cli = PostfixAdmin::CLI.new
|
11
|
+
cli.db_setup
|
12
|
+
include PostfixAdmin
|
13
|
+
|
14
|
+
require "pry"
|
15
|
+
Pry.start
|
16
|
+
|
17
|
+
# require "irb"
|
18
|
+
# IRB.start(__FILE__)
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
version: '3.8'
|
2
|
+
|
3
|
+
services:
|
4
|
+
app:
|
5
|
+
build: .
|
6
|
+
tty: true
|
7
|
+
ports:
|
8
|
+
- '7080:80'
|
9
|
+
volumes:
|
10
|
+
- .:/app
|
11
|
+
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
12
|
+
tmpfs:
|
13
|
+
- /tmp
|
14
|
+
- /run
|
15
|
+
stop_signal: SIGRTMIN+3
|
16
|
+
db:
|
17
|
+
image: mariadb:10
|
18
|
+
volumes:
|
19
|
+
- ./spec/postfix.v1841.sql:/docker-entrypoint-initdb.d/postfix.sql
|
20
|
+
environment:
|
21
|
+
- MYSQL_RANDOM_ROOT_PASSWORD=yes
|
22
|
+
- MYSQL_USER=postfix
|
23
|
+
- MYSQL_PASSWORD=password
|
24
|
+
- MYSQL_DATABASE=postfix
|
data/{bin → exe}/postfix_admin
RENAMED
data/lib/postfix_admin.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'postfix_admin/concerns/dovecot_cram_md5_password'
|
2
|
+
|
3
|
+
module PostfixAdmin
|
4
|
+
class Admin < ApplicationRecord
|
5
|
+
self.table_name = :admin
|
6
|
+
self.primary_key = :username
|
7
|
+
|
8
|
+
include DovecotCramMD5Password
|
9
|
+
|
10
|
+
validates :username, presence: true, uniqueness: { case_sensitive: false },
|
11
|
+
format: { with: RE_EMAIL_LIKE_WITH_ANCHORS,
|
12
|
+
message: "must be a valid email address" }
|
13
|
+
|
14
|
+
has_many :domain_admins, foreign_key: :username, dependent: :delete_all
|
15
|
+
has_many :rel_domains, through: :domain_admins
|
16
|
+
|
17
|
+
attr_accessor :domain_ids
|
18
|
+
attribute :form_super_admin, :boolean, default: false
|
19
|
+
|
20
|
+
# just in case
|
21
|
+
validate on: :update do |admin|
|
22
|
+
admin.errors.add(:username, 'cannot be changed') if admin.username_changed?
|
23
|
+
end
|
24
|
+
|
25
|
+
def super_admin?
|
26
|
+
if @super_admin.nil?
|
27
|
+
@super_admin = rel_domains.exists?("ALL")
|
28
|
+
else
|
29
|
+
@super_admin
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def super_admin=(value)
|
34
|
+
if value
|
35
|
+
domain_ids = self.rel_domain_ids.dup
|
36
|
+
domain_ids << "ALL"
|
37
|
+
self.rel_domain_ids = domain_ids
|
38
|
+
save!
|
39
|
+
else
|
40
|
+
domain_admins.where(domain: "ALL").delete_all
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def has_admin?(admin)
|
45
|
+
self == admin || super_admin?
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_domain?(domain)
|
49
|
+
!rel_domains.where(domain: ["ALL", domain.domain]).empty?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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
|
+
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
|
+
|
41
|
+
before_validation do |a|
|
42
|
+
unless a.address
|
43
|
+
a.address = "#{a.local_part}@#{a.domain}" unless a.local_part.empty?
|
44
|
+
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
|
+
end
|
52
|
+
|
53
|
+
def mailbox?
|
54
|
+
!!mailbox
|
55
|
+
end
|
56
|
+
|
57
|
+
def pure_alias?
|
58
|
+
!mailbox
|
59
|
+
end
|
60
|
+
|
61
|
+
def gotos
|
62
|
+
goto.split(",")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'postfix_admin/concerns/existing_timestamp'
|
3
|
+
|
4
|
+
module PostfixAdmin
|
5
|
+
class ApplicationRecord < ActiveRecord::Base
|
6
|
+
self.abstract_class = true
|
7
|
+
|
8
|
+
include ExistingTimestamp
|
9
|
+
|
10
|
+
RE_DOMAIN_NAME_LIKE_BASE = '([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}'
|
11
|
+
RE_EMAIL_LIKE_BASE = '[^@\s]+@([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}'
|
12
|
+
|
13
|
+
RE_DOMAIN_NAME_LIKE = /#{RE_DOMAIN_NAME_LIKE_BASE}/
|
14
|
+
RE_EMAIL_LIKE = /#{RE_EMAIL_LIKE_BASE}/
|
15
|
+
|
16
|
+
RE_DOMAIN_NAME_LIKE_WITH_ANCHORS = /\A#{RE_DOMAIN_NAME_LIKE_BASE}\z/
|
17
|
+
RE_EMAIL_LIKE_WITH_ANCHORS = /\A#{RE_EMAIL_LIKE_BASE}\z/
|
18
|
+
|
19
|
+
scope :active, -> { where(active: true) }
|
20
|
+
|
21
|
+
def inactive?
|
22
|
+
!active?
|
23
|
+
end
|
24
|
+
|
25
|
+
def active_str
|
26
|
+
active? ? "Active" : "Inactive"
|
27
|
+
end
|
28
|
+
|
29
|
+
# This is a workaround to set current time to timestamp columns when a record is created.
|
30
|
+
# Activerecord does not insert timestamps if default values are set for the columns.
|
31
|
+
before_create :set_current_time_to_timestamp_columns, if: :has_timestamp_columns?
|
32
|
+
|
33
|
+
def set_current_time_to_timestamp_columns
|
34
|
+
now = Time.now
|
35
|
+
self.created = now
|
36
|
+
self.modified = now
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_timestamp_columns?
|
40
|
+
column_names = self.class.column_names
|
41
|
+
column_names.include?("created") && column_names.include?("modified")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/postfix_admin/base.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
require 'postfix_admin/models'
|
2
1
|
require 'postfix_admin/error'
|
3
2
|
|
4
3
|
require 'date'
|
5
|
-
require '
|
4
|
+
require 'postfix_admin/models'
|
6
5
|
|
7
6
|
module PostfixAdmin
|
8
7
|
class Base
|
9
8
|
attr_reader :config
|
10
9
|
|
11
10
|
DEFAULT_CONFIG = {
|
12
|
-
'database' => '
|
11
|
+
'database' => 'mysql2://postfix:password@localhost/postfix',
|
13
12
|
'aliases' => 30,
|
14
13
|
'mailboxes' => 30,
|
15
14
|
'maxquota' => 100,
|
@@ -17,71 +16,78 @@ module PostfixAdmin
|
|
17
16
|
}
|
18
17
|
|
19
18
|
def initialize(config)
|
20
|
-
db_setup(config['database'])
|
21
|
-
if local_part_required?
|
22
|
-
eval <<"EOS"
|
23
|
-
class ::PostfixAdmin::Mailbox
|
24
|
-
property :local_part, String
|
25
|
-
end
|
26
|
-
EOS
|
27
|
-
DataMapper.finalize
|
28
|
-
end
|
29
19
|
@config = {}
|
20
|
+
@config[:database] = config['database']
|
30
21
|
@config[:aliases] = config['aliases'] || 30
|
31
22
|
@config[:mailboxes] = config['mailboxes'] || 30
|
32
23
|
@config[:maxquota] = config['maxquota'] || 100
|
33
|
-
@config[:mailbox_quota] = @config[:maxquota] * KB_TO_MB
|
34
24
|
@config[:scheme] = config['scheme'] || 'CRAM-MD5'
|
35
25
|
end
|
36
26
|
|
37
|
-
def db_setup
|
38
|
-
|
39
|
-
|
27
|
+
def db_setup
|
28
|
+
raise "'database' parameter is required in '#{CLI.config_file}'" unless @config[:database]
|
29
|
+
|
30
|
+
uri = URI.parse(@config[:database])
|
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}'")
|
35
|
+
end
|
36
|
+
|
37
|
+
if uri.scheme != "mysql2"
|
38
|
+
raise "'#{uri.scheme}' is not supported as a DB adopter. Use 'mysql2' instead in '#{CLI.config_file}'."
|
39
|
+
end
|
40
|
+
|
41
|
+
ActiveRecord::Base.establish_connection(uri.to_s)
|
42
|
+
|
43
|
+
rescue LoadError => e
|
44
|
+
raise e.message
|
40
45
|
end
|
41
46
|
|
42
47
|
def add_admin_domain(user_name, domain_name)
|
43
48
|
admin_domain_check(user_name, domain_name)
|
44
49
|
|
45
50
|
admin = Admin.find(user_name)
|
46
|
-
|
47
|
-
|
51
|
+
domain = Domain.find(domain_name)
|
52
|
+
|
53
|
+
if admin.has_domain?(domain)
|
54
|
+
raise Error, "#{user_name} is already registered as admin of #{domain_name}."
|
48
55
|
end
|
49
56
|
|
50
|
-
|
51
|
-
admin.domains << domain
|
57
|
+
admin.rel_domains << domain
|
52
58
|
admin.save or raise "Relation Error: Domain of Admin"
|
53
59
|
end
|
54
60
|
|
55
61
|
def delete_admin_domain(user_name, domain_name)
|
56
62
|
admin_domain_check(user_name, domain_name)
|
57
63
|
|
58
|
-
admin
|
59
|
-
|
60
|
-
|
64
|
+
admin = Admin.find(user_name)
|
65
|
+
domain_admin_query = admin.domain_admins.where(domain: domain_name)
|
66
|
+
|
67
|
+
unless domain_admin_query.take
|
68
|
+
raise Error, "#{user_name} is not registered as admin of #{domain_name}."
|
61
69
|
end
|
62
70
|
|
63
|
-
|
64
|
-
admin.domains.delete(domain)
|
65
|
-
admin.save or "Could not save Admin"
|
71
|
+
domain_admin_query.delete_all
|
66
72
|
end
|
67
73
|
|
68
74
|
def add_admin(username, password)
|
69
75
|
password_check(password)
|
70
76
|
|
71
|
-
if Admin.
|
72
|
-
raise Error, "#{username} is already
|
77
|
+
if Admin.exists?(username)
|
78
|
+
raise Error, "#{username} is already registered as admin."
|
73
79
|
end
|
74
80
|
admin = Admin.new
|
75
81
|
admin.attributes = {
|
76
|
-
:
|
77
|
-
:
|
82
|
+
username: username,
|
83
|
+
password: password,
|
78
84
|
}
|
79
85
|
unless admin.save
|
80
|
-
raise "Could not save Admin #{admin.errors.map
|
86
|
+
raise "Could not save Admin #{admin.errors.map(&:to_s).join}"
|
81
87
|
end
|
82
88
|
end
|
83
89
|
|
84
|
-
def add_account(address, password, in_name=nil)
|
90
|
+
def add_account(address, password, in_name = nil)
|
85
91
|
name = in_name || ''
|
86
92
|
password_check(password)
|
87
93
|
|
@@ -91,68 +97,68 @@ EOS
|
|
91
97
|
user, domain_name = address_split(address)
|
92
98
|
path = "#{domain_name}/#{address}/"
|
93
99
|
|
94
|
-
unless Domain.
|
100
|
+
unless Domain.exists?(domain_name)
|
95
101
|
raise Error, "Could not find domain #{domain_name}"
|
96
102
|
end
|
97
103
|
|
98
|
-
if Alias.
|
99
|
-
raise Error, "#{address} is already
|
104
|
+
if Alias.exists?(address)
|
105
|
+
raise Error, "#{address} is already registered."
|
100
106
|
end
|
101
107
|
|
102
108
|
domain = Domain.find(domain_name)
|
103
|
-
domain.aliases << Alias.mailbox(address)
|
104
109
|
|
105
|
-
mailbox = Mailbox.new
|
106
110
|
attributes = {
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
111
|
+
username: address,
|
112
|
+
password: password,
|
113
|
+
name: name,
|
114
|
+
maildir: path,
|
115
|
+
local_part: user,
|
116
|
+
quota_mb: @config[:maxquota]
|
112
117
|
}
|
113
118
|
|
114
|
-
|
115
|
-
attributes[:local_part] = user
|
116
|
-
end
|
119
|
+
mailbox = Mailbox.new(attributes)
|
117
120
|
|
118
|
-
|
121
|
+
domain.rel_mailboxes << mailbox
|
119
122
|
|
120
|
-
domain.mailboxes << mailbox
|
121
123
|
unless domain.save
|
122
|
-
raise "Could not save Mailbox and Domain #{mailbox.errors.map
|
124
|
+
raise "Could not save Mailbox and Domain #{mailbox.errors.map(&:to_s).join} #{domain.errors.map(&:to_s).join}"
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
126
128
|
def add_alias(address, goto)
|
127
|
-
if Mailbox.
|
129
|
+
if Mailbox.exists?(address)
|
128
130
|
raise Error, "mailbox #{address} is already registered!"
|
129
131
|
end
|
130
|
-
if Alias.
|
132
|
+
if Alias.exists?(address)
|
131
133
|
raise Error, "alias #{address} is already registered!"
|
132
134
|
end
|
133
|
-
|
134
|
-
|
135
|
+
|
136
|
+
local_part, domain_name = address_split(address)
|
137
|
+
|
138
|
+
unless Domain.exists?(domain_name)
|
135
139
|
raise Error, "Invalid domain! #{domain_name}"
|
136
140
|
end
|
141
|
+
|
137
142
|
domain = Domain.find(domain_name)
|
138
143
|
|
139
|
-
|
140
|
-
|
141
|
-
:
|
142
|
-
:goto => goto,
|
144
|
+
attributes = {
|
145
|
+
local_part: local_part,
|
146
|
+
goto: goto
|
143
147
|
}
|
144
|
-
domain.
|
148
|
+
domain.rel_aliases << Alias.new(attributes)
|
145
149
|
domain.save or raise "Could not save Alias"
|
146
150
|
end
|
147
151
|
|
148
152
|
def delete_alias(address)
|
149
|
-
if Mailbox.
|
153
|
+
if Mailbox.exists?(address)
|
150
154
|
raise Error, "Can not delete mailbox by delete_alias. Use delete_account"
|
151
155
|
end
|
152
|
-
|
156
|
+
|
157
|
+
unless Alias.exists?(address)
|
153
158
|
raise Error, "#{address} is not found!"
|
154
159
|
end
|
155
|
-
|
160
|
+
|
161
|
+
Alias.where(address: address).delete_all
|
156
162
|
end
|
157
163
|
|
158
164
|
def add_domain(domain_name)
|
@@ -160,56 +166,65 @@ EOS
|
|
160
166
|
if domain_name !~ /.+\..+/
|
161
167
|
raise Error, "Ivalid domain! #{domain_name}"
|
162
168
|
end
|
163
|
-
if Domain.
|
169
|
+
if Domain.exists?(domain_name)
|
164
170
|
raise Error, "#{domain_name} is already registered!"
|
165
171
|
end
|
166
172
|
domain = Domain.new
|
167
173
|
domain.attributes = {
|
168
|
-
:
|
169
|
-
:
|
170
|
-
:
|
171
|
-
:
|
172
|
-
:
|
174
|
+
domain: domain_name,
|
175
|
+
description: domain_name,
|
176
|
+
aliases: @config[:aliases],
|
177
|
+
mailboxes: @config[:mailboxes],
|
178
|
+
maxquota: @config[:maxquota],
|
173
179
|
}
|
174
|
-
domain.save
|
180
|
+
domain.save!
|
175
181
|
end
|
176
182
|
|
177
183
|
def delete_domain(domain_name)
|
178
184
|
domain_name = domain_name.downcase
|
179
|
-
unless Domain.
|
185
|
+
unless Domain.exists?(domain_name)
|
180
186
|
raise Error, "Could not find domain #{domain_name}"
|
181
187
|
end
|
182
188
|
|
183
189
|
domain = Domain.find(domain_name)
|
184
|
-
domain.
|
185
|
-
domain.
|
186
|
-
|
187
|
-
domain.
|
190
|
+
domain.rel_mailboxes.delete_all
|
191
|
+
domain.rel_aliases.delete_all
|
192
|
+
|
193
|
+
admin_names = domain.admins.map(&:username)
|
194
|
+
|
195
|
+
domain.admins.delete_all
|
188
196
|
|
189
197
|
admin_names.each do |name|
|
190
|
-
next unless Admin.
|
198
|
+
next unless Admin.exists?(name)
|
199
|
+
|
191
200
|
admin = Admin.find(name)
|
192
|
-
|
201
|
+
|
202
|
+
# check if the admin is needed or not
|
203
|
+
if admin.rel_domains.empty?
|
204
|
+
admin.destroy
|
205
|
+
end
|
193
206
|
end
|
194
|
-
|
207
|
+
|
208
|
+
domain.destroy
|
195
209
|
end
|
196
210
|
|
197
211
|
def delete_admin(user_name)
|
198
|
-
unless Admin.
|
212
|
+
unless Admin.exists?(user_name)
|
199
213
|
raise Error, "Could not find admin #{user_name}"
|
200
214
|
end
|
215
|
+
|
201
216
|
admin = Admin.find(user_name)
|
202
|
-
admin.
|
203
|
-
admin.destroy
|
217
|
+
admin.rel_domains.delete_all
|
218
|
+
admin.destroy!
|
204
219
|
end
|
205
220
|
|
206
221
|
def delete_account(address)
|
207
|
-
unless Alias.
|
222
|
+
unless Alias.exists?(address) && Mailbox.exists?(address)
|
208
223
|
raise Error, "Could not find account #{address}"
|
209
224
|
end
|
210
225
|
|
211
|
-
Mailbox.
|
212
|
-
Alias.
|
226
|
+
Mailbox.where(username: address).delete_all
|
227
|
+
Alias.where(address: address).delete_all
|
213
228
|
end
|
214
229
|
|
215
230
|
def address_split(address)
|
@@ -218,14 +233,9 @@ EOS
|
|
218
233
|
|
219
234
|
private
|
220
235
|
|
221
|
-
# postfixadmin DB upgrade Number 495 loca_part added
|
222
|
-
def local_part_required?
|
223
|
-
Config.first.value.to_i >= 495
|
224
|
-
end
|
225
|
-
|
226
236
|
def admin_domain_check(user_name, domain_name)
|
227
|
-
raise Error, "#{user_name} is not
|
228
|
-
raise Error, "Could not find domain #{domain_name}" unless Domain.
|
237
|
+
raise Error, "#{user_name} is not registered as admin." unless Admin.exists?(user_name)
|
238
|
+
raise Error, "Could not find domain #{domain_name}" unless Domain.exists?(domain_name)
|
229
239
|
end
|
230
240
|
|
231
241
|
def password_check(password)
|