tmuxme 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d66f4cedbba19c4a4b0942af1a45749f41437613
4
+ data.tar.gz: f0ab574d9600d278e0676a235f4c8a2c5528e837
5
+ SHA512:
6
+ metadata.gz: 0905c1851374b473116ae596ddf4471842298456e6175db639d68bec1a702c5110f49d27d06a22152787b6f44f431a23c9f5063293de85195e440f696af4d2eb
7
+ data.tar.gz: 64ff7056b16657534275e83973b264a080bc454ad7e1d272fb9fd92a55c25c87383d947c5b8af72ea48dd35c37589397feb568f5cceb1fa4a7a4445810a92e79
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ tmuxme_client
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.0.0-p247
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tmuxme_client.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Andrew De Ponte, ReachLocal Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # TmuxmeClient
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'tmuxme_client'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install tmuxme_client
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/tmuxme ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rest-client'
5
+ require 'net/ssh'
6
+ require 'json'
7
+ require 'thread'
8
+
9
+ Thread.abort_on_exception = true
10
+
11
+ def generate_authorized_keys_content(public_keys)
12
+ cleaned_keys = []
13
+ public_keys.each do |pk|
14
+ cleaned_keys << "command=\"tmux -S /tmp/tmuxme_pair_sock attach\" #{pk.strip}"
15
+ end
16
+ return cleaned_keys.join("\n")
17
+ end
18
+
19
+ if ARGV.length < 1
20
+ puts "You can't pair program with yourself silly."
21
+ puts "Usage: tmuxme user1 [user2...]"
22
+ exit
23
+ end
24
+
25
+ invitees = ARGV.dup
26
+ pairers = []
27
+
28
+ remote_port = nil
29
+ remote_port_lock = Mutex.new
30
+
31
+ begin
32
+ # back up users authorized_keys file
33
+ if !File.exists?("#{ENV['HOME']}/.ssh/authorized_keys.tmuxme.original")
34
+ puts "- Backing up ~/.ssh/authorized_keys to ~/.ssh/authorized_keys.tmuxme.original to store it the first time tmuxme was run"
35
+ FileUtils.cp("#{ENV['HOME']}/.ssh/authorized_keys", "#{ENV['HOME']}/.ssh/authorized_keys.tmuxme.original")
36
+ end
37
+ puts "- Backing up ~/.ssh/authorized_keys to ~/.ssh/authorized_keys.tmuxme.backup"
38
+ FileUtils.cp("#{ENV['HOME']}/.ssh/authorized_keys", "#{ENV['HOME']}/.ssh/authorized_keys.tmuxme.backup")
39
+
40
+ public_keys = []
41
+ # fetch the specified users public keys
42
+ invitees.each do |invitee|
43
+ begin
44
+ response = RestClient.get "http://tmux.me/api/v1/users/#{invitee}/public_keys.json"
45
+ current_invitees_public_keys = JSON.parse(response.to_s)
46
+ if current_invitees_public_keys.empty?
47
+ puts
48
+ puts "Warning: Pair (#{invitee}) does not have any public keys on tmux.me. Ask them to add one."
49
+ else
50
+ pairers << invitee
51
+ public_keys.concat(current_invitees_public_keys)
52
+ end
53
+ rescue => e
54
+ case e.response.code
55
+ when 404
56
+ puts
57
+ puts "Warning: Pair (#{invitee}) is not a tmux.me registered user. Please ask them to signup and add their public key."
58
+ end
59
+ end
60
+ end
61
+
62
+ if public_keys.empty?
63
+ puts
64
+ puts "Error: Either the users you provided don't exist or they don't have keys on tmux.me."
65
+ exit 1
66
+ end
67
+
68
+ # generate the new authorized_keys content from obtained public keys
69
+ content = generate_authorized_keys_content(public_keys)
70
+
71
+ original_authorized_keys_content = File.read("#{ENV['HOME']}/.ssh/authorized_keys")
72
+
73
+ # prepend the generated content to the authorized_keys file
74
+ puts "- Updating ~/.ssh/authorized_keys with (#{pairers.join(', ')}) public keys"
75
+ new_authorized_keys_content = [content, original_authorized_keys_content].join("\n")
76
+ File.open("#{ENV['HOME']}/.ssh/authorized_keys", "w") do |f|
77
+ f.write(new_authorized_keys_content)
78
+ end
79
+
80
+ # setup the remote port forward (need to spin off this in a sep thread)
81
+ Thread.new do
82
+ port = nil
83
+ while true
84
+ # Fetch an un-used high numbered port from the tmux.me REST api.
85
+ remote_port_lock.synchronize {
86
+ remote_port = 6000 + rand(50000)
87
+ port = remote_port
88
+ }
89
+
90
+ begin
91
+ # Starts the tunnel but blocks so would probably need to throw this in a child
92
+ # thread of the process.
93
+ Net::SSH.start("tmux.me", "tunnel") do |ssh|
94
+ ssh.forward.remote(22, "localhost", port, "0.0.0.0")
95
+ ssh.loop { true }
96
+ end
97
+ rescue Exception => e
98
+ puts e.message
99
+ next
100
+ end
101
+ end
102
+ end
103
+
104
+ # launch detached tmux sessions
105
+ `tmux -S /tmp/tmuxme_pair_sock new-session -s tmuxme -d`
106
+
107
+ puts
108
+ puts "E-mail invites will be sent to (#{pairers.join(', ')}) when you press enter below."
109
+ puts "However, to manually invite (#{pairers.join(', ')}) to the pairing session instruct them to run the following:"
110
+ puts
111
+ remote_port_lock.synchronize {
112
+ puts "\tssh #{ENV['USER']}@tmux.me -p #{remote_port}"
113
+ }
114
+ puts
115
+ print "Press enter to invite (#{pairers.join(', ')}) via e-mail and attach to the tmux session."
116
+ $stdout.flush
117
+ garbage = $stdin.gets
118
+
119
+ # notify tmux.me service that the pairing session is ready
120
+ puts "Sending invites to (#{pairers.join(', ')})."
121
+ remote_port_lock.synchronize {
122
+ RestClient.post "http://tmux.me/api/v1/pairing_sessions", :system_user => ENV['USER'], :pairing_users => pairers, :port_number => remote_port
123
+ }
124
+
125
+ # attach to tmux session and wait for that process to exit
126
+ `tmux -S /tmp/tmuxme_pair_sock attach`
127
+ ensure
128
+ puts
129
+ puts "- Restoring ~/.ssh/authorized_keys from ~/.ssh/authorized_keys.tmuxme.backup"
130
+ # when the tmux process exits then restore the authorized_keys file
131
+ FileUtils.cp("#{ENV['HOME']}/.ssh/authorized_keys.tmuxme.backup", "#{ENV['HOME']}/.ssh/authorized_keys")
132
+ end
@@ -0,0 +1,3 @@
1
+ module Tmuxme
2
+ VERSION = "0.0.1"
3
+ end
data/lib/tmuxme.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "tmuxme/version"
2
+
3
+ module Tmuxme
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,95 @@
1
+ #!/bin/sh
2
+
3
+ function getAvailableHiddenUserUid()
4
+ {
5
+ local __UIDS=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -ugr)
6
+ local __NewUID
7
+ for __NewUID in $__UIDS
8
+ do
9
+ if [[ $__NewUID -lt 499 && $__NewUID -ne 498 ]] ; then
10
+ break;
11
+ fi
12
+ done
13
+
14
+ echo $((__NewUID+1))
15
+ }
16
+
17
+ function generateRandomPassword()
18
+ {
19
+ echo `date | md5`
20
+ }
21
+
22
+
23
+ # Make sure only root can run our script
24
+ if [[ $EUID -ne 0 ]]; then
25
+ echo "This script must be run as root" 1>&2
26
+ exit 1
27
+ fi
28
+
29
+ # USER_UID=499 # this should be a number under 500 so it is a hidden account
30
+ USER_UID=$(getAvailableHiddenUserUid)
31
+
32
+ # This script is design to provide a simple mechanism to help with automating
33
+ # the process of creating an account for gitosis to use on systems.
34
+
35
+ # The following are variables which are likely to change per installation.
36
+ USERNAME="tmuxme"
37
+ USER_FULL_NAME="tmuxme"
38
+
39
+ # The following are variables unlikely to change but possibly could change
40
+ # per installation.
41
+ PRIMARY_GID=1000
42
+
43
+ # The following are variables which are highly unlikely to change and may
44
+ # only change for differences in the operating system.
45
+ USER_SHELL="/bin/bash" # Mac OS X 10.5.6
46
+ # LOC_DOMAIN="/Local/Default" # Mac OS X 10.5.6
47
+ LOC_DOMAIN="." # Mac OS X 10.5.6
48
+
49
+ PASSWORD=$(generateRandomPassword)
50
+
51
+ # Tell the system to automatically hide user accounts thate have a UID < 500
52
+ # LOGIN_WIN_PREFS="/Library/Preferences/com.apple.loginwindow"
53
+ # defaults write ${LOGIN_WIN_PREFS} Hide500Users -bool YES
54
+ #
55
+ # Create the user entry.
56
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME}
57
+
58
+ # Set the users shell.
59
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME} UserShell ${USER_SHELL}
60
+
61
+ # Set the users full name.
62
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME} RealName "${USER_FULL_NAME}"
63
+
64
+ # Associate the user with a unique id.
65
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME} UniqueID ${USER_UID}
66
+
67
+ # Associate the user with a primary gorup id.
68
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME} PrimaryGroupID ${PRIMARY_GID}
69
+
70
+ # Create the users home directory.
71
+ dscl ${LOC_DOMAIN} -create /Users/${USERNAME} NFSHomeDirectory /Users/${USERNAME}
72
+
73
+ # Set the users password.
74
+ dscl ${LOC_DOMAIN} -passwd /Users/${USERNAME} ${PASSWORD}
75
+
76
+
77
+ mkdir -p /Users/${USERNAME}/.ssh
78
+ touch /Users/${USERNAME}/.ssh/authorized_keys
79
+ chown -R ${USER_UID}:${PRIMARY_GID} /Users/${USERNAME}
80
+ chmod 0700 /Users/${USERNAME}/.ssh
81
+ chmod 0600 /Users/${USERNAME}/.ssh/authorized_keys
82
+
83
+ # Enable Remote Login if it is not currently enabled.
84
+ systemsetup -setremotelogin on &>/dev/null
85
+
86
+ if [[ $(dscl ${LOC_DOMAIN} list /Groups | grep 'access_ssh') = 'com.apple.access_ssh' ]]; then
87
+ # Remote Access is limted to specific users
88
+ USER_GENERATED_UID=$(dscl . -read /Users/${USERNAME} GeneratedUID | awk '{print $2}')
89
+ dscl ${LOC_DOMAIN} -read /Groups/com.apple.access_ssh GroupMembership | grep ${USERNAME} &>/dev/null
90
+ if [[ $? -ne 0 ]]; then # user is not in access list
91
+ # Append the "tmuxme" user to the list of users allowed to connect remotely
92
+ dscl ${LOC_DOMAIN} -append /Groups/com.apple.access_ssh GroupMembers ${USER_GENERATED_UID}
93
+ dscl ${LOC_DOMAIN} -append /Groups/com.apple.access_ssh GroupMembership ${USERNAME}
94
+ fi
95
+ fi
data/tmuxme.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tmuxme/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tmuxme"
8
+ spec.version = Tmuxme::VERSION
9
+ spec.authors = ["Andrew De Ponte"]
10
+ spec.email = ["cyphactor@gmail.com"]
11
+ spec.description = %q{The official client for the http://tmux.me pair programming service}
12
+ spec.summary = %q{Command line client for the http://tmux.me pairing service.}
13
+ spec.homepage = "http://tmux.me"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency "rest-client", "~> 1.6.7"
25
+ spec.add_dependency "net-ssh", "~> 2.6.8"
26
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tmuxme
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew De Ponte
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-ssh
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.6.8
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.6.8
69
+ description: The official client for the http://tmux.me pair programming service
70
+ email:
71
+ - cyphactor@gmail.com
72
+ executables:
73
+ - tmuxme
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .ruby-gemset
79
+ - .ruby-version
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/tmuxme
85
+ - lib/tmuxme.rb
86
+ - lib/tmuxme/version.rb
87
+ - scripts/tmuxme_install
88
+ - tmuxme.gemspec
89
+ homepage: http://tmux.me
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.0.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Command line client for the http://tmux.me pairing service.
113
+ test_files: []