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.
- data/README.md +34 -2
- data/lib/git_wit/authorized_keys.rb +3 -2
- data/lib/git_wit/shell.rb +59 -16
- data/lib/git_wit/version.rb +1 -1
- data/lib/tasks/git_wit_shell.rake +8 -0
- data/test/dummy/log/development.log +5195 -0
- data/test/dummy/tmp/git/fuck.git/HEAD +1 -0
- data/test/dummy/tmp/git/fuck.git/config +6 -0
- data/test/dummy/tmp/git/fuck.git/description +1 -0
- data/test/dummy/tmp/git/fuck.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/fuck.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/fuck.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/fuck.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/fuck.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/fuck.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/fuck.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/fuck.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/fuck.git/info/exclude +6 -0
- data/test/dummy/tmp/git/lkasdjf.git/HEAD +1 -0
- data/test/dummy/tmp/git/lkasdjf.git/config +6 -0
- data/test/dummy/tmp/git/lkasdjf.git/description +1 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/lkasdjf.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/lkasdjf.git/info/exclude +6 -0
- data/test/dummy/tmp/git/new/test.git/HEAD +1 -0
- data/test/dummy/tmp/git/new/test.git/config +6 -0
- data/test/dummy/tmp/git/new/test.git/description +1 -0
- data/test/dummy/tmp/git/new/test.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/new/test.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/new/test.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/new/test.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/new/test.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/new/test.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/new/test.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/new/test.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/new/test.git/info/exclude +6 -0
- data/test/dummy/tmp/git/testing.git/HEAD +1 -0
- data/test/dummy/tmp/git/testing.git/config +6 -0
- data/test/dummy/tmp/git/testing.git/description +1 -0
- data/test/dummy/tmp/git/testing.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/testing.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/testing.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/testing.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/testing.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/testing.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/testing.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/testing.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/testing.git/info/exclude +6 -0
- data/test/dummy/tmp/git/under_scored/sub.git/HEAD +1 -0
- data/test/dummy/tmp/git/under_scored/sub.git/config +6 -0
- data/test/dummy/tmp/git/under_scored/sub.git/description +1 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/under_scored/sub.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/under_scored/sub.git/info/exclude +6 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/HEAD +1 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/config +6 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/description +1 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/applypatch-msg.sample +15 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/commit-msg.sample +24 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/post-update.sample +8 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-applypatch.sample +14 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-commit.sample +50 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/pre-rebase.sample +169 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/hooks/update.sample +128 -0
- data/test/dummy/tmp/git/work/pls/thnx.git/info/exclude +6 -0
- 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),
|
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
|
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
|
-
|
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
|
-
|
5
|
-
|
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
|
-
|
11
|
-
|
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
|
-
|
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.
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
data/lib/git_wit/version.rb
CHANGED