gisha 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93b0594a1fe45986e9e48148b14493568fcab357
4
- data.tar.gz: d2f52e5418b300d44d8468583b3dc1ea85f8e1fc
3
+ metadata.gz: 23a165dc20f07b0389d63be595b0573ba241e6a1
4
+ data.tar.gz: a4db26b3058f4f56efaae71118e6d4a399980242
5
5
  SHA512:
6
- metadata.gz: dcf47888df6efdc9c70412f592e0393065ba09ddb3e5f96b326b371b8897d441b40c555ca0d5569357ffd065f0b08b431394ebfcf981ee0ecfe792c914b52f14
7
- data.tar.gz: 7e383d45f7a4fa7352da5c860559b1be6e30548a1a78da2f366537e767ea41f5f91bcac5ba1f1d9c621f47023a335193374e038b4f01f3475c34da0ed81d48c1
6
+ metadata.gz: a898671ee83df216bac2019253323ed84845db5007e7a0a2150e2bbb9a4017c6962a780fdf74d5670ae045c59c0c27991a00bd98ef046344eca015ed3801b171
7
+ data.tar.gz: 17c96c31904d9674bfd1e02d01a7bff0a2aa3c7c1704b33b9854b584f32f48f6bb5215fd4e2deab71ddc5df6bdd26e55824bb02de2526714d102f2f3e37ee13c
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in gisha.gemspec
4
4
  gemspec
5
+
6
+ group :development, :test do
7
+ gem 'coveralls', require: false
8
+ gem 'rspec'
9
+ gem 'webmock'
10
+ gem 'vcr'
11
+ end
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task default: :spec
data/gisha.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'clamp'
22
+ spec.add_dependency 'rugged'
22
23
 
23
24
  spec.add_development_dependency 'bundler', '~> 1.5'
24
25
  spec.add_development_dependency 'rake'
data/lib/gisha.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  require 'gisha/version'
2
2
 
3
3
  module Gisha
4
+
5
+ module Commands
6
+ autoload 'Receive', 'gisha/commands/receive'
7
+ autoload 'Key', 'gisha/commands/key'
8
+ end
9
+
4
10
  autoload 'CLI', 'gisha/cli'
5
11
  end
data/lib/gisha/cli.rb CHANGED
@@ -1,29 +1,63 @@
1
1
  require 'clamp'
2
+ require 'tempfile'
3
+ require 'shellwords'
4
+
5
+ require 'rugged'
2
6
 
3
7
  module Gisha
4
8
 
5
- class AuthCommand < Clamp::Command
6
- parameter 'USER', 'username that was provided to the server'
9
+ class ReceiveCommand < Clamp::Command
10
+ parameter 'KEY_ID', 'id to identify the key'
11
+
12
+ def execute
13
+ Commands::Receive.new(key_id).exec
14
+ end
15
+ end
16
+
17
+ class AddKeyCommand < Clamp::Command
18
+ parameter 'ID', 'id to identify the key'
7
19
  parameter 'KEY', 'public key that was provided to the server'
20
+ parameter 'AUTH_FILE', 'file containing public keys for public key authentication;'
8
21
 
9
22
  def execute
10
- puts "authenticate #{user} with #{key}"
23
+ Commands::Key.new(auth_file, id, key).add
11
24
  end
12
25
 
13
26
  end
14
27
 
15
- class ReceiveCommand < Clamp::Command
16
- parameter 'PATH', 'path of the repo that was pushed to'
17
- parameter 'COMMIT', 'SHA of the commit that was pushed to master'
28
+ class DeleleteKeyCommand < Clamp::Command
29
+ parameter 'ID', 'id to identify the key'
30
+ parameter 'AUTH_FILE', 'file containing public keys for public key authentication;'
31
+
32
+ def execute
33
+ Commands::Key.new(auth_file, id).del
34
+ end
35
+ end
36
+
37
+ class CreateRepositoryCommand < Clamp::Command
38
+ parameter 'PATH', 'path to create repository'
39
+
40
+ def execute
41
+ Rugged::Repository.init_at(path, :bare)
42
+ end
43
+ end
44
+
45
+ class DeleteRepositoryCommand < Clamp::Command
46
+ parameter 'PATH', 'path to delete repository'
18
47
 
19
48
  def execute
20
- puts "received #{commit} for repository #{path}"
49
+ puts "delete repository #{path}"
21
50
  end
22
51
  end
23
52
 
24
53
  class CLI < Clamp::Command
25
- subcommand 'auth', 'Authenticate user', AuthCommand
26
- subcommand 'receive', 'Receive what is pushed into the repository', ReceiveCommand
54
+ subcommand 'keys:add', 'add new key', AddKeyCommand
55
+ subcommand 'keys:del', 'delete key', DeleleteKeyCommand
56
+
57
+ subcommand 'repositories:create', 'create repository', CreateRepositoryCommand
58
+ subcommand 'repositories:delete', 'delete repository', DeleteRepositoryCommand
59
+
60
+ subcommand 'receive', 'receive what is pushed into the repository', ReceiveCommand
27
61
  end
28
62
 
29
63
  end
@@ -0,0 +1,54 @@
1
+ module Gisha
2
+ class Commands::Key
3
+ attr_reader :auth_file, :id, :key
4
+
5
+ def initialize(auth_file, id, key = nil)
6
+ @auth_file = auth_file
7
+ @id = id
8
+ @key = key
9
+ end
10
+
11
+ def add
12
+ lock do
13
+ open(auth_file, 'a') { |file| file.puts(key_line) }
14
+ end
15
+ end
16
+
17
+ def del
18
+ lock do
19
+ Tempfile.open('authorized_keys') do |temp|
20
+ open(auth_file, 'r+') do |current|
21
+ current.each do |line|
22
+ temp.puts(line) unless line.include?("gisha receive key-#{id}")
23
+ end
24
+ end
25
+ temp.close
26
+ FileUtils.cp(temp.path, auth_file)
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ private
33
+
34
+ def key_line
35
+ auth_line = "command=\"gisha receive key-#{id}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty #{key}"
36
+ end
37
+
38
+ def lock(timeout = 10)
39
+ File.open(lock_file, "w+") do |f|
40
+ begin
41
+ f.flock File::LOCK_EX
42
+ Timeout::timeout(timeout) { yield }
43
+ ensure
44
+ f.flock File::LOCK_UN
45
+ end
46
+ end
47
+ end
48
+
49
+ def lock_file
50
+ @lock_file ||= auth_file + '.lock'
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,63 @@
1
+ module Gisha
2
+ class Commands::Receive
3
+ class DisallowedCommandError < StandardError; end
4
+
5
+ attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name
6
+
7
+ def initialize(key_id)
8
+ @key_id = key_id
9
+ end
10
+
11
+ def exec
12
+ if origin_cmd
13
+ parse_cmd
14
+ if git_cmds.include?(git_cmd)
15
+ process_cmd
16
+ else
17
+ raise DisallowedCommandError
18
+ end
19
+ end
20
+ end
21
+
22
+ def repos_path
23
+ @repos_path ||= File.join(ENV['HOME'], "repositories")
24
+ end
25
+
26
+ private
27
+
28
+ def process_cmd
29
+ repo_full_path = File.join(repos_path, repo_name)
30
+ exec_cmd(@git_cmd, repo_full_path)
31
+ end
32
+
33
+ def exec_cmd(*args)
34
+ Kernel::exec({'PATH' => ENV['PATH'], 'LD_LIBRARY_PATH' => ENV['LD_LIBRARY_PATH'], 'KEY_ID' => key_id}, *args, unsetenv_others: true)
35
+ end
36
+
37
+ def parse_cmd
38
+ args = Shellwords.shellwords(origin_cmd)
39
+ raise DisallowedCommandError unless args.count == 2
40
+ @git_cmd = args[0]
41
+ @repo_name = escape_path(args[1])
42
+ end
43
+
44
+ def origin_cmd
45
+ @origin_cmd ||= ENV['SSH_ORIGINAL_COMMAND']
46
+ end
47
+
48
+ def git_cmds
49
+ %w(git-upload-pack git-receive-pack git-upload-archive)
50
+ end
51
+
52
+ def escape_path(path)
53
+ full_repo_path = File.join(repos_path, path)
54
+
55
+ if File.absolute_path(full_repo_path) == full_repo_path
56
+ path
57
+ else
58
+ abort "Wrong repository path"
59
+ end
60
+ end
61
+
62
+ end
63
+ end
data/lib/gisha/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Gisha
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gisha::Commands::Receive do
4
+ let(:key_id) { "key-#{rand(100) + 100}" }
5
+
6
+ subject do
7
+ Gisha::Commands::Receive.new(key_id).tap do |receive|
8
+ allow(receive).to receive_messages(exec_cmd: :exec_called)
9
+ end
10
+ end
11
+
12
+ describe :initialize do
13
+ before { ssh_cmd 'git-receive-pack' }
14
+
15
+ it { expect(subject.key_id).to be_eql(key_id) }
16
+ end
17
+
18
+
19
+ describe :parse_cmd do
20
+ context 'w/o namespace' do
21
+ before do
22
+ ssh_cmd 'git-upload-pack gisha.git'
23
+ subject.send :parse_cmd
24
+ end
25
+
26
+ it { expect(subject.repo_name).to be_eql('gisha.git') }
27
+ it { expect(subject.git_cmd).to be_eql('git-upload-pack') }
28
+
29
+ end
30
+
31
+ context 'namespace' do
32
+ before do
33
+ ssh_cmd 'git-upload-pack algonauti/gisha.git'
34
+ subject.send :parse_cmd
35
+ end
36
+
37
+ it { expect(subject.repo_name).to be_eql('algonauti/gisha.git') }
38
+ it { expect(subject.git_cmd).to be_eql('git-upload-pack') }
39
+ end
40
+
41
+ context 'with an invalid number of arguments' do
42
+ before { ssh_cmd 'foobar' }
43
+
44
+ it "should raise an DisallowedCommandError" do
45
+ expect { subject.send :parse_cmd }.to raise_error(Gisha::Commands::Receive::DisallowedCommandError)
46
+ end
47
+ end
48
+ end
49
+
50
+ describe :exec do
51
+ context 'git-upload-pack' do
52
+ before { ssh_cmd 'git-upload-pack gitlab-ci.git' }
53
+ after { subject.exec }
54
+
55
+ it "should process the command" do
56
+ allow(subject).to receive_messages(process_cmd: :process_cmd_called)
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ def ssh_cmd(cmd)
63
+ ENV['SSH_ORIGINAL_COMMAND'] = cmd
64
+ end
65
+
66
+ end
@@ -0,0 +1,10 @@
1
+ require 'vcr'
2
+ require 'webmock'
3
+
4
+ require 'gisha'
5
+
6
+ VCR.configure do |c|
7
+ c.cassette_library_dir = 'spec/vcr_cassettes'
8
+ c.hook_into :webmock
9
+ c.configure_rspec_metadata!
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gisha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salvatore Ferrucci
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-09 00:00:00.000000000 Z
11
+ date: 2014-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rugged
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -61,8 +75,6 @@ extensions: []
61
75
  extra_rdoc_files: []
62
76
  files:
63
77
  - ".gitignore"
64
- - ".ruby-gemset"
65
- - ".ruby-version"
66
78
  - Gemfile
67
79
  - LICENSE.txt
68
80
  - README.md
@@ -71,7 +83,11 @@ files:
71
83
  - gisha.gemspec
72
84
  - lib/gisha.rb
73
85
  - lib/gisha/cli.rb
86
+ - lib/gisha/commands/key.rb
87
+ - lib/gisha/commands/receive.rb
74
88
  - lib/gisha/version.rb
89
+ - spec/lib/gisha/commands/receive_spec.rb
90
+ - spec/spec_helper.rb
75
91
  homepage: https://github.com/algonauti/gisha
76
92
  licenses:
77
93
  - MIT
@@ -96,4 +112,6 @@ rubygems_version: 2.2.2
96
112
  signing_key:
97
113
  specification_version: 4
98
114
  summary: Easily accept and handle arbitrary git pushes
99
- test_files: []
115
+ test_files:
116
+ - spec/lib/gisha/commands/receive_spec.rb
117
+ - spec/spec_helper.rb
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- gisha
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.1.0