Klaus Demo ~jonashaag/klaus / 874b542
Whole-site password protection #88 It's now possible to require HTTP authentication for all of the Web interface (not only push/pull). This isn't available from the command line. Note that when both whole-site password protection and Smart HTTP mode is enabled, push is allowed by default. It can be disallowed using the 'disable_push' option. Jonas Haag 7 years ago
1 changed file(s) with 36 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
6060 self.add_url_rule(rule, view_func=getattr(views, endpoint))
6161
6262
63 def make_app(repos, site_name, use_smarthttp=False, htdigest_file=None):
63 def make_app(repos, site_name, use_smarthttp=False, htdigest_file=None,
64 require_browser_auth=False, disable_push=False):
6465 """
6566 Returns a WSGI app with all the features (smarthttp, authentication)
6667 already patched in.
68
69 :param repos: List of paths of repositories to serve.
70 :param site_name: Name of the Web site (e.g. "John Doe's Git Repositories")
71 :param use_smarthttp: Enable Git Smart HTTP mode, which makes it possible to
72 pull from the served repositories. If `htdigest_file` is set as well,
73 also allow to push for authenticated users.
74 :param require_browser_auth: Require HTTP authentication according to the
75 credentials in `htdigest_file` for ALL access to the Web interface.
76 Requires the `htdigest_file` option to be set.
77 :param disable_push: Disable push support. This is required in case both
78 `use_smarthttp` and `require_browser_auth` (and thus `htdigest_file`)
79 are set, but push should not be supported.
80 :param htdigest_file: A *file-like* object that contains the HTTP auth credentials.
6781 """
6882 app = Klaus(
6983 repos,
8397 backend=dulwich_backend,
8498 fallback_app=app.wsgi_app,
8599 )
100 dulwich_wrapped_app = utils.SubUri(dulwich_wrapped_app)
86101
87102 # `receive-pack` is requested by the "client" on a push
88103 # (the "server" is asked to *receive* packs), i.e. we need to secure
99114 # failed for /info/refs, but since it's used to upload stuff to the server
100115 # we must secure it anyway for security reasons.
101116 PATTERN = r'^/[^/]+/(info/refs\?service=git-receive-pack|git-receive-pack)$'
102 if htdigest_file:
117 if htdigest_file and not disable_push:
103118 # .htdigest file given. Use it to read the push-er credentials from.
104 app.wsgi_app = httpauth.DigestFileHttpAuthMiddleware(
105 htdigest_file,
106 wsgi_app=utils.SubUri(dulwich_wrapped_app),
107 routes=[PATTERN],
108 )
119 if require_browser_auth:
120 # No need to secure push'ing if we already require HTTP auth
121 # for all of the Web interface.
122 app.wsgi_app = dulwich_wrapped_app
123 else:
124 # Web interface isn't already secured. Require authentication for push'ing.
125 app.wsgi_app = httpauth.DigestFileHttpAuthMiddleware(
126 htdigest_file,
127 wsgi_app=dulwich_wrapped_app,
128 routes=[PATTERN],
129 )
109130 else:
110 # no .htdigest file given. Disable push-ing. Semantically we should
131 # No .htdigest file given. Disable push-ing. Semantically we should
111132 # use HTTP 403 here but since that results in freaky error messages
112133 # (see above) we keep asking for authentication (401) instead.
113134 # Git will print a nice error message after a few tries.
114135 app.wsgi_app = httpauth.AlwaysFailingAuthMiddleware(
115 wsgi_app=utils.SubUri(dulwich_wrapped_app),
136 wsgi_app=dulwich_wrapped_app,
116137 routes=[PATTERN],
117138 )
118139
140 if require_browser_auth:
141 app.wsgi_app = httpauth.DigestFileHttpAuthMiddleware(
142 htdigest_file,
143 wsgi_app=app.wsgi_app
144 )
145
119146 return app