ssh-hull 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +44 -0
- data/.gitignore +27 -0
- data/.rubocop.yml +62 -0
- data/.tool-versions +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +142 -0
- data/LICENSE +19 -0
- data/README.md +12 -0
- data/Rakefile +7 -0
- data/bin/bundle +114 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bomb +12 -0
- data/config/locales/en.yml +71 -0
- data/config/locales/fr.yml +71 -0
- data/exe/ssh-hull +12 -0
- data/exe/ssh-tunnel +1 -0
- data/lib/ssh-hull/cli.rb +113 -0
- data/lib/ssh-hull/logger.rb +6 -0
- data/lib/ssh-hull/ui/application.rb +47 -0
- data/lib/ssh-hull/ui/forms/application_form.rb +69 -0
- data/lib/ssh-hull/ui/forms/host_form.rb +27 -0
- data/lib/ssh-hull/ui/forms/tunnel_form.rb +31 -0
- data/lib/ssh-hull/ui/helpers/application_window_helper.rb +233 -0
- data/lib/ssh-hull/ui/helpers/common/form_helper.rb +169 -0
- data/lib/ssh-hull/ui/helpers/common/minimize_helper.rb +46 -0
- data/lib/ssh-hull/ui/helpers/common/modal_helper.rb +43 -0
- data/lib/ssh-hull/ui/helpers/common/toolbar_helper.rb +106 -0
- data/lib/ssh-hull/ui/helpers/common/translation_helper.rb +18 -0
- data/lib/ssh-hull/ui/helpers/common/tree_view_helper.rb +40 -0
- data/lib/ssh-hull/ui/helpers/host_window_helper.rb +230 -0
- data/lib/ssh-hull/ui/helpers/tunnel_window_helper.rb +96 -0
- data/lib/ssh-hull/ui/models/config.rb +82 -0
- data/lib/ssh-hull/ui/models/host.rb +90 -0
- data/lib/ssh-hull/ui/models/tunnel.rb +118 -0
- data/lib/ssh-hull/ui/status_icon.rb +45 -0
- data/lib/ssh-hull/ui/windows/about_window.rb +32 -0
- data/lib/ssh-hull/ui/windows/application_window.rb +42 -0
- data/lib/ssh-hull/ui/windows/hosts/delete_window.rb +56 -0
- data/lib/ssh-hull/ui/windows/hosts/edit_window.rb +39 -0
- data/lib/ssh-hull/ui/windows/hosts/new_window.rb +45 -0
- data/lib/ssh-hull/ui/windows/tunnels/delete_window.rb +57 -0
- data/lib/ssh-hull/ui/windows/tunnels/edit_window.rb +39 -0
- data/lib/ssh-hull/ui/windows/tunnels/new_window.rb +45 -0
- data/lib/ssh-hull/version.rb +17 -0
- data/lib/ssh-tunnel.rb +94 -0
- data/resources/gresources.xml +13 -0
- data/resources/ui/about_window.glade +48 -0
- data/resources/ui/application_window.glade +196 -0
- data/resources/ui/hosts/delete_window.glade +74 -0
- data/resources/ui/hosts/edit_window.glade +331 -0
- data/resources/ui/hosts/new_window.glade +328 -0
- data/resources/ui/tunnels/delete_window.glade +73 -0
- data/resources/ui/tunnels/edit_window.glade +305 -0
- data/resources/ui/tunnels/new_window.glade +305 -0
- data/snap/snapcraft.yaml +48 -0
- data/spec/factories/host.rb +22 -0
- data/spec/factories/tunnel.rb +16 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/ssh_tunnel/ui/forms/host_form_spec.rb +103 -0
- data/spec/ssh_tunnel/ui/forms/tunnel_form_spec.rb +132 -0
- data/spec/ssh_tunnel/ui/models/host_spec.rb +116 -0
- data/spec/ssh_tunnel/ui/models/tunnel_spec.rb +43 -0
- data/spec/ssh_tunnel_spec.rb +45 -0
- data/ssh-hull.gemspec +38 -0
- metadata +320 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Helpers
|
6
|
+
module TunnelWindowHelper
|
7
|
+
|
8
|
+
include SSHTunnel::UI::Helpers::Common::ModalHelper
|
9
|
+
include SSHTunnel::UI::Helpers::Common::TranslationHelper
|
10
|
+
include SSHTunnel::UI::Helpers::Common::FormHelper::InstanceMethods
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
base.extend(SSHTunnel::UI::Helpers::Common::FormHelper::ClassMethods)
|
15
|
+
end
|
16
|
+
|
17
|
+
FORM_BUTTONS = %i[submit cancel].freeze
|
18
|
+
FORM_FIELDS = {
|
19
|
+
name: {
|
20
|
+
type: :text,
|
21
|
+
},
|
22
|
+
type: {
|
23
|
+
type: :select,
|
24
|
+
},
|
25
|
+
local_host: {
|
26
|
+
type: :text,
|
27
|
+
},
|
28
|
+
local_port: {
|
29
|
+
type: :text,
|
30
|
+
},
|
31
|
+
remote_host: {
|
32
|
+
type: :text,
|
33
|
+
},
|
34
|
+
remote_port: {
|
35
|
+
type: :text,
|
36
|
+
},
|
37
|
+
auto_start: {
|
38
|
+
type: :checkbox,
|
39
|
+
},
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
|
43
|
+
module ClassMethods
|
44
|
+
|
45
|
+
def init
|
46
|
+
bind_buttons(FORM_BUTTONS)
|
47
|
+
bind_form_fields(FORM_FIELDS.keys)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def initialize(application, window, tunnel)
|
54
|
+
super
|
55
|
+
|
56
|
+
# Set instance variables
|
57
|
+
@tunnel = tunnel
|
58
|
+
@host = tunnel.parent
|
59
|
+
|
60
|
+
# Bind listeners
|
61
|
+
set_input_labels(scope: :tunnel)
|
62
|
+
|
63
|
+
# Load tunnels combobox
|
64
|
+
load_tunnels_combobox
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
|
71
|
+
def load_tunnels_combobox
|
72
|
+
input_type.append('local', t('form.tunnel.local'))
|
73
|
+
input_type.append('remote', t('form.tunnel.remote'))
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def form_fields
|
78
|
+
FORM_FIELDS
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def form_object
|
83
|
+
SSHTunnel::UI::Forms::TunnelForm.new(@tunnel)
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def save_and_reload_view
|
88
|
+
@application.config.save!
|
89
|
+
close
|
90
|
+
@window.reload_tunnels_treeview(@host)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Models
|
6
|
+
class Config
|
7
|
+
|
8
|
+
attr_reader :file, :data, :hosts
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(file)
|
12
|
+
@file = file
|
13
|
+
load!
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def load!
|
18
|
+
@data = load_json_file(file)
|
19
|
+
@hosts = load_hosts
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def add_host(host)
|
24
|
+
@hosts << host
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def remove_host(host)
|
29
|
+
@hosts.delete(host)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def save!
|
34
|
+
write_yaml_file(file, to_hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def to_hash
|
39
|
+
marshal_dump(hosts: hosts.sort_by(&:name).map(&:to_hash))
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
|
46
|
+
def load_json_file(file)
|
47
|
+
return hash_with_indifferent_access unless File.exist?(file)
|
48
|
+
|
49
|
+
content = File.read(file)
|
50
|
+
return hash_with_indifferent_access if content.empty?
|
51
|
+
|
52
|
+
hash_with_indifferent_access JSON.parse(content)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def load_hosts
|
57
|
+
(data[:hosts] || []).map do |host_attr|
|
58
|
+
SSHTunnel::UI::Models::Host.new(host_attr)
|
59
|
+
end.sort_by(&:name)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def write_yaml_file(file, data)
|
64
|
+
File.open(file, 'w+') do |f|
|
65
|
+
f.write JSON.pretty_generate(data)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def hash_with_indifferent_access(hash = {})
|
71
|
+
hash.with_indifferent_access
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def marshal_dump(data = {})
|
76
|
+
JSON.parse(data.to_json)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Models
|
6
|
+
class Host
|
7
|
+
|
8
|
+
attr_accessor :uuid, :name, :user, :host, :port, :identity_file, :tunnels
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
@uuid = opts.fetch(:uuid) { SecureRandom.uuid }
|
13
|
+
@name = opts.fetch(:name, '')
|
14
|
+
@user = opts[:user]
|
15
|
+
@host = opts[:host]
|
16
|
+
@port = opts[:port]
|
17
|
+
@identity_file = opts[:identity_file]
|
18
|
+
@tunnels = opts.fetch(:tunnels, []).map { |t_attr| Tunnel.new(t_attr.merge(parent: self)) }
|
19
|
+
@started = false
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
name
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def port
|
29
|
+
@port.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
{
|
35
|
+
uuid: uuid,
|
36
|
+
name: name,
|
37
|
+
user: user,
|
38
|
+
host: host,
|
39
|
+
port: @port,
|
40
|
+
identity_file: identity_file,
|
41
|
+
tunnels: tunnels.sort_by(&:name).map(&:to_hash),
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def add_tunnel(tunnel)
|
47
|
+
@tunnels << tunnel
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def remove_tunnel(tunnel)
|
52
|
+
@tunnels.delete(tunnel)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def auto_start!
|
57
|
+
started = tunnels.map(&:auto_start!)
|
58
|
+
@started = started.any?
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def started?
|
63
|
+
@started
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def start_tunnels!
|
68
|
+
tunnels.each(&:start!)
|
69
|
+
@started = true
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def stop_tunnels!
|
74
|
+
tunnels.each(&:stop!)
|
75
|
+
@started = false
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def toggle_tunnels!
|
80
|
+
if started?
|
81
|
+
stop_tunnels!
|
82
|
+
else
|
83
|
+
start_tunnels!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Models
|
6
|
+
class Tunnel
|
7
|
+
|
8
|
+
attr_accessor :uuid, :name, :parent, :type, :local_host, :local_port, :remote_host, :remote_port, :auto_start
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
@uuid = opts.fetch(:uuid) { SecureRandom.uuid }
|
13
|
+
@name = opts.fetch(:name, '')
|
14
|
+
@parent = opts[:parent]
|
15
|
+
@type = opts[:type]
|
16
|
+
@local_host = opts[:local_host]
|
17
|
+
@local_port = opts[:local_port]
|
18
|
+
@remote_host = opts[:remote_host]
|
19
|
+
@remote_port = opts[:remote_port]
|
20
|
+
@auto_start = opts[:auto_start]
|
21
|
+
@process = nil
|
22
|
+
@started = false
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"#{parent} - #{name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def local_port
|
32
|
+
@local_port.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def remote_port
|
37
|
+
@remote_port.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def to_hash
|
42
|
+
{
|
43
|
+
uuid: uuid,
|
44
|
+
name: name,
|
45
|
+
type: type,
|
46
|
+
local_host: local_host,
|
47
|
+
local_port: @local_port,
|
48
|
+
remote_host: remote_host,
|
49
|
+
remote_port: @remote_port,
|
50
|
+
auto_start: auto_start,
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def auto_start?
|
56
|
+
@auto_start == true
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def auto_start!
|
61
|
+
return false unless auto_start?
|
62
|
+
|
63
|
+
start!
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def started?
|
69
|
+
@started
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def start!
|
74
|
+
return if started?
|
75
|
+
|
76
|
+
SSHTunnel.logger.info "Starting tunnel : #{self}"
|
77
|
+
|
78
|
+
@process = Subprocess.popen(command, stdout: '/dev/null', stderr: '/dev/null', stdin: Subprocess::PIPE)
|
79
|
+
@started = true
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# See: https://www.redhat.com/archives/libvir-list/2007-September/msg00106.html
|
84
|
+
# to avoid zombie when terminating process
|
85
|
+
def stop!
|
86
|
+
return unless started?
|
87
|
+
return if @process.nil?
|
88
|
+
|
89
|
+
SSHTunnel.logger.info "Stopping tunnel : #{self}"
|
90
|
+
|
91
|
+
@process.terminate
|
92
|
+
@process.wait
|
93
|
+
@started = false
|
94
|
+
@process = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def command
|
99
|
+
cmd = [
|
100
|
+
'/usr/bin/ssh',
|
101
|
+
'-N',
|
102
|
+
'-t',
|
103
|
+
'-x',
|
104
|
+
'-o', 'ExitOnForwardFailure=yes',
|
105
|
+
"-l#{parent.user}",
|
106
|
+
"-L#{local_host}:#{local_port}:#{remote_host}:#{remote_port}",
|
107
|
+
"-p#{parent.port}"
|
108
|
+
]
|
109
|
+
|
110
|
+
cmd << "-i#{parent.identity_file}" if parent.identity_file.present?
|
111
|
+
cmd << parent.host
|
112
|
+
cmd
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
class StatusIcon
|
6
|
+
|
7
|
+
def initialize(application, window)
|
8
|
+
@application = application
|
9
|
+
@window = window
|
10
|
+
@status_icon = Gtk::StatusIcon.new
|
11
|
+
@menu = Gtk::Menu.new
|
12
|
+
|
13
|
+
configure_status_icon
|
14
|
+
create_popup_menu
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
|
21
|
+
def configure_status_icon
|
22
|
+
@status_icon.icon_name = 'network-workgroup-symbolic'
|
23
|
+
@status_icon.signal_connect('activate') { |_icon| @window.toggle! }
|
24
|
+
@status_icon.signal_connect('popup-menu') { |_tray, button, time| @menu.popup(nil, nil, button, time) }
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def create_popup_menu
|
29
|
+
# Build menu items
|
30
|
+
info = Gtk::ImageMenuItem.new(label: 'Modifier')
|
31
|
+
info.signal_connect('activate') { @window.show }
|
32
|
+
|
33
|
+
quit = Gtk::ImageMenuItem.new(label: 'Quitter')
|
34
|
+
quit.signal_connect('activate') { @application.quit }
|
35
|
+
|
36
|
+
# Create menu
|
37
|
+
@menu.append(info)
|
38
|
+
@menu.append(Gtk::SeparatorMenuItem.new)
|
39
|
+
@menu.append(quit)
|
40
|
+
@menu.show_all
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
class AboutWindow < Gtk::AboutDialog
|
7
|
+
|
8
|
+
# Register the class in the GLib world
|
9
|
+
type_register
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def init
|
14
|
+
# Set the template from the resources binary
|
15
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/about_window.glade'
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
include SSHTunnel::UI::Helpers::Common::TranslationHelper
|
21
|
+
|
22
|
+
|
23
|
+
def initialize(application)
|
24
|
+
super application: application
|
25
|
+
|
26
|
+
set_title t('window.about')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
class ApplicationWindow < Gtk::ApplicationWindow
|
7
|
+
|
8
|
+
# Register the class in the GLib world
|
9
|
+
type_register
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def init
|
14
|
+
# Set the template from the resources binary
|
15
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/application_window.glade'
|
16
|
+
super
|
17
|
+
|
18
|
+
bind_template_child 'hosts_scrolled_window'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
include SSHTunnel::UI::Helpers::ApplicationWindowHelper
|
24
|
+
|
25
|
+
|
26
|
+
def initialize(application)
|
27
|
+
super application: application
|
28
|
+
|
29
|
+
# Set instance variables
|
30
|
+
@application = application
|
31
|
+
|
32
|
+
# Set window title
|
33
|
+
set_title 'SSH Tunnel Manager'
|
34
|
+
|
35
|
+
# Load hosts treeview
|
36
|
+
load_hosts_treeview
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
module Hosts
|
7
|
+
class DeleteWindow < Gtk::Window
|
8
|
+
|
9
|
+
# Register the class in the GLib world
|
10
|
+
type_register
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def init
|
15
|
+
# Set the template from the resources binary
|
16
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/hosts/delete_window.glade'
|
17
|
+
|
18
|
+
bind_template_child 'button_submit'
|
19
|
+
bind_template_child 'button_cancel'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
include SSHTunnel::UI::Helpers::Common::ModalHelper
|
25
|
+
include SSHTunnel::UI::Helpers::Common::TranslationHelper
|
26
|
+
|
27
|
+
|
28
|
+
def initialize(application, window, host)
|
29
|
+
super
|
30
|
+
|
31
|
+
# Set window title
|
32
|
+
set_title t('window.host.remove', host: host)
|
33
|
+
|
34
|
+
# Set instance variables
|
35
|
+
@host = host
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
|
42
|
+
def bind_submit_button
|
43
|
+
button_submit.label = t('button.submit')
|
44
|
+
button_submit.signal_connect :clicked do
|
45
|
+
@application.config.remove_host(@host)
|
46
|
+
@application.config.save!
|
47
|
+
@window.reload_hosts_treeview
|
48
|
+
close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
module Hosts
|
7
|
+
class EditWindow < Gtk::Window
|
8
|
+
|
9
|
+
# Register the class in the GLib world
|
10
|
+
type_register
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def init
|
15
|
+
# Set the template from the resources binary
|
16
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/hosts/edit_window.glade'
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
include SSHTunnel::UI::Helpers::HostWindowHelper
|
23
|
+
|
24
|
+
|
25
|
+
def initialize(application, window, host)
|
26
|
+
super
|
27
|
+
|
28
|
+
# Set window title
|
29
|
+
set_title t('window.host.edit', host: @host)
|
30
|
+
|
31
|
+
# Fills input fields
|
32
|
+
restore_form_values(@host)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
module Hosts
|
7
|
+
class NewWindow < Gtk::Window
|
8
|
+
|
9
|
+
# Register the class in the GLib world
|
10
|
+
type_register
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def init
|
15
|
+
# Set the template from the resources binary
|
16
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/hosts/new_window.glade'
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
include SSHTunnel::UI::Helpers::HostWindowHelper
|
23
|
+
|
24
|
+
|
25
|
+
def initialize(application, window, host)
|
26
|
+
super
|
27
|
+
|
28
|
+
# Set window title
|
29
|
+
set_title t('window.host.new')
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
|
36
|
+
def save_and_reload_view
|
37
|
+
@application.config.add_host(@host)
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SSHTunnel
|
4
|
+
module UI
|
5
|
+
module Windows
|
6
|
+
module Tunnels
|
7
|
+
class DeleteWindow < Gtk::Window
|
8
|
+
|
9
|
+
# Register the class in the GLib world
|
10
|
+
type_register
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def init
|
15
|
+
# Set the template from the resources binary
|
16
|
+
set_template resource: '/com/ungtb10d/ssh-hull/ui/tunnels/delete_window.glade'
|
17
|
+
|
18
|
+
bind_template_child 'button_submit'
|
19
|
+
bind_template_child 'button_cancel'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
include SSHTunnel::UI::Helpers::Common::ModalHelper
|
25
|
+
include SSHTunnel::UI::Helpers::Common::TranslationHelper
|
26
|
+
|
27
|
+
|
28
|
+
def initialize(application, window, tunnel)
|
29
|
+
super
|
30
|
+
|
31
|
+
# Set window title
|
32
|
+
set_title t('window.tunnel.remove', tunnel: tunnel.name)
|
33
|
+
|
34
|
+
# Set instance variables
|
35
|
+
@tunnel = tunnel
|
36
|
+
@host = tunnel.parent
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
|
43
|
+
def bind_submit_button
|
44
|
+
button_submit.label = t('button.submit')
|
45
|
+
button_submit.signal_connect :clicked do
|
46
|
+
@host.remove_tunnel(@tunnel)
|
47
|
+
@application.config.save!
|
48
|
+
@window.reload_tunnels_treeview(@host)
|
49
|
+
close
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|