forked from tsg-ut/ctfd-plugin-tsgctf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gcpuploader.py
78 lines (63 loc) · 2.43 KB
/
gcpuploader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import os
import os.path
import string
import sys
from flask import current_app, redirect
from google.oauth2 import service_account
from google.cloud import storage
from werkzeug.utils import secure_filename
from CTFd.utils import get_app_config
from CTFd.utils.uploads import UPLOADERS
from CTFd.utils.uploads.uploaders import BaseUploader
from CTFd.utils.encoding import hexencode
# Requires setting GCP_STORE_CRED and GCP_STORE_BUCKET vars
# and GCP_STORE_CRED should be a json file for our private key creds
#
# Should also modify the requirements.in and requiremnts.txt file to have
# google-cloud-storage==1.33.0 dependency
class GCPUploader(BaseUploader):
def __init__(self):
super(BaseUploader, self).__init__()
self.gcp = storage.Client.from_service_account_json(
get_app_config('GCP_STORE_CRED'))
self.bucket = self.gcp.get_bucket(get_app_config("GCP_STORE_BUCKET"))
def _clean_filename(self, c):
if c in string.ascii_letters + string.digits + "-" + "_" + ".":
return True
def store(self, fileobj, filename):
blob = self.bucket.blob(filename)
blob.upload_from_file(fileobj)
blob.make_public()
return filename
def upload(self, file_obj, filename):
filename = filter(
self._clean_filename, secure_filename(filename).replace(" ", "_")
)
filename = "".join(filename)
if len(filename) <= 0:
return False
md5hash = hexencode(os.urandom(16))
dst = md5hash + "/" + filename
return self.store(file_obj, dst)
def download(self, filename):
blob = self.bucket.blob(filename)
return redirect(blob.public_url)
def delete(self, filename):
try:
# Might have an error if it's not there
blob = self.bucket.blob(filename)
blob.delete()
except:
import traceback
traceback.print_exc(file=sys.stdout)
def sync(self):
local_folder = current_app.config.get("UPLOAD_FOLDER")
for blob in self.bucket.list_blobs():
if blob.name.endswith("/") is False:
local_path = os.path.join(local_folder, blob.name)
directory = os.path.dirname(local_path)
if not os.path.exists(directory):
os.makedirs(directory)
blob.download_to_file(local_path)
def load(app):
UPLOADERS['gcp'] = GCPUploader