postfix_admin 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/postfix_admin.png)](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
|