git_handler 0.2.1 → 0.2.2
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.
- data/.travis.yml +2 -1
- data/Gemfile +1 -1
- data/LICENSE +18 -0
- data/README.md +2 -9
- data/examples/readonly.rb +20 -0
- data/examples/simple.rb +12 -0
- data/git_handler.gemspec +7 -7
- data/lib/git_handler.rb +1 -0
- data/lib/git_handler/authorized_keys.rb +21 -25
- data/lib/git_handler/configuration.rb +33 -8
- data/lib/git_handler/git_command.rb +31 -7
- data/lib/git_handler/public_key.rb +9 -0
- data/lib/git_handler/request.rb +38 -1
- data/lib/git_handler/session.rb +25 -10
- data/lib/git_handler/version.rb +1 -1
- data/spec/command_spec.rb +33 -15
- data/spec/configuration_spec.rb +12 -0
- data/spec/session_spec.rb +33 -8
- metadata +81 -59
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2012-2013 Dan Sosedoff <dan.sosedoff@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# GitHandler [](http://travis-ci.org/sosedoff/git-handler)
|
2
2
|
|
3
|
-
|
4
|
-
application-based control layer for Git request processing.
|
3
|
+
Accept and handle git repository requests over SSH
|
5
4
|
|
6
5
|
## Installation
|
7
6
|
|
@@ -220,10 +219,4 @@ rake test
|
|
220
219
|
|
221
220
|
## License
|
222
221
|
|
223
|
-
|
224
|
-
|
225
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
226
|
-
|
227
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
228
|
-
|
229
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
222
|
+
See LICENSE file for details
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'git_handler'
|
3
|
+
|
4
|
+
config = GitHandler::Configuration.new
|
5
|
+
|
6
|
+
begin
|
7
|
+
session = GitHandler::Session.new(config)
|
8
|
+
session.execute(ARGV.dup, ENV.dup.to_hash) do |req|
|
9
|
+
unless req.read
|
10
|
+
STDERR.puts "Readonly"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Now, replace current process with git shell
|
16
|
+
exec('git-shell', '-c', req.command)
|
17
|
+
rescue Exception => ex
|
18
|
+
STDERR.puts "Error: #{ex.message}"
|
19
|
+
exit(1)
|
20
|
+
end
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'git_handler'
|
3
|
+
|
4
|
+
config = GitHandler::Configuration.new
|
5
|
+
|
6
|
+
begin
|
7
|
+
session = GitHandler::Session.new(config)
|
8
|
+
session.execute(ARGV.dup, ENV.dup.to_hash)
|
9
|
+
rescue Exception => ex
|
10
|
+
STDERR.puts "Error: #{ex.message}"
|
11
|
+
exit(1)
|
12
|
+
end
|
data/git_handler.gemspec
CHANGED
@@ -3,17 +3,17 @@ require File.expand_path('../lib/git_handler/version', __FILE__)
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "git_handler"
|
5
5
|
s.version = GitHandler::VERSION
|
6
|
-
s.summary = "
|
7
|
-
s.description = "
|
8
|
-
s.homepage = "http://github.com/sosedoff/
|
6
|
+
s.summary = "Library to handle git requests over SSH"
|
7
|
+
s.description = "Library to handle git requests over SSH"
|
8
|
+
s.homepage = "http://github.com/sosedoff/git-handler"
|
9
9
|
s.authors = ["Dan Sosedoff"]
|
10
10
|
s.email = ["dan.sosedoff@gmail.com"]
|
11
11
|
|
12
|
-
s.add_development_dependency 'rake', '~> 0
|
13
|
-
s.add_development_dependency 'rspec', '~> 2.
|
14
|
-
s.add_development_dependency 'simplecov', '~> 0.
|
12
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
13
|
+
s.add_development_dependency 'rspec', '~> 2.13'
|
14
|
+
s.add_development_dependency 'simplecov', '~> 0.7'
|
15
15
|
|
16
|
-
s.add_runtime_dependency 'sshkey', '~> 1.
|
16
|
+
s.add_runtime_dependency 'sshkey', '~> 1.5'
|
17
17
|
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/git_handler.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
module GitHandler
|
2
2
|
module AuthorizedKeys
|
3
|
+
# Write formatted keys content to file
|
4
|
+
# @param path [String] path path to authorized_keys file
|
5
|
+
# @param keys [Array<PublicKey>] public key objects
|
6
|
+
# @param command [String] custom command for the key
|
7
|
+
def self.write_keys(path, keys, command)
|
8
|
+
content = keys.map { |k| k.to_system_key(command) }.join("\n").strip
|
9
|
+
self.write(path, content)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Write a single key formatted content to file
|
13
|
+
# @param path [String] authorized keys file path
|
14
|
+
# @param key [PublicKey] public key object
|
15
|
+
# @param command [String] custom command for the key
|
16
|
+
def self.write_key(path, key, command)
|
17
|
+
self.write_keys(path, [key], command)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
3
22
|
# Write contents to file with lock
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# content - String buffer
|
7
|
-
#
|
23
|
+
# @param path [String] output file path
|
24
|
+
# @param content [String] key content
|
8
25
|
def self.write(path, content)
|
9
26
|
raise ArgumentError, "File \"#{path}\" does not exist." if !File.exists?(path)
|
10
27
|
raise ArgumentError, "File \"#{path}\" is not writable." if !File.writable?(path)
|
@@ -15,26 +32,5 @@ module GitHandler
|
|
15
32
|
f.flock(File::LOCK_UN)
|
16
33
|
end
|
17
34
|
end
|
18
|
-
|
19
|
-
# Write formatted keys content to file
|
20
|
-
#
|
21
|
-
# path - Path to authorized_keys file
|
22
|
-
# keys - Array of GitHandler::PublicKey instances
|
23
|
-
# command - A custom command for the key
|
24
|
-
#
|
25
|
-
def self.write_keys(path, keys, command)
|
26
|
-
content = keys.map { |k| k.to_system_key(command) }.join("\n").strip
|
27
|
-
self.write(path, content)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Write a single key formatted content to file
|
31
|
-
#
|
32
|
-
# path - Path to the output file
|
33
|
-
# key - GitHandler::PublicKey instance
|
34
|
-
# command - A custom command for the key
|
35
|
-
#
|
36
|
-
def self.write_key(path, key, command)
|
37
|
-
self.write_keys(path, [key], command)
|
38
|
-
end
|
39
35
|
end
|
40
36
|
end
|
@@ -1,23 +1,48 @@
|
|
1
1
|
module GitHandler
|
2
2
|
class Configuration
|
3
|
+
DEFAULT_USER = 'git'
|
4
|
+
DEFAULT_HOME = '/home/git'
|
5
|
+
|
6
|
+
# @return [String] Git user name
|
3
7
|
attr_reader :user
|
8
|
+
|
9
|
+
# @return [String] Full path to home directory
|
4
10
|
attr_reader :home_path
|
11
|
+
|
12
|
+
# @return [String] Full path to repositories directory
|
5
13
|
attr_reader :repos_path
|
14
|
+
|
15
|
+
# @return [String] Full path to log file
|
6
16
|
attr_reader :log_path
|
7
17
|
|
18
|
+
# @return [Boolean] Log requests
|
19
|
+
attr_reader :log
|
20
|
+
|
21
|
+
# @return [Boolean] Raise errors for home and repository path
|
22
|
+
attr_reader :raise_errors
|
23
|
+
|
8
24
|
# Initialize a new Configuration instance with options hash
|
9
25
|
#
|
10
26
|
# Valid options:
|
11
|
-
# :user
|
12
|
-
# :home_path
|
13
|
-
# :repos_path
|
14
|
-
# :
|
27
|
+
# :user - Git user (git)
|
28
|
+
# :home_path - Git user home path (/home/git)
|
29
|
+
# :repos_path - Path to repositories (/home/git/repositories)
|
30
|
+
# :log - Log requests (true)
|
31
|
+
# :log_path - Git access log path (/home/git/access.log)
|
32
|
+
# :raise_errors - Raise errors (true)
|
15
33
|
#
|
34
|
+
# @param [Hash] options options hash
|
16
35
|
def initialize(options={})
|
17
|
-
@user
|
18
|
-
@home_path
|
19
|
-
@repos_path
|
20
|
-
@log_path
|
36
|
+
@user = options[:user] || DEFAULT_USER
|
37
|
+
@home_path = options[:home_path] || DEFAULT_HOME
|
38
|
+
@repos_path = options[:repos_path] || File.join(@home_path, 'repositories')
|
39
|
+
@log_path = options[:log_path] || File.join(@home_path, 'access.log')
|
40
|
+
|
41
|
+
@log = true
|
42
|
+
@raise_errors = true
|
43
|
+
|
44
|
+
@log = false if options[:log] == false
|
45
|
+
@raise_errors = false if options[:raise_errors] == false
|
21
46
|
end
|
22
47
|
end
|
23
48
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module GitHandler
|
2
2
|
module GitCommand
|
3
|
-
GIT_COMMAND = /\A(git
|
3
|
+
GIT_COMMAND = /\A(git[-|\s]upload-pack|git[-|\s]upload-archive|git[-|\s]receive-pack) '(.*)'\z/
|
4
|
+
GIT_REPO = /\A[a-z\d\-\_\.]{1,128}.git?\z/i
|
4
5
|
|
5
6
|
COMMANDS_READONLY = [
|
6
7
|
'git-upload-pack',
|
@@ -14,6 +15,9 @@ module GitHandler
|
|
14
15
|
'git receive-pack'
|
15
16
|
]
|
16
17
|
|
18
|
+
# Parse original git command
|
19
|
+
# @param [String] cmd git command string
|
20
|
+
# @return [Hash] parse result
|
17
21
|
def parse_command(cmd)
|
18
22
|
unless valid_command?(cmd)
|
19
23
|
raise ParseError, "Invalid command: #{cmd}"
|
@@ -23,6 +27,10 @@ module GitHandler
|
|
23
27
|
action = match.first
|
24
28
|
repo = match.last
|
25
29
|
|
30
|
+
unless valid_repository?(repo)
|
31
|
+
raise ParseError, "Invalid repository: #{repo}"
|
32
|
+
end
|
33
|
+
|
26
34
|
{
|
27
35
|
:action => action,
|
28
36
|
:repo => repo,
|
@@ -31,16 +39,32 @@ module GitHandler
|
|
31
39
|
}
|
32
40
|
end
|
33
41
|
|
34
|
-
|
35
|
-
|
42
|
+
# Check if valid git command
|
43
|
+
# @param [String] str command string
|
44
|
+
# @return [Boolean]
|
45
|
+
def valid_command?(str)
|
46
|
+
str =~ GIT_COMMAND ? true : false
|
36
47
|
end
|
37
48
|
|
38
|
-
|
39
|
-
|
49
|
+
# Check if read command
|
50
|
+
# @param [String] str command string
|
51
|
+
# @return [Boolean]
|
52
|
+
def read_command?(str)
|
53
|
+
COMMANDS_READONLY.include?(str)
|
40
54
|
end
|
41
55
|
|
42
|
-
|
43
|
-
|
56
|
+
# Check if write command
|
57
|
+
# @param [String] str command string
|
58
|
+
# @return [Boolean]
|
59
|
+
def write_command?(str)
|
60
|
+
COMMANDS_WRITE.include?(str)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Check if repository name is valid
|
64
|
+
# @param [String] name repository name
|
65
|
+
# @return [Boolean]
|
66
|
+
def valid_repository?(name)
|
67
|
+
name =~ GIT_REPO ? true : false
|
44
68
|
end
|
45
69
|
end
|
46
70
|
end
|
@@ -22,18 +22,27 @@ module GitHandler
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# Check if public key contents is valid
|
26
|
+
# @return [Boolean]
|
25
27
|
def valid?
|
26
28
|
SSHKey.valid_ssh_public_key?(@content)
|
27
29
|
end
|
28
30
|
|
31
|
+
# Get public key MD5 checksum
|
32
|
+
# @return [String]
|
29
33
|
def md5
|
30
34
|
Digest::MD5.hexdigest(@content)
|
31
35
|
end
|
32
36
|
|
37
|
+
# Get public key SHA1 checksum
|
38
|
+
# @return [String]
|
33
39
|
def sha1
|
34
40
|
Digest::SHA1.hexdigest(@content)
|
35
41
|
end
|
36
42
|
|
43
|
+
# Convert public key to system key with arbitrary command
|
44
|
+
# @param [String] command arbitrary command
|
45
|
+
# @return [String]
|
37
46
|
def to_system_key(command)
|
38
47
|
"command=\"#{command}\",#{COMMAND_OPTIONS.join(",")} #{@content}"
|
39
48
|
end
|
data/lib/git_handler/request.rb
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
3
|
module GitHandler
|
4
|
-
class Request
|
4
|
+
class Request
|
5
|
+
# @return [String] Remote IP address
|
6
|
+
attr_reader :remote_ip
|
7
|
+
|
8
|
+
# @return [Array] Request arguments
|
9
|
+
attr_reader :args
|
10
|
+
|
11
|
+
# @return [Hash] Request environment
|
12
|
+
attr_reader :env
|
13
|
+
|
14
|
+
# @return [String] Git command
|
15
|
+
attr_reader :command
|
16
|
+
|
17
|
+
# @return [Boolean] Read command flag
|
18
|
+
attr_reader :read
|
19
|
+
|
20
|
+
# @return [Boolean] Write command flag
|
21
|
+
attr_reader :write
|
22
|
+
|
23
|
+
# @return [Boolean] Git repository name
|
24
|
+
attr_reader :repo
|
25
|
+
|
26
|
+
# @return [String] Repository path
|
27
|
+
attr_reader :repo_path
|
28
|
+
|
29
|
+
# Initialize a new Request instance
|
30
|
+
# @param [Hash] options request options
|
31
|
+
def initialize(options={})
|
32
|
+
@remote_ip = options[:remote_ip]
|
33
|
+
@args = options[:args]
|
34
|
+
@env = options[:env]
|
35
|
+
@command = options[:command]
|
36
|
+
@read = options[:read]
|
37
|
+
@write = options[:write]
|
38
|
+
@repo = options[:repo]
|
39
|
+
@repo_path = options[:repo_path]
|
40
|
+
end
|
41
|
+
end
|
5
42
|
end
|
data/lib/git_handler/session.rb
CHANGED
@@ -14,16 +14,18 @@ module GitHandler
|
|
14
14
|
raise SessionError, 'Configuration required!'
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
if config.raise_errors == true
|
18
|
+
unless File.exists?(config.home_path)
|
19
|
+
raise ConfigurationError, "Home path does not exist!"
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
unless File.exists?(config.repos_path)
|
23
|
+
raise ConfigurationError, "Repositories path does not exist!"
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
@config = config
|
26
|
-
@log
|
28
|
+
@log = Logger.new(@config.log_path)
|
27
29
|
end
|
28
30
|
|
29
31
|
# Execute session
|
@@ -51,10 +53,14 @@ module GitHandler
|
|
51
53
|
:write => command[:write]
|
52
54
|
)
|
53
55
|
|
54
|
-
|
56
|
+
if config.log == true
|
57
|
+
log_request(request)
|
58
|
+
end
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
if config.raise_errors == true
|
61
|
+
unless File.exist?(request.repo_path)
|
62
|
+
raise SessionError, "Repository #{request.repo} does not exist!"
|
63
|
+
end
|
58
64
|
end
|
59
65
|
|
60
66
|
if block_given?
|
@@ -103,11 +109,13 @@ module GitHandler
|
|
103
109
|
end
|
104
110
|
|
105
111
|
# Check if session environment is valid
|
112
|
+
# @return [Boolean]
|
106
113
|
def valid_environment?
|
107
114
|
env['USER'] == config.user && env['HOME'] == config.home_path
|
108
115
|
end
|
109
116
|
|
110
117
|
# Check if session request is valid
|
118
|
+
# @return [Boolean]
|
111
119
|
def valid_request?
|
112
120
|
if env.include_all?(['SSH_CLIENT', 'SSH_CONNECTION', 'SSH_ORIGINAL_COMMAND'])
|
113
121
|
if valid_command?(env['SSH_ORIGINAL_COMMAND'])
|
@@ -119,8 +127,15 @@ module GitHandler
|
|
119
127
|
|
120
128
|
private
|
121
129
|
|
130
|
+
# Log incoming request details
|
131
|
+
# @param req [Request] request instance
|
132
|
+
#
|
133
|
+
# Example output:
|
134
|
+
# I, [2012-10-19T22:54:11.402583 #4212] INFO -- : 10.0.0.1 "git-upload-pack 'PATH'" arg1 arg2
|
135
|
+
#
|
122
136
|
def log_request(req)
|
123
|
-
|
137
|
+
message = [req.remote_ip, req.command, req.args.join(' ')].join(' ')
|
138
|
+
log.info(message)
|
124
139
|
end
|
125
140
|
end
|
126
141
|
end
|
data/lib/git_handler/version.rb
CHANGED
data/spec/command_spec.rb
CHANGED
@@ -17,6 +17,34 @@ describe GitHandler::GitCommand do
|
|
17
17
|
command.valid_command?("git-receive-pack 'repo'\ngit-upload-pack 'repo'").should be_false
|
18
18
|
end
|
19
19
|
|
20
|
+
it 'detects a valid git repository' do
|
21
|
+
command.valid_repository?('repo.git').should be_true
|
22
|
+
command.valid_repository?('repo123456.git').should be_true
|
23
|
+
command.valid_repository?('repo-name.git').should be_true
|
24
|
+
command.valid_repository?('repo_name.git').should be_true
|
25
|
+
command.valid_repository?('repo.name.git').should be_true
|
26
|
+
command.valid_repository?('repo.name.git.git').should be_true
|
27
|
+
|
28
|
+
command.valid_repository?('repo').should be_false
|
29
|
+
command.valid_repository?("repo\nname.git").should be_false
|
30
|
+
command.valid_repository?("repo&.name.git").should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'detects read command' do
|
34
|
+
command.read_command?('git-receive-pack').should be_false
|
35
|
+
command.read_command?('git-upload-pack').should be_true
|
36
|
+
command.read_command?('git upload-pack').should be_true
|
37
|
+
command.read_command?('git-upload-archive').should be_true
|
38
|
+
command.read_command?('git upload-archive').should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'detects write command' do
|
42
|
+
command.write_command?("git-upload-pack").should be_false
|
43
|
+
command.write_command?("git-upload-archive").should be_false
|
44
|
+
command.write_command?("git receive-pack").should be_true
|
45
|
+
command.write_command?("git-receive-pack").should be_true
|
46
|
+
end
|
47
|
+
|
20
48
|
context '.parse_command' do
|
21
49
|
it 'raises error on invalid git command' do
|
22
50
|
proc { command.parse_command("invalid command") }.
|
@@ -26,6 +54,11 @@ describe GitHandler::GitCommand do
|
|
26
54
|
should_not raise_error GitHandler::ParseError
|
27
55
|
end
|
28
56
|
|
57
|
+
it 'raises an error on invalid repository name' do
|
58
|
+
proc { command.parse_command("git-receive-pack 'invalid-repo'") }.
|
59
|
+
should raise_error GitHandler::ParseError, "Invalid repository: invalid-repo"
|
60
|
+
end
|
61
|
+
|
29
62
|
it 'returns a proper action and repo' do
|
30
63
|
result = command.parse_command("git-receive-pack 'repo.git'")
|
31
64
|
result.should be_a Hash
|
@@ -37,19 +70,4 @@ describe GitHandler::GitCommand do
|
|
37
70
|
)
|
38
71
|
end
|
39
72
|
end
|
40
|
-
|
41
|
-
it 'detects read command' do
|
42
|
-
command.read_command?('git-receive-pack').should be_false
|
43
|
-
command.read_command?('git-upload-pack').should be_true
|
44
|
-
command.read_command?('git upload-pack').should be_true
|
45
|
-
command.read_command?('git-upload-archive').should be_true
|
46
|
-
command.read_command?('git upload-archive').should be_true
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'detects write command' do
|
50
|
-
command.write_command?("git-upload-pack").should be_false
|
51
|
-
command.write_command?("git-upload-archive").should be_false
|
52
|
-
command.write_command?("git receive-pack").should be_true
|
53
|
-
command.write_command?("git-receive-pack").should be_true
|
54
|
-
end
|
55
73
|
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -7,5 +7,17 @@ describe GitHandler::Configuration do
|
|
7
7
|
config.home_path.should eq('/home/git')
|
8
8
|
config.repos_path.should eq('/home/git/repositories')
|
9
9
|
config.log_path.should eq('/home/git/access.log')
|
10
|
+
config.raise_errors.should be_true
|
11
|
+
config.log.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should disable error checks' do
|
15
|
+
config = GitHandler::Configuration.new(:raise_errors => false)
|
16
|
+
config.raise_errors.should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should disable logger' do
|
20
|
+
config = GitHandler::Configuration.new(:log => false)
|
21
|
+
config.log.should be_false
|
10
22
|
end
|
11
23
|
end
|
data/spec/session_spec.rb
CHANGED
@@ -12,16 +12,41 @@ describe GitHandler::Session do
|
|
12
12
|
should raise_error GitHandler::SessionError, 'Configuration required!'
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
context 'with error checks' do
|
16
|
+
it 'raises error if home path does not exist' do
|
17
|
+
config = GitHandler::Configuration.new(:home_path => '/var/foo')
|
18
|
+
proc { GitHandler::Session.new(config) }.
|
19
|
+
should raise_error GitHandler::ConfigurationError, "Home path does not exist!"
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'raises error if repos path does not exist' do
|
23
|
+
config = GitHandler::Configuration.new(:home_path => '/tmp', :repos_path => '/var/foo')
|
24
|
+
proc { GitHandler::Session.new(config) }.
|
25
|
+
should raise_error GitHandler::ConfigurationError, "Repositories path does not exist!"
|
26
|
+
end
|
19
27
|
end
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
context 'without error checks' do
|
30
|
+
it 'should not raise error if home path does not exist' do
|
31
|
+
config = GitHandler::Configuration.new(
|
32
|
+
:home_path => '/var/foo',
|
33
|
+
:raise_errors => false
|
34
|
+
)
|
35
|
+
|
36
|
+
proc { GitHandler::Session.new(config) }.
|
37
|
+
should_not raise_error GitHandler::ConfigurationError, "Home path does not exist!"
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should not raise error if repos path does not exist' do
|
41
|
+
config = GitHandler::Configuration.new(
|
42
|
+
:home_path => '/tmp',
|
43
|
+
:repos_path => '/var/foo',
|
44
|
+
:raise_errors => false
|
45
|
+
)
|
46
|
+
|
47
|
+
proc { GitHandler::Session.new(config) }.
|
48
|
+
should_not raise_error GitHandler::ConfigurationError, "Repositories path does not exist!"
|
49
|
+
end
|
25
50
|
end
|
26
51
|
end
|
27
52
|
|
metadata
CHANGED
@@ -1,77 +1,96 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_handler
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.2.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Dan Sosedoff
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: rake
|
17
|
-
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
18
|
+
requirements:
|
21
19
|
- - ~>
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version:
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '10.0'
|
24
22
|
type: :development
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: rspec
|
28
23
|
prerelease: false
|
29
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '10.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
30
33
|
none: false
|
31
|
-
requirements:
|
34
|
+
requirements:
|
32
35
|
- - ~>
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version:
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.13'
|
35
38
|
type: :development
|
36
|
-
version_requirements: *id002
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: simplecov
|
39
39
|
prerelease: false
|
40
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.13'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
41
49
|
none: false
|
42
|
-
requirements:
|
50
|
+
requirements:
|
43
51
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version:
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.7'
|
46
54
|
type: :development
|
47
|
-
version_requirements: *id003
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: sshkey
|
50
55
|
prerelease: false
|
51
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.7'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sshkey
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
52
65
|
none: false
|
53
|
-
requirements:
|
66
|
+
requirements:
|
54
67
|
- - ~>
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version:
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.5'
|
57
70
|
type: :runtime
|
58
|
-
|
59
|
-
|
60
|
-
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.5'
|
78
|
+
description: Library to handle git requests over SSH
|
79
|
+
email:
|
61
80
|
- dan.sosedoff@gmail.com
|
62
81
|
executables: []
|
63
|
-
|
64
82
|
extensions: []
|
65
|
-
|
66
83
|
extra_rdoc_files: []
|
67
|
-
|
68
|
-
files:
|
84
|
+
files:
|
69
85
|
- .gitignore
|
70
86
|
- .rspec
|
71
87
|
- .travis.yml
|
72
88
|
- Gemfile
|
89
|
+
- LICENSE
|
73
90
|
- README.md
|
74
91
|
- Rakefile
|
92
|
+
- examples/readonly.rb
|
93
|
+
- examples/simple.rb
|
75
94
|
- git_handler.gemspec
|
76
95
|
- lib/git_handler.rb
|
77
96
|
- lib/git_handler/authorized_keys.rb
|
@@ -92,34 +111,37 @@ files:
|
|
92
111
|
- spec/public_key_spec.rb
|
93
112
|
- spec/session_spec.rb
|
94
113
|
- spec/spec_helper.rb
|
95
|
-
homepage: http://github.com/sosedoff/
|
114
|
+
homepage: http://github.com/sosedoff/git-handler
|
96
115
|
licenses: []
|
97
|
-
|
98
116
|
post_install_message:
|
99
117
|
rdoc_options: []
|
100
|
-
|
101
|
-
require_paths:
|
118
|
+
require_paths:
|
102
119
|
- lib
|
103
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
121
|
none: false
|
105
|
-
requirements:
|
106
|
-
- -
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version:
|
109
|
-
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
hash: 1698053310635960184
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
130
|
none: false
|
111
|
-
requirements:
|
112
|
-
- -
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
version:
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: 1698053310635960184
|
115
138
|
requirements: []
|
116
|
-
|
117
139
|
rubyforge_project:
|
118
|
-
rubygems_version: 1.8.
|
140
|
+
rubygems_version: 1.8.25
|
119
141
|
signing_key:
|
120
142
|
specification_version: 3
|
121
|
-
summary:
|
122
|
-
test_files:
|
143
|
+
summary: Library to handle git requests over SSH
|
144
|
+
test_files:
|
123
145
|
- spec/authorized_keys_spec.rb
|
124
146
|
- spec/command_spec.rb
|
125
147
|
- spec/configuration_spec.rb
|