amp 0.5.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.
- 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
|