git_wit 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/README.md +34 -2
  2. data/lib/git_wit/authorized_keys.rb +3 -2
  3. data/lib/git_wit/shell.rb +59 -16
  4. data/lib/git_wit/version.rb +1 -1
  5. data/lib/tasks/git_wit_shell.rake +8 -0
  6. data/test/dummy/log/development.log +5195 -0
  7. data/test/dummy/tmp/git/fuck.git/HEAD +1 -0
  8. data/test/dummy/tmp/git/fuck.git/config +6 -0
  9. data/test/dummy/tmp/git/fuck.git/description +1 -0
  10. data/test/dummy/tmp/git/fuck.git/hooks/applypatch-msg.sample +15 -0
  11. data/test/dummy/tmp/git/fuck.git/hooks/commit-msg.sample +24 -0
  12. data/test/dummy/tmp/git/fuck.git/hooks/post-update.sample +8 -0
  13. data/test/dummy/tmp/git/fuck.git/hooks/pre-applypatch.sample +14 -0
  14. data/test/dummy/tmp/git/fuck.git/hooks/pre-commit.sample +50 -0
  15. data/test/dummy/tmp/git/fuck.git/hooks/pre-rebase.sample +169 -0
  16. data/test/dummy/tmp/git/fuck.git/hooks/prepare-commit-msg.sample +36 -0
  17. data/test/dummy/tmp/git/fuck.git/hooks/update.sample +128 -0
  18. data/test/dummy/tmp/git/fuck.git/info/exclude +6 -0
  19. data/test/dummy/tmp/git/lkasdjf.git/HEAD +1 -0
  20. data/test/dummy/tmp/git/lkasdjf.git/config +6 -0
  21. data/test/dummy/tmp/git/lkasdjf.git/description +1 -0
  22. data/test/dummy/tmp/git/lkasdjf.git/hooks/applypatch-msg.sample +15 -0
  23. data/test/dummy/tmp/git/lkasdjf.git/hooks/commit-msg.sample +24 -0
  24. data/test/dummy/tmp/git/lkasdjf.git/hooks/post-update.sample +8 -0
  25. data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-applypatch.sample +14 -0
  26. data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-commit.sample +50 -0
  27. data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-rebase.sample +169 -0
  28. data/test/dummy/tmp/git/lkasdjf.git/hooks/prepare-commit-msg.sample +36 -0
  29. data/test/dummy/tmp/git/lkasdjf.git/hooks/update.sample +128 -0
  30. data/test/dummy/tmp/git/lkasdjf.git/info/exclude +6 -0
  31. data/test/dummy/tmp/git/new/test.git/HEAD +1 -0
  32. data/test/dummy/tmp/git/new/test.git/config +6 -0
  33. data/test/dummy/tmp/git/new/test.git/description +1 -0
  34. data/test/dummy/tmp/git/new/test.git/hooks/applypatch-msg.sample +15 -0
  35. data/test/dummy/tmp/git/new/test.git/hooks/commit-msg.sample +24 -0
  36. data/test/dummy/tmp/git/new/test.git/hooks/post-update.sample +8 -0
  37. data/test/dummy/tmp/git/new/test.git/hooks/pre-applypatch.sample +14 -0
  38. data/test/dummy/tmp/git/new/test.git/hooks/pre-commit.sample +50 -0
  39. data/test/dummy/tmp/git/new/test.git/hooks/pre-rebase.sample +169 -0
  40. data/test/dummy/tmp/git/new/test.git/hooks/prepare-commit-msg.sample +36 -0
  41. data/test/dummy/tmp/git/new/test.git/hooks/update.sample +128 -0
  42. data/test/dummy/tmp/git/new/test.git/info/exclude +6 -0
  43. data/test/dummy/tmp/git/testing.git/HEAD +1 -0
  44. data/test/dummy/tmp/git/testing.git/config +6 -0
  45. data/test/dummy/tmp/git/testing.git/description +1 -0
  46. data/test/dummy/tmp/git/testing.git/hooks/applypatch-msg.sample +15 -0
  47. data/test/dummy/tmp/git/testing.git/hooks/commit-msg.sample +24 -0
  48. data/test/dummy/tmp/git/testing.git/hooks/post-update.sample +8 -0
  49. data/test/dummy/tmp/git/testing.git/hooks/pre-applypatch.sample +14 -0
  50. data/test/dummy/tmp/git/testing.git/hooks/pre-commit.sample +50 -0
  51. data/test/dummy/tmp/git/testing.git/hooks/pre-rebase.sample +169 -0
  52. data/test/dummy/tmp/git/testing.git/hooks/prepare-commit-msg.sample +36 -0
  53. data/test/dummy/tmp/git/testing.git/hooks/update.sample +128 -0
  54. data/test/dummy/tmp/git/testing.git/info/exclude +6 -0
  55. data/test/dummy/tmp/git/under_scored/sub.git/HEAD +1 -0
  56. data/test/dummy/tmp/git/under_scored/sub.git/config +6 -0
  57. data/test/dummy/tmp/git/under_scored/sub.git/description +1 -0
  58. data/test/dummy/tmp/git/under_scored/sub.git/hooks/applypatch-msg.sample +15 -0
  59. data/test/dummy/tmp/git/under_scored/sub.git/hooks/commit-msg.sample +24 -0
  60. data/test/dummy/tmp/git/under_scored/sub.git/hooks/post-update.sample +8 -0
  61. data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-applypatch.sample +14 -0
  62. data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-commit.sample +50 -0
  63. data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-rebase.sample +169 -0
  64. data/test/dummy/tmp/git/under_scored/sub.git/hooks/prepare-commit-msg.sample +36 -0
  65. data/test/dummy/tmp/git/under_scored/sub.git/hooks/update.sample +128 -0
  66. data/test/dummy/tmp/git/under_scored/sub.git/info/exclude +6 -0
  67. data/test/dummy/tmp/git/work/pls/thnx.git/HEAD +1 -0
  68. data/test/dummy/tmp/git/work/pls/thnx.git/config +6 -0
  69. data/test/dummy/tmp/git/work/pls/thnx.git/description +1 -0
  70. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/applypatch-msg.sample +15 -0
  71. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/commit-msg.sample +24 -0
  72. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/post-update.sample +8 -0
  73. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-applypatch.sample +14 -0
  74. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-commit.sample +50 -0
  75. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-rebase.sample +169 -0
  76. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/prepare-commit-msg.sample +36 -0
  77. data/test/dummy/tmp/git/work/pls/thnx.git/hooks/update.sample +128 -0
  78. data/test/dummy/tmp/git/work/pls/thnx.git/info/exclude +6 -0
  79. metadata +150 -5
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # GitWit
2
2
 
3
3
  [![Build Status](https://travis-ci.org/xdissent/git_wit.png?branch=master)](https://travis-ci.org/xdissent/git_wit)
4
+ [![Gem Version](https://badge.fury.io/rb/git_wit.png)](http://badge.fury.io/rb/git_wit)
4
5
 
5
6
  Dead simple Git hosting for Rails apps.
6
7
 
@@ -83,12 +84,43 @@ Your server will ask you for a username and password when you push - use
83
84
  `writer` for both and it should accept your changes.
84
85
 
85
86
 
87
+ ## SSL
88
+
89
+ You **really** should turn `insecure_auth` and `insecure_write` back to `false`
90
+ as quickly as possible and enable SSL for read/write access. GitWit doesn't
91
+ need any special SSL configuration - just flip SSL on in whatever web server
92
+ is running Rails. You can also use the
93
+ [tunnels](https://github.com/jugyo/tunnels) gem to run your app with SSL in
94
+ development. Just add it to the Gemfile and run `bundle install` followed by
95
+ `sudo tunnels` (or `rvmsudo tunnels` for RVM). For `rails s`, which runs on
96
+ port 3000 by default, run `sudo tunnels 443 3000`. Now you may clone
97
+ repositories over HTTPS:
98
+
99
+ ```console
100
+ $ git clone https://localhost/example.git
101
+ ```
102
+
103
+
104
+ ## A quick note about "local requests"
105
+
106
+ The default Rails development environment has a config value called
107
+ `consider_all_requests_local`, which is `true`. This prevents GitWit from
108
+ correctly handling authentication responses in some cases. It's not a big deal,
109
+ you'll just be asked to re-authenticate more often and some responses will be
110
+ slightly misleading. But the alternative solution, which is to set
111
+ `consider_all_requests_local` to `false`, disables any special Rails error
112
+ handling - quite a bummer for development. It would be nice to sort this out a
113
+ little better in the future. Note that the production environment uses `false`
114
+ by default and handles errors appropriately.
115
+
116
+
86
117
  ## Advanced Usage (Devise, Cancan, etc.)
87
118
 
88
119
  See [`test/dummy`](https://github.com/xdissent/git_wit/tree/master/test/dummy)
89
120
  for an example app that integrates
90
121
  [Devise](https://github.com/plataformatec/devise),
91
- [Cancan](https://github.com/ryanb/cancan), and
122
+ [Cancan](https://github.com/ryanb/cancan),
123
+ [rolify](https://github.com/EppO/rolify) and
92
124
  [twitter-bootstrap-rails](https://github.com/seyhunak/twitter-bootstrap-rails).
93
125
  Example controllers for managing repositories and public keys are included.
94
126
 
@@ -96,7 +128,7 @@ Example controllers for managing repositories and public keys are included.
96
128
  ## SSH support - AKA: The hard part
97
129
 
98
130
  To enable git operations over SSH, you **must have a dedicated SSH user**. This
99
- user will *only* be used for SSH autentication. Immediately after successfully
131
+ user will *only* be used for SSH authentication. Immediately after successfully
100
132
  authenticating, the SSH user will `sudo` to the application user to continue
101
133
  with the git operation. This eliminates the need for all the bat-shit crazy git
102
134
  pulls/pushes and SSH wrappers and crap that are typical of gitolite/gitosis
@@ -92,9 +92,10 @@ module GitWit
92
92
  SHELL_OPTIONS = %w(no-port-forwarding no-X11-forwarding
93
93
  no-agent-forwarding no-pty)
94
94
 
95
- def self.shell_key_for_username(username, key)
95
+ def self.shell_key_for_username(username, key, debug = false)
96
96
  key = self.new key if key.is_a? String
97
- key.options = [%(command="gw-shell #{username}"), *SHELL_OPTIONS]
97
+ debug = debug ? "--debug " : ""
98
+ key.options = [%(command="gw-shell #{debug}#{username}"), *SHELL_OPTIONS]
98
99
  key
99
100
  end
100
101
  end
data/lib/git_wit/shell.rb CHANGED
@@ -1,18 +1,33 @@
1
1
  module GitWit
2
2
  module Shell
3
3
  SHELL_COMMANDS = %w(git-upload-pack git-receive-pack git-upload-archive)
4
- SUDO_ENV_KEYS = %w(SSH_ORIGINAL_COMMAND GEM_HOME GEM_PATH PATH
5
- BUNDLE_GEMFILE RAILS_ENV)
4
+
5
+ def self.run
6
+ exec_with_sudo!
7
+ return run_debug if debug?
8
+ boot_app
9
+ command, repository = parse_ssh_original_command
10
+ user = authenticate! ARGV[0]
11
+ authorize! command, user, repository
12
+
13
+ repo_path = File.expand_path File.join(GitWit.repositories_path, repository)
14
+ cmd = ["git", "shell", "-c", "#{command} '#{repo_path}'"]
15
+ Rails.logger.info "GitWit SSH command: #{cmd.join " "}"
16
+ exec *cmd
17
+ end
6
18
 
7
19
  def self.exec_with_sudo!(user = app_user)
8
20
  return if running_as?(user)
9
21
  Dir.chdir rails_root
10
- env = SUDO_ENV_KEYS.map { |k| "#{k}=#{ENV[k]}" if ENV[k] }.compact
11
- env << "RAILS_ROOT=#{rails_root}" << "TERM=dumb"
12
- cmd = ["sudo", "-u", "##{app_user}", *env, "-s", $PROGRAM_NAME, *ARGV]
22
+ ENV["TERM"] = "dumb"
23
+ cmd = ["sudo", "-u", "##{app_user}", $PROGRAM_NAME, *ARGV]
13
24
  exec *cmd
14
25
  end
15
26
 
27
+ def self.debug?
28
+ ARGV.include? "--debug"
29
+ end
30
+
16
31
  def self.running_as?(user)
17
32
  Process.uid == user
18
33
  end
@@ -33,7 +48,9 @@ module GitWit
33
48
 
34
49
  def self.parse_ssh_original_command
35
50
  /^(?<cmd>git-[^\s]+)\s+'(?<repository>[^']+\.git)'/ =~ ENV["SSH_ORIGINAL_COMMAND"]
36
- abort "Uknown command #{cmd}" unless SHELL_COMMANDS.include? cmd
51
+ unless SHELL_COMMANDS.include? cmd
52
+ abort "Unknown command: #{ENV["SSH_ORIGINAL_COMMAND"]}"
53
+ end
37
54
  [cmd, repository]
38
55
  end
39
56
 
@@ -56,17 +73,43 @@ module GitWit
56
73
  abort "Unauthorized" unless authorize command, user, repository
57
74
  end
58
75
 
59
- def self.run
60
- exec_with_sudo!
61
- boot_app
62
- command, repository = parse_ssh_original_command
63
- user = authenticate! ARGV[0]
64
- authorize! command, user, repository
76
+ def self.run_debug
77
+ require "pp"
78
+ puts "*** GitWit DEBUG ***\n\n"
79
+ puts "ENVIRONMENT:"
80
+ pp ENV
81
+ puts "\n*** GitWit DEBUG ***\n"
82
+ end
83
+ end
65
84
 
66
- repo_path = File.expand_path File.join(GitWit.repositories_path, repository)
67
- cmd = ["git", "shell", "-c", "#{command} '#{repo_path}'"]
68
- Rails.logger.info "GitWit SSH command: #{cmd.join " "}"
69
- exec *cmd
85
+ def self.run_shell_test(quiet = true)
86
+ success = false
87
+ Dir.mktmpdir do |ssh|
88
+ user = "git_wit_shell_test"
89
+ key_file = File.join ssh, "id_rsa"
90
+ pub_key_file = "#{key_file}.pub"
91
+
92
+ cmd = %(ssh-keygen -q -t rsa -C "#{user}" -f "#{key_file}" -N "")
93
+ puts "Running #{cmd}" unless quiet
94
+ `#{cmd}`
95
+
96
+ pub_key = File.open(pub_key_file) { |f| f.read }
97
+ debug_key = AuthorizedKeys::Key.shell_key_for_username user, pub_key, true
98
+ authorized_keys_file.add debug_key
99
+ puts "Added key: #{debug_key}" unless quiet
100
+
101
+ cmd = %(SSH_AUTH_SOCK="" ssh -i "#{key_file}" #{GitWit.ssh_user}@localhost test 123)
102
+ puts "Running #{cmd}" unless quiet
103
+ out = `#{cmd}`
104
+ puts out unless quiet
105
+ success = $?.success?
106
+ if success
107
+ puts "Success" unless quiet
108
+ else
109
+ puts "ERROR!" unless quiet
110
+ end
111
+ authorized_keys_file.remove debug_key
70
112
  end
113
+ success
71
114
  end
72
115
  end
@@ -1,3 +1,3 @@
1
1
  module GitWit
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,8 @@
1
+ namespace :git_wit do
2
+ namespace :shell do
3
+ desc "Debug the ssh shell"
4
+ task test: :environment do
5
+ GitWit.run_shell_test(false)
6
+ end
7
+ end
8
+ end