postfix_admin 0.1.0 → 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 +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Dockerfile +24 -0
- data/README.md +57 -27
- data/Rakefile +6 -0
- data/bin/console +18 -0
- data/docker-compose.yml +24 -0
- data/docker-entrypoint.sh +5 -0
- data/exe/postfix_admin +6 -0
- data/lib/postfix_admin.rb +4 -0
- 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 +138 -81
- data/lib/postfix_admin/cli.rb +321 -119
- 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 +32 -0
- 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 -171
- data/lib/postfix_admin/quota.rb +6 -0
- data/lib/postfix_admin/runner.rb +136 -30
- data/lib/postfix_admin/version.rb +1 -1
- data/postfix_admin.gemspec +20 -11
- metadata +91 -54
- data/bin/postfix_admin +0 -9
- data/spec/base_spec.rb +0 -218
- data/spec/cli_spec.rb +0 -165
- data/spec/models_spec.rb +0 -136
- data/spec/postfix_admin.conf +0 -5
- data/spec/postfix_test.sql +0 -250
- data/spec/runner_spec.rb +0 -144
- data/spec/spec_helper.rb +0 -160
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a83f945f0f977fc80b8715b899af26d908b3d6b1169d27fae9cf92089bac5082
|
4
|
+
data.tar.gz: f8f63116ece1064079b99f986fc26778c4f4affc28ae8dbd3beca3496a595186
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 22f7cc6d351d3a7e63ba95e653ac21f4b1eeebaebb5a717810477ab0d700dbb3199eeee042ca34909aee1c959bb7d27fe705d1c332895e7bb38ae0cc1f3e9120
|
7
|
+
data.tar.gz: 821bb8bac75277e3faf303f1db8292256cc9bbcf40cb2de6f63f9c3c38e40f84c5739849edc159ddec8bf262d9fa9e5ea8f9bac15e8dce37f2691f0a017e2772
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +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
|
+
|
5
|
+
## 0.1.4
|
6
|
+
* Added "log" subcommand
|
7
|
+
|
8
|
+
## 0.1.3
|
9
|
+
* Support for activation and deactivation of domain, admin and account
|
10
|
+
* Added "edit_admin" subcommand
|
11
|
+
|
12
|
+
## 0.1.2
|
13
|
+
* Support password hash by doveadm (external subcommand)
|
14
|
+
* Show active status
|
15
|
+
* Don't show passwords using list format
|
16
|
+
|
17
|
+
## 0.1.1, release 2013-05-10
|
18
|
+
* Fixed string length of password
|
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,6 +1,20 @@
|
|
1
|
-
|
1
|
+
[](https://rubygems.org/gems/postfix_admin)
|
2
2
|
|
3
|
-
|
3
|
+
# postfix_admin
|
4
|
+
|
5
|
+
Command Line Tools for Postfix Admin
|
6
|
+
|
7
|
+
## Description
|
8
|
+
|
9
|
+
* Postfix Admin (Original Web-based Application)
|
10
|
+
+ Web Site http://postfixadmin.sourceforge.net/
|
11
|
+
+ GitHub https://github.com/postfixadmin/postfixadmin
|
12
|
+
|
13
|
+
* Postfix Admin 3.2 is supported.
|
14
|
+
|
15
|
+
* MySQL/MariaDB is supported.
|
16
|
+
|
17
|
+
* Other database engines are not supported.
|
4
18
|
|
5
19
|
## Installation
|
6
20
|
|
@@ -8,32 +22,48 @@ Install postfix_admin as:
|
|
8
22
|
|
9
23
|
$ gem install postfix_admin
|
10
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
|
+
|
11
37
|
## Usage
|
12
38
|
|
13
|
-
|
14
|
-
postfix_admin account_passwd user@example.com new_password # Change password of account
|
15
|
-
postfix_admin add_account user@example.com password # Add an account
|
16
|
-
postfix_admin add_admin admin@example.com password # Add an admin user
|
17
|
-
postfix_admin add_admin_domain admin@example.com example.com # Add admin_domain
|
18
|
-
postfix_admin add_alias alias@example.com goto@example.net # Add an alias
|
19
|
-
postfix_admin add_domain example.com # Add a domain
|
20
|
-
postfix_admin admin_passwd admin@example.com new_password # Change password of admin
|
21
|
-
postfix_admin delete_account user@example.com # Delete an account
|
22
|
-
postfix_admin delete_admin admin@example.com # Delete an admin
|
23
|
-
postfix_admin delete_alias alias@example.com # Delete an alias
|
24
|
-
postfix_admin delete_domain example.com # Delete a domain
|
25
|
-
postfix_admin help [TASK] # Describe available tasks or one specific task
|
26
|
-
postfix_admin setup example.com password # Setup a domain
|
27
|
-
postfix_admin show # List of domains
|
28
|
-
postfix_admin summary [example.com] # Summarize the usage of PostfixAdmin
|
29
|
-
postfix_admin super_admin admin@example.com # Enable super admin flag of an admin
|
30
|
-
postfix_admin version # Show postfix_admin version
|
31
|
-
```
|
39
|
+
List the postfix_admin subcommands as:
|
32
40
|
|
33
|
-
|
41
|
+
$ postfix_admin
|
34
42
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
```
|
44
|
+
Commands:
|
45
|
+
postfix_admin account_passwd user@example.com new_password # Change password of account
|
46
|
+
postfix_admin add_account user@example.com password # Add an account
|
47
|
+
postfix_admin add_admin admin@example.com password # Add an admin user
|
48
|
+
postfix_admin add_admin_domain admin@example.com example.com # Add admin_domain
|
49
|
+
postfix_admin add_alias alias@example.com goto@example.net # Add an alias
|
50
|
+
postfix_admin add_domain example.com # Add a domain
|
51
|
+
postfix_admin admin_passwd admin@example.com new_password # Change password of admin
|
52
|
+
postfix_admin delete_account user@example.com # Delete an account
|
53
|
+
postfix_admin delete_admin admin@example.com # Delete an admin
|
54
|
+
postfix_admin delete_admin_domain admin@example.com example.com # Delete admin_domain
|
55
|
+
postfix_admin delete_alias alias@example.com # Delete an alias
|
56
|
+
postfix_admin delete_domain example.com # Delete a domain
|
57
|
+
postfix_admin dump # Dump all data
|
58
|
+
postfix_admin edit_account user@example.com # Edit an account
|
59
|
+
postfix_admin edit_admin admin@example.com # Edit an admin user
|
60
|
+
postfix_admin edit_alias alias@example.com # Edit an alias
|
61
|
+
postfix_admin edit_domain example.com # Edit a domain limitation
|
62
|
+
postfix_admin help [COMMAND] # Describe available commands or one specific command
|
63
|
+
postfix_admin log # Show action logs
|
64
|
+
postfix_admin schemes # List all supported password schemes
|
65
|
+
postfix_admin setup example.com password # Setup a domain
|
66
|
+
postfix_admin show [example.com | admin@example.com | user@example.com] # Show domains or admins or mailboxes
|
67
|
+
postfix_admin summary [example.com] # Summarize the usage of PostfixAdmin
|
68
|
+
postfix_admin version # Show postfix_admin version
|
69
|
+
```
|
data/Rakefile
ADDED
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/exe/postfix_admin
ADDED
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,188 +1,245 @@
|
|
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
|
-
'maxquota' => 100
|
14
|
+
'maxquota' => 100,
|
15
|
+
'scheme' => 'CRAM-MD5',
|
16
16
|
}
|
17
17
|
|
18
18
|
def initialize(config)
|
19
|
-
db_setup(config['database'])
|
20
19
|
@config = {}
|
20
|
+
@config[:database] = config['database']
|
21
21
|
@config[:aliases] = config['aliases'] || 30
|
22
22
|
@config[:mailboxes] = config['mailboxes'] || 30
|
23
23
|
@config[:maxquota] = config['maxquota'] || 100
|
24
|
-
@config[:
|
24
|
+
@config[:scheme] = config['scheme'] || 'CRAM-MD5'
|
25
25
|
end
|
26
26
|
|
27
|
-
def db_setup
|
28
|
-
|
29
|
-
DataMapper.finalize
|
30
|
-
end
|
27
|
+
def db_setup
|
28
|
+
raise "'database' parameter is required in '#{CLI.config_file}'" unless @config[:database]
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
raise Error, "Could not find domain #{domain_name}"
|
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}'")
|
38
35
|
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
raise Error, "#{username} is already resistered as admin of #{domain_name}."
|
37
|
+
if uri.scheme != "mysql2"
|
38
|
+
raise "'#{uri.scheme}' is not supported as a DB adopter. Use 'mysql2' instead in '#{CLI.config_file}'."
|
43
39
|
end
|
44
40
|
|
41
|
+
ActiveRecord::Base.establish_connection(uri.to_s)
|
42
|
+
|
43
|
+
rescue LoadError => e
|
44
|
+
raise e.message
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_admin_domain(user_name, domain_name)
|
48
|
+
admin_domain_check(user_name, domain_name)
|
49
|
+
|
50
|
+
admin = Admin.find(user_name)
|
45
51
|
domain = Domain.find(domain_name)
|
46
|
-
|
52
|
+
|
53
|
+
if admin.has_domain?(domain)
|
54
|
+
raise Error, "#{user_name} is already registered as admin of #{domain_name}."
|
55
|
+
end
|
56
|
+
|
57
|
+
admin.rel_domains << domain
|
47
58
|
admin.save or raise "Relation Error: Domain of Admin"
|
48
59
|
end
|
49
60
|
|
61
|
+
def delete_admin_domain(user_name, domain_name)
|
62
|
+
admin_domain_check(user_name, domain_name)
|
63
|
+
|
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}."
|
69
|
+
end
|
70
|
+
|
71
|
+
domain_admin_query.delete_all
|
72
|
+
end
|
73
|
+
|
50
74
|
def add_admin(username, password)
|
51
|
-
|
52
|
-
|
75
|
+
password_check(password)
|
76
|
+
|
77
|
+
if Admin.exists?(username)
|
78
|
+
raise Error, "#{username} is already registered as admin."
|
53
79
|
end
|
54
80
|
admin = Admin.new
|
55
81
|
admin.attributes = {
|
56
|
-
:
|
57
|
-
:
|
82
|
+
username: username,
|
83
|
+
password: password,
|
58
84
|
}
|
59
|
-
admin.save
|
85
|
+
unless admin.save
|
86
|
+
raise "Could not save Admin #{admin.errors.map(&:to_s).join}"
|
87
|
+
end
|
60
88
|
end
|
61
89
|
|
62
|
-
def add_account(address, password)
|
90
|
+
def add_account(address, password, in_name = nil)
|
91
|
+
name = in_name || ''
|
92
|
+
password_check(password)
|
93
|
+
|
63
94
|
if address !~ /.+\@.+\..+/
|
64
95
|
raise Error, "Invalid mail address #{address}"
|
65
96
|
end
|
66
97
|
user, domain_name = address_split(address)
|
67
98
|
path = "#{domain_name}/#{address}/"
|
68
99
|
|
69
|
-
unless Domain.
|
100
|
+
unless Domain.exists?(domain_name)
|
70
101
|
raise Error, "Could not find domain #{domain_name}"
|
71
102
|
end
|
72
103
|
|
73
|
-
if Alias.
|
74
|
-
raise Error, "#{address} is already
|
104
|
+
if Alias.exists?(address)
|
105
|
+
raise Error, "#{address} is already registered."
|
75
106
|
end
|
76
107
|
|
77
108
|
domain = Domain.find(domain_name)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
mailbox.attributes = {
|
87
|
-
:username => address,
|
88
|
-
:password => password,
|
89
|
-
:name => '',
|
90
|
-
:maildir => path,
|
91
|
-
:quota => @config[:mailbox_quota],
|
92
|
-
# :local_part => user,
|
109
|
+
|
110
|
+
attributes = {
|
111
|
+
username: address,
|
112
|
+
password: password,
|
113
|
+
name: name,
|
114
|
+
maildir: path,
|
115
|
+
local_part: user,
|
116
|
+
quota_mb: @config[:maxquota]
|
93
117
|
}
|
94
|
-
|
95
|
-
|
118
|
+
|
119
|
+
mailbox = Mailbox.new(attributes)
|
120
|
+
|
121
|
+
domain.rel_mailboxes << mailbox
|
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
|
96
126
|
end
|
97
127
|
|
98
128
|
def add_alias(address, goto)
|
99
|
-
if Mailbox.
|
129
|
+
if Mailbox.exists?(address)
|
100
130
|
raise Error, "mailbox #{address} is already registered!"
|
101
131
|
end
|
102
|
-
if Alias.
|
132
|
+
if Alias.exists?(address)
|
103
133
|
raise Error, "alias #{address} is already registered!"
|
104
134
|
end
|
105
|
-
|
106
|
-
|
135
|
+
|
136
|
+
local_part, domain_name = address_split(address)
|
137
|
+
|
138
|
+
unless Domain.exists?(domain_name)
|
107
139
|
raise Error, "Invalid domain! #{domain_name}"
|
108
140
|
end
|
141
|
+
|
109
142
|
domain = Domain.find(domain_name)
|
110
143
|
|
111
|
-
|
112
|
-
|
113
|
-
:
|
114
|
-
:goto => goto,
|
144
|
+
attributes = {
|
145
|
+
local_part: local_part,
|
146
|
+
goto: goto
|
115
147
|
}
|
116
|
-
domain.
|
148
|
+
domain.rel_aliases << Alias.new(attributes)
|
117
149
|
domain.save or raise "Could not save Alias"
|
118
150
|
end
|
119
151
|
|
120
152
|
def delete_alias(address)
|
121
|
-
if Mailbox.
|
153
|
+
if Mailbox.exists?(address)
|
122
154
|
raise Error, "Can not delete mailbox by delete_alias. Use delete_account"
|
123
155
|
end
|
124
|
-
|
156
|
+
|
157
|
+
unless Alias.exists?(address)
|
125
158
|
raise Error, "#{address} is not found!"
|
126
159
|
end
|
127
|
-
|
160
|
+
|
161
|
+
Alias.where(address: address).delete_all
|
128
162
|
end
|
129
163
|
|
130
164
|
def add_domain(domain_name)
|
165
|
+
domain_name = domain_name.downcase
|
131
166
|
if domain_name !~ /.+\..+/
|
132
167
|
raise Error, "Ivalid domain! #{domain_name}"
|
133
168
|
end
|
134
|
-
if Domain.
|
169
|
+
if Domain.exists?(domain_name)
|
135
170
|
raise Error, "#{domain_name} is already registered!"
|
136
171
|
end
|
137
172
|
domain = Domain.new
|
138
173
|
domain.attributes = {
|
139
|
-
:
|
140
|
-
:
|
141
|
-
:
|
142
|
-
:
|
143
|
-
:
|
174
|
+
domain: domain_name,
|
175
|
+
description: domain_name,
|
176
|
+
aliases: @config[:aliases],
|
177
|
+
mailboxes: @config[:mailboxes],
|
178
|
+
maxquota: @config[:maxquota],
|
144
179
|
}
|
145
|
-
domain.save
|
180
|
+
domain.save!
|
146
181
|
end
|
147
182
|
|
148
183
|
def delete_domain(domain_name)
|
149
|
-
|
184
|
+
domain_name = domain_name.downcase
|
185
|
+
unless Domain.exists?(domain_name)
|
150
186
|
raise Error, "Could not find domain #{domain_name}"
|
151
187
|
end
|
152
188
|
|
153
189
|
domain = Domain.find(domain_name)
|
154
|
-
domain.
|
155
|
-
domain.
|
156
|
-
|
157
|
-
|
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
|
158
196
|
|
159
|
-
|
197
|
+
admin_names.each do |name|
|
198
|
+
next unless Admin.exists?(name)
|
199
|
+
|
200
|
+
admin = Admin.find(name)
|
201
|
+
|
202
|
+
# check if the admin is needed or not
|
203
|
+
if admin.rel_domains.empty?
|
204
|
+
admin.destroy
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
domain.destroy
|
160
209
|
end
|
161
210
|
|
162
211
|
def delete_admin(user_name)
|
163
|
-
unless Admin.
|
212
|
+
unless Admin.exists?(user_name)
|
164
213
|
raise Error, "Could not find admin #{user_name}"
|
165
214
|
end
|
215
|
+
|
166
216
|
admin = Admin.find(user_name)
|
167
|
-
admin.
|
168
|
-
admin.destroy
|
217
|
+
admin.rel_domains.delete_all
|
218
|
+
admin.destroy!
|
169
219
|
end
|
170
220
|
|
171
221
|
def delete_account(address)
|
172
|
-
unless Alias.
|
222
|
+
unless Alias.exists?(address) && Mailbox.exists?(address)
|
173
223
|
raise Error, "Could not find account #{address}"
|
174
224
|
end
|
175
225
|
|
176
|
-
Mailbox.
|
177
|
-
Alias.
|
178
|
-
end
|
179
|
-
|
180
|
-
def delete_unnecessary_admins
|
181
|
-
Admin.unnecessary.destroy or raise "Could not destroy Admin"
|
226
|
+
Mailbox.where(username: address).delete_all
|
227
|
+
Alias.where(address: address).delete_all
|
182
228
|
end
|
183
229
|
|
184
230
|
def address_split(address)
|
185
231
|
address.split('@')
|
186
232
|
end
|
233
|
+
|
234
|
+
private
|
235
|
+
|
236
|
+
def admin_domain_check(user_name, domain_name)
|
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)
|
239
|
+
end
|
240
|
+
|
241
|
+
def password_check(password)
|
242
|
+
raise Error, "Empty password" if password.nil? || password.empty?
|
243
|
+
end
|
187
244
|
end
|
188
245
|
end
|