]> git.ipfire.org Git - pbs.git/blame - src/web/uploads.py
Merge Pakfire Hub into the main webapp
[pbs.git] / src / web / uploads.py
CommitLineData
a097e88a
MT
1#!/usr/bin/python3
2###############################################################################
3# #
4# Pakfire - The IPFire package management system #
5# Copyright (C) 2011 Pakfire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
fe59762c 22import io
a097e88a
MT
23import tornado.web
24
f062b044 25from . import base
a097e88a
MT
26from .. import users
27
a097e88a 28@tornado.web.stream_request_body
f062b044
MT
29class APIv1IndexHandler(base.APIMixin, tornado.web.RequestHandler):
30 # Allow users to perform uploads
31 allow_users = True
32
a097e88a 33 def initialize(self):
fe59762c
MT
34 # Buffer to cache the uploaded content
35 self.buffer = io.BytesIO()
36
37 def data_received(self, data):
38 """
39 Called when some data is being received
40 """
41 self.buffer.write(data)
42
962e472b
MT
43 @tornado.web.authenticated
44 def get(self):
45 uploads = []
46
47 for upload in self.current_user.uploads:
48 uploads.append({
49 "id" : upload.uuid,
50 "filename" : upload.filename,
51 "size" : upload.size,
52
53 "created_at" : upload.created_at.isoformat(),
54 "expires_at" : upload.expires_at.isoformat(),
55 })
56
57 self.finish({
58 "status" : "ok",
59 "uploads" : uploads,
60 })
61
fe59762c
MT
62 @tornado.web.authenticated
63 async def put(self):
64 """
65 Called after the entire file has been received
66 """
a097e88a 67 # Fetch the filename
7ef2c528 68 filename = self.get_argument("filename")
a097e88a
MT
69
70 # Fetch file size
7ef2c528 71 size = self.get_argument_int("size")
a097e88a 72
fe59762c
MT
73 # Fetch the digest argument
74 algo, delim, hexdigest = self.get_argument("digest").partition(":")
75
76 # Convert hexdigest
77 digest = bytes.fromhex(hexdigest)
78
79 # Move to the beginning of the buffer
80 self.buffer.seek(0)
81
7ef2c528
MT
82 # Create a new upload
83 with self.db.transaction():
a097e88a 84 try:
fe59762c 85 upload = self.backend.uploads.create(
7ef2c528
MT
86 filename,
87 size=size,
f062b044 88 uploader=self.current_user,
7ef2c528 89 )
fe59762c 90
a097e88a
MT
91 except users.QuotaExceededError as e:
92 raise tornado.web.HTTPError(400,
93 "Quota exceeded for %s" % self.current_user) from e
94
fe59762c
MT
95 # Import the payload from the buffer
96 await upload.copyfrom(self.buffer)
a097e88a 97
fe59762c
MT
98 # Check the digest
99 if not await upload.check_digest(algo, digest):
100 # 422 - Unprocessable Entity
101 raise tornado.web.HTTPError(422, "Digest did not match")
a097e88a
MT
102
103 # Send the ID of the upload back to the client
104 self.finish({
fe59762c
MT
105 "id" : upload.uuid,
106 "expires_at" : upload.expires_at.isoformat(),
a097e88a 107 })
9eaf98bf 108
f062b044
MT
109
110class APIv1DetailHandler(base.APIMixin, tornado.web.RequestHandler):
111 # Allow users to perform uploads
112 allow_users = True
113
9eaf98bf 114 @tornado.web.authenticated
f062b044 115 async def delete(self, uuid):
9eaf98bf
MT
116 """
117 Deletes an upload with a certain UUID
118 """
9eaf98bf
MT
119 # Fetch the upload
120 upload = self.backend.uploads.get_by_uuid(uuid)
121 if not upload:
122 raise tornado.web.HTTPError(404, "Could not find upload %s" % uuid)
123
124 # Check for permissions
125 if not upload.has_perm(self.current_user):
126 raise tornado.web.HTTPError(403, "%s has no permission to delete %s" \
127 % (self.current_user, upload))
128
129 # Delete the upload
130 with self.db.transaction():
131 await upload.delete()
132
133 self.finish({
134 "status" : "ok",
135 })