postfix_admin 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in postfix_admin.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Hitoshi Kurokawa
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # PostfixAdmin
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'postfix_admin'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install postfix_admin
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/postfix_admin ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ require 'postfix_admin'
5
+ require 'postfix_admin/cli'
6
+
7
+ class PostfixAdminCommand < Thor
8
+ def initialize(*args)
9
+ super
10
+ @cli = PostfixAdmin::CLI.new
11
+ end
12
+ desc "show", "List of domains"
13
+ def show(domain=nil)
14
+ if domain
15
+ @cli.show_domain_account(domain)
16
+ else
17
+ @cli.show_domain
18
+ @cli.show_admin
19
+ end
20
+ end
21
+
22
+ desc "add_domain", "add a domain"
23
+ def add_domain(domain=nil)
24
+ if domain
25
+ if @cli.add_domain(domain)
26
+ puts %Q!"#{domain}" is successfully registered.!
27
+ end
28
+ @cli.show_domain
29
+ else
30
+ puts "USAGE: #{$0} add_domain example.com"
31
+ exit
32
+ end
33
+ end
34
+
35
+ desc "delete_domain", "delete a domain"
36
+ def delete_domain(domain=nil)
37
+ if domain
38
+ if @cli.delete_domain(domain)
39
+ puts %Q!"#{domain}" is successfully deleted.!
40
+ end
41
+ @cli.show_domain
42
+ else
43
+ puts "USAGE: #{$0} delete_domain example.com"
44
+ exit
45
+ end
46
+ end
47
+
48
+ desc "add_account", "add an account"
49
+ def add_account(address=nil,password=nil)
50
+ if address && password
51
+ if @cli.add_account(address, password)
52
+ puts %Q!"#{address}" is successfully registered.!
53
+ end
54
+ @cli.show_domain_account(address.split(/@/)[1])
55
+ else
56
+ puts "USAGE: #{$0} add_account user@example.com password"
57
+ exit
58
+ end
59
+ end
60
+
61
+ desc "add_admin", "add an admin user"
62
+ def add_admin(user_name=nil, password=nil)
63
+ if user_name && password
64
+ if @cli.add_admin(user_name, password)
65
+ puts %Q!"#{user_name}" is successfully registered as admin.!
66
+ end
67
+ @cli.show_admin
68
+ else
69
+ puts "USAGE: #{$0} add_admin user@example.com password"
70
+ exit
71
+ end
72
+ end
73
+
74
+ desc "add_admin_domain", "add admin_domain"
75
+ def add_admin_domain(user_name=nil, domain=nil)
76
+ if user_name && domain
77
+ if @cli.add_admin_domain(user_name, domain)
78
+ puts %Q!"#{domain}" is appended in the domains of #{user_name}.!
79
+ end
80
+ @cli.show_admin_domain(user_name)
81
+ else
82
+ puts "USAGE: #{$0} add_admin_domain user@example.com example.com"
83
+ exit
84
+ end
85
+ end
86
+
87
+ desc "add_alias", "add an alias"
88
+ def add_alias(address=nil, goto=nil)
89
+ if address && goto
90
+ if @cli.add_alias(address, goto)
91
+ puts %Q!"#{address}: #{goto}" is successfully registered as alias.!
92
+ end
93
+ @cli.show_domain_account(address.split(/@/)[1])
94
+ else
95
+ puts "USAGE: #{$0} add_alias user@example.com goto@example.com"
96
+ exit
97
+ end
98
+ end
99
+ end
100
+
101
+ PostfixAdminCommand.start
@@ -0,0 +1,123 @@
1
+ require 'yaml'
2
+ require 'postfix_admin'
3
+
4
+ class PostfixAdmin
5
+ class CLI
6
+ CONFIG_FILE = '.postfix_admin.conf'
7
+ MIN_NUM_PASSWORD_CHARACTER = 5
8
+
9
+ def initialize
10
+ @config = load_config
11
+ @admin = PostfixAdmin.new(@config)
12
+ end
13
+ # ~/.postfix_adminrc
14
+ # database: mysql://postfix:password@localhost/postfix
15
+ # aliases: 30
16
+ # mailboxes: 30
17
+ # maxquota: 100
18
+ def load_config
19
+ unless File.exist?(config_file)
20
+ create_config
21
+ puts "configure file: #{config_file} was generated.\nPlease execute after edit it."
22
+ exit
23
+ end
24
+ open(config_file) do |f|
25
+ YAML.load(f.read)
26
+ end
27
+ end
28
+ def create_config
29
+ config = {
30
+ 'database' => 'mysql://postfix:password@localhost/postfix',
31
+ 'aliases' => 30,
32
+ 'mailboxes' => 30,
33
+ 'maxquota' => 100
34
+ }
35
+ open(config_file, 'w') do |f|
36
+ f.write config.to_yaml
37
+ end
38
+ File.chmod(0600, config_file)
39
+ end
40
+ def config_file
41
+ File.expand_path(CONFIG_FILE, ENV['HOME'])
42
+ end
43
+ def print_line
44
+ puts "-"*85
45
+ end
46
+ def show_domain
47
+ print_line
48
+ puts " No. domain alias mail quota"
49
+ print_line
50
+ @admin.domains.each_with_index do |domain, i|
51
+ printf("%4d %-20s %4d %4d %4d\n", i+1, domain.domain, domain.aliases, domain.mailboxes, domain.maxquota)
52
+ end
53
+ print_line
54
+ end
55
+ def show_admin
56
+ admins = @admin.admins
57
+ if admins.count == 0
58
+ puts "No admin in database\n"
59
+ return
60
+ end
61
+ print_line
62
+ puts " No. username password"
63
+ print_line
64
+ admins.each_with_index do |admin, i|
65
+ printf("%4d %-20s %10s\n", i+1, admin.username, admin.password)
66
+ end
67
+ print_line
68
+ end
69
+ def show_domain_account(domain)
70
+ mailboxes = @admin.mailboxes(domain)
71
+ if mailboxes.count == 0
72
+ puts "No address in #{domain}\n"
73
+ return
74
+ end
75
+ print_line
76
+ puts " No. address password quota(M) maildir"
77
+ print_line
78
+ mailboxes.each_with_index do |mailbox, i|
79
+ printf("%4d %-20s %10s %7.1f %-30s\n", i+1, mailbox.username, mailbox.password, mailbox.quota.to_f/1024000.0, mailbox.maildir)
80
+ end
81
+ print_line
82
+ end
83
+ def show_admin_domain(user_name)
84
+ domain_admins = @admin.admin_domains(user_name)
85
+ if domain_admins.count == 0
86
+ puts "No domain in database\n"
87
+ return
88
+ end
89
+ print_line
90
+ puts " No. domain"
91
+ print_line
92
+ domain_admins.each_with_index do |domain_admin, i|
93
+ printf("%4d %-20s\n", i+1, domain_admin.domain)
94
+ end
95
+ print_line
96
+ end
97
+ def add_domain(domain)
98
+ @admin.add_domain(domain)
99
+ end
100
+ def add_admin(user_name, password)
101
+ validate_password(password)
102
+ @admin.add_admin(user_name, password)
103
+ end
104
+ def add_account(address, password)
105
+ validate_password(password)
106
+ @admin.add_account(address, password)
107
+ end
108
+ def add_alias(address, goto)
109
+ @admin.add_alias(address, goto)
110
+ end
111
+ def add_admin_domain(user_name, domain)
112
+ @admin.add_admin_domain(user_name, domain)
113
+ end
114
+ def delete_domain(domain)
115
+ @admin.delete_domain(domain)
116
+ end
117
+ def validate_password(password)
118
+ if password.size < MIN_NUM_PASSWORD_CHARACTER
119
+ raise "Error: Password is too short. It should be larger than #{MIN_NUM_PASSWORD_CHARACTER}"
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,61 @@
1
+ require 'data_mapper'
2
+
3
+ class PostfixAdmin
4
+ class Admin
5
+ include ::DataMapper::Resource
6
+ property :username, String, :key => true
7
+ property :password, String
8
+ property :created, DateTime
9
+ property :modified, DateTime
10
+
11
+ storage_names[:default] = 'admin'
12
+ end
13
+
14
+ class Domain
15
+ include ::DataMapper::Resource
16
+ property :domain, String, :key => true
17
+ property :aliases, Integer
18
+ property :mailboxes, Integer
19
+ property :maxquota, Integer
20
+ property :transport, String
21
+ property :backupmx, Integer
22
+ property :description, String
23
+
24
+ storage_names[:default] = 'domain'
25
+ end
26
+
27
+ class DomainAdmin
28
+ include ::DataMapper::Resource
29
+ property :username, String, :key => true
30
+ property :domain, String, :key => true
31
+ property :created, DateTime
32
+
33
+ storage_names[:default] = 'domain_admins'
34
+ end
35
+
36
+ class Mailbox
37
+ include ::DataMapper::Resource
38
+ property :username, String, :key => true
39
+ property :name, String
40
+ property :password, String
41
+ property :domain, String
42
+ property :maildir, String
43
+ property :quota, Integer
44
+ # property :local_part, String
45
+ property :created, DateTime
46
+ property :modified, DateTime
47
+
48
+ storage_names[:default] = 'mailbox'
49
+ end
50
+
51
+ class Alias
52
+ include ::DataMapper::Resource
53
+ property :address, String, :key => true
54
+ property :goto, Text, :key => true
55
+ property :domain, String
56
+ property :created, DateTime
57
+ property :modified, DateTime
58
+
59
+ storage_names[:default] = 'alias'
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ class PostfixAdmin
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,158 @@
1
+ require "postfix_admin/version"
2
+ require 'postfix_admin/models'
3
+
4
+ require 'date'
5
+ require 'data_mapper'
6
+
7
+ class PostfixAdmin
8
+ def initialize(config)
9
+ DataMapper.setup(:default, config['database'])
10
+ DataMapper.finalize
11
+ @config = {}
12
+ @config[:aliases] = config['aliases'] || 30
13
+ @config[:mailboxes] = config['mailboxes'] || 30
14
+ @config[:maxquota] = config['maxquota'] || 100
15
+ @config[:mailbox_quota] = @config[:maxquota] * 1024 * 1000
16
+ end
17
+ def add_admin_domain(username, domain)
18
+ unless admin_exist?(username)
19
+ raise "Error: #{username} is not resistered as admin."
20
+ end
21
+ unless domain_exist?(domain)
22
+ raise "Error: Invalid domain #{domain}!"
23
+ end
24
+ if admin_domain_exist?(username, domain)
25
+ raise "Error: #{username} is already resistered as admin of #{domain}."
26
+ end
27
+
28
+ domain_admin = DomainAdmin.new
29
+ domain_admin.attributes = {
30
+ :username => username,
31
+ :domain => domain,
32
+ :created => DateTime.now
33
+ }
34
+ domain_admin.save
35
+ end
36
+ def add_admin(username, password)
37
+ if admin_exist?(username)
38
+ raise "Error: #{username} is already resistered as admin."
39
+ end
40
+ admin = Admin.new
41
+ admin.attributes = {
42
+ :username => username,
43
+ :password => password,
44
+ :created => DateTime.now,
45
+ :modified => DateTime.now
46
+ }
47
+ admin.save
48
+ end
49
+ def add_account(address, password)
50
+ if address !~ /.+\@.+\..+/
51
+ raise "Error: Invalid mail address! #{address}"
52
+ end
53
+ user, domain = address.split(/@/)
54
+ path = "#{domain}/#{address}/"
55
+
56
+ unless domain_exist?(domain)
57
+ raise "Error: Invalid domain! #{address}"
58
+ end
59
+
60
+ if alias_exist?(address)
61
+ raise "Error: #{address} is already resistered."
62
+ end
63
+ mail_alias = Alias.new
64
+ mail_alias.attributes = {
65
+ :address => address,
66
+ :goto => address,
67
+ :domain => domain,
68
+ :created => DateTime.now,
69
+ :modified => DateTime.now
70
+ }
71
+ mail_alias.save
72
+
73
+ mailbox = Mailbox.new
74
+ mailbox.attributes = {
75
+ :username => address,
76
+ :password => password,
77
+ :name => '',
78
+ :maildir => path,
79
+ :quota => @config[:mailbox_quota],
80
+ :domain => domain,
81
+ # :local_part => user,
82
+ :created => DateTime.now,
83
+ :modified => DateTime.now
84
+ }
85
+ mailbox.save
86
+ end
87
+ def add_alias(address, goto)
88
+ if alias_exist?(address)
89
+ goto_text = "#{address},#{goto}"
90
+ mail_alias = Alias.first(:address => address)
91
+ mail_alias.update(:goto => goto_text, :modified => DateTime.now)
92
+ else
93
+ raise "Error: Invalid mail address! #{address}"
94
+ end
95
+ end
96
+ def add_domain(domain_name)
97
+ if domain_name !~ /.+\..+/
98
+ raise "Error: Ivalid domain! #{domain_name}"
99
+ end
100
+ if domain_exist?(domain_name)
101
+ raise "Error: #{domain_name} is already registered!"
102
+ end
103
+ domain = Domain.new
104
+ domain.attributes = {
105
+ :domain => domain_name,
106
+ :description => domain_name,
107
+ :aliases => @config[:aliases],
108
+ :mailboxes => @config[:mailboxes],
109
+ :maxquota => @config[:maxquota],
110
+ :transport => "virtual",
111
+ :backupmx => 0
112
+ }
113
+ domain.save
114
+ end
115
+ def delete_domain(domain)
116
+ unless domain_exist?(domain)
117
+ raise "Error: #{domain} is not found!"
118
+ end
119
+ username = "admin@#{domain}"
120
+ Admin.all(:username => username).destroy
121
+ DomainAdmin.all(:username => username).destroy
122
+ Mailbox.all(:domain => domain).destroy
123
+ Alias.all(:domain => domain).destroy
124
+ Domain.all(:domain => domain).destroy
125
+ end
126
+ def admin_domain_exist?(username, domain)
127
+ DomainAdmin.all(:username => username, :domain => domain).count != 0
128
+ end
129
+ def admin_exist?(admin)
130
+ Admin.all(:username => admin).count != 0
131
+ end
132
+ def alias_exist?(address)
133
+ Alias.all(:address => address).count != 0
134
+ end
135
+ def domain_exist?(domain)
136
+ Domain.all(:domain => domain).count != 0
137
+ end
138
+ def domains
139
+ Domain.all(:domain.not => 'ALL', :order => :domain)
140
+ end
141
+ def admins
142
+ Admin.all(:order => 'username')
143
+ end
144
+ def mailboxes(domain=nil)
145
+ if domain
146
+ Mailbox.all(:domain => domain, :order => :username)
147
+ else
148
+ Mailbox.all(:order => :username)
149
+ end
150
+ end
151
+ def admin_domains(username=nil)
152
+ if username
153
+ DomainAdmin.all(:username => username, :order => :domain)
154
+ else
155
+ DomainAdmin.all(:order => :domain)
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/postfix_admin/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.add_development_dependency 'thor'
6
+ gem.add_development_dependency 'data_mapper'
7
+ gem.add_development_dependency 'dm-mysql-adapter'
8
+
9
+ gem.authors = ["Hitoshi Kurokawa"]
10
+ gem.email = ["hitoshi@nextseed.jp"]
11
+ gem.description = %q{Command Line Tools of PostfixAdmin}
12
+ gem.summary = gem.description
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "postfix_admin"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = PostfixAdmin::VERSION
21
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postfix_admin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Hitoshi Kurokawa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: data_mapper
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: dm-mysql-adapter
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Command Line Tools of PostfixAdmin
63
+ email:
64
+ - hitoshi@nextseed.jp
65
+ executables:
66
+ - postfix_admin
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE
73
+ - README.md
74
+ - Rakefile
75
+ - bin/postfix_admin
76
+ - lib/postfix_admin.rb
77
+ - lib/postfix_admin/cli.rb
78
+ - lib/postfix_admin/models.rb
79
+ - lib/postfix_admin/version.rb
80
+ - postfix_admin.gemspec
81
+ homepage: ''
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Command Line Tools of PostfixAdmin
105
+ test_files: []