git-lighttp 0.3.0

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +11 -0
  3. data/Makefile +41 -0
  4. data/README.pt-BR.rdoc +81 -0
  5. data/README.rdoc +75 -0
  6. data/Rakefile +50 -0
  7. data/doc/releases/v0.1.0.rdoc +11 -0
  8. data/doc/releases/v0.2.0.rdoc +24 -0
  9. data/doc/releases/v0.3.0.rdoc +13 -0
  10. data/git-lighttp.gemspec +25 -0
  11. data/lib/git/lighttp.rb +365 -0
  12. data/lib/git/lighttp/extensions.rb +73 -0
  13. data/lib/git/lighttp/http_backend.rb +178 -0
  14. data/lib/git/lighttp/treeish.rb +28 -0
  15. data/lib/git/lighttp/version.rb +26 -0
  16. data/test/all.rb +12 -0
  17. data/test/config_test.rb +43 -0
  18. data/test/fixtures/config.yml +13 -0
  19. data/test/fixtures/htgroup +3 -0
  20. data/test/fixtures/htpasswd +4 -0
  21. data/test/fixtures/mycode.git/HEAD +1 -0
  22. data/test/fixtures/mycode.git/config +4 -0
  23. data/test/fixtures/mycode.git/description +1 -0
  24. data/test/fixtures/mycode.git/hooks/applypatch-msg.sample +15 -0
  25. data/test/fixtures/mycode.git/hooks/commit-msg.sample +24 -0
  26. data/test/fixtures/mycode.git/hooks/post-commit.sample +8 -0
  27. data/test/fixtures/mycode.git/hooks/post-receive.sample +15 -0
  28. data/test/fixtures/mycode.git/hooks/post-update.sample +8 -0
  29. data/test/fixtures/mycode.git/hooks/pre-applypatch.sample +14 -0
  30. data/test/fixtures/mycode.git/hooks/pre-commit.sample +46 -0
  31. data/test/fixtures/mycode.git/hooks/pre-rebase.sample +169 -0
  32. data/test/fixtures/mycode.git/hooks/prepare-commit-msg.sample +36 -0
  33. data/test/fixtures/mycode.git/hooks/update.sample +128 -0
  34. data/test/fixtures/mycode.git/info/exclude +6 -0
  35. data/test/fixtures/mycode.git/info/refs +3 -0
  36. data/test/fixtures/mycode.git/objects/02/83eb96425444e17b97182e1ba9f216cc67c132 +0 -0
  37. data/test/fixtures/mycode.git/objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd +1 -0
  38. data/test/fixtures/mycode.git/objects/0d/eed0a56fa8f5f2a788d58b3ea235afd547b828 +2 -0
  39. data/test/fixtures/mycode.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  40. data/test/fixtures/mycode.git/objects/5e/54a0767e0c380f3baab17938d68c7f464cf171 +1 -0
  41. data/test/fixtures/mycode.git/objects/63/9b96262e7e19ca2169575e797b234098b8a72e +0 -0
  42. data/test/fixtures/mycode.git/objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9 +1 -0
  43. data/test/fixtures/mycode.git/objects/b6/f3f0fabeaaaaf2db22b8ef98f59115baec7ef9 +0 -0
  44. data/test/fixtures/mycode.git/objects/be/118435b9d908fd4a689cd8b0cc98059911a31a +0 -0
  45. data/test/fixtures/mycode.git/objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6 +0 -0
  46. data/test/fixtures/mycode.git/objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea +0 -0
  47. data/test/fixtures/mycode.git/objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20 +0 -0
  48. data/test/fixtures/mycode.git/objects/ed/1c3a255ab3fce056dc31cd82df9f61a4d9fa22 +0 -0
  49. data/test/fixtures/mycode.git/objects/info/alternates +0 -0
  50. data/test/fixtures/mycode.git/objects/info/http-alternates +0 -0
  51. data/test/fixtures/mycode.git/objects/info/packs +2 -0
  52. data/test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx +0 -0
  53. data/test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack +0 -0
  54. data/test/fixtures/mycode.git/packed-refs +4 -0
  55. data/test/fixtures/mycode.git/refs/heads/master +1 -0
  56. data/test/fixtures/mycode.git/refs/tags/v0.1.0 +1 -0
  57. data/test/helpers.rb +53 -0
  58. data/test/htgroup_test.rb +29 -0
  59. data/test/htpasswd_test.rb +63 -0
  60. data/test/http_backend_authentication_test.rb +61 -0
  61. data/test/http_backend_test.rb +123 -0
  62. data/test/project_handler_test.rb +45 -0
  63. data/test/treeish_test.rb +33 -0
  64. metadata +121 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c42b6bc5a9164165905fec6ee9a64e010d18cd52
4
+ data.tar.gz: 6886a3e0b6f059e483b43c4e1c34541fbba8976b
5
+ SHA512:
6
+ metadata.gz: dc3f5819df08305540b53233b4159c47dab26b73c5fe6f7b238303b27dae7496f397d61e1f06a4f8cd4e71d603e76ae97729dfa2534a8b3b612a7f4c287833ca
7
+ data.tar.gz: 4eaec72837984539df8bc799f7eb0a1f42c69bdfc2e552e780297dc374cdad305489c33ee649e7f5a53e8c1c09212a2dda680d220c8312371da9b9867bd571b6
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'json'
5
+
6
+ group :coding do
7
+ gem 'minitest'
8
+ gem 'minitest-rg'
9
+ gem 'rack-test'
10
+ end
11
+
data/Makefile ADDED
@@ -0,0 +1,41 @@
1
+ .SHELL: /bin/sh
2
+
3
+ name = git-lighttp
4
+ version = 0.3.0
5
+ specfile = $(name).gemspec
6
+ package = $(name)-$(version).gem
7
+
8
+ ctags = '/.*alias(_method)?[[:space:]]+:([[:alnum:]_=!?]+),?[[:space:]]+:([[:alnum:]_=!]+)/\\2/f/'
9
+
10
+ all:: check
11
+
12
+ ctags:
13
+ ctags --recurse=yes --tag-relative=yes --totals=yes --extra=+f --fields=+iaS --regex-ruby=$(ctags)
14
+
15
+ clean:
16
+ rm -rf $(name)-*.gem
17
+ rm -rf *.lock
18
+ rm -rf doc/api/**
19
+
20
+ check:
21
+ ruby test/all.rb
22
+
23
+ docs:
24
+ rdoc -o doc/api -H -f fivefish -m README.rdoc
25
+
26
+ build:
27
+ gem $@ $(specfile)
28
+
29
+ dist: build
30
+
31
+ push: build
32
+ gem $@ $(package)
33
+
34
+ release: push
35
+
36
+ install: build
37
+ gem $@ --local $(package)
38
+
39
+ uninstall: build
40
+ gem $@ $(package) -v$(version)
41
+
data/README.pt-BR.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = Git-Lighttp - Web mais esperta para o Git
2
+
3
+ {<img src="https://badge.fury.io/rb/git-lighttp.svg" alt="Gem Version" />}[https://badge.fury.io/rb/git-lighttp]
4
+
5
+ == DESCRIÇÃO
6
+
7
+ Este projeto foi inspirado no {Grack}[http://github.com/schacon/grack], um
8
+ servidor de processos Smart-HTTP (escrito por
9
+ {Scott Chacon}[http://github.com/schacon]), mas projetado usando
10
+ {Sinatra}[http://www.sinatrarb.com] e visa substituir o `git-http-backend`
11
+ original incluindo novas funcionalidades.
12
+
13
+ O objetivo principal do <b>Git-Lighttp</b> é implementar as seguintes
14
+ funcionalidades:
15
+
16
+ - Smart-HTTP, baseado no _git-http-backend_.
17
+ - Autenticação flexível baseado em banco de dados ou arquivo de configuração
18
+ como <tt>.htpasswd</tt>.
19
+ - API para obter informações sobre o repositório (_Treeish_).
20
+
21
+ == SINOPSE
22
+
23
+ Instale o Git-Lighttp usando {Rubygems}[http://rubygems.org/gems/git-lighttp].
24
+
25
+ gem install git-lighttp
26
+
27
+ Ou faça um _checkout_ do projeto hospedado no
28
+ {Github}[http://github.com/hallison/git-lighttp].
29
+
30
+ git clone https://github.com/hallison/git-lighttp.git
31
+ ...
32
+ cd git-lighttp
33
+ rake install
34
+
35
+ Configure o arquivo Rackup (<tt>config.ru</tt>) usando as seguintes instruções:
36
+
37
+ # config.ru
38
+ require "git/lighttp"
39
+
40
+ Git::Lighttp::HttpBackend.configure do |server|
41
+ server.project_root = "/home/git/repositories"
42
+ server.git_path = "/usr/bin/git"
43
+ server.get_any_file = true
44
+ server.upload_pack = true
45
+ server.receive_pack = false
46
+ server.authenticate = true
47
+ end
48
+
49
+ $ rackup --port 2011 --daemonize
50
+ $ git clone http://localhost:2011/mycode.git
51
+
52
+ Você poderá usar o arquivo <tt>.netrc</tt> para melhorar sua conexão. Coloque
53
+ isso:
54
+
55
+ machine <servidor> login <usuario> password <senha>
56
+
57
+ O Git-Lighttp está em desenvolvimento, então ainda há muitas melhorias a serem
58
+ feitas. Por favor, nos ajude a melhorar o projeto enviando seu comentário nos
59
+ {problemas}[http://github.com/hallison/git-lighttp/issues] encontrados ou
60
+ enviando um email para
61
+ {hallisonbatista@gmail.com}[mailto:hallisonbatista@gmail.com].
62
+
63
+ Discuta no {Google Groups}[http://groups.google.com/group/git-lighttp].
64
+
65
+ == AUTORES
66
+
67
+ Escrito por Hallison Batista <hallisonbatista@gmail.com>.
68
+
69
+ == ERROS
70
+
71
+ Se você encontrar um erro, por favor, informe no
72
+ {gerenciador de erros}[http://github.com/hallison/git-lighttp] do projeto
73
+ Git-Lighttp no Github.
74
+
75
+ == LICENÇA
76
+
77
+ Git-Lighttp é Copyright (c) 2011-2015 Hallison Batista.
78
+
79
+ Este é um _software_ livre e pode ser redistribuído sob os termos
80
+ especificados em LICENSE.txt.
81
+
data/README.rdoc ADDED
@@ -0,0 +1,75 @@
1
+ = Git-Lighttp - Web smarty for Git
2
+
3
+ {<img src="https://badge.fury.io/rb/git-lighttp.svg" alt="Gem Version" />}[https://badge.fury.io/rb/git-lighttp]
4
+
5
+ == DESCRIPTION
6
+
7
+ This project was inspired in the {Grack}[http://github.com/schacon/grack]
8
+ Smart-HTTP server handler (written by
9
+ {Scott Chacon}[http://github.com/schacon]) but developed using
10
+ {Sinatra}[http://www.sinatrarb.com] and aims replace the original
11
+ `git-http-backend` including new features.
12
+
13
+ The main goal of the <b>Git-Lighttp</b> is implement the following useful features.
14
+
15
+ - Smart-HTTP, based on _git-http-backend_.
16
+ - Authentication flexible based on database or configuration file like .+htpasswd+.
17
+ - API to get information about repository (_Treeish_).
18
+
19
+ == SINOPSIS
20
+
21
+ Install the Git-Lighttp using {Rubygems}[http://rubygems.org/gems/git-lighttp].
22
+
23
+ gem install git-lighttp
24
+
25
+ Or checkout the project hosted on {Github}[http://github.com/hallison/git-lighttp].
26
+
27
+ git clone https://github.com/hallison/git-lighttp.git
28
+ ...
29
+ cd git-lighttp
30
+ rake install
31
+
32
+ Configure the Rackup file (<tt>config.ru</tt>) using the following instructions:
33
+
34
+ # config.ru
35
+ require "git/lighttp"
36
+
37
+ Git::Lighttp::HttpBackend.configure do |server|
38
+ server.project_root = "/home/git/repositories"
39
+ server.git_path = "/usr/bin/git"
40
+ server.get_any_file = true
41
+ server.upload_pack = true
42
+ server.receive_pack = false
43
+ server.authenticate = true
44
+ end
45
+
46
+ $ rackup --port 2011 --daemonize
47
+ $ git clone http://localhost:2011/mycode.git
48
+
49
+ You can use the <tt>.netrc</tt> for improve your connection. Put this:
50
+
51
+ machine <host> login <username> password <password>
52
+
53
+ The Git-Lighttp is under development, so there are still many improvements to be
54
+ made. Please, help us to improve the project sending your feedback to
55
+ {issues}[http://github.com/hallison/git-lighttp] or sending email to
56
+ {hallisonbatista@gmail.com}[mailto:hallisonbatista@gmail.com].
57
+
58
+ Discuss in {Google Groups}[http://groups.google.com/group/git-lighttp].
59
+
60
+ == AUTHORS
61
+
62
+ Written by Hallison Batista <hallisonbatista@gmail.com>.
63
+
64
+ == BUGS
65
+
66
+ If you find a bug, please report it at the Git-Lighttp project's
67
+ {issues tracker}[http://github.com/hallison/git-lighttp] on Github.
68
+
69
+ == LICENSE
70
+
71
+ Git-Lighttp is Copyright (c) 2011-2015 Hallison Batista.
72
+
73
+ This is free software, and may be redistributed under the terms specified in
74
+ LICENSE.txt.
75
+
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ require "git/lighttp"
2
+
3
+ def spec
4
+ @spec ||= Gem::Specification.load("git-lighttp.gemspec")
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :test, [:file] do |spec, args|
9
+ Dir["test/#{args.file}*_test.rb"].each do |file|
10
+ sh "ruby #{file}"
11
+ end
12
+ end
13
+
14
+ desc "API Documentation (RDoc)"
15
+ task :doc do
16
+ sh "rdoc -o doc/api -H -f hanna -m README.rdoc"
17
+ end
18
+
19
+ desc "Build tags"
20
+ task :tags do
21
+ rbalias = '/.*alias(_method)?[[:space:]]+:([[:alnum:]_=!?]+),?[[:space:]]+:([[:alnum:]_=!]+)/\\2/f/'
22
+ sh "ctags", "--recurse=yes",
23
+ "--tag-relative=yes",
24
+ "--totals=yes",
25
+ "--extra=+f",
26
+ "--fields=+iaS",
27
+ "--regex-ruby="+rbalias
28
+ end
29
+
30
+ desc "Build #{spec.file_name}"
31
+ task :build => "#{spec.name}.gemspec" do
32
+ sh "gem build #{spec.name}.gemspec"
33
+ end
34
+
35
+ desc "Release #{spec.file_name}"
36
+ task :release => :build do
37
+ sh "gem push #{spec.file_name}"
38
+ end
39
+
40
+ desc "Install gem file #{spec.file_name}"
41
+ task :install => :build do
42
+ sh "gem install -l #{spec.file_name}"
43
+ end
44
+
45
+ desc "Uninstall gem #{spec.name} v#{spec.version}"
46
+ task :uninstall do
47
+ sh "gem uninstall #{spec.name} -v #{spec.version}"
48
+ end
49
+
50
+ task :default => :test
@@ -0,0 +1,11 @@
1
+ == Git-Lighttp v0.1.0
2
+
3
+ Implementation of the basic features:
4
+
5
+ - Smart-HTTP implementation.
6
+ - Authentication using +htpasswd+ features (only crypt algorithm).
7
+ - Basic configuration in Rackup file.
8
+
9
+ This is a beta version. For more informations about this release,
10
+ please visit <http://github.com/hallison/git-lighttp>.
11
+
@@ -0,0 +1,24 @@
1
+ == Git-Lighttp v0.2.0
2
+
3
+ Implementation of viewer for browsing of source code:
4
+
5
+ - Fixes in tasks.
6
+ - Adding of classes for handle repositories.
7
+ - Improvements in all helpers.
8
+ - Base controller for shared settings
9
+ - The project handler has been improved to find a repository and run the
10
+ command line for get files and informations.
11
+ - The HTTP Backend class has been updated for use the new changes in project
12
+ handler.
13
+ - Fixes in RPC service to POST git-upload-pack
14
+ - The repository was passed as current directory instead of the full path.
15
+ - Adding of tree in project handler
16
+ - Adding of viewer for browsing of source code
17
+ - The recursive tree has been removed for improve performance.
18
+ - Small improvements in helpers and tests.
19
+
20
+ This is a beta version. For more informations about this release,
21
+ please visit <http://github.com/codigorama/git-lighttp>.
22
+
23
+
24
+
@@ -0,0 +1,13 @@
1
+ == Git-Lighttp v0.3.0
2
+
3
+ Improvements and new features.
4
+
5
+ - Fixes in the Sinatra compatibility.
6
+ - Improvements in the treeish middleware.
7
+ - HTTP group support.
8
+ - The configuration can be made the rack-way, using the class itself.
9
+ - The project renamed from Git-Webby to Git-Lighttp.
10
+
11
+ This is a beta version. For more informations about this release,
12
+ please visit <http://github.com/hallison/git-lighttp>.
13
+
@@ -0,0 +1,25 @@
1
+ require "git/lighttp"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.platform = Gem::Platform::RUBY
5
+ spec.name = "git-lighttp"
6
+ spec.summary = "Git Web implementation of the Light (Smart) HTTP and other features"
7
+ spec.authors = ["Hallison Batista"]
8
+ spec.email = "hallisonbatista@gmail.com"
9
+ spec.homepage = "http://github.com/hallison/git-lighttp"
10
+ spec.rubyforge_project = spec.name
11
+ spec.version = Git::Lighttp::VERSION
12
+ spec.date = Git::Lighttp::RELEASE
13
+ spec.test_files = spec.files.select{ |path| path =~ /^test\/.*/ }
14
+ spec.require_paths = ["lib"]
15
+ spec.files = %x[git ls-files].split.reject do |out|
16
+ out =~ %r{^\.} || out =~ %r{/^doc/api/}
17
+ end
18
+ spec.description = <<-end.gsub /^ /,''
19
+ Git::Lighttp is a implementation of the several features:
20
+ - Smart HTTP which works like as git-http-backend.
21
+ - Show info pages about the projects.
22
+ end
23
+ spec.add_dependency "sinatra"
24
+ end
25
+
@@ -0,0 +1,365 @@
1
+ # Standard requirements
2
+ require "yaml"
3
+
4
+ # 3rd part requirements
5
+ require "sinatra/base"
6
+ require "json"
7
+
8
+ # Internal requirements
9
+ require "git/lighttp/extensions"
10
+ require "git/lighttp/version"
11
+
12
+ # See <b>Git::Lighttp</b> for documentation.
13
+ module Git
14
+
15
+ # The main goal of the <b>Git::Lighttp</b> is implement the following useful
16
+ # features.
17
+ #
18
+ # - Smart-HTTP, based on _git-http-backend_.
19
+ # - Authentication flexible based on database or configuration file like <tt>.htpasswd</tt>.
20
+ # - API to get information about repository.
21
+ #
22
+ # This class configure the needed variables used by application. See
23
+ # Config::DEFAULTS for the values will be initialized by default.
24
+ #
25
+ # Basically, the +default+ attribute set the values that will be necessary
26
+ # by all applications.
27
+ #
28
+ # The HTTP-Backend application is configured by +http_backend+ attribute
29
+ # to set the Git RCP CLI. More details about this feature, see the
30
+ # {git-http-backend official
31
+ # page}[http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html]
32
+ #
33
+ # For tree view (JSON API) just use the attribute +treeish+.
34
+ #
35
+ # [*default*]
36
+ # Default configuration. All attributes will be used by all modular
37
+ # applications.
38
+ #
39
+ # *project_root* ::
40
+ # Sets the root directory where repositories have been
41
+ # placed.
42
+ # *git_path* ::
43
+ # Path to the git command line.
44
+ #
45
+ # [*treeish*]
46
+ # Configuration for Treeish JSON API.
47
+ #
48
+ # *authenticate* ::
49
+ # Sets if the tree view server requires authentication.
50
+ #
51
+ # [*http_backend*]
52
+ # HTTP-Backend configuration.
53
+ #
54
+ # *authenticate* ::
55
+ # Sets if authentication is required.
56
+ #
57
+ # *get_any_file* ::
58
+ # Like +http.getanyfile+.
59
+ #
60
+ # *upload_pack* ::
61
+ # Like +http.uploadpack+.
62
+ #
63
+ # *receive_pack* ::
64
+ # Like +http.receivepack+.
65
+ module Lighttp
66
+
67
+ class ProjectHandler #:nodoc:
68
+
69
+ # Path to git comamnd
70
+ attr_reader :path
71
+
72
+ attr_reader :project_root
73
+
74
+ attr_reader :repository
75
+
76
+ def initialize(project_root, path = "/usr/bin/git")
77
+ @repository = nil
78
+ @path = check_path(File.expand_path(path))
79
+ @project_root = check_path(File.expand_path(project_root))
80
+ end
81
+
82
+ def path_to(*args)
83
+ File.join(@repository || @project_root, *(args.compact.map(&:to_s)))
84
+ end
85
+
86
+ def repository=(name)
87
+ @repository = check_path(path_to(name))
88
+ end
89
+
90
+ def cli(command, *args)
91
+ %Q[#{@path} #{args.unshift(command.to_s.gsub("_","-")).compact.join(" ")}]
92
+ end
93
+
94
+ def run(command, *args)
95
+ chdir{ %x[#{cli command, *args}] }
96
+ end
97
+
98
+ def read_file(*file)
99
+ File.read(path_to(*file))
100
+ end
101
+
102
+ def loose_object_path(*hash)
103
+ path_to(:objects, *hash)
104
+ end
105
+
106
+ def pack_idx_path(pack)
107
+ path_to(:objects, :pack, pack)
108
+ end
109
+
110
+ def info_packs_path
111
+ path_to(:objects, :info, :packs)
112
+ end
113
+
114
+ def tree(ref = "HEAD", path = "")
115
+ list = run("ls-tree --abbrev=6 --full-tree --long #{ref}:#{path}")
116
+ if list
117
+ tree = []
118
+ list.scan %r{^(\d{3})(\d)(\d)(\d) (\w.*?) (.{6})[ \t]{0,}(.*?)\t(.*?)\n}m do
119
+ object = {
120
+ :ftype => ftype[$1],
121
+ :fperm => "#{fperm[$2.to_i]}#{fperm[$3.to_i]}#{fperm[$4.to_i]}",
122
+ :otype => $5.to_sym,
123
+ :ohash => $6,
124
+ :fsize => fsize($7, 2),
125
+ :fname => $8
126
+ }
127
+ object[:objects] = nil if object[:otype] == :tree
128
+ tree << object
129
+ end
130
+ tree
131
+ else
132
+ nil
133
+ end
134
+ end
135
+
136
+ private
137
+
138
+ def repository_path(name)
139
+ bare = name =~ /\w\.git/ ? name : %W[#{name} .git]
140
+ check_path(path_to(*bare))
141
+ end
142
+
143
+ def check_path(path)
144
+ path && !path.empty? && File.ftype(path) && path
145
+ end
146
+
147
+ def chdir(&block)
148
+ Dir.chdir(@repository || @project_root, &block)
149
+ end
150
+
151
+ def ftype
152
+ { "120" => "l", "100" => "-", "040" => "d" }
153
+ end
154
+
155
+ def fperm
156
+ [ "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" ]
157
+ end
158
+
159
+ def fsize(str, scale = 1)
160
+ units = [ :b, :kb, :mb, :gb, :tb ]
161
+ value = str.to_f
162
+ size = 0.0
163
+ units.each_index do |i|
164
+ size = value / 1024**i
165
+ return [format("%.#{scale}f", size).to_f, units[i].to_s.upcase] if size <= 10
166
+ end
167
+ end
168
+
169
+ end
170
+
171
+ class Htpasswd #:nodoc:
172
+
173
+ def initialize(file)
174
+ require "webrick/httpauth/htpasswd"
175
+ @handler = WEBrick::HTTPAuth::Htpasswd.new(file)
176
+ yield self if block_given?
177
+ end
178
+
179
+ def find(username) #:yield: password, salt
180
+ password = @handler.get_passwd(nil, username, false)
181
+ if block_given?
182
+ yield password ? [password, password[0,2]] : [nil, nil]
183
+ else
184
+ password
185
+ end
186
+ end
187
+
188
+ def authenticated?(username, password)
189
+ self.find username do |crypted, salt|
190
+ crypted && salt && crypted == password.crypt(salt)
191
+ end
192
+ end
193
+
194
+ def create(username, password)
195
+ @handler.set_passwd(nil, username, password)
196
+ end
197
+ alias update create
198
+
199
+ def destroy(username)
200
+ @handler.delete_passwd(nil, username)
201
+ end
202
+
203
+ def include?(username)
204
+ users.include? username
205
+ end
206
+
207
+ def size
208
+ users.size
209
+ end
210
+
211
+ def write!
212
+ @handler.flush
213
+ end
214
+
215
+ private
216
+
217
+ def users
218
+ @handler.each{|username, password| username }
219
+ end
220
+ end
221
+
222
+ class Htgroup #:nodoc:
223
+
224
+ def initialize(file)
225
+ require "webrick/httpauth/htgroup"
226
+ WEBrick::HTTPAuth::Htgroup.class_eval do
227
+ attr_reader :group
228
+ end
229
+ @handler = WEBrick::HTTPAuth::Htgroup.new(file)
230
+ yield self if block_given?
231
+ end
232
+
233
+ def members(group)
234
+ @handler.members(group)
235
+ end
236
+
237
+ def groups(username)
238
+ @handler.group.select do |group, members|
239
+ members.include? username
240
+ end.keys
241
+ end
242
+
243
+ end
244
+
245
+ module GitHelpers #:nodoc:
246
+
247
+ def git
248
+ @git ||= ProjectHandler.new(settings.project_root, settings.git_path)
249
+ end
250
+
251
+ def repository
252
+ git.repository ||= (params[:repository] || params[:captures].first)
253
+ git
254
+ end
255
+
256
+ def content_type_for_git(name, *suffixes)
257
+ content_type("application/x-git-#{name}-#{suffixes.compact.join("-")}")
258
+ end
259
+
260
+ end
261
+
262
+ module AuthenticationHelpers #:nodoc:
263
+
264
+ def htpasswd
265
+ @htpasswd ||= Htpasswd.new(git.path_to("htpasswd"))
266
+ end
267
+
268
+ def authentication
269
+ @authentication ||= Rack::Auth::Basic::Request.new request.env
270
+ end
271
+
272
+ def authenticated?
273
+ request.env["REMOTE_USER"] && request.env["git.lighttp.authenticated"]
274
+ end
275
+
276
+ def authenticate(username, password)
277
+ checked = [ username, password ] == authentication.credentials
278
+ validated = authentication.provided? && authentication.basic?
279
+ granted = htpasswd.authenticated? username, password
280
+ if checked and validated and granted
281
+ request.env["git.lighttp.authenticated"] = true
282
+ request.env["REMOTE_USER"] = authentication.username
283
+ else
284
+ nil
285
+ end
286
+ end
287
+
288
+ def unauthorized!(realm = Git::Lighttp::info)
289
+ headers "WWW-Authenticate" => %(Basic realm="#{realm}")
290
+ throw :halt, [ 401, "Authorization Required" ]
291
+ end
292
+
293
+ def bad_request!
294
+ throw :halt, [ 400, "Bad Request" ]
295
+ end
296
+
297
+ def authenticate!
298
+ return if authenticated?
299
+ unauthorized! unless authentication.provided?
300
+ bad_request! unless authentication.basic?
301
+ unauthorized! unless authenticate(*authentication.credentials)
302
+ request.env["REMOTE_USER"] = authentication.username
303
+ end
304
+
305
+ def access_granted?(username, password)
306
+ authenticated? || authenticate(username, password)
307
+ end
308
+
309
+ end # AuthenticationHelpers
310
+
311
+ # Servers
312
+ autoload :HttpBackend, "git/lighttp/http_backend"
313
+ autoload :Treeish, "git/lighttp/treeish"
314
+
315
+ class << self
316
+
317
+ def config
318
+ @config ||= {
319
+ :default => {
320
+ :project_root => "/home/git",
321
+ :git_path => "/usr/bin/git"
322
+ },
323
+ :treeish => {
324
+ :authenticate => false
325
+ },
326
+ :http_backend => {
327
+ :authenticate => true,
328
+ :get_any_file => true,
329
+ :upload_pack => true,
330
+ :receive_pack => false
331
+ }
332
+ }.to_struct
333
+ end
334
+
335
+ # Configure Git::Lighttp modules using keys. See Config for options.
336
+ def configure(&block)
337
+ yield config
338
+ config
339
+ end
340
+
341
+ def load_config_file(file)
342
+ YAML.load_file(file).to_struct.each_pair do |app, options|
343
+ options.each_pair do |option, value|
344
+ config[app][option] = value
345
+ end
346
+ end
347
+ config
348
+ rescue IndexError => error
349
+ abort "configuration option not found"
350
+ end
351
+
352
+ end
353
+
354
+ class Application < Sinatra::Base #:nodoc:
355
+
356
+ set :project_root, lambda { Git::Lighttp.config.default.project_root }
357
+ set :git_path, lambda { Git::Lighttp.config.default.git_path }
358
+
359
+ mime_type :json, "application/json"
360
+
361
+ end
362
+
363
+ end
364
+
365
+ end