schleuder 2.2.4 → 3.2.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/README.md +138 -0
- data/Rakefile +136 -0
- data/bin/pinentry-clearpassphrase +72 -0
- data/bin/schleuder +9 -89
- data/bin/schleuder-api-daemon +4 -0
- data/db/migrate/20140501103532_create_lists.rb +39 -0
- data/db/migrate/20140501112859_create_subscriptions.rb +21 -0
- data/db/migrate/201508092100_add_language_to_lists.rb +11 -0
- data/db/migrate/20150812165700_change_keywords_admin_only_defaults.rb +8 -0
- data/db/migrate/20150813235800_add_forward_all_incoming_to_admins.rb +11 -0
- data/db/migrate/201508141727_change_send_encrypted_only_default.rb +8 -0
- data/db/migrate/201508222143_add_logfiles_to_keep_to_lists.rb +11 -0
- data/db/migrate/201508261723_rename_delivery_disabled_to_delivery_enabled_and_change_default.rb +14 -0
- data/db/migrate/201508261815_strip_gpg_passphrase.rb +11 -0
- data/db/migrate/201508261827_remove_default_mime.rb +9 -0
- data/db/migrate/20160501172700_fix_headers_to_meta_defaults.rb +8 -0
- data/db/migrate/20170713215059_add_internal_footer_to_list.rb +11 -0
- data/db/schema.rb +62 -0
- data/etc/init.d/schleuder-api-daemon +87 -0
- data/etc/list-defaults.yml +123 -0
- data/etc/postfix/schleuder_sqlite.cf +28 -0
- data/etc/schleuder-api-daemon.service +10 -0
- data/etc/schleuder.cron.weekly +6 -0
- data/etc/schleuder.yml +61 -0
- data/lib/schleuder-api-daemon.rb +420 -0
- data/lib/schleuder.rb +81 -47
- data/lib/schleuder/cli.rb +334 -0
- data/lib/schleuder/cli/cert.rb +24 -0
- data/lib/schleuder/cli/schleuder_cert_manager.rb +84 -0
- data/lib/schleuder/cli/subcommand_fix.rb +11 -0
- data/lib/schleuder/conf.rb +131 -0
- data/lib/schleuder/errors/active_model_error.rb +15 -0
- data/lib/schleuder/errors/base.rb +17 -0
- data/lib/schleuder/errors/decryption_failed.rb +16 -0
- data/lib/schleuder/errors/fatal_error.rb +13 -0
- data/lib/schleuder/errors/file_not_found.rb +14 -0
- data/lib/schleuder/errors/invalid_listname.rb +13 -0
- data/lib/schleuder/errors/key_adduid_failed.rb +13 -0
- data/lib/schleuder/errors/key_generation_failed.rb +16 -0
- data/lib/schleuder/errors/keyword_admin_only.rb +13 -0
- data/lib/schleuder/errors/list_exists.rb +13 -0
- data/lib/schleuder/errors/list_not_found.rb +14 -0
- data/lib/schleuder/errors/list_property_missing.rb +14 -0
- data/lib/schleuder/errors/listdir_problem.rb +16 -0
- data/lib/schleuder/errors/loading_list_settings_failed.rb +14 -0
- data/lib/schleuder/errors/message_empty.rb +14 -0
- data/lib/schleuder/errors/message_not_from_admin.rb +13 -0
- data/lib/schleuder/errors/message_sender_not_subscribed.rb +13 -0
- data/lib/schleuder/errors/message_too_big.rb +14 -0
- data/lib/schleuder/errors/message_unauthenticated.rb +13 -0
- data/lib/schleuder/errors/message_unencrypted.rb +13 -0
- data/lib/schleuder/errors/message_unsigned.rb +13 -0
- data/lib/schleuder/errors/standard_error.rb +5 -0
- data/lib/schleuder/errors/too_many_keys.rb +17 -0
- data/lib/schleuder/errors/unknown_list_option.rb +14 -0
- data/lib/schleuder/filters/auth_filter.rb +39 -0
- data/lib/schleuder/filters/bounces_filter.rb +12 -0
- data/lib/schleuder/filters/forward_filter.rb +17 -0
- data/lib/schleuder/filters/forward_incoming.rb +13 -0
- data/lib/schleuder/filters/hotmail_message_filter.rb +25 -0
- data/lib/schleuder/filters/max_message_size.rb +14 -0
- data/lib/schleuder/filters/request_filter.rb +26 -0
- data/lib/schleuder/filters/send_key_filter.rb +20 -0
- data/lib/schleuder/filters/strip_alternative_filter.rb +21 -0
- data/lib/schleuder/filters_runner.rb +83 -0
- data/lib/schleuder/gpgme/ctx.rb +274 -0
- data/lib/schleuder/gpgme/import_status.rb +27 -0
- data/lib/schleuder/gpgme/key.rb +212 -0
- data/lib/schleuder/gpgme/sub_key.rb +13 -0
- data/lib/schleuder/gpgme/user_id.rb +22 -0
- data/lib/schleuder/list.rb +318 -127
- data/lib/schleuder/list_builder.rb +139 -0
- data/lib/schleuder/listlogger.rb +31 -0
- data/lib/schleuder/logger.rb +23 -0
- data/lib/schleuder/logger_notifications.rb +69 -0
- data/lib/schleuder/mail/message.rb +482 -0
- data/lib/schleuder/mail/parts_list.rb +9 -0
- data/lib/schleuder/plugin_runners/base.rb +91 -0
- data/lib/schleuder/plugin_runners/list_plugins_runner.rb +24 -0
- data/lib/schleuder/plugin_runners/request_plugins_runner.rb +27 -0
- data/lib/schleuder/plugins/attach_listkey.rb +17 -0
- data/lib/schleuder/plugins/get_version.rb +7 -0
- data/lib/schleuder/plugins/key_management.rb +113 -0
- data/lib/schleuder/plugins/list_management.rb +15 -0
- data/lib/schleuder/plugins/resend.rb +196 -0
- data/lib/schleuder/plugins/sign_this.rb +46 -0
- data/lib/schleuder/plugins/subscription_management.rb +140 -0
- data/lib/schleuder/runner.rb +130 -0
- data/lib/schleuder/subscription.rb +98 -0
- data/lib/schleuder/validators/boolean_validator.rb +7 -0
- data/lib/schleuder/validators/email_validator.rb +7 -0
- data/lib/schleuder/validators/fingerprint_validator.rb +7 -0
- data/lib/schleuder/validators/greater_than_zero_validator.rb +7 -0
- data/lib/schleuder/validators/no_line_breaks_validator.rb +7 -0
- data/lib/schleuder/version.rb +1 -1
- data/locales/de.yml +179 -0
- data/locales/en.yml +179 -0
- metadata +305 -108
- checksums.yaml.gz.sig +0 -3
- data.tar.gz.sig +0 -2
- data/LICENSE +0 -339
- data/README +0 -32
- data/bin/schleuder-fix-gem-dependencies +0 -37
- data/bin/schleuder-init-setup +0 -37
- data/bin/schleuder-migrate-v2.1-to-v2.2 +0 -225
- data/bin/schleuder-newlist +0 -413
- data/contrib/check-expired-keys.rb +0 -60
- data/contrib/mutt-schleuder-colors.rc +0 -10
- data/contrib/mutt-schleuder-resend.vim +0 -24
- data/contrib/smtpserver.rb +0 -76
- data/ext/default-list.conf +0 -149
- data/ext/default-members.conf +0 -7
- data/ext/list.conf.example +0 -14
- data/ext/schleuder.conf +0 -64
- data/lib/schleuder/archiver.rb +0 -46
- data/lib/schleuder/crypt.rb +0 -210
- data/lib/schleuder/errors.rb +0 -5
- data/lib/schleuder/list_config.rb +0 -146
- data/lib/schleuder/log/listlogger.rb +0 -57
- data/lib/schleuder/log/outputter/emailoutputter.rb +0 -120
- data/lib/schleuder/log/outputter/metaemailoutputter.rb +0 -50
- data/lib/schleuder/log/schleuderlogger.rb +0 -34
- data/lib/schleuder/mail.rb +0 -873
- data/lib/schleuder/mailer.rb +0 -26
- data/lib/schleuder/member.rb +0 -69
- data/lib/schleuder/plugin.rb +0 -54
- data/lib/schleuder/processor.rb +0 -363
- data/lib/schleuder/schleuder_config.rb +0 -75
- data/lib/schleuder/storage.rb +0 -84
- data/lib/schleuder/utils.rb +0 -80
- data/man/schleuder-newlist.8 +0 -174
- data/man/schleuder.8 +0 -416
- data/plugins/README +0 -20
- data/plugins/manage_keys_plugin.rb +0 -113
- data/plugins/manage_members_plugin.rb +0 -156
- data/plugins/manage_self_plugin.rb +0 -26
- data/plugins/resend_plugin.rb +0 -35
- data/plugins/sign_this_plugin.rb +0 -14
- data/plugins/version_plugin.rb +0 -12
- metadata.gz.sig +0 -0
data/lib/schleuder.rb
CHANGED
|
@@ -1,49 +1,83 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
# Stdlib
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'singleton'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
require 'pathname'
|
|
6
|
+
require 'syslog/logger'
|
|
7
|
+
require 'logger'
|
|
8
|
+
require 'open3'
|
|
9
|
+
|
|
10
|
+
# Require mandatory libs. The database-layer-lib is required below.
|
|
11
|
+
require 'mail-gpg'
|
|
12
|
+
require 'active_record'
|
|
13
|
+
|
|
14
|
+
# An extra from mail-gpg
|
|
15
|
+
require 'hkp'
|
|
16
|
+
|
|
17
|
+
# Load schleuder
|
|
18
|
+
libdir = Pathname.new(__FILE__).dirname.realpath
|
|
19
|
+
rootdir = libdir.dirname
|
|
20
|
+
$:.unshift libdir
|
|
21
|
+
|
|
22
|
+
# Monkeypatches
|
|
23
|
+
require 'schleuder/mail/parts_list.rb'
|
|
24
|
+
require 'schleuder/mail/message.rb'
|
|
25
|
+
require 'schleuder/gpgme/import_status.rb'
|
|
26
|
+
require 'schleuder/gpgme/key.rb'
|
|
27
|
+
require 'schleuder/gpgme/sub_key.rb'
|
|
28
|
+
require 'schleuder/gpgme/ctx.rb'
|
|
29
|
+
require 'schleuder/gpgme/user_id.rb'
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
require '
|
|
24
|
-
|
|
25
|
-
require
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
require '
|
|
29
|
-
require '
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
require 'schleuder/
|
|
34
|
-
require 'schleuder/
|
|
35
|
-
require 'schleuder/
|
|
36
|
-
|
|
37
|
-
require
|
|
31
|
+
# The Code[tm]
|
|
32
|
+
require 'schleuder/errors/base'
|
|
33
|
+
Dir["#{libdir}/schleuder/errors/*.rb"].each do |file|
|
|
34
|
+
require file
|
|
35
|
+
end
|
|
36
|
+
# Load schleuder/conf before the other classes, it defines constants!
|
|
37
|
+
require 'schleuder/conf'
|
|
38
|
+
require 'schleuder/version'
|
|
39
|
+
require 'schleuder/logger_notifications'
|
|
40
|
+
require 'schleuder/logger'
|
|
41
|
+
require 'schleuder/listlogger'
|
|
42
|
+
require 'schleuder/plugin_runners/base'
|
|
43
|
+
require 'schleuder/plugin_runners/list_plugins_runner'
|
|
44
|
+
require 'schleuder/plugin_runners/request_plugins_runner'
|
|
45
|
+
Dir["#{libdir}/schleuder/plugins/*.rb"].each do |file|
|
|
46
|
+
require file
|
|
47
|
+
end
|
|
48
|
+
require 'schleuder/filters_runner'
|
|
49
|
+
Dir["#{libdir}/schleuder/filters/*.rb"].each do |file|
|
|
50
|
+
require file
|
|
51
|
+
end
|
|
52
|
+
Dir["#{libdir}/schleuder/validators/*.rb"].each do |file|
|
|
53
|
+
require file
|
|
54
|
+
end
|
|
55
|
+
require 'schleuder/runner'
|
|
38
56
|
require 'schleuder/list'
|
|
39
|
-
require 'schleuder/
|
|
40
|
-
require 'schleuder/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
require 'schleuder/list_builder'
|
|
58
|
+
require 'schleuder/subscription'
|
|
59
|
+
|
|
60
|
+
# Setup
|
|
61
|
+
ENV["SCHLEUDER_CONFIG"] ||= '/etc/schleuder/schleuder.yml'
|
|
62
|
+
ENV["SCHLEUDER_LIST_DEFAULTS"] ||= '/etc/schleuder/list-defaults.yml'
|
|
63
|
+
ENV["SCHLEUDER_ENV"] ||= 'production'
|
|
64
|
+
ENV["SCHLEUDER_ROOT"] = rootdir.to_s
|
|
65
|
+
|
|
66
|
+
GPGME::Ctx.set_gpg_path_from_env
|
|
67
|
+
GPGME::Ctx.check_gpg_version
|
|
68
|
+
|
|
69
|
+
# TODO: Test if database is writable if sqlite.
|
|
70
|
+
ActiveRecord::Base.establish_connection(Schleuder::Conf.database)
|
|
71
|
+
ActiveRecord::Base.logger = Schleuder.logger
|
|
72
|
+
|
|
73
|
+
Mail.defaults do
|
|
74
|
+
delivery_method :smtp, Schleuder::Conf.smtp_settings.symbolize_keys
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
I18n.load_path += Dir["#{rootdir}/locales/*.yml"]
|
|
78
|
+
I18n.enforce_available_locales = true
|
|
79
|
+
I18n.default_locale = :en
|
|
80
|
+
|
|
81
|
+
File.umask(0027)
|
|
82
|
+
|
|
83
|
+
include Schleuder
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'gpgme'
|
|
4
|
+
|
|
5
|
+
require_relative '../schleuder'
|
|
6
|
+
require 'schleuder/cli/subcommand_fix'
|
|
7
|
+
require 'schleuder/cli/schleuder_cert_manager'
|
|
8
|
+
require 'schleuder/cli/cert'
|
|
9
|
+
|
|
10
|
+
module Schleuder
|
|
11
|
+
class Cli < Thor
|
|
12
|
+
|
|
13
|
+
register(Cert,
|
|
14
|
+
'cert',
|
|
15
|
+
'cert ...',
|
|
16
|
+
'Generate TLS-certificate and show fingerprint')
|
|
17
|
+
|
|
18
|
+
map '-v' => :version
|
|
19
|
+
map '--version' => :version
|
|
20
|
+
desc 'version', 'Show version of schleuder'
|
|
21
|
+
def version
|
|
22
|
+
say Schleuder::VERSION
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc 'new_api_key', 'Generate a new API key to be used by a client.'
|
|
26
|
+
def new_api_key
|
|
27
|
+
require 'securerandom'
|
|
28
|
+
puts SecureRandom.hex(32)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc 'work list@hostname < message', 'Run a message through a list.'
|
|
32
|
+
def work(listname)
|
|
33
|
+
message = STDIN.read
|
|
34
|
+
|
|
35
|
+
error = Schleuder::Runner.new.run(message, listname)
|
|
36
|
+
if error.kind_of?(StandardError)
|
|
37
|
+
fatal error
|
|
38
|
+
end
|
|
39
|
+
rescue => exc
|
|
40
|
+
begin
|
|
41
|
+
Schleuder.logger.fatal(exc.message_with_backtrace, message)
|
|
42
|
+
# Don't use FatalError here to reduce dependency on other code.
|
|
43
|
+
say I18n.t('errors.fatalerror')
|
|
44
|
+
rescue => e
|
|
45
|
+
# Give users a clue what to do in case everything blows up.
|
|
46
|
+
# As apparently even the logging raised exceptions we can't even store
|
|
47
|
+
# any information in the logs.
|
|
48
|
+
fatal "A serious, unhandleable error happened. Please contact the administrators of this system or service and provide them with the following information:\n\n#{e.message}"
|
|
49
|
+
end
|
|
50
|
+
exit 1
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc 'check_keys', 'Check all lists for unusable or expiring keys and send the results to the list-admins. (This is supposed to be run from cron weekly.)'
|
|
54
|
+
def check_keys
|
|
55
|
+
List.all.each do |list|
|
|
56
|
+
I18n.locale = list.language
|
|
57
|
+
|
|
58
|
+
text = list.check_keys
|
|
59
|
+
|
|
60
|
+
if text && ! text.empty?
|
|
61
|
+
msg = "#{I18n.t('check_keys_intro', email: list.email)}\n\n#{text}"
|
|
62
|
+
list.logger.notify_admin(msg, nil, I18n.t('check_keys'))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
desc 'refresh_keys [list1@example.com]', "Refresh all keys of all list from the keyservers sequentially (one by one or on the passed list). (This is supposed to be run from cron weekly.)"
|
|
68
|
+
def refresh_keys(list=nil)
|
|
69
|
+
work_on_lists(:refresh_keys,list)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc 'pin_keys [list1@example.com]', "Find keys for subscriptions without a pinned key and try to pin a certain key (one by one or based on the passed list)."
|
|
73
|
+
def pin_keys(list=nil)
|
|
74
|
+
work_on_lists(:pin_keys,list)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
desc 'install', "Set-up or update Schleuder environment (create folders, copy files, fill the database)."
|
|
78
|
+
def install
|
|
79
|
+
config_dir = Pathname.new(ENV['SCHLEUDER_CONFIG']).dirname
|
|
80
|
+
root_dir = Pathname.new(ENV['SCHLEUDER_ROOT'])
|
|
81
|
+
|
|
82
|
+
# Check if lists_dir contains v2-data.
|
|
83
|
+
if Dir.glob("#{Conf.lists_dir}/*/*/members.conf").size > 0
|
|
84
|
+
msg = "Lists directory #{Conf.lists_dir} appears to contain data from a Schleuder version 2.x installation.\nPlease move it out of the way or configure a different `lists_dir` in `#{ENV['SCHLEUDER_CONFIG']}`.\nTo migrate lists from Schleuder v2 to Schleuder v3 please use `schleuder migrate_v2_list` after the installation succeeded."
|
|
85
|
+
fatal msg, 2
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
[Conf.lists_dir, Conf.listlogs_dir, config_dir].each do |dir|
|
|
89
|
+
dir = Pathname.new(dir)
|
|
90
|
+
if ! dir.exist?
|
|
91
|
+
begin
|
|
92
|
+
dir.mkpath
|
|
93
|
+
rescue Errno::EACCES => exc
|
|
94
|
+
problem_dir = exc.message.split(' - ').last
|
|
95
|
+
fatal "Cannot create required directory due to lacking write permissions: #{problem_dir}.\nPlease fix the permissions or create the directory manually and then run this command again."
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
Pathname.glob(root_dir.join("etc").join("*.yml")).each do |file|
|
|
101
|
+
target = config_dir.join(file.basename)
|
|
102
|
+
if ! target.exist?
|
|
103
|
+
if target.dirname.writable?
|
|
104
|
+
FileUtils.cp file, target
|
|
105
|
+
else
|
|
106
|
+
fatal "Cannot copy default config file due to lacking write permissions, please copy manually and then run this command again:\n#{file.realpath} → #{target}"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if ActiveRecord::SchemaMigration.table_exists?
|
|
112
|
+
say shellexec("cd #{root_dir} && rake db:migrate")
|
|
113
|
+
else
|
|
114
|
+
say shellexec("cd #{root_dir} && rake db:init")
|
|
115
|
+
if Conf.database['adapter'].match(/sqlite/)
|
|
116
|
+
say "NOTE: The database was prepared using sqlite. If you prefer to use a different DBMS please edit the 'database'-section in /etc/schleuder/schleuder.yml, create the database, install the corresponding ruby-library (e.g. `gem install mysql`) and run this current command again"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if ! File.exist?(Conf.api['tls_cert_file']) || ! File.exist?(Conf.api['tls_key_file'])
|
|
121
|
+
Schleuder::Cert.new.generate
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
say "Schleuder has been set up. You can now create a new list using `schleuder-cli`.\nWe hope you enjoy!"
|
|
125
|
+
rescue => exc
|
|
126
|
+
fatal exc.message
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
desc 'migrate-v2-list /path/to/listdir', 'Migrate list from v2.2 to v3.'
|
|
130
|
+
def migrate_v2_list(path)
|
|
131
|
+
dir = Pathname.new(path)
|
|
132
|
+
if ! dir.readable? || ! dir.directory?
|
|
133
|
+
fatal "Not a readable directory: `#{path}`."
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
%w[list.conf members.conf pubring.gpg].each do |file|
|
|
137
|
+
if ! (dir + file).exist?
|
|
138
|
+
fatal "Not a complete schleuder v2.2 listdir: missing #{file}"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
conf = YAML.load(File.read(dir + 'list.conf'))
|
|
143
|
+
if conf.nil? || conf.empty?
|
|
144
|
+
fatal "list.conf is blank"
|
|
145
|
+
end
|
|
146
|
+
listname = conf['myaddr']
|
|
147
|
+
if listname.nil? || listname.empty?
|
|
148
|
+
fatal "myaddr is blank in list.conf"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Identify list-fingerprint.
|
|
152
|
+
ENV['GNUPGHOME'] = dir.to_s
|
|
153
|
+
listkey = GPGME::Key.find(:public, "<#{listname}>").first
|
|
154
|
+
if listkey.nil?
|
|
155
|
+
fatal "Failed to identify the list's OpenPGP-key!"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Create list.
|
|
159
|
+
begin
|
|
160
|
+
list, messages = Schleuder::ListBuilder.new({email: listname, fingerprint: listkey.fingerprint}).run
|
|
161
|
+
rescue => exc
|
|
162
|
+
fatal exc
|
|
163
|
+
end
|
|
164
|
+
if messages
|
|
165
|
+
fatal messages.values.join(" - ")
|
|
166
|
+
elsif list.errors.any?
|
|
167
|
+
fatal list.errors.full_messages.join(" - ")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Import keys
|
|
171
|
+
list.import_key(File.read(dir + 'pubring.gpg'))
|
|
172
|
+
list.import_key(File.read(dir + 'secring.gpg'))
|
|
173
|
+
|
|
174
|
+
# Clear passphrase of imported list-key.
|
|
175
|
+
output = list.key.clearpassphrase(conf['gpg_password'])
|
|
176
|
+
if output.present?
|
|
177
|
+
fatal "while clearing passphrase of list-key: #{output.inspect}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Set list-options.
|
|
181
|
+
List.configurable_attributes.each do |option|
|
|
182
|
+
option = option.to_s
|
|
183
|
+
if conf.keys.include?(option)
|
|
184
|
+
value = case option
|
|
185
|
+
when /^keywords_/
|
|
186
|
+
filter_keywords(conf[option])
|
|
187
|
+
when 'log_level'
|
|
188
|
+
conf[option].to_s.downcase
|
|
189
|
+
else
|
|
190
|
+
conf[option]
|
|
191
|
+
end
|
|
192
|
+
list.set_attribute(option, value)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Set changed options.
|
|
197
|
+
changed_options = {
|
|
198
|
+
'prefix' => 'subject_prefix',
|
|
199
|
+
'prefix_in' => 'subject_prefix_in',
|
|
200
|
+
'prefix_out' => 'subject_prefix_out',
|
|
201
|
+
'dump_incoming_mail' => 'forward_all_incoming_to_admins',
|
|
202
|
+
'receive_from_member_emailaddresses_only' => 'receive_from_subscribed_emailaddresses_only',
|
|
203
|
+
'bounces_notify_admin' => 'bounces_notify_admins',
|
|
204
|
+
'max_message_size' => 'max_message_size_kb'
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
changed_options.each do |old, new|
|
|
208
|
+
if conf.keys.include?(old)
|
|
209
|
+
list.set_attribute(new, conf[old])
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
list.save!
|
|
213
|
+
|
|
214
|
+
# Subscribe members
|
|
215
|
+
members = YAML.load(File.read(dir + 'members.conf'))
|
|
216
|
+
members.uniq!{|m| m['email'] }
|
|
217
|
+
members.each do |member|
|
|
218
|
+
fingerprint = find_fingerprint(member, list)
|
|
219
|
+
list.subscribe(member['email'], fingerprint)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Subscribe or flag admins
|
|
223
|
+
conf['admins'].each do |member|
|
|
224
|
+
sub = list.subscriptions.where(email: member['email']).first
|
|
225
|
+
if sub
|
|
226
|
+
sub.admin = true
|
|
227
|
+
sub.save!
|
|
228
|
+
else
|
|
229
|
+
adminfpr = find_fingerprint(member, list)
|
|
230
|
+
# if we didn't find an already imported subscription for the admin
|
|
231
|
+
# address, it wasn't a member, so we don't enable delivery for it
|
|
232
|
+
list.subscribe(member['email'], adminfpr, true, false)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Notify of removed options
|
|
237
|
+
say "Please note: the following options have been *removed*:
|
|
238
|
+
* `default_mime` for lists (we only support pgp/mime for now),
|
|
239
|
+
* `archive` for lists,
|
|
240
|
+
* `gpg_passphrase` for lists,
|
|
241
|
+
* `log_file`, `log_io`, `log_syslog` for lists (we only log to
|
|
242
|
+
syslog (before list-creation) and a file (after it) for now),
|
|
243
|
+
* `mime` for subscriptions/members (we only support pgp/mime for now),
|
|
244
|
+
* `send_encrypted_only` for members/subscriptions.
|
|
245
|
+
|
|
246
|
+
If you really miss any of them please tell us.
|
|
247
|
+
|
|
248
|
+
Please also note that the following keywords have been renamed:
|
|
249
|
+
* list-members => list-subscriptions
|
|
250
|
+
* add-member => subscribe
|
|
251
|
+
* delete-member => unsubscribe
|
|
252
|
+
|
|
253
|
+
Please notify the users and admins of this list of these changes.
|
|
254
|
+
"
|
|
255
|
+
|
|
256
|
+
say "\nList #{listname} migrated to schleuder v3."
|
|
257
|
+
if messages.present?
|
|
258
|
+
say messages.gsub(' // ', "\n")
|
|
259
|
+
end
|
|
260
|
+
rescue => exc
|
|
261
|
+
fatal "#{exc}\n#{exc.backtrace.first}"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
no_commands do
|
|
265
|
+
def fatal(msg, exitcode=1)
|
|
266
|
+
error("Error: #{msg}")
|
|
267
|
+
exit exitcode
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
KEYWORDS = {
|
|
271
|
+
'add-member' => 'subscribe',
|
|
272
|
+
'delete-member' => 'unsubscribe',
|
|
273
|
+
'list-members' => 'list-subscriptions',
|
|
274
|
+
'subscribe' => 'subscribe',
|
|
275
|
+
'unsubscribe' => 'unsubscribe',
|
|
276
|
+
'list-subscriptions' => 'list-subscriptions',
|
|
277
|
+
'set-finterprint' => 'set-fingerprint',
|
|
278
|
+
'add-key' => 'add-key',
|
|
279
|
+
'delete-key' => 'delete-key',
|
|
280
|
+
'list-keys' => 'list-keys',
|
|
281
|
+
'get-key' => 'get-key',
|
|
282
|
+
'fetch-key' => 'fetch-key'
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
def filter_keywords(value)
|
|
286
|
+
Array(value).map do |keyword|
|
|
287
|
+
KEYWORDS[keyword.downcase]
|
|
288
|
+
end.compact
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def find_fingerprint(member, list)
|
|
292
|
+
email = member['email']
|
|
293
|
+
fingerprint = member['key_fingerprint']
|
|
294
|
+
if fingerprint.present?
|
|
295
|
+
return fingerprint
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
key = list.distinct_key(email)
|
|
299
|
+
if key
|
|
300
|
+
return key.fingerprint
|
|
301
|
+
else
|
|
302
|
+
return nil
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def shellexec(cmd)
|
|
307
|
+
result = `#{cmd} 2>&1`
|
|
308
|
+
if $?.exitstatus > 0
|
|
309
|
+
exit $?.exitstatus
|
|
310
|
+
end
|
|
311
|
+
result
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
private
|
|
316
|
+
|
|
317
|
+
def work_on_lists(subj, list=nil)
|
|
318
|
+
selected_lists = if list.nil?
|
|
319
|
+
List.all
|
|
320
|
+
else
|
|
321
|
+
List.where(email: list)
|
|
322
|
+
end
|
|
323
|
+
selected_lists.each do |list|
|
|
324
|
+
I18n.locale = list.language
|
|
325
|
+
output = list.send(subj)
|
|
326
|
+
if output.present?
|
|
327
|
+
msg = "#{I18n.t("#{subj}_intro", email: list.email)}\n\n#{output}"
|
|
328
|
+
list.logger.notify_admin(msg, nil, I18n.t(subj))
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
end
|
|
334
|
+
end
|