]>
Commit | Line | Data |
---|---|---|
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 | 22 | import io |
a097e88a MT |
23 | import tornado.web |
24 | ||
f062b044 | 25 | from . import base |
a097e88a MT |
26 | from .. import users |
27 | ||
a097e88a | 28 | @tornado.web.stream_request_body |
f062b044 MT |
29 | class 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 | |
110 | class 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 | }) |