securevpn-xyz-http-hooks 1.3.3

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +39 -0
  5. data/LICENSE +19 -0
  6. data/README.md +22 -0
  7. data/bin/openvpn-activate +6 -0
  8. data/bin/openvpn-authenticate +8 -0
  9. data/bin/openvpn-connect +6 -0
  10. data/bin/openvpn-disconnect +7 -0
  11. data/lib/api/activation.rb +37 -0
  12. data/lib/api/authentication.rb +23 -0
  13. data/lib/api/billing.rb +55 -0
  14. data/lib/api/connect.rb +21 -0
  15. data/lib/api/connection.rb +70 -0
  16. data/lib/api/disconnect.rb +21 -0
  17. data/lib/exceptions/option_not_found.rb +2 -0
  18. data/lib/openvpn-http-hooks.rb +19 -0
  19. data/lib/openvpn_password_authenticator.rb +18 -0
  20. data/lib/option/base.rb +30 -0
  21. data/lib/option/i2p.rb +28 -0
  22. data/lib/option/proxy.rb +66 -0
  23. data/lib/option/repository.rb +18 -0
  24. data/lib/signer.rb +7 -0
  25. data/lib/system/openvpn_status.rb +19 -0
  26. data/lib/system/openvpn_status_log_parser.rb +30 -0
  27. data/lib/system/openvpn_status_log_reader.rb +29 -0
  28. data/openvpn-http-hooks.gemspec +16 -0
  29. data/spec/fixtures/active_connections.txt +10 -0
  30. data/spec/fixtures/multiple_connections.txt +11 -0
  31. data/spec/lib/api/activation_spec.rb +30 -0
  32. data/spec/lib/api/authentication_spec.rb +29 -0
  33. data/spec/lib/api/billing_spec.rb +71 -0
  34. data/spec/lib/api/connect_spec.rb +40 -0
  35. data/spec/lib/api/connection_spec.rb +59 -0
  36. data/spec/lib/api/disconnect_spec.rb +40 -0
  37. data/spec/lib/openvpn_password_authenticator_spec.rb +52 -0
  38. data/spec/lib/option/base_spec.rb +26 -0
  39. data/spec/lib/option/i2p_spec.rb +19 -0
  40. data/spec/lib/option/proxy_spec.rb +32 -0
  41. data/spec/lib/option/repository_spec.rb +25 -0
  42. data/spec/lib/signer_spec.rb +21 -0
  43. data/spec/lib/system/openvpn_status_log_parser_spec.rb +25 -0
  44. data/spec/lib/system/openvpn_status_log_reader_spec.rb +33 -0
  45. data/spec/lib/system/openvpn_status_spec.rb +22 -0
  46. data/spec/spec_helper.rb +9 -0
  47. metadata +133 -0
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Api::Disconnect do
4
+ subject { described_class.new }
5
+
6
+ describe '#invoke' do
7
+ before do
8
+ subject.stubs(:response).returns(
9
+ JSON.parse(
10
+ '{"id":101,"common_name":"login","options":["i2p", "proxy"],"option_attributes":{"i2p":{"attr1": "value1"},"proxy":{"attr2": "value2"}}}'
11
+ )
12
+ )
13
+ subject.stubs(:trigger_script_return)
14
+ subject.stubs(:success_api_call?).returns(api_call_validation_result)
15
+ end
16
+
17
+ context 'successfull script call' do
18
+ let(:api_call_validation_result) { true }
19
+
20
+ it 'activates options' do
21
+ Option::I2p.any_instance.expects(:deactivate!)
22
+ Option::Proxy.any_instance.expects(:deactivate!)
23
+ subject.invoke
24
+ end
25
+ end
26
+
27
+ context 'unsuccessfull call' do
28
+ let(:api_call_validation_result) { false }
29
+
30
+ it 'does not activate options' do
31
+ Option::I2p.any_instance.expects(:deactivate!).never
32
+ subject.invoke
33
+ end
34
+ end
35
+ end
36
+
37
+ it 'represents disconnect action' do
38
+ expect(subject.action).to eq 'disconnect'
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe OpenvpnPasswordAuthenticator do
5
+ let!(:args) { [path_to_file] }
6
+ let!(:file) { Tempfile.new('credentials') }
7
+ let(:path_to_file) { file.path }
8
+ let(:file_content) { "login\npassword" }
9
+ let(:api_adapter_class) { Api::Authentication }
10
+ subject { described_class.new(args, api_adapter_class) }
11
+
12
+ before do
13
+ file.write(file_content)
14
+ file.rewind
15
+ end
16
+
17
+ describe ".new" do
18
+ it "read file with credentials" do
19
+ File.expects(:read).with(path_to_file).returns(file_content)
20
+ subject
21
+ end
22
+
23
+ it "creates new adapter instance with credentials" do
24
+ api_adapter_class.expects(:new).with('login', 'password')
25
+ subject
26
+ end
27
+ end
28
+
29
+ describe ".authenticate" do
30
+ before do
31
+ subject.api.stubs(:valid_credentials?).returns(validation_result)
32
+ end
33
+
34
+ context "credentials valid" do
35
+ let(:validation_result) { true }
36
+
37
+ it "exits with 0 code" do
38
+ subject.expects(:exit).with(0)
39
+ subject.authenticate
40
+ end
41
+ end
42
+
43
+ context "credentials invaid" do
44
+ let(:validation_result) { false }
45
+
46
+ it "exits with 1 code" do
47
+ subject.expects(:exit).with(1)
48
+ subject.authenticate
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Option::Base do
4
+ subject { described_class }
5
+ let(:common_name) { "login" }
6
+ let(:attributes) { Hash[] }
7
+
8
+ describe 'activate' do
9
+ it 'creates instance of class and calls activate! on it' do
10
+ object = mock()
11
+ object.expects(:activate!)
12
+ subject.expects(:new).with(common_name, attributes).returns(object)
13
+ subject.activate(common_name, attributes)
14
+ end
15
+ end
16
+
17
+ describe 'deactivate' do
18
+ it 'creates instance of class and calls deactivate! on it' do
19
+ object = mock()
20
+ object.expects(:deactivate!)
21
+ subject.expects(:new).with(common_name, attributes).returns(object)
22
+ subject.deactivate(common_name, attributes)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Option::I2p do
4
+ subject { described_class.new('login', {}) }
5
+
6
+ describe '.activate' do
7
+ it 'adds firewall rules' do
8
+ subject.expects(:add_firewall_routes)
9
+ subject.activate!
10
+ end
11
+ end
12
+
13
+ describe '.deactivate' do
14
+ it 'removes firewall rules' do
15
+ subject.expects(:remove_firewall_routes)
16
+ subject.deactivate!
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Option::Proxy do
4
+ subject { described_class.new(common_name, attributes) }
5
+ let(:common_name) { 'login' }
6
+ let(:attributes) { Hash[] }
7
+
8
+ describe '.activate!' do
9
+ it 'has attributes assigned' do
10
+ expect(subject.attributes).to eq attributes
11
+ end
12
+
13
+ it 'it starts proxy daemon and firewall rules' do
14
+ subject.expects(:start_proxy_daemon).returns(9090)
15
+ subject.expects(:add_firewall_rules).with(9090)
16
+ subject.activate!
17
+ end
18
+ end
19
+
20
+ describe '.deactivate!' do
21
+ it 'has attributes assigned' do
22
+ expect(subject.attributes).to eq attributes
23
+ end
24
+
25
+ it 'stops daemon, removes firewall rule and cleans relays list' do
26
+ Option::Proxy::RelayManager.any_instance.stubs(:free).with(anything).returns(9090)
27
+ subject.expects(:remove_firewall_rules).with(9090)
28
+ subject.expects(:kill_proxy_daemon).with(9090)
29
+ subject.deactivate!
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Option::Repository do
4
+ describe '.find_by_code' do
5
+ subject { described_class.find_by_code(option_code) }
6
+
7
+ context 'option exists' do
8
+ let(:option_code) { 'i2p' }
9
+
10
+ it 'returns option class by code' do
11
+ expect(subject).to eq Option::I2p
12
+ end
13
+ end
14
+
15
+ context 'option does not exist' do
16
+ let(:option_code) { 'some_option' }
17
+
18
+ it 'raises error' do
19
+ expect {
20
+ subject
21
+ }.to raise_error OptionNotFound
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Signer do
4
+ describe ".sign_hash" do
5
+ let(:hash) { Hash[a: "a", c: "c", b: "b"] }
6
+ let(:key) { "some_key" }
7
+ subject { described_class.sign_hash(hash, key) }
8
+
9
+ it "sorts hash by values" do
10
+ expect(subject).not_to eq Digest::MD5.hexdigest("#{hash.values.join}#{key}")
11
+ end
12
+
13
+ it "joins values" do
14
+ expect(subject).not_to eq Digest::MD5.hexdigest("#{hash.values.sort}#{key}")
15
+ end
16
+
17
+ it "appends key to values" do
18
+ expect(subject).not_to eq Digest::MD5.hexdigest("#{hash.values.sort.join}")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe System::OpenvpnStatusLogParser do
4
+ describe '.new' do
5
+ subject { described_class }
6
+
7
+ it 'calls parse method' do
8
+ subject.any_instance.expects(:parse)
9
+ subject.new("")
10
+ end
11
+ end
12
+
13
+ describe 'parse' do
14
+ let(:contents) { File.read('spec/fixtures/multiple_connections.txt') }
15
+ subject { described_class.new(contents) }
16
+
17
+ it 'returns status' do
18
+ expect(subject.status.class).to eq System::OpenvpnStatus
19
+ end
20
+
21
+ it 'status includes all connected clients' do
22
+ expect(subject.status.clients_list.size).to eq 2
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe System::OpenvpnStatusLogReader do
4
+ let!(:file_contents) { File.read('spec/fixtures/active_connections.txt') }
5
+ let(:common_name) { "e0c187715fa9e1bb9fd96882dfa7af22" }
6
+ let(:path_to_log) { described_class::LOGFILE_PATH }
7
+
8
+ before { File.stubs(:read).with(path_to_log).returns(file_contents) }
9
+
10
+ describe '.vpn_ip' do
11
+ subject { described_class }
12
+
13
+ it 'creates new instance and vpn_ip_for on it' do
14
+ object = mock()
15
+ object.expects(:vpn_ip_for).with(common_name)
16
+ subject.expects(:new).returns(object)
17
+ subject.vpn_ip(common_name)
18
+ end
19
+ end
20
+
21
+ describe '.new' do
22
+ it 'reads logfile' do
23
+ object = described_class.new
24
+ expect(object.log_content).not_to be_nil
25
+ end
26
+ end
27
+
28
+ describe '.vpn_ip_for' do
29
+ it 'returns user virtual ip by common name' do
30
+ expect(described_class.vpn_ip(common_name)).to eq '10.77.2.6'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe System::OpenvpnStatus do
4
+ subject { described_class.new }
5
+
6
+ describe '.current_virtual_address' do
7
+ let(:virtual_address) { '10.0.0.1' }
8
+ before { ENV['ifconfig_pool_remote_ip'] = virtual_address }
9
+
10
+ it 'returns ENV vars value' do
11
+ expect(described_class.current_virtual_address).to eq virtual_address
12
+ end
13
+ end
14
+
15
+ it 'clients list is a hash' do
16
+ expect(subject.clients_list.class).to eq Hash
17
+ end
18
+
19
+ it 'clients_list is empty' do
20
+ expect(subject.clients_list).to be_empty
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec/autorun'
2
+ require 'webmock/rspec'
3
+ require 'openvpn-http-hooks'
4
+
5
+ RSpec.configure do |config|
6
+ config.mock_with :mocha
7
+ end
8
+
9
+
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: securevpn-xyz-http-hooks
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Victor Ivanov at securevpn.xyz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Trigger on openvpn events and notify HTTP API for securevpn.xyz
56
+ email: admin@securevpn.xyz
57
+ executables:
58
+ - openvpn-activate
59
+ - openvpn-authenticate
60
+ - openvpn-connect
61
+ - openvpn-disconnect
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".rspec"
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE
69
+ - README.md
70
+ - bin/openvpn-activate
71
+ - bin/openvpn-authenticate
72
+ - bin/openvpn-connect
73
+ - bin/openvpn-disconnect
74
+ - lib/api/activation.rb
75
+ - lib/api/authentication.rb
76
+ - lib/api/billing.rb
77
+ - lib/api/connect.rb
78
+ - lib/api/connection.rb
79
+ - lib/api/disconnect.rb
80
+ - lib/exceptions/option_not_found.rb
81
+ - lib/openvpn-http-hooks.rb
82
+ - lib/openvpn_password_authenticator.rb
83
+ - lib/option/base.rb
84
+ - lib/option/i2p.rb
85
+ - lib/option/proxy.rb
86
+ - lib/option/repository.rb
87
+ - lib/signer.rb
88
+ - lib/system/openvpn_status.rb
89
+ - lib/system/openvpn_status_log_parser.rb
90
+ - lib/system/openvpn_status_log_reader.rb
91
+ - openvpn-http-hooks.gemspec
92
+ - spec/fixtures/active_connections.txt
93
+ - spec/fixtures/multiple_connections.txt
94
+ - spec/lib/api/activation_spec.rb
95
+ - spec/lib/api/authentication_spec.rb
96
+ - spec/lib/api/billing_spec.rb
97
+ - spec/lib/api/connect_spec.rb
98
+ - spec/lib/api/connection_spec.rb
99
+ - spec/lib/api/disconnect_spec.rb
100
+ - spec/lib/openvpn_password_authenticator_spec.rb
101
+ - spec/lib/option/base_spec.rb
102
+ - spec/lib/option/i2p_spec.rb
103
+ - spec/lib/option/proxy_spec.rb
104
+ - spec/lib/option/repository_spec.rb
105
+ - spec/lib/signer_spec.rb
106
+ - spec/lib/system/openvpn_status_log_parser_spec.rb
107
+ - spec/lib/system/openvpn_status_log_reader_spec.rb
108
+ - spec/lib/system/openvpn_status_spec.rb
109
+ - spec/spec_helper.rb
110
+ homepage: https://securevpn.xyz
111
+ licenses: []
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: HTTP hooks for OpenVPN server on securevpn.xyz
133
+ test_files: []