amp 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.hgignore +26 -0
- data/AUTHORS +2 -0
- data/History.txt +6 -0
- data/LICENSE +37 -0
- data/MANIFESTO +7 -0
- data/Manifest.txt +294 -0
- data/README.md +129 -0
- data/Rakefile +102 -0
- data/SCHEDULE.markdown +12 -0
- data/STYLE +27 -0
- data/TODO.markdown +149 -0
- data/ampfile.rb +47 -0
- data/bin/amp +30 -0
- data/bin/amp1.9 +30 -0
- data/ext/amp/bz2/README.txt +39 -0
- data/ext/amp/bz2/bz2.c +1582 -0
- data/ext/amp/bz2/extconf.rb +77 -0
- data/ext/amp/bz2/mkmf.log +29 -0
- data/ext/amp/mercurial_patch/extconf.rb +5 -0
- data/ext/amp/mercurial_patch/mpatch.c +405 -0
- data/ext/amp/priority_queue/extconf.rb +5 -0
- data/ext/amp/priority_queue/priority_queue.c +947 -0
- data/ext/amp/support/extconf.rb +5 -0
- data/ext/amp/support/support.c +250 -0
- data/lib/amp.rb +200 -0
- data/lib/amp/commands/command.rb +507 -0
- data/lib/amp/commands/command_support.rb +137 -0
- data/lib/amp/commands/commands/config.rb +143 -0
- data/lib/amp/commands/commands/help.rb +29 -0
- data/lib/amp/commands/commands/init.rb +10 -0
- data/lib/amp/commands/commands/templates.rb +137 -0
- data/lib/amp/commands/commands/version.rb +7 -0
- data/lib/amp/commands/commands/workflow.rb +28 -0
- data/lib/amp/commands/commands/workflows/git/add.rb +65 -0
- data/lib/amp/commands/commands/workflows/git/copy.rb +27 -0
- data/lib/amp/commands/commands/workflows/git/mv.rb +23 -0
- data/lib/amp/commands/commands/workflows/git/rm.rb +60 -0
- data/lib/amp/commands/commands/workflows/hg/add.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/addremove.rb +86 -0
- data/lib/amp/commands/commands/workflows/hg/annotate.rb +46 -0
- data/lib/amp/commands/commands/workflows/hg/archive.rb +126 -0
- data/lib/amp/commands/commands/workflows/hg/branch.rb +28 -0
- data/lib/amp/commands/commands/workflows/hg/branches.rb +30 -0
- data/lib/amp/commands/commands/workflows/hg/bundle.rb +115 -0
- data/lib/amp/commands/commands/workflows/hg/clone.rb +95 -0
- data/lib/amp/commands/commands/workflows/hg/commit.rb +42 -0
- data/lib/amp/commands/commands/workflows/hg/copy.rb +31 -0
- data/lib/amp/commands/commands/workflows/hg/debug/dirstate.rb +32 -0
- data/lib/amp/commands/commands/workflows/hg/debug/index.rb +36 -0
- data/lib/amp/commands/commands/workflows/hg/default.rb +9 -0
- data/lib/amp/commands/commands/workflows/hg/diff.rb +30 -0
- data/lib/amp/commands/commands/workflows/hg/forget.rb +11 -0
- data/lib/amp/commands/commands/workflows/hg/heads.rb +25 -0
- data/lib/amp/commands/commands/workflows/hg/identify.rb +23 -0
- data/lib/amp/commands/commands/workflows/hg/import.rb +135 -0
- data/lib/amp/commands/commands/workflows/hg/incoming.rb +85 -0
- data/lib/amp/commands/commands/workflows/hg/info.rb +18 -0
- data/lib/amp/commands/commands/workflows/hg/log.rb +21 -0
- data/lib/amp/commands/commands/workflows/hg/manifest.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/merge.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/move.rb +28 -0
- data/lib/amp/commands/commands/workflows/hg/outgoing.rb +61 -0
- data/lib/amp/commands/commands/workflows/hg/pull.rb +74 -0
- data/lib/amp/commands/commands/workflows/hg/push.rb +20 -0
- data/lib/amp/commands/commands/workflows/hg/remove.rb +45 -0
- data/lib/amp/commands/commands/workflows/hg/resolve.rb +83 -0
- data/lib/amp/commands/commands/workflows/hg/revert.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/root.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/serve.rb +38 -0
- data/lib/amp/commands/commands/workflows/hg/status.rb +116 -0
- data/lib/amp/commands/commands/workflows/hg/tag.rb +69 -0
- data/lib/amp/commands/commands/workflows/hg/tags.rb +27 -0
- data/lib/amp/commands/commands/workflows/hg/tip.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/update.rb +27 -0
- data/lib/amp/commands/commands/workflows/hg/verify.rb +9 -0
- data/lib/amp/commands/commands/workflows/hg/view.rb +36 -0
- data/lib/amp/commands/dispatch.rb +181 -0
- data/lib/amp/commands/hooks.rb +81 -0
- data/lib/amp/dependencies/amp_support.rb +1 -0
- data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +103 -0
- data/lib/amp/dependencies/minitar.rb +979 -0
- data/lib/amp/dependencies/priority_queue.rb +18 -0
- data/lib/amp/dependencies/priority_queue/c_priority_queue.rb +1 -0
- data/lib/amp/dependencies/priority_queue/poor_priority_queue.rb +46 -0
- data/lib/amp/dependencies/priority_queue/ruby_priority_queue.rb +525 -0
- data/lib/amp/dependencies/python_config.rb +211 -0
- data/lib/amp/dependencies/trollop.rb +713 -0
- data/lib/amp/dependencies/zip/ioextras.rb +155 -0
- data/lib/amp/dependencies/zip/stdrubyext.rb +111 -0
- data/lib/amp/dependencies/zip/tempfile_bugfixed.rb +186 -0
- data/lib/amp/dependencies/zip/zip.rb +1850 -0
- data/lib/amp/dependencies/zip/zipfilesystem.rb +609 -0
- data/lib/amp/dependencies/zip/ziprequire.rb +90 -0
- data/lib/amp/encoding/base85.rb +97 -0
- data/lib/amp/encoding/binary_diff.rb +82 -0
- data/lib/amp/encoding/difflib.rb +166 -0
- data/lib/amp/encoding/mercurial_diff.rb +378 -0
- data/lib/amp/encoding/mercurial_patch.rb +1 -0
- data/lib/amp/encoding/patch.rb +292 -0
- data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +123 -0
- data/lib/amp/extensions/ditz.rb +41 -0
- data/lib/amp/extensions/lighthouse.rb +167 -0
- data/lib/amp/graphs/ancestor.rb +147 -0
- data/lib/amp/graphs/copies.rb +261 -0
- data/lib/amp/merges/merge_state.rb +164 -0
- data/lib/amp/merges/merge_ui.rb +322 -0
- data/lib/amp/merges/simple_merge.rb +450 -0
- data/lib/amp/profiling_hacks.rb +36 -0
- data/lib/amp/repository/branch_manager.rb +234 -0
- data/lib/amp/repository/dir_state.rb +950 -0
- data/lib/amp/repository/journal.rb +203 -0
- data/lib/amp/repository/lock.rb +207 -0
- data/lib/amp/repository/repositories/bundle_repository.rb +214 -0
- data/lib/amp/repository/repositories/http_repository.rb +377 -0
- data/lib/amp/repository/repositories/local_repository.rb +2661 -0
- data/lib/amp/repository/repository.rb +94 -0
- data/lib/amp/repository/store.rb +485 -0
- data/lib/amp/repository/tag_manager.rb +319 -0
- data/lib/amp/repository/updatable.rb +532 -0
- data/lib/amp/repository/verification.rb +431 -0
- data/lib/amp/repository/versioned_file.rb +475 -0
- data/lib/amp/revlogs/bundle_revlogs.rb +246 -0
- data/lib/amp/revlogs/changegroup.rb +217 -0
- data/lib/amp/revlogs/changelog.rb +338 -0
- data/lib/amp/revlogs/changeset.rb +521 -0
- data/lib/amp/revlogs/file_log.rb +165 -0
- data/lib/amp/revlogs/index.rb +493 -0
- data/lib/amp/revlogs/manifest.rb +195 -0
- data/lib/amp/revlogs/node.rb +18 -0
- data/lib/amp/revlogs/revlog.rb +1032 -0
- data/lib/amp/revlogs/revlog_support.rb +126 -0
- data/lib/amp/server/amp_user.rb +44 -0
- data/lib/amp/server/extension/amp_extension.rb +396 -0
- data/lib/amp/server/extension/authorization.rb +201 -0
- data/lib/amp/server/fancy_http_server.rb +252 -0
- data/lib/amp/server/fancy_views/_browser.haml +28 -0
- data/lib/amp/server/fancy_views/_diff_file.haml +13 -0
- data/lib/amp/server/fancy_views/_navbar.haml +17 -0
- data/lib/amp/server/fancy_views/changeset.haml +31 -0
- data/lib/amp/server/fancy_views/commits.haml +32 -0
- data/lib/amp/server/fancy_views/file.haml +35 -0
- data/lib/amp/server/fancy_views/file_diff.haml +23 -0
- data/lib/amp/server/fancy_views/harshcss/all_hallows_eve.css +72 -0
- data/lib/amp/server/fancy_views/harshcss/amy.css +147 -0
- data/lib/amp/server/fancy_views/harshcss/twilight.css +138 -0
- data/lib/amp/server/fancy_views/stylesheet.sass +175 -0
- data/lib/amp/server/http_server.rb +140 -0
- data/lib/amp/server/repo_user_management.rb +287 -0
- data/lib/amp/support/amp_config.rb +164 -0
- data/lib/amp/support/amp_ui.rb +287 -0
- data/lib/amp/support/docs.rb +54 -0
- data/lib/amp/support/generator.rb +78 -0
- data/lib/amp/support/ignore.rb +144 -0
- data/lib/amp/support/loaders.rb +93 -0
- data/lib/amp/support/logger.rb +103 -0
- data/lib/amp/support/match.rb +151 -0
- data/lib/amp/support/multi_io.rb +87 -0
- data/lib/amp/support/openers.rb +121 -0
- data/lib/amp/support/ruby_19_compatibility.rb +66 -0
- data/lib/amp/support/support.rb +1095 -0
- data/lib/amp/templates/blank.commit.erb +23 -0
- data/lib/amp/templates/blank.log.erb +18 -0
- data/lib/amp/templates/default.commit.erb +23 -0
- data/lib/amp/templates/default.log.erb +26 -0
- data/lib/amp/templates/template.rb +165 -0
- data/site/Rakefile +24 -0
- data/site/src/about/ampfile.haml +57 -0
- data/site/src/about/commands.haml +106 -0
- data/site/src/about/index.haml +33 -0
- data/site/src/about/performance.haml +31 -0
- data/site/src/about/workflows.haml +34 -0
- data/site/src/contribute/index.haml +65 -0
- data/site/src/contribute/style.haml +297 -0
- data/site/src/css/active4d.css +114 -0
- data/site/src/css/all_hallows_eve.css +72 -0
- data/site/src/css/all_themes.css +3299 -0
- data/site/src/css/amp.css +260 -0
- data/site/src/css/amy.css +147 -0
- data/site/src/css/blackboard.css +88 -0
- data/site/src/css/brilliance_black.css +605 -0
- data/site/src/css/brilliance_dull.css +599 -0
- data/site/src/css/cobalt.css +149 -0
- data/site/src/css/cur_amp.css +185 -0
- data/site/src/css/dawn.css +121 -0
- data/site/src/css/eiffel.css +121 -0
- data/site/src/css/espresso_libre.css +109 -0
- data/site/src/css/idle.css +62 -0
- data/site/src/css/iplastic.css +80 -0
- data/site/src/css/lazy.css +73 -0
- data/site/src/css/mac_classic.css +123 -0
- data/site/src/css/magicwb_amiga.css +104 -0
- data/site/src/css/pastels_on_dark.css +188 -0
- data/site/src/css/reset.css +55 -0
- data/site/src/css/slush_poppies.css +85 -0
- data/site/src/css/spacecadet.css +51 -0
- data/site/src/css/sunburst.css +180 -0
- data/site/src/css/twilight.css +137 -0
- data/site/src/css/zenburnesque.css +91 -0
- data/site/src/get/index.haml +32 -0
- data/site/src/helpers.rb +121 -0
- data/site/src/images/amp_logo.png +0 -0
- data/site/src/images/carbonica.png +0 -0
- data/site/src/images/revolution.png +0 -0
- data/site/src/images/tab-bg.png +0 -0
- data/site/src/images/tab-sliding-left.png +0 -0
- data/site/src/images/tab-sliding-right.png +0 -0
- data/site/src/include/_footer.haml +22 -0
- data/site/src/include/_header.haml +17 -0
- data/site/src/index.haml +104 -0
- data/site/src/learn/index.haml +46 -0
- data/site/src/scripts/jquery-1.3.2.min.js +19 -0
- data/site/src/scripts/jquery.cookie.js +96 -0
- data/tasks/stats.rake +155 -0
- data/tasks/yard.rake +171 -0
- data/test/dirstate_tests/dirstate +0 -0
- data/test/dirstate_tests/hgrc +5 -0
- data/test/dirstate_tests/test_dir_state.rb +192 -0
- data/test/functional_tests/resources/.hgignore +2 -0
- data/test/functional_tests/resources/STYLE.txt +25 -0
- data/test/functional_tests/resources/command.rb +372 -0
- data/test/functional_tests/resources/commands/annotate.rb +57 -0
- data/test/functional_tests/resources/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/commands/heads.rb +22 -0
- data/test/functional_tests/resources/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/commands/status.rb +90 -0
- data/test/functional_tests/resources/version2/.hgignore +5 -0
- data/test/functional_tests/resources/version2/STYLE.txt +25 -0
- data/test/functional_tests/resources/version2/command.rb +372 -0
- data/test/functional_tests/resources/version2/commands/annotate.rb +45 -0
- data/test/functional_tests/resources/version2/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version2/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version2/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version2/commands/status.rb +90 -0
- data/test/functional_tests/resources/version3/.hgignore +5 -0
- data/test/functional_tests/resources/version3/STYLE.txt +31 -0
- data/test/functional_tests/resources/version3/command.rb +376 -0
- data/test/functional_tests/resources/version3/commands/annotate.rb +45 -0
- data/test/functional_tests/resources/version3/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version3/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version3/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version3/commands/status.rb +90 -0
- data/test/functional_tests/resources/version4/.hgignore +5 -0
- data/test/functional_tests/resources/version4/STYLE.txt +31 -0
- data/test/functional_tests/resources/version4/command.rb +376 -0
- data/test/functional_tests/resources/version4/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version4/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version4/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version4/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version4/commands/status.rb +90 -0
- data/test/functional_tests/resources/version5_1/.hgignore +5 -0
- data/test/functional_tests/resources/version5_1/STYLE.txt +2 -0
- data/test/functional_tests/resources/version5_1/command.rb +374 -0
- data/test/functional_tests/resources/version5_1/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version5_1/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version5_1/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version5_1/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version5_1/commands/status.rb +90 -0
- data/test/functional_tests/resources/version5_2/.hgignore +5 -0
- data/test/functional_tests/resources/version5_2/STYLE.txt +14 -0
- data/test/functional_tests/resources/version5_2/command.rb +376 -0
- data/test/functional_tests/resources/version5_2/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version5_2/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version5_2/commands/newz.rb +12 -0
- data/test/functional_tests/resources/version5_2/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version5_2/commands/status.rb +90 -0
- data/test/functional_tests/test_functional.rb +604 -0
- data/test/localrepo_tests/test_local_repo.rb +121 -0
- data/test/localrepo_tests/testrepo.tar.gz +0 -0
- data/test/manifest_tests/00manifest.i +0 -0
- data/test/manifest_tests/test_manifest.rb +72 -0
- data/test/merge_tests/base.txt +10 -0
- data/test/merge_tests/expected.local.txt +16 -0
- data/test/merge_tests/local.txt +11 -0
- data/test/merge_tests/remote.txt +11 -0
- data/test/merge_tests/test_merge.rb +26 -0
- data/test/revlog_tests/00changelog.i +0 -0
- data/test/revlog_tests/revision_added_changelog.i +0 -0
- data/test/revlog_tests/test_adding_index.i +0 -0
- data/test/revlog_tests/test_revlog.rb +333 -0
- data/test/revlog_tests/testindex.i +0 -0
- data/test/store_tests/store.tar.gz +0 -0
- data/test/store_tests/test_fncache_store.rb +122 -0
- data/test/test_amp.rb +9 -0
- data/test/test_base85.rb +14 -0
- data/test/test_bdiff.rb +42 -0
- data/test/test_commands.rb +122 -0
- data/test/test_difflib.rb +50 -0
- data/test/test_helper.rb +15 -0
- data/test/test_journal.rb +29 -0
- data/test/test_match.rb +134 -0
- data/test/test_mdiff.rb +74 -0
- data/test/test_mpatch.rb +14 -0
- data/test/test_support.rb +24 -0
- metadata +385 -0
@@ -0,0 +1,201 @@
|
|
1
|
+
# Stolen from http://github.com/integrity/sinatra-authorization/blob/0761b5cc58597227364a9c8f3e91fcfc43154555/lib/sinatra/authorization.rb
|
2
|
+
# thank you!
|
3
|
+
|
4
|
+
require "sinatra/base"
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
# Code adapted from {Ryan Tomayko}[http://tomayko.com/about] and
|
8
|
+
# {Christopher Schneid}[http://gittr.com], shared under an MIT License
|
9
|
+
# Code significantly refactored for Amp
|
10
|
+
module AbstractAuthorization
|
11
|
+
def unauthorized!(www_authenticate = challenge)
|
12
|
+
response["WWW-Authenticate"] = challenge
|
13
|
+
throw :halt, [ 401, 'Authorization Required' ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def bad_request!
|
17
|
+
throw :halt, [ 400, 'Bad Request' ]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Convenience method to determine if a user is logged in
|
21
|
+
def authorized?
|
22
|
+
!!request.env['REMOTE_USER']
|
23
|
+
end
|
24
|
+
alias :logged_in? :authorized?
|
25
|
+
|
26
|
+
# Name provided by the current user to log in
|
27
|
+
def current_user
|
28
|
+
request.env['REMOTE_USER']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# HTTP Authorization helpers for Sinatra.
|
34
|
+
#
|
35
|
+
# In your helpers module, include Sinatra::Authorization and then define
|
36
|
+
# an #authorize(user, password) method to handle user provided
|
37
|
+
# credentials.
|
38
|
+
#
|
39
|
+
# Inside your events, call #login_required to trigger the HTTP
|
40
|
+
# Authorization window to pop up in the browser.
|
41
|
+
#
|
42
|
+
# Code adapted from {Ryan Tomayko}[http://tomayko.com/about] and
|
43
|
+
# {Christopher Schneid}[http://gittr.com], shared under an MIT License
|
44
|
+
# Code significantly refactored for Amp
|
45
|
+
module BasicAuthorization
|
46
|
+
include AbstractAuthorization
|
47
|
+
#
|
48
|
+
# # From you app, call set :authorization_realm, "my app" to set this
|
49
|
+
# # or define a #authorization_realm method in your helpers block.
|
50
|
+
def challenge
|
51
|
+
%(Basic realm="#{options.authorization_realm}")
|
52
|
+
end
|
53
|
+
|
54
|
+
# Call in any event that requires authentication
|
55
|
+
def login_required
|
56
|
+
return if authorized?
|
57
|
+
unauthorized! unless auth.provided?
|
58
|
+
bad_request! unless auth.basic?
|
59
|
+
unauthorized! unless authorize(*auth.credentials)
|
60
|
+
request.env['REMOTE_USER'] = auth.username
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
##
|
65
|
+
# Whether or not the supplied username and password (and path) combination
|
66
|
+
# are, as Taco Bell says, "Good To Go".
|
67
|
+
#
|
68
|
+
# @param [String] username the plaintext that is passed in from the browser
|
69
|
+
# @param [String] password the plaintext (!!!!!!) password from the browser
|
70
|
+
# @return [Boolean] is the user/pass/path combo authorized?
|
71
|
+
def authorize(username, password)
|
72
|
+
repo = self.class.amp_repositories[request.path_info]
|
73
|
+
return true unless repo && repos[repo]
|
74
|
+
|
75
|
+
user = get_user_and_permissions repo, username # user = {:user => ..., :read => ..., :write => ...}
|
76
|
+
return false if command_reads?(params["cmd"]) && !user[:read]
|
77
|
+
return false if !command_reads?(params["cmd"]) &&
|
78
|
+
!user[:write] && repo_is_private?(repo)
|
79
|
+
|
80
|
+
user[:user].password == password
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def auth
|
86
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# liberally lifted and modified from Rack's source
|
91
|
+
# Code slightly refactored for Amp
|
92
|
+
module DigestAuthorization
|
93
|
+
include AbstractAuthorization
|
94
|
+
|
95
|
+
def opaque; "DEADBEEF"; end
|
96
|
+
|
97
|
+
QOP = 'auth'.freeze
|
98
|
+
|
99
|
+
def login_required
|
100
|
+
auth = Rack::Auth::Digest::Request.new(request.env)
|
101
|
+
unauthorized! unless auth.provided?
|
102
|
+
bad_request! if !auth.digest?
|
103
|
+
if valid?(auth)
|
104
|
+
if auth.nonce.stale?
|
105
|
+
return unauthorized!(challenge(:stale => true))
|
106
|
+
else
|
107
|
+
request.env["REMOTE_USER"] = auth.username
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
unauthorized!
|
112
|
+
end
|
113
|
+
|
114
|
+
##
|
115
|
+
# This method verifies that the digest provided is accurate. This is the only
|
116
|
+
# method involved in the authentication process that requires knowledge of the login
|
117
|
+
# system, so it is exposed here, rather than {Sinatra::DigestAuthorization}.
|
118
|
+
#
|
119
|
+
# @param [Rack::Request] auth The request being used for authorization
|
120
|
+
# @return [Boolean] is the user allowed to view the given material?
|
121
|
+
def valid_digest?(auth)
|
122
|
+
repo = self.class.amp_repositories[request.path_info]
|
123
|
+
# no repo OR no users added to repo --> Access to anyone
|
124
|
+
return true unless repo && repos[repo]
|
125
|
+
|
126
|
+
user = get_user_and_permissions repo, auth.username
|
127
|
+
# User not in the system at all? Denied!
|
128
|
+
return false unless user
|
129
|
+
|
130
|
+
# if we're private
|
131
|
+
if repo_is_private?(repo)
|
132
|
+
# and the command is read-only, but user cannot read, they get Ben Wallace'd
|
133
|
+
return false if command_reads?(params["cmd"]) && !user[:read]
|
134
|
+
end
|
135
|
+
|
136
|
+
# Command is write-only, but user cannot write --> Denied. Private/non-private doesn't matter.
|
137
|
+
return false if command_writes?(params["cmd"]) && !user[:write]
|
138
|
+
|
139
|
+
# Can't short-circuit this one. Just run the digest.
|
140
|
+
digest(auth, user[:user].password) == auth.response
|
141
|
+
end
|
142
|
+
|
143
|
+
def auth_params(hash = {})
|
144
|
+
param = Rack::Auth::Digest::Params.new do |param|
|
145
|
+
param['realm'] = options.authorization_realm
|
146
|
+
param['nonce'] = Rack::Auth::Digest::Nonce.new.to_s
|
147
|
+
param['opaque'] = H(opaque)
|
148
|
+
param['qop'] = QOP
|
149
|
+
hash.each { |k, v| param[k] = v }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def challenge(hash = {})
|
154
|
+
"Digest #{auth_params(hash)}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def valid?(auth)
|
158
|
+
valid_opaque?(auth) && valid_nonce?(auth) && valid_digest?(auth)
|
159
|
+
end
|
160
|
+
|
161
|
+
def valid_qop?(auth)
|
162
|
+
QOP == auth.qop
|
163
|
+
end
|
164
|
+
|
165
|
+
def valid_opaque?(auth)
|
166
|
+
H(opaque) == auth.opaque
|
167
|
+
end
|
168
|
+
|
169
|
+
def valid_nonce?(auth)
|
170
|
+
auth.nonce.valid?
|
171
|
+
end
|
172
|
+
|
173
|
+
def md5(data)
|
174
|
+
::Digest::MD5.hexdigest(data)
|
175
|
+
end
|
176
|
+
|
177
|
+
alias :H :md5
|
178
|
+
|
179
|
+
def KD(secret, data)
|
180
|
+
H([secret, data] * ':')
|
181
|
+
end
|
182
|
+
|
183
|
+
def A1(auth, password)
|
184
|
+
[ auth.username, auth.realm, password ] * ':'
|
185
|
+
end
|
186
|
+
|
187
|
+
def A2(auth)
|
188
|
+
[ auth.method, auth.uri ] * ':'
|
189
|
+
end
|
190
|
+
|
191
|
+
def digest(auth, password)
|
192
|
+
# change false to match if we ever store hashed passes
|
193
|
+
password_hash = false ? password : H(A1(auth, password))
|
194
|
+
|
195
|
+
KD(password_hash, [ auth.nonce, auth.nc, auth.cnonce, QOP, H(A2(auth)) ] * ':')
|
196
|
+
end
|
197
|
+
end
|
198
|
+
# add them in
|
199
|
+
helpers BasicAuthorization
|
200
|
+
helpers DigestAuthorization
|
201
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'haml'
|
3
|
+
require 'sass'
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
alias_method :get, :[]
|
7
|
+
##
|
8
|
+
# Same as #[], but will take regexps and try to match those.
|
9
|
+
# This will bug out if you are using regexps as keys
|
10
|
+
#
|
11
|
+
# @return [Hash, Value] will return either a hash (if supplied with a regexp)
|
12
|
+
# or whatever it would normally return.
|
13
|
+
def [](key)
|
14
|
+
case key
|
15
|
+
when Regexp
|
16
|
+
select {|k, _| k =~ key }.to_hash
|
17
|
+
else
|
18
|
+
get key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Amp
|
24
|
+
module Servers
|
25
|
+
|
26
|
+
class FancyHTTPServer < HTTPAuthorizedServer
|
27
|
+
|
28
|
+
set :views, File.expand_path(File.join(File.dirname(__FILE__), "fancy_views"))
|
29
|
+
enable :static
|
30
|
+
set :public, File.expand_path(File.join(File.dirname(__FILE__), "fancy_views"))
|
31
|
+
|
32
|
+
def self.amp_repository(http_path, repo, opts={})
|
33
|
+
super(http_path, repo)
|
34
|
+
|
35
|
+
http_path.chomp!('/')
|
36
|
+
path_slashed = http_path + "/"
|
37
|
+
|
38
|
+
get "#{http_path}/changeset/:changeset/?" do |cs|
|
39
|
+
@changeset = repo[cs]
|
40
|
+
haml :changeset, :locals => {:root => http_path, :repo => repo}
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
[http_path+"/", "#{http_path}/commits/?", "#{http_path}/commits/:page/?"].each do |path|
|
45
|
+
get path do
|
46
|
+
haml :commits, :locals => {:root => http_path, :opts => opts, :repo => repo, :page => params[:page].to_i}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
get "#{http_path}/users/:user" do
|
52
|
+
if users[params[:user]]
|
53
|
+
"You are browsing user #{params[:user]} in a repository located at #{repo.inspect}"
|
54
|
+
else
|
55
|
+
"User #{params[:user].inspect} not found :-("
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
["#{http_path}/code/:changeset/?*", "#{http_path}/code/?*"].each do |p|
|
60
|
+
get p do
|
61
|
+
path = params[:splat].join
|
62
|
+
path = path.shift('/').chomp('/') # clean it of slashes
|
63
|
+
changeset_node = params[:changeset] || "tip"
|
64
|
+
changeset = repo[changeset_node]
|
65
|
+
|
66
|
+
info = load_browser_info changeset, path
|
67
|
+
file_list, path, vf_cur, orig_path = info[:file_list], info[:path], info[:vf_cur], info[:orig_path]
|
68
|
+
|
69
|
+
haml :file, :locals => {:root => http_path, :repo => repo, :file_list => file_list,
|
70
|
+
:path => path, :vf_cur => vf_cur, :orig_path => orig_path,
|
71
|
+
:changeset => changeset}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
get "#{http_path}/diff/:changeset/*" do
|
76
|
+
path = params[:splat].join
|
77
|
+
path = path.shift('/').chomp('/') # clean it of slashes
|
78
|
+
changeset_node = params[:changeset] || "tip"
|
79
|
+
changeset = repo[changeset_node]
|
80
|
+
|
81
|
+
info = load_browser_info changeset, path
|
82
|
+
file_list, path, vf_cur, orig_path = info[:file_list], info[:path], info[:vf_cur], info[:orig_path]
|
83
|
+
|
84
|
+
haml :file_diff, :locals => {:root => http_path, :repo => repo, :file_list => file_list,
|
85
|
+
:path => path, :vf_cur => vf_cur, :orig_path => orig_path,
|
86
|
+
:changeset => changeset}
|
87
|
+
end
|
88
|
+
|
89
|
+
get "#{http_path}/raw/:changeset/*" do
|
90
|
+
changeset_node = params[:changeset]
|
91
|
+
path = params[:splat].join.shift("/").chomp("/")
|
92
|
+
|
93
|
+
changeset = repo[changeset_node]
|
94
|
+
vf_cur = changeset.get_file path
|
95
|
+
|
96
|
+
content_type "text/plain"
|
97
|
+
vf_cur.data
|
98
|
+
end
|
99
|
+
|
100
|
+
get '/stylesheet.css' do
|
101
|
+
content_type 'text/css', :charset => 'utf-8'
|
102
|
+
sass :stylesheet
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
helpers do
|
108
|
+
|
109
|
+
def load_browser_info(changeset, path)
|
110
|
+
|
111
|
+
mapping = changeset.manifest
|
112
|
+
orig_path = nil
|
113
|
+
# if the path is a file (because we only keep track of files)
|
114
|
+
if mapping[path]
|
115
|
+
# give it the appropriate information (the versioned file)
|
116
|
+
vf_cur = changeset.get_file(path)
|
117
|
+
file_list = [] # and return an empty file_list
|
118
|
+
orig_path = path
|
119
|
+
path = Dir.dirname path
|
120
|
+
end
|
121
|
+
|
122
|
+
files = mapping.files.select {|f| Dir.dirname(f) == path }.map {|f| f[path.size..-1].shift '/' }
|
123
|
+
dirs = mapping.files.select {|f| File.amp_directories_to(f, true).index(path) && Dir.dirname(f) != path } # only go one deep
|
124
|
+
dirs.map! do |d|
|
125
|
+
idx = File.amp_directories_to(d, true).index path
|
126
|
+
File.amp_directories_to(d, true)[idx - 1][path.size..-1].shift '/'
|
127
|
+
end.uniq!
|
128
|
+
|
129
|
+
path = path.empty? ? '' : path + '/'
|
130
|
+
|
131
|
+
file_list = files.map do |name|
|
132
|
+
{:link => path + name ,
|
133
|
+
:type => :file,
|
134
|
+
:name => name }
|
135
|
+
end
|
136
|
+
|
137
|
+
file_list += dirs.map do |name|
|
138
|
+
{:link => path + name,
|
139
|
+
:type => :directory ,
|
140
|
+
:name => name }
|
141
|
+
end
|
142
|
+
|
143
|
+
file_list.sort! {|h1, h2| h1[:name] <=> h2[:name] } # alphabetically sorted
|
144
|
+
vf_cur ||= if mapping[/#{path}readme/i].any? # map[//] returns a hash
|
145
|
+
change_id = params[:changeset] || "tip"
|
146
|
+
readme = mapping[/#{path}readme/i].keys.first
|
147
|
+
orig_path = readme
|
148
|
+
changeset.get_file readme
|
149
|
+
else
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
153
|
+
path = path.chomp '/' # path will not have any trailing slashes
|
154
|
+
|
155
|
+
{:path => path, :vf_cur => vf_cur, :file_list => file_list, :orig_path => orig_path}
|
156
|
+
end
|
157
|
+
|
158
|
+
def link(root, action, changeset_node, after_path, opts={})
|
159
|
+
after_path = "/#{after_path}" if after_path
|
160
|
+
changeset_node = changeset_node[0..11]
|
161
|
+
text = opts.delete(:text) || changeset_node
|
162
|
+
additional_opts = opts.map {|key, value| %{#{key}="#{value}"}}.join(" ")
|
163
|
+
%{<a href="#{root}/#{action}/#{changeset_node}#{after_path}" #{additional_opts}>
|
164
|
+
#{text}
|
165
|
+
</a>}
|
166
|
+
end
|
167
|
+
|
168
|
+
def link_to_changeset(root, changeset_node, opts={})
|
169
|
+
link(root, :changeset, changeset_node, nil, opts)
|
170
|
+
end
|
171
|
+
|
172
|
+
def link_to_file(root, changeset_node, file=nil, opts={})
|
173
|
+
opts[:text] ||= file
|
174
|
+
link(root, :code, changeset_node, file, opts)
|
175
|
+
end
|
176
|
+
|
177
|
+
def link_to_file_raw(root, changeset_node, file=nil, opts={})
|
178
|
+
opts[:text] ||= file
|
179
|
+
link(root, :raw, changeset_node, file, opts)
|
180
|
+
end
|
181
|
+
|
182
|
+
def link_to_file_diff(root, changeset_node, file=nil, opts={})
|
183
|
+
opts[:text] ||= file
|
184
|
+
link(root, :diff, changeset_node, file, opts)
|
185
|
+
end
|
186
|
+
|
187
|
+
def highlight_text(text, opts = {:format => "ruby", :theme => "twilight", :lines => false})
|
188
|
+
require 'uv'
|
189
|
+
::Haml::Helpers.preserve(Uv.parse( text.rstrip, "xhtml", opts[:format].to_s, opts[:lines], opts[:theme]))
|
190
|
+
end
|
191
|
+
|
192
|
+
def rel_date(o_date)
|
193
|
+
a = (Time.now-o_date).to_i
|
194
|
+
case a
|
195
|
+
when 0 then return 'just now'
|
196
|
+
when 1 then return 'a second ago'
|
197
|
+
when 2..59 then return a.to_s+' seconds ago'
|
198
|
+
when 60..119 then return 'a minute ago' #120 = 2 minutes
|
199
|
+
when 120..3540 then return (a/60).to_i.to_s+' minutes ago'
|
200
|
+
when 3541..7100 then return 'an hour ago' # 3600 = 1 hour
|
201
|
+
when 7101..82800 then return ((a+99)/3600).to_i.to_s+' hours ago'
|
202
|
+
when 82801..172000 then return 'a day ago' # 86400 = 1 day
|
203
|
+
when 172001..518400 then return ((a+800)/(60*60*24)).to_i.to_s+' days ago'
|
204
|
+
end
|
205
|
+
return o_date.strftime("%B %d, %Y")
|
206
|
+
end
|
207
|
+
|
208
|
+
def format_for_filename(ext)
|
209
|
+
ext = File.extname(ext)
|
210
|
+
return :text if ext.nil? || ext.empty?
|
211
|
+
|
212
|
+
case ext.downcase
|
213
|
+
when ".rb"
|
214
|
+
:ruby
|
215
|
+
when ".py"
|
216
|
+
:python
|
217
|
+
when ".cpp"
|
218
|
+
:"c++"
|
219
|
+
when ".txt"
|
220
|
+
:text
|
221
|
+
else
|
222
|
+
ext[1..-1].to_sym
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def parse_diff(input_diff)
|
227
|
+
line_counter_a, line_counter_b = 0, 0
|
228
|
+
input_diff.split_lines_better.map do |line|
|
229
|
+
if line[0,1] == ' '
|
230
|
+
res = %{<li class='diff-unmod'><pre>#{line_counter_a} #{line_counter_b} #{line.rstrip}</pre></li>\n}
|
231
|
+
line_counter_a += 1
|
232
|
+
line_counter_b += 1
|
233
|
+
elsif line[0,3] == '+++'
|
234
|
+
elsif line[0,3] == '---'
|
235
|
+
elsif line[0,1] == '+'
|
236
|
+
res = %{<li class='diff-add'><pre>#{" " * line_counter_b.to_s.size} #{line_counter_b} #{line.rstrip}</pre></li>\n}
|
237
|
+
line_counter_b += 1
|
238
|
+
elsif line[0,1] == '-'
|
239
|
+
res = %{<li class='diff-del'><pre>#{line_counter_a} #{" " * line_counter_a.to_s.size} #{line.rstrip}</pre></li>\n}
|
240
|
+
line_counter_a += 1
|
241
|
+
elsif line[0,2] == '@@'
|
242
|
+
line_counter_a, line_counter_b = line.scan(/\-(\d+),\d+ \+(\d+),\d+/).shift.map {|x| x.to_i}
|
243
|
+
res = %{<li class='diff-ctx'><pre> #{line.rstrip}</pre></li>\n}
|
244
|
+
end
|
245
|
+
res
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|