schleuder-cli 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ module SchleuderCli
2
+ class Subscriptions < Thor
3
+ include Helper
4
+ extend SubcommandFix
5
+
6
+ desc 'list <list@hostname>', 'List subscriptions to list.'
7
+ def list(listname)
8
+ subscriptions = get(url(:subscriptions, {list_id: listname}))
9
+ subscriptions.each do |subscription|
10
+ email = subscription['email']
11
+ fingerprint = subscription['fingerprint'].empty? ? 'N/A' : subscription['fingerprint']
12
+ admin = subscription['admin'] ? 'admin' : ''
13
+ delivery_enabled = subscription['delivery_enabled'] ? '' : 'Delivery disabled!'
14
+ say "#{email}\t#{fingerprint}\t#{admin}\t#{delivery_enabled}\n"
15
+ end
16
+ say "\n"
17
+ end
18
+
19
+ desc 'new <list@hostname> <user@example.org> [<fingerprint> | </path/to/public.key>]', 'Subscribe email-address to list.'
20
+ long_desc 'Subscribe an email-address to a list, optionally setting the fingerprint and/or importing public keys from a file.'
21
+ def new(listname, email, fingerprint_or_keyfile=nil)
22
+ if fingerprint_or_keyfile =~ Conf::FINGERPRINT_REGEXP
23
+ fingerprint = fingerprint_or_keyfile
24
+ else
25
+ fingerprint = import_key_and_find_fingerprint(listname, fingerprint_or_keyfile)
26
+ end
27
+
28
+ subscribe(listname, email, fingerprint)
29
+ end
30
+
31
+ desc 'list-options', 'List available options for subscriptions.'
32
+ def list_options()
33
+ say get(url(:subscriptions, 'configurable_attributes')).join("\n")
34
+ end
35
+
36
+ desc 'show <list@hostname> <user@hostname> <option>', 'Get the value of a subscription-option'
37
+ def show(listname, email, option)
38
+ subscription = get(url(:subscriptions, email, {list_id: listname}))
39
+ check_option_presence(subscription, option)
40
+ show_value(subscription[option])
41
+ end
42
+
43
+ desc 'set <list@hostname> <user@hostname> <option> <value>', 'Set the value of a subscription-option'
44
+ def set(listname, email, option, value=nil)
45
+ patch(url(:subscriptions, email, {list_id: listname}), {option => value})
46
+ show_value(value)
47
+ end
48
+
49
+ desc 'delete <list@hostname> <user@example.org>', 'Unsubscribe user@example.org from list@hostname.'
50
+ def delete(listname, email)
51
+ delete_req(url(:subscriptions, email, {list_id: listname}))
52
+ say "#{email} unsubscribed from #{listname}."
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ module SchleuderCli
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,25 @@
1
+ require 'thor'
2
+ require 'json'
3
+ require 'pathname'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'cgi'
7
+ require 'singleton'
8
+ require 'yaml'
9
+ require 'base64'
10
+
11
+ rootdir = Pathname.new(__FILE__).dirname.dirname.realpath
12
+ $:.unshift File.join(rootdir, 'lib')
13
+
14
+ # TODO: don't always `require` everything, only the relevant classes.
15
+ require 'schleuder-cli/conf'
16
+ require 'schleuder-cli/helper'
17
+ require 'schleuder-cli/version'
18
+ require 'schleuder-cli/subcommand_fix'
19
+ require 'schleuder-cli/subscriptions'
20
+ require 'schleuder-cli/lists'
21
+ require 'schleuder-cli/keys'
22
+ require 'schleuder-cli/base'
23
+ require 'schleuder-cli/openssl_ssl_patch'
24
+
25
+ ENV["SCHLEUDER_CLI_CONFIG"] ||= File.join(ENV['HOME'], '.schleuder-cli/schleuder-cli.yml')
@@ -0,0 +1,97 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "SCHLEUDER\-CLI" "8" "January 2017" "" ""
5
+ .
6
+ .SH "NAME"
7
+ schleuder\-cli \- manage \fBschleuder\fR(8)\-lists, subscriptions, and keys\.
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBschleuder\-cli\fR \fIcmd\fR <args\.\.\.>
11
+ .
12
+ .P
13
+ \fBschleuder\-cli\fR help
14
+ .
15
+ .SH "DESCRIPTION"
16
+ schleuder\-cli is a command line tool to create, configure, and delete schleuder\-lists, subscriptions, and OpenPGP\-keys\.
17
+ .
18
+ .P
19
+ It uses the \fBschleuder\fR(8) API, provided by \fBschleuder\-api\-daemon\fR(8)\.
20
+ .
21
+ .P
22
+ Authentication and TLS\-verification are mandatory\. You need an API\-key and the fingerprint of the TLS\-certificate of \fBschleuer\-api\-daemon\fR(8), respectively\. Both should be provided by the operators of \fBschleuer\-api\-daemon\fR(8)\.
23
+ .
24
+ .P
25
+ schleuder\-cli does \fInot\fR authorize access\. Only people who are supposed to have full access to all lists should be allowed to use it on/with your server\.
26
+ .
27
+ .SH "ENVIRONMENT"
28
+ .
29
+ .SS "Configuration"
30
+ SchleuderCli reads its settings from a file that it by default expects at \fB$HOME/\.schleuder\-cli/schleuder\-cli\.yml\fR\. To make it read a different file set the environment variable \fBSCHLEUDER_CLI_CONFIG\fR to the path to your file\. E\.g\.:
31
+ .
32
+ .IP "" 4
33
+ .
34
+ .nf
35
+
36
+ SCHLEUDER_CLI_CONFIG=/usr/local/etc/schleuder\-cli\.yml schleuder\-cli \.\.\.
37
+ .
38
+ .fi
39
+ .
40
+ .IP "" 0
41
+ .
42
+ .P
43
+ The configuration file specifies how to connect to the Schleuder API\. If it doesn\'t exist, it will be filled with the default settings\.
44
+ .
45
+ .P
46
+ The default settings will work out of the box with the default settings of Schleuder if both are running on the same host\.
47
+ .
48
+ .SS "Options"
49
+ These are the configuration file options and their default values:
50
+ .
51
+ .TP
52
+ \fBhost\fR
53
+ The hostname (or IP\-address) to connect to\. Default: \fIlocalhost\fR\.
54
+ .
55
+ .TP
56
+ \fBpost\fR
57
+ The port to connect to\. Default: \fI4443\fR\.
58
+ .
59
+ .TP
60
+ \fBtls_fingerprint\fR
61
+ TLS\-fingerprint of the Schleuder API\. To be fetched from the API operators\. Default: empty\.
62
+ .
63
+ .TP
64
+ \fBapi_key\fR
65
+ Key to authenticate with against the Schleuder API\. To be fetched from the API operators\. Default: empty\.
66
+ .
67
+ .SH "FILES"
68
+ .
69
+ .TP
70
+ \fB$HOME/\.schleuder\-cli/schleuder\-cli\.yml\fR
71
+ default path of schleuder\-cli configuration file\.
72
+ .
73
+ .P
74
+ The configuration file is formatted as YAML\. See \fIhttp://www\.yaml\.org/\fR for more details\.
75
+ .
76
+ .SH "BUGS"
77
+ Known bugs are listed on the schleuder\-cli bugtracker at \fIhttps://0xacab\.org/schleuder/schleuder\-cli/issues\fR
78
+ .
79
+ .SH "SEE ALSO"
80
+ \fBschleuder\fR(8), \fBschleuder\-api\-daemon\fR(8)\.
81
+ .
82
+ .TP
83
+ Website of \fBschleuder\-cli\fR
84
+ \fIhttps://0xacab\.org/schleuder/schleuder\-cli/\fR
85
+ .
86
+ .TP
87
+ Website of \fBschleuder\fR
88
+ \fIhttps://schleuder\.org/\fR
89
+ .
90
+ .TP
91
+ More extensive documentation for \fBschleuder\fR
92
+ \fIhttps://schleuder\.org/docs/\fR
93
+ .
94
+ .TP
95
+ \fBschleuder\-web\fR, the web interface for list\-management
96
+ \fIhttps://0xacab\.org/schleuder/schleuder\-web/\fR
97
+
@@ -0,0 +1,80 @@
1
+ schleuder-cli(8)
2
+ ================
3
+
4
+ ## NAME
5
+
6
+ schleuder-cli - manage `schleuder`(8)-lists, subscriptions, and keys.
7
+
8
+ ## SYNOPSIS
9
+
10
+ `schleuder-cli` <cmd> <args...>
11
+
12
+ `schleuder-cli` help
13
+
14
+ ## DESCRIPTION
15
+
16
+ schleuder-cli is a command line tool to create, configure, and delete schleuder-lists, subscriptions, and OpenPGP-keys.
17
+
18
+ It uses the `schleuder`(8) API, provided by `schleuder-api-daemon`(8).
19
+
20
+ Authentication and TLS-verification are mandatory. You need an API-key and the fingerprint of the TLS-certificate of `schleuer-api-daemon`(8), respectively. Both should be provided by the operators of `schleuer-api-daemon`(8).
21
+
22
+ schleuder-cli does *not* authorize access. Only people who are supposed to have full access to all lists should be allowed to use it on/with your server.
23
+
24
+
25
+ ## ENVIRONMENT
26
+
27
+ ### Configuration
28
+
29
+
30
+ SchleuderCli reads its settings from a file that it by default expects at `$HOME/.schleuder-cli/schleuder-cli.yml`. To make it read a different file set the environment variable `SCHLEUDER_CLI_CONFIG` to the path to your file. E.g.:
31
+
32
+ SCHLEUDER_CLI_CONFIG=/usr/local/etc/schleuder-cli.yml schleuder-cli ...
33
+
34
+ The configuration file specifies how to connect to the Schleuder API. If it doesn't exist, it will be filled with the default settings.
35
+
36
+ The default settings will work out of the box with the default settings of Schleuder if both are running on the same host.
37
+
38
+ ### Options
39
+
40
+ These are the configuration file options and their default values:
41
+
42
+ * `host`:
43
+ The hostname (or IP-address) to connect to. Default: <localhost>.
44
+ * `post`:
45
+ The port to connect to. Default: <4443>.
46
+ * `tls_fingerprint`:
47
+ TLS-fingerprint of the Schleuder API. To be fetched from the API operators. Default: empty.
48
+ * `api_key`:
49
+ Key to authenticate with against the Schleuder API. To be fetched from the API operators. Default: empty.
50
+
51
+
52
+ ## FILES
53
+
54
+ * `$HOME/.schleuder-cli/schleuder-cli.yml`:
55
+ default path of schleuder-cli configuration file.
56
+
57
+ The configuration file is formatted as YAML. See
58
+ <http://www.yaml.org/> for more details.
59
+
60
+ ## BUGS
61
+
62
+ Known bugs are listed on the schleuder-cli bugtracker at
63
+ <https://0xacab.org/schleuder/schleuder-cli/issues>
64
+
65
+ ## SEE ALSO
66
+
67
+ `schleuder`(8),
68
+ `schleuder-api-daemon`(8).
69
+
70
+ * Website of `schleuder-cli`:
71
+ <https://0xacab.org/schleuder/schleuder-cli/>
72
+
73
+ * Website of `schleuder`:
74
+ <https://schleuder.org/>
75
+
76
+ * More extensive documentation for `schleuder`:
77
+ <https://schleuder.org/docs/>
78
+
79
+ * `schleuder-web`, the web interface for list-management:
80
+ <https://0xacab.org/schleuder/schleuder-web/>
@@ -0,0 +1,52 @@
1
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
2
+ Version: GnuPG/MacGPG2 v2
3
+
4
+ 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
50
+ gpCMrbUUdX4=
51
+ =H2Gw
52
+ -----END PGP PUBLIC KEY BLOCK-----
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe "#keys" do
4
+ it "imports keys from a file" do
5
+ listname = "testlist-#{rand}@localhost"
6
+ output = run_cli("lists new #{listname} admin@localhost")
7
+ expect(output).to include("List #{listname} successfully created!")
8
+
9
+ output = run_cli("keys import #{listname} spec/two_keys.asc")
10
+ expect(output).to eql("Imported: 0x59C71FB38AEE22E091C78259D06350440F759BD3 schleuder@example.org 2016-12-06\nImported: 0xA725BD56B0CA28BF3D05F45D3EBD901AEB9C74E4 first@example.net 2020-04-07\n")
11
+ ensure
12
+ run_cli("lists delete #{listname} --YES")
13
+ end
14
+
15
+ it "complains about unreadable file" do
16
+ output = run_cli("keys import something doesnotexist.txt")
17
+ expect(output).to eql("File not found: doesnotexist.txt\n")
18
+ end
19
+
20
+ it "tells about failed imports" do
21
+ listname = "testlist-#{rand}@localhost"
22
+ output = run_cli("lists new #{listname} admin@localhost")
23
+ expect(output).to include("List #{listname} successfully created!")
24
+
25
+ output = run_cli("keys import #{listname} LICENSE.txt")
26
+ expect(output).to eql("LICENSE.txt did not contain any keys!\n")
27
+ end
28
+
29
+ it "properly reports non-existing list" do
30
+ output = run_cli("keys import something spec/example_key.txt")
31
+ expect(output).to eql("Schleuder could not find the requested resource, please check your input.\n")
32
+ end
33
+ end
34
+
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe SchleuderCli do
4
+ it "creates a list without admin-fingerprint" do
5
+ listname = "testlist-#{rand}@localhost"
6
+ output = run_cli("lists new #{listname} admin@localhost")
7
+ expect(output).to eql("List #{listname} successfully created! Don't forget to hook it into your MTA.\nadmin@localhost subscribed to #{listname} without setting a fingerprint.\n")
8
+
9
+ output = run_cli("lists list")
10
+ expect(output).to include("#{listname}")
11
+ output = run_cli("subscriptions list #{listname}")
12
+ expect(output).to include("admin@localhost N/A admin")
13
+ ensure
14
+ run_cli("lists delete #{listname} --YES")
15
+ end
16
+
17
+ it "creates a list and imports keys from file but doesn't set fingerprint because the imported file contains multiple keys" do
18
+ listname = "testlist-#{rand}@localhost"
19
+ output = run_cli("lists new #{listname} admin@localhost spec/two_keys.asc")
20
+ expect(output).to eql("List #{listname} successfully created! Don't forget to hook it into your MTA.\nImported: 0x59C71FB38AEE22E091C78259D06350440F759BD3 schleuder@example.org 2016-12-06\nImported: 0xA725BD56B0CA28BF3D05F45D3EBD901AEB9C74E4 first@example.net 2020-04-07\nspec/two_keys.asc contains more than one key, cannot determine which fingerprint to use. Please set it manually!\nadmin@localhost subscribed to #{listname} without setting a fingerprint.\n")
21
+
22
+ output = run_cli("lists list")
23
+ expect(output).to include("#{listname}")
24
+ output = run_cli("subscriptions list #{listname}")
25
+ expect(output).to eql("admin@localhost N/A admin\t\n\n")
26
+
27
+ output = run_cli("keys list #{listname}")
28
+ expect(output).to include("A725BD56B0CA28BF3D05F45D3EBD901AEB9C74E4 first@example.net\n59C71FB38AEE22E091C78259D06350440F759BD3 schleuder@example.org\n")
29
+ ensure
30
+ run_cli("lists delete #{listname} --YES")
31
+ end
32
+
33
+ it "creates a list with admin-fingerprint taken from imported key-file" do
34
+ listname = "testlist-#{rand}@localhost"
35
+ output = run_cli("lists new #{listname} admin@localhost spec/example_key.txt")
36
+ expect(output).to eql("List #{listname} successfully created! Don't forget to hook it into your MTA.\nImported: 0xC4D60F8833789C7CAA44496FD3FFA6613AB10ECE schleuder2@example.org 2016-12-12\nadmin@localhost subscribed to #{listname} with fingerprint C4D60F8833789C7CAA44496FD3FFA6613AB10ECE.\n")
37
+
38
+ output = run_cli("lists list")
39
+ expect(output).to include("#{listname}")
40
+ output = run_cli("subscriptions list #{listname}")
41
+ expect(output).to include("admin@localhost C4D60F8833789C7CAA44496FD3FFA6613AB10ECE admin")
42
+ ensure
43
+ run_cli("lists delete #{listname} --YES")
44
+ end
45
+
46
+ it "does not create a list if key-file does not exist" do
47
+ listname = "testlist-#{rand}@localhost"
48
+ output = run_cli("lists new #{listname} admin@localhost doesnotexist.txt")
49
+ expect(output).to eql("File not found: doesnotexist.txt\n")
50
+
51
+ output = run_cli("lists list")
52
+ expect(output).not_to include("#{listname}")
53
+ end
54
+
55
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe SchleuderCli do
4
+
5
+ it "returns a help message when run without argument" do
6
+ output = run_cli
7
+ expect(output).to include("schleuder-cli help")
8
+ expect(output).to include("schleuder-cli keys")
9
+ expect(output).to include("schleuder-cli lists")
10
+ expect(output).to include("schleuder-cli subscriptions")
11
+ expect(output).to include("schleuder-cli version")
12
+ end
13
+
14
+ it "returns a help message for a subcommand when run without argument" do
15
+ output = run_cli('lists')
16
+ expect(output).to_not include("schleuder-cli help")
17
+ expect(output).to include("schleuder-cli lists help")
18
+ expect(output).to include("schleuder-cli lists delete")
19
+ expect(output).to include("schleuder-cli lists list")
20
+ expect(output).to include("schleuder-cli lists list-options")
21
+ expect(output).to include("schleuder-cli lists new")
22
+ expect(output).to include("schleuder-cli lists set")
23
+ expect(output).to include("schleuder-cli lists show")
24
+ end
25
+
26
+ it "returns the version" do
27
+ output = run_cli('-v').chomp
28
+ expect(output).to eq(SchleuderCli::VERSION)
29
+ end
30
+
31
+ end
@@ -0,0 +1,4 @@
1
+ host: localhost
2
+ port: 4443
3
+ tls_fingerprint: f1efd802fc6845eb56213e75f6929e619152999acab13dc06aebcaa0d1830374
4
+ api_key: test_api_key
@@ -0,0 +1,31 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+ require 'schleuder-cli'
4
+
5
+ RSpec.configure do |config|
6
+ config.expect_with :rspec do |expectations|
7
+ # This option will default to `true` in RSpec 4. It makes the `description`
8
+ # and `failure_message` of custom matchers include text for helper methods
9
+ # defined using `chain`, e.g.:
10
+ # be_bigger_than(2).and_smaller_than(4).description
11
+ # # => "be bigger than 2 and smaller than 4"
12
+ # ...rather than:
13
+ # # => "be bigger than 2"
14
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
15
+ end
16
+
17
+ config.order = :random
18
+
19
+ # rspec-mocks config goes here. You can use an alternate test double
20
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
21
+ config.mock_with :rspec do |mocks|
22
+ # Prevents you from mocking or stubbing a method that does not exist on
23
+ # a real object. This is generally recommended, and will default to
24
+ # `true` in RSpec 4.
25
+ mocks.verify_partial_doubles = true
26
+ end
27
+ end
28
+
29
+ def run_cli(args='')
30
+ `SCHLEUDER_CLI_CONFIG='spec/schleuder-cli.yml' bin/schleuder-cli #{args} 2>&1`
31
+ end
data/spec/two_keys.asc ADDED
@@ -0,0 +1,76 @@
1
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
2
+
3
+ mQINBFhGvz0BEADXbbTWo/PStyTznAo/f1UobY0EiVPNKNERvYua2Pnq8BwOQ5bS
4
+ qvmWTb+9Fe9PRpmmqqKKeKjMX9yNjYZweqZ2Tda6C9B6shLme/bWotoXYCEjmP4t
5
+ g9uWJmu2x+UHH+SSH752eDlTOtz9mZqNjcKlwvZtHcfu3FwvPQ7xqYt3f2Q/e8ES
6
+ T2f02oI6uEuiBbuO0ZtLX2IMeygPc8ErBY+EAqJ9Q41SpO9rwGf3vKs7NZnE1Jjz
7
+ 6myvVGf+NTdzpuk0tWxNSgESBeL86nhoKxwKSoCT12vcprMhZ5SPhkMed1nhLE31
8
+ rHiK7L9md85rzC5QD20T9HYhsjMcVrsC3v1u1UsfWI3TWi47S6P7XbWEunnMmDlJ
9
+ g8xijEl2Em93YusMn+Yue2lASpwyB8yHJSn2iRvP3mX+JhKV6r+PNk4PuRzm/Qnu
10
+ LCeljEllIyc4tnvEtVcl4SyVw8tkM8WMt8d5oAJtiP5CKndUhjR05F9VinS/T4Wq
11
+ hQemigQsLOlYS9v1+xOlMWIPqkZenOZyjyY+qRHySN+NByzRUpQ6ruBsQrG3mwQV
12
+ ddhlbLOH4YBl6v2rLAOOLfa+f+T2pZD/ogp6R0oy1ViJoQvZaL3aDviJ8+rSMgxu
13
+ y0KnXwLxIQUGJFTUI/V8blHQXL/aaMl0G8GNehXWq4gzhiJCHq4suo93nQARAQAB
14
+ tCpTY2hsZXVkZXIgVGVzdFVzZXIgPHNjaGxldWRlckBleGFtcGxlLm9yZz6JAjgE
15
+ EwECACIFAlhGvz0CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJENBjUEQP
16
+ dZvTHBUP/0OTg+8oJV8O3nYN/ADK8OzVScK4jJhnEtmwZPvkhjZ2iiANaBmVK1Ll
17
+ jZ5dEImwhGOsblYy2ZC+N3ZrgYmSJkBYcCmCKxwnBrDGozJOwtFg+68JMTn2tkfA
18
+ bVKgNoBOVvvtd/dshPEBDl32NUiK/U5VWiie6lLRkMI/2ltpWgX8RannfX8Atmwc
19
+ Wtycw2bLQaAJGGdTISdSo2wpw5D0ZM/Ud5+V4hiOkEGSsbabRwAdqLslZnEtC99n
20
+ b3orR4ABeIDnifxFyIlOKX5lhAbNgYG7W33AyXFYuYiIaD2WDYmaccWKxbsx07Ed
21
+ vHQ5AMvaVgtuMg8WXZXnGreFvZXg2ZYdNlElzt6b/GzPJ3OYcWizDVzbZF8Mlopr
22
+ eBCW5aaGLQkGP5FlNuivMcai7xTUw+gB2lRDqpB2hP0zNrv7L7M/W5UhMf6MccVE
23
+ WYJx28Bb+jy7jcJNkg34lO3ff1Pqw9j+h8W9//z7dA4FaZwMQD+pugjQ2a+xgpEQ
24
+ 1M5JYrTg143xoK1ZZXH1x2HuebdpWqfc98gTo9foVdQbVe1FwSfrqm2c8uN8lmey
25
+ vbU/mjEdixrSFf4uft0qK+dgswVyFQliwzQRT8cr9QIlOoCkcdvoW/MvQ9FaiF26
26
+ rGOJjjlB5/tsPpdY2V8Cz7Ej0iK9FlpYi3UtHSHCGLn710x8jg7WuQINBFhGvz0B
27
+ EAC7MOUHnfgDEMyWV/R16sfprQ6ThqrFio3kHHzFQ2pg9jW3xFTzqiiiTKsVVua4
28
+ NJlweMMMxlzzj3r8fA6Ao5FmnVIHOkK3eUfcRRSoPRvubHPnIjdEek3AyR3WnixA
29
+ lLx+shY1ZHQyaTKOlVk+7etii3wSRIB7p9J6qXCRbvgi4cKM/UcrEfWXtDvWISMW
30
+ Cum88+tJ5TH4uKsl8iSgTCh6haqtPTc1c0mmacEAmmQq43J+s4FLvvj3f9kkWQir
31
+ iFedulAtniQi+fQe3/G3U+BGegvCY9KcXQJsMgwV2m02G4zATrE5RFQq7hz8u0Xg
32
+ nP+CT+yLRg339WwLZG20y8eKK2rngoeg+IUc1Bmjl25XMKLPYjye75DfVxAV0hH3
33
+ nVgpOTEXVTBYEcI6I/D+X8vNdHMK0xp1bjKAcWW6UgnToMVFuRfkRVfZYSWCJIMS
34
+ 4X6icZb+VVRoy9Fflu9xAiApHIf/c7t1kC7Q0LfgMgcbYJwzBUu442U1RpnZ8WLy
35
+ b+hJ+IakrcsCw9SZgtuJhYcWLb7Sb5SJfldxv0gTnOzkwOd01PolG/ASbPndk0hs
36
+ HOsy+ijtrnciVDz3exwfvP6QY6cGIxJ6vUx57VfPzsPSS7MTd6Yyv3BYQn3MkIbA
37
+ t+L6nHFLnZAwb6KWk6dHhZuSHiBJ0QdLu95MhhOzvOJ2swARAQABiQIfBBgBAgAJ
38
+ BQJYRr89AhsMAAoJENBjUEQPdZvTHrYP/AvoY6qEsVBkN2N3O/6TMfJic8BH7TIg
39
+ g5L+QrdreHFWvMGMjG6VwyFbSOK/3U9Y7TR3IKKHdvknrHGn4dT5bHAcCKmpV3jo
40
+ PjDlo+UcwSW0gi7YITghHwVJ1AoK0yw3wD5N+Eq/xMUYw7tyGyipoQML5keauw4u
41
+ sU/TMwFcGYQLrQ5c4CSDmfORHC34h0nNnG3olNWAkAloXTSOys5P6BZAr1B5WnFX
42
+ 2wdxj0HkodBrE6OG8ZtDm7EE50iKKUO5sJMbfamesPVfWQFM4Rx08OdqnV/mmcy1
43
+ IcJFf4xsrC5u9fZsG3ovtTDWKyGVrST/g3JeVmvVWfMJfdwb838rp9fhAgqfO4lF
44
+ L2kCGlZB0iW16DpAs22HOsJgUTtkf7TTvr/DXdGoamuTfckrcJESC7HBi8QDZL8S
45
+ 9iNjgjr8zwmO35evJ/0JgoVhOjknwFzUAR9RGtYCT+IdZqmVcxIkeULjMzJkIwt5
46
+ J3W4uxiy6E9uAsZC9srg9sUZvYd1vavRZ/r55jFA8PdyzpITNPmZ3XrceGoV8T4N
47
+ Qs7Zp5WOthe7oLoPP+UU17lDXHuH9rIUhzKl5QL2Z59H214VDRi5VcQLkn6OpzqW
48
+ 6T/ikr8tewq5VLEY1G35G9XH1VHTS5VNpuoi/imJKl187AYCzA+EZQlnLvmk6WE6
49
+ /J2/tBYro55umQENBF6MQ70BCACnZ+w3KMnV2XTXiO0EbqqI4nkeSNaS9940qXPL
50
+ bvrtudlOs9oUCRMF6mMMohhPzsQYiNiI+l88cQvtKI05D3aTUIC9WxQOofM0YG1p
51
+ DF9kkR3BIedLH0bGOIEUuUDQ/CS8lscsPyKSV7TduSeZjCifxxQDY3U7oJFnfUWL
52
+ Ds8v9f3fYx4+YERj/9TsPe5skW4P22/3S4RekGhsBXfeQtCY/P/5W+3LyTT/LgNO
53
+ yqFVdKBuKCxB5zaOqIkn+73nDY+7z6e84wXgMpVaA2wTI2fACCiWHQBOgiKsrj08
54
+ 1Z7KHlUCWyDN3YQEwUexpU3MV19S8OtkzOVkyZtlBJU6uuypABEBAAG0KDxmaXJz
55
+ dEBleGFtcGxlLm5ldD4gPHNlY29uZEBleGFtcGxlLm5ldD6JAU4EEwEKADgWIQSn
56
+ Jb1WsMoovz0F9F0+vZAa65x05AUCXoxDvQIbAwULCQgHAwUVCgkICwUWAgMBAAIe
57
+ AQIXgAAKCRA+vZAa65x05PlFCACR0kYJe9Wv5c8a0rdwDt+hsJduiwbXq7ClJJC+
58
+ +cVVPRaNlCJ7nQ75feWvV0FlefJXJpnitqN89s6z2bWD+Tx+jwfoy7KQPbv1whIv
59
+ 6WOYCBKJxLDLWOk63PTItk+ZT5oHuzRf60JNYOAPTnu8R8GjoPXxq115I7XmlfuE
60
+ S369MZjMRuiGEm+f4a8duMGcTVKqK8ajBZnAw/CW6PL91SkAqfrj2ORXyO5BwzgD
61
+ VvAFZ4iNtxhzqZm4X9wuAm2GVeSsmMPLnS1yLaNUpW6OHbMapiij0cboytEqvwdU
62
+ uSLjFT4591Om6RcvAERCE36d/hY14zcFocXxMdv5Gi6BkSrCuQENBF6MQ70BCACh
63
+ 0OfejvcwueKx9pB5rstlomP08BwPn0rzoexoXDfRRAoBg+LDbEm4Ia2yEsBKqorK
64
+ jXtD3YebYxxCSbBWYofKooES3aSRjavn/Rp5guYTaHm7NPOCe6q1qJ/3/+P+shEB
65
+ dDhRc4OW8/+hA6MP+BIiAhm9kgFBxGmBPXsdCqCQkAIYMaPrUQ+NvQL81mx5qkTI
66
+ 5Sf+lxIAFTQaH/M8TmECRaLebH5tp+Va6spllOkqpbkweqgpTKA8y2z4g2gdut6z
67
+ oWak09ozWVmx8ziQMKNM8u41jRQXmJpGuww+DHp4bJLhzojyGju+NuE9DHov33dP
68
+ epiTs17dviksWwPGN2B3ABEBAAGJATYEGAEKACAWIQSnJb1WsMoovz0F9F0+vZAa
69
+ 65x05AUCXoxDvQIbDAAKCRA+vZAa65x05ATnCACTIOmO3agDRuHuEk45nZD4zUG+
70
+ owYOn0fgtxgJStb4AzZiXfPJNtXgfkj2oJc3oJNX0pU6smkhjtv38nBTy45G3Lk7
71
+ F4DazxIzKd6dHa/7VXvelQEohzx/7z1gDE2Y0RVMyxJ5gL0gIqvp5oK99ZFhhI3x
72
+ TKFAaAYUw4ixV8186XtKK5Zxey2jwqO11GaGGuQ1MC+2yhMa3Pxg9PeX3nan9VXc
73
+ /RQaIACe3UobATRkMex94jBcAO4S12EX4x2z/7X9LD61MzMWc3FRNjqJPakqxrP1
74
+ 1Y/DYLfH93wGFasHsoQJMhsoMP6ufLBA5oUf1r40J+NYXYhVipbqiE9P00J4
75
+ =GUbH
76
+ -----END PGP PUBLIC KEY BLOCK-----
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schleuder-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - schleuder dev team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.13'
55
+ description: Schleuder-cli enables creating, configuring, and deleting schleuder-lists,
56
+ subscriptions, keys, etc.
57
+ email: team@schleuder.org
58
+ executables:
59
+ - schleuder-cli
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - README.md
64
+ - bin/schleuder-cli
65
+ - lib/schleuder-cli.rb
66
+ - lib/schleuder-cli/base.rb
67
+ - lib/schleuder-cli/conf.rb
68
+ - lib/schleuder-cli/helper.rb
69
+ - lib/schleuder-cli/keys.rb
70
+ - lib/schleuder-cli/lists.rb
71
+ - lib/schleuder-cli/openssl_ssl_patch.rb
72
+ - lib/schleuder-cli/subcommand_fix.rb
73
+ - lib/schleuder-cli/subscriptions.rb
74
+ - lib/schleuder-cli/version.rb
75
+ - man/schleuder-cli.8
76
+ - man/schleuder-cli.8.ron
77
+ - spec/example_key.txt
78
+ - spec/integration/keys_spec.rb
79
+ - spec/integration/lists_spec.rb
80
+ - spec/schleuder-cli.yml
81
+ - spec/schleuder-cli/cli_spec.rb
82
+ - spec/spec_helper.rb
83
+ - spec/two_keys.asc
84
+ homepage: https://schleuder.org/
85
+ licenses:
86
+ - GPL-3.0-only
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.5.4
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: A command line tool to configure schleuder-lists.
107
+ test_files:
108
+ - spec/example_key.txt
109
+ - spec/integration/keys_spec.rb
110
+ - spec/integration/lists_spec.rb
111
+ - spec/schleuder-cli.yml
112
+ - spec/schleuder-cli/cli_spec.rb
113
+ - spec/spec_helper.rb
114
+ - spec/two_keys.asc