By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

 gitHTTP.py

View raw Download
text/x-script.python • 2.75 kiB
Python script, ASCII text executable
        
            
1
import uuid
2
3
from app import app, User, Repo, db, bcrypt
4
import os
5
import shutil
6
import config
7
import flask
8
import git
9
import subprocess
10
from flask_httpauth import HTTPBasicAuth
11
import zlib
12
13
auth = HTTPBasicAuth(realm=config.AUTH_REALM)
14
15
16
@auth.verify_password
17
def verifyPassword(username, password):
18
user = User.query.filter_by(username=username).first()
19
20
if user and bcrypt.check_password_hash(user.passwordHashed, password):
21
flask.g.user = username
22
return True
23
24
return False
25
26
27
def gitCommand(repo, data, *args):
28
if not os.path.isdir(repo):
29
raise FileNotFoundError("Repo not found")
30
env = os.environ.copy()
31
32
command = ["git", *args]
33
print("RUNNING GIT COMMAND")
34
print(" ".join(command))
35
proc = subprocess.Popen(" ".join(command), cwd=repo, env=env, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
36
print(command)
37
38
if data:
39
proc.stdin.write(data)
40
41
out, err = proc.communicate()
42
return out
43
44
45
@app.route("/git/<username>/<repository>/git-upload-pack", methods=["POST"])
46
@auth.login_required
47
def gitUploadPack(username, repository):
48
serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
49
text = gitCommand(serverRepoLocation, flask.request.data, "upload-pack", "--stateless-rpc", ".")
50
51
return flask.Response(text, content_type="application/x-git-upload-pack-result")
52
53
54
@app.route("/git/<username>/<repository>/git-receive-pack", methods=["POST"])
55
@auth.login_required
56
def gitReceivePack(username, repository):
57
serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
58
text = gitCommand(serverRepoLocation, flask.request.data, "receive-pack", "--stateless-rpc", ".")
59
60
return flask.Response(text, content_type="application/x-git-receive-pack-result")
61
62
63
@app.route("/git/<username>/<repository>/info/refs", methods=["GET"])
64
@auth.login_required
65
def gitInfoRefs(username, repository):
66
serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository, ".git")
67
service = flask.request.args.get("service")
68
69
if service.startswith("git"):
70
service = service[4:]
71
72
print(service)
73
74
serviceLine = f"# service=git-{service}\n"
75
serviceLine = (f"{len(serviceLine) + 4:04x}" + serviceLine).encode()
76
77
if service == "upload-pack":
78
text = serviceLine + b"0000" + gitCommand(serverRepoLocation, None, "upload-pack", "--stateless-rpc", "--advertise-refs", "--http-backend-info-refs", ".")
79
elif service == "receive-pack":
80
text = serviceLine + b"0000" + gitCommand(serverRepoLocation, None, "receive-pack", "--http-backend-info-refs", ".")
81
82
response = flask.Response(text, content_type=f"application/x-git-{service}-advertisement")
83
response.headers["Cache-Control"] = "no-cache"
84
85
return response
86
87