smailr 0.7.0 → 0.8.2
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 +5 -5
- data/bin/smailr +7 -0
- data/lib/smailr/cli.rb +21 -2
- data/lib/smailr/model.rb +9 -3
- data/lib/smailr/version.rb +3 -0
- data/lib/smailr.rb +41 -11
- metadata +84 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 711ed3fbc0dd02795b873d6b8c5dae375ee2db772765d607550040b1946357f2
|
|
4
|
+
data.tar.gz: bdd43490822316051212b776a8834eb6ae41348d3df98fbe887d152126ab9f3e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 79c3f97dea293a130fdfa8ba385c8609700b3d91b0d3268f9e7bca211bb207cf21f643d4df0b64ac93ebaa8f274e23de4156773d0a47e1ae4ed7748142d78791
|
|
7
|
+
data.tar.gz: dbbacb1c5f7940d1bed41b22ba809faa5628698924e77f68ee4336e8550010cab560f863c87b2ed6dda56195ad2a6f4391067003f98c788b3cb9b8e84c6a3e78
|
data/bin/smailr
CHANGED
data/lib/smailr/cli.rb
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
require 'commander'
|
|
2
2
|
|
|
3
|
+
class String
|
|
4
|
+
def unindent
|
|
5
|
+
gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
3
9
|
module Smailr
|
|
4
10
|
class Cli
|
|
5
11
|
|
|
@@ -52,7 +58,7 @@ module Smailr
|
|
|
52
58
|
c.example 'Add a domain', 'smailr add example.com'
|
|
53
59
|
c.example 'Add a mailbox', 'smailr add user@example.com'
|
|
54
60
|
c.example 'Add an alias', 'smailr add alias@localdom.com --alias user@example.com,user1@example.com'
|
|
55
|
-
c.example 'Setup DKIM for a domain', 'smailr add ono.at --dkim'
|
|
61
|
+
c.example 'Setup DKIM for a domain', 'smailr add ono.at --dkim mail'
|
|
56
62
|
c.option '--alias DESTINATION', String, 'Specify the alias destination.'
|
|
57
63
|
c.option '--password PASSWORD', String, 'The password for a new mailbox. If you omit this option, it prompts for one.'
|
|
58
64
|
c.option '--dkim SELECTOR', String, 'Add a DKIM Key with the specified selector for domain.'
|
|
@@ -65,8 +71,16 @@ module Smailr
|
|
|
65
71
|
if options.dkim
|
|
66
72
|
selector = options.dkim
|
|
67
73
|
key = Smailr::Dkim.add(address, selector)
|
|
74
|
+
key_fmt = key.split("\n").slice(1..-2).join
|
|
68
75
|
|
|
69
|
-
puts
|
|
76
|
+
puts <<-EOM.unindent
|
|
77
|
+
.
|
|
78
|
+
DKIM is active now, please setup domainkey records in zone #{address}:
|
|
79
|
+
|
|
80
|
+
_domainkey IN TXT "t=y\; o=~\;"
|
|
81
|
+
#{selector}._domainkey IN TXT "v=DKIM1\; t=y\; k=rsa\; p=#{key_fmt}
|
|
82
|
+
.
|
|
83
|
+
EOM
|
|
70
84
|
else
|
|
71
85
|
Smailr::Domain.add(address)
|
|
72
86
|
end
|
|
@@ -92,6 +106,11 @@ module Smailr
|
|
|
92
106
|
case args[0]
|
|
93
107
|
when /^[^@][A-Z0-9.-]+\.[A-Z]{2,6}$/i then
|
|
94
108
|
domain = Smailr::Model::Domain[:fqdn => args[0]]
|
|
109
|
+
unless domain
|
|
110
|
+
error "No such domain: #{args[0]}"
|
|
111
|
+
exit 1
|
|
112
|
+
end
|
|
113
|
+
|
|
95
114
|
domain.mailboxes.each do |mbox|
|
|
96
115
|
puts "m: #{mbox.localpart}@#{args[0]}"
|
|
97
116
|
end
|
data/lib/smailr/model.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'bcrypt'
|
|
2
2
|
|
|
3
3
|
module Smailr
|
|
4
4
|
module Model
|
|
@@ -30,8 +30,14 @@ module Smailr
|
|
|
30
30
|
many_to_one :domain
|
|
31
31
|
|
|
32
32
|
def password=(clear)
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
crypted = BCrypt::Password.create(
|
|
34
|
+
clear,
|
|
35
|
+
cost: BCrypt::Engine::DEFAULT_COST,
|
|
36
|
+
salt: BCrypt::Engine.generate_salt
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
self[:password_scheme] = '{BLF-CRYPT}'
|
|
40
|
+
self[:password] = crypted
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
def rm_related
|
data/lib/smailr.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
|
+
require 'smailr/version'
|
|
2
3
|
|
|
3
4
|
require 'fileutils'
|
|
4
5
|
require 'logger'
|
|
@@ -19,29 +20,61 @@ module Smailr
|
|
|
19
20
|
|
|
20
21
|
# Exception Classes
|
|
21
22
|
class MissingDomain < StandardError ; end
|
|
22
|
-
|
|
23
|
-
VERSION = '0.7.0'
|
|
23
|
+
class ConfigurationError < StandardError ; end
|
|
24
24
|
|
|
25
25
|
class << self;
|
|
26
26
|
attr_accessor :config
|
|
27
27
|
attr_accessor :config_files
|
|
28
|
-
attr_accessor :load_config
|
|
29
28
|
attr_accessor :contrib_directory
|
|
30
29
|
attr_accessor :migrations_directory
|
|
30
|
+
attr_accessor :bundled_config_file
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def self.load_config
|
|
34
34
|
config = {}
|
|
35
|
-
config_files.
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
runtime_config_files = config_files.reject { |f| f == bundled_config_file }
|
|
36
|
+
readable_runtime_config_files = runtime_config_files.select { |f| File.file?(f) && File.readable?(f) }
|
|
37
|
+
unreadable_runtime_config_files = runtime_config_files.select { |f| File.exist?(f) && !File.readable?(f) }
|
|
38
|
+
|
|
39
|
+
if readable_runtime_config_files.empty?
|
|
40
|
+
if unreadable_runtime_config_files.any?
|
|
41
|
+
raise ConfigurationError, "Cannot read configuration file: #{unreadable_runtime_config_files.join(', ')}"
|
|
38
42
|
end
|
|
43
|
+
|
|
44
|
+
raise ConfigurationError, "Cannot find configuration file. Checked: #{runtime_config_files.join(', ')}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if bundled_config_file && File.readable?(bundled_config_file)
|
|
48
|
+
config.merge!(YAML.load_file(bundled_config_file) || {})
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
readable_runtime_config_files.each do |f|
|
|
52
|
+
config.merge!(YAML.load_file(f) || {})
|
|
39
53
|
end
|
|
54
|
+
|
|
40
55
|
self.config = config
|
|
41
56
|
end
|
|
42
57
|
|
|
43
58
|
def self.db_connect
|
|
59
|
+
unless self.config && self.config['database']
|
|
60
|
+
raise ConfigurationError, "Configuration file is missing database settings."
|
|
61
|
+
end
|
|
62
|
+
|
|
44
63
|
Sequel.connect(self.config['database'])
|
|
64
|
+
rescue Sequel::DatabaseConnectionError => e
|
|
65
|
+
raise ConfigurationError, "Cannot open database connection: #{e.message}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.initialize!
|
|
69
|
+
load_config
|
|
70
|
+
|
|
71
|
+
unless defined?(Smailr::Model)
|
|
72
|
+
require 'smailr/model'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Smailr.send(:remove_const, :DB) if Smailr.const_defined?(:DB, false)
|
|
76
|
+
Smailr.const_set(:DB, db_connect)
|
|
77
|
+
Smailr::DB.sql_log_level = :debug
|
|
45
78
|
end
|
|
46
79
|
|
|
47
80
|
def self.logger
|
|
@@ -66,8 +99,5 @@ end
|
|
|
66
99
|
|
|
67
100
|
Smailr.contrib_directory ||= File.expand_path('../../contrib', __FILE__)
|
|
68
101
|
Smailr.migrations_directory ||= File.expand_path('../../migrations', __FILE__)
|
|
69
|
-
Smailr.
|
|
70
|
-
Smailr.
|
|
71
|
-
Smailr::DB = Smailr::db_connect
|
|
72
|
-
require 'smailr/model'
|
|
73
|
-
Smailr::DB.sql_log_level = :debug
|
|
102
|
+
Smailr.bundled_config_file ||= File.expand_path('../../smailr.yml', __FILE__)
|
|
103
|
+
Smailr.config_files ||= [ Smailr.bundled_config_file, '/etc/smailr.yml' ]
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smailr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stefan Schlesinger
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-05-05 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: commander
|
|
@@ -26,18 +25,94 @@ dependencies:
|
|
|
26
25
|
version: '4.3'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: sequel
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '6.0'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '5.0'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '6.0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: bcrypt
|
|
29
48
|
requirement: !ruby/object:Gem::Requirement
|
|
30
49
|
requirements:
|
|
31
50
|
- - "~>"
|
|
32
51
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
52
|
+
version: '3.1'
|
|
34
53
|
type: :runtime
|
|
35
54
|
prerelease: false
|
|
36
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
56
|
requirements:
|
|
38
57
|
- - "~>"
|
|
39
58
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
59
|
+
version: '3.1'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: logger
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '0'
|
|
67
|
+
type: :runtime
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: net-smtp
|
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '0'
|
|
81
|
+
type: :runtime
|
|
82
|
+
prerelease: false
|
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
- !ruby/object:Gem::Dependency
|
|
89
|
+
name: minitest
|
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0'
|
|
95
|
+
type: :development
|
|
96
|
+
prerelease: false
|
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0'
|
|
102
|
+
- !ruby/object:Gem::Dependency
|
|
103
|
+
name: minitest-mock
|
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - ">="
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0'
|
|
109
|
+
type: :development
|
|
110
|
+
prerelease: false
|
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - ">="
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '0'
|
|
41
116
|
description: |-
|
|
42
117
|
Smailr is a CLI tool which lets you manage your virtual mailhosting setup
|
|
43
118
|
from the shell. It currently uses SQLite as a backend, samples for Dovecot/Exim provided.
|
|
@@ -60,6 +135,7 @@ files:
|
|
|
60
135
|
- lib/smailr/mailbox.rb
|
|
61
136
|
- lib/smailr/model.rb
|
|
62
137
|
- lib/smailr/setup.rb
|
|
138
|
+
- lib/smailr/version.rb
|
|
63
139
|
- migrations/001_domains.rb
|
|
64
140
|
- migrations/002_mailboxes.rb
|
|
65
141
|
- migrations/003_aliases.rb
|
|
@@ -99,7 +175,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
99
175
|
requirements:
|
|
100
176
|
- - ">="
|
|
101
177
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '
|
|
178
|
+
version: '3.1'
|
|
103
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
180
|
requirements:
|
|
105
181
|
- - ">="
|
|
@@ -108,9 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
108
184
|
requirements:
|
|
109
185
|
- Exim
|
|
110
186
|
- Dovecot
|
|
111
|
-
|
|
112
|
-
rubygems_version: 2.4.6
|
|
113
|
-
signing_key:
|
|
187
|
+
rubygems_version: 4.0.6
|
|
114
188
|
specification_version: 4
|
|
115
189
|
summary: Simple MAIL manageR - Virtual mail hosting management from the CLI
|
|
116
190
|
test_files: []
|
|
191
|
+
...
|