837 def do_capabilities(self, req): |
837 def do_capabilities(self, req): |
838 resp = 'unbundle' |
838 resp = 'unbundle' |
839 req.httphdr("application/mercurial-0.1", length=len(resp)) |
839 req.httphdr("application/mercurial-0.1", length=len(resp)) |
840 req.write(resp) |
840 req.write(resp) |
841 |
841 |
|
842 def check_perm(self, req, op, default): |
|
843 '''check permission for operation based on user auth. |
|
844 return true if op allowed, else false. |
|
845 default is policy to use if no config given.''' |
|
846 |
|
847 user = req.env.get('REMOTE_USER') |
|
848 |
|
849 deny = self.repo.ui.config('web', 'deny_' + op, '') |
|
850 deny = deny.replace(',', ' ').split() |
|
851 |
|
852 if deny and (not user or deny == ['*'] or user in deny): |
|
853 return False |
|
854 |
|
855 allow = self.repo.ui.config('web', 'allow_' + op, '') |
|
856 allow = allow.replace(',', ' ').split() |
|
857 |
|
858 return (allow and (allow == ['*'] or user in allow)) or default |
|
859 |
842 def do_unbundle(self, req): |
860 def do_unbundle(self, req): |
|
861 def bail(response, headers={}): |
|
862 length = int(req.env['CONTENT_LENGTH']) |
|
863 for s in util.filechunkiter(req, limit=length): |
|
864 # drain incoming bundle, else client will not see |
|
865 # response when run outside cgi script |
|
866 pass |
|
867 req.httphdr("application/mercurial-0.1", headers=headers) |
|
868 req.write('0\n') |
|
869 req.write(response) |
|
870 |
|
871 # require ssl by default, auth info cannot be sniffed and |
|
872 # replayed |
|
873 ssl_req = self.repo.ui.configbool('web', 'push_ssl', True) |
|
874 if ssl_req and not req.env.get('HTTPS'): |
|
875 bail(_('ssl required\n')) |
|
876 return |
|
877 |
|
878 # do not allow push unless explicitly allowed |
|
879 if not self.check_perm(req, 'push', False): |
|
880 bail(_('push not authorized\n'), |
|
881 headers={'status': '401 Unauthorized'}) |
|
882 return |
|
883 |
|
884 req.httphdr("application/mercurial-0.1") |
|
885 |
843 their_heads = req.form['heads'][0].split(' ') |
886 their_heads = req.form['heads'][0].split(' ') |
844 |
887 |
845 def check_heads(): |
888 def check_heads(): |
846 heads = map(hex, self.repo.heads()) |
889 heads = map(hex, self.repo.heads()) |
847 return their_heads == [hex('force')] or their_heads == heads |
890 return their_heads == [hex('force')] or their_heads == heads |
848 |
891 |
849 req.httphdr("application/mercurial-0.1") |
|
850 |
|
851 # fail early if possible |
892 # fail early if possible |
852 if not check_heads(): |
893 if not check_heads(): |
853 req.write('0\n') |
894 bail(_('unsynced changes\n')) |
854 req.write(_('unsynced changes\n')) |
|
855 return |
895 return |
856 |
896 |
857 # do not lock repo until all changegroup data is |
897 # do not lock repo until all changegroup data is |
858 # streamed. save to temporary file. |
898 # streamed. save to temporary file. |
859 |
899 |