|
1 | 1 | package handlers |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "database/sql" |
5 | | - "encoding/base64" |
6 | | - "encoding/json" |
7 | 4 | "io" |
8 | 5 | "net/http" |
9 | 6 | "os" |
10 | 7 | "strconv" |
11 | | - "strings" |
12 | 8 |
|
13 | 9 | "github.com/DataManager-Go/DataManagerServer/handlers/web" |
14 | 10 | "github.com/DataManager-Go/DataManagerServer/models" |
15 | 11 | libdm "github.com/DataManager-Go/libdatamanager" |
16 | 12 | "github.com/JojiiOfficial/gaw" |
17 | | - "github.com/gabriel-vasile/mimetype" |
18 | 13 | "github.com/gorilla/mux" |
19 | 14 | "github.com/h2non/filetype" |
20 | | - log "github.com/sirupsen/logrus" |
21 | 15 | "gorm.io/gorm" |
22 | 16 | ) |
23 | 17 |
|
24 | | -//UploadfileHandler handler for uploading files |
25 | | -func UploadfileHandler(handlerData web.HandlerData, w http.ResponseWriter, r *http.Request) error { |
26 | | - var request libdm.UploadRequestStruct |
27 | | - |
28 | | - // Get data from header |
29 | | - requestData := r.Header.Get(libdm.HeaderRequest) |
30 | | - if len(requestData) == 0 { |
31 | | - return RErrBadRequest |
32 | | - } |
33 | | - |
34 | | - // Decode header base64 |
35 | | - rBaseBytes, err := base64.StdEncoding.DecodeString(requestData) |
36 | | - if err != nil { |
37 | | - return RErrBadRequest |
38 | | - } |
39 | | - |
40 | | - // Parse json from request header |
41 | | - err = json.Unmarshal(rBaseBytes, &request) |
42 | | - if err != nil { |
43 | | - return RErrBadRequest |
44 | | - } |
45 | | - |
46 | | - // Check requested encryption type |
47 | | - if len(request.Encryption) > 0 && !libdm.IsValidCipher(request.Encryption) { |
48 | | - return RErrNotSupported.Prepend("Encryption") |
49 | | - } |
50 | | - |
51 | | - // Validating request, for desired upload Type |
52 | | - switch request.UploadType { |
53 | | - case libdm.FileUploadType: |
54 | | - { |
55 | | - // Check if user is allowed to upload files |
56 | | - if !handlerData.User.CanUploadFiles() { |
57 | | - return RErrNotAllowed.Append("to upload files") |
58 | | - } |
59 | | - } |
60 | | - case libdm.URLUploadType: |
61 | | - { |
62 | | - // Check if user is allowed to upload URLs |
63 | | - if !handlerData.User.AllowedToUploadURLs() { |
64 | | - return RErrNotAllowed.Append("to upload URLs") |
65 | | - } |
66 | | - |
67 | | - // Check if url is set and valid |
68 | | - if len(request.URL) == 0 || !isValidHTTPURL(request.URL) { |
69 | | - return RErrMissing.Append("or malformed URL") |
70 | | - } |
71 | | - } |
72 | | - default: |
73 | | - { |
74 | | - // Send error if UploadType was not found |
75 | | - return RErrInvalid.Append("upload type") |
76 | | - } |
77 | | - } |
78 | | - |
79 | | - var namespace *models.Namespace |
80 | | - var file *models.File |
81 | | - var replaceMode bool |
82 | | - |
83 | | - if request.ReplaceFile > 0 { |
84 | | - replaceMode = true |
85 | | - |
86 | | - // Find file |
87 | | - file, err = models.FindFile(handlerData.Db, request.ReplaceFile, handlerData.User.ID) |
88 | | - if err != nil || file == nil || file.Namespace == nil { |
89 | | - return RErrNotFound.Prepend("File") |
90 | | - } |
91 | | - |
92 | | - // Use new name if set |
93 | | - if len(request.Name) > 0 { |
94 | | - file.Name = request.Name |
95 | | - } |
96 | | - |
97 | | - // Select namespace |
98 | | - if len(request.Attributes.Namespace) > 0 { |
99 | | - // Find namespace specified by client |
100 | | - namespace = models.FindNamespace(handlerData.Db, request.Attributes.Namespace, handlerData.User) |
101 | | - file.Namespace = namespace |
102 | | - } else { |
103 | | - namespace = file.Namespace |
104 | | - } |
105 | | - } else { |
106 | | - if len(request.Name) == 0 { |
107 | | - request.Name = gaw.RandString(25) |
108 | | - } |
109 | | - |
110 | | - // Select namespace |
111 | | - namespace = models.FindNamespace(handlerData.Db, request.Attributes.Namespace, handlerData.User) |
112 | | - |
113 | | - // Generate file |
114 | | - file = &models.File{ |
115 | | - Namespace: namespace, |
116 | | - Name: request.Name, |
117 | | - } |
118 | | - |
119 | | - // Pick a random, not already used name for file |
120 | | - if !file.SetUniqueFilename(handlerData.Db) { |
121 | | - sendServerError(w) |
122 | | - return nil |
123 | | - } |
124 | | - } |
125 | | - |
126 | | - // Check if namespace is valid and user has access to it |
127 | | - if !handleNamespaceErorrs(namespace, handlerData.User, w) { |
128 | | - return nil |
129 | | - } |
130 | | - |
131 | | - // Set Tags, Groups and encryption |
132 | | - if len(request.Attributes.Tags) > 0 { |
133 | | - file.Tags = models.TagsFromStringArr(request.Attributes.Tags, *namespace, handlerData.User) |
134 | | - } |
135 | | - if len(request.Attributes.Groups) > 0 { |
136 | | - file.Groups = models.GroupsFromStringArr(request.Attributes.Groups, *namespace, handlerData.User) |
137 | | - } |
138 | | - file.SetEncryption(request.Encryption) |
139 | | - |
140 | | - if request.Public { |
141 | | - // Determine public name |
142 | | - publicName := request.PublicName |
143 | | - if len(publicName) == 0 { |
144 | | - publicName = gaw.RandString(25) |
145 | | - } |
146 | | - |
147 | | - // Set file public name |
148 | | - file.PublicFilename = sql.NullString{ |
149 | | - String: publicName, |
150 | | - Valid: true, |
151 | | - } |
152 | | - file.IsPublic = true |
153 | | - |
154 | | - // Check if public name already exists |
155 | | - _, found, _ := models.GetPublicFile(handlerData.Db, publicName) |
156 | | - if found { |
157 | | - return RErrAlreadyExists.Prepend("public name") |
158 | | - } |
159 | | - } |
160 | | - |
161 | | - // Create local file |
162 | | - localFile := handlerData.Config.GetStorageFile(file.LocalName) |
163 | | - f, err := os.Create(localFile) |
164 | | - if err != nil { |
165 | | - return err |
166 | | - } |
167 | | - |
168 | | - // Read from the desired source (file/url) |
169 | | - switch request.UploadType { |
170 | | - case libdm.FileUploadType: |
171 | | - { |
172 | | - // Read requestd file |
173 | | - size, checksum, err := readMultipartToFile(f, r.Body, w) |
174 | | - |
175 | | - // Close file and log error only |
176 | | - LogError(f.Close()) |
177 | | - |
178 | | - // success is false if the calculated |
179 | | - // and provided hash are not equal |
180 | | - if err != nil { |
181 | | - // Only shredder file if not in replace mode |
182 | | - if request.ReplaceFile == 0 { |
183 | | - go models.ShredderFile(localFile, -1) |
184 | | - } |
185 | | - |
186 | | - // If error is a timeout error, send timeout error and close connectio |
187 | | - if err == http.ErrHandlerTimeout { |
188 | | - err = RErrTimeout |
189 | | - } |
190 | | - |
191 | | - return err |
192 | | - } |
193 | | - |
194 | | - file.FileSize = size |
195 | | - file.Checksum = checksum |
196 | | - } |
197 | | - case libdm.URLUploadType: |
198 | | - { |
199 | | - // Read from HTTP request |
200 | | - status, err := downloadHTTP(handlerData.User, request.URL, f, file) |
201 | | - if err != nil { |
202 | | - return RErrBadRequest.Prepend(err.Error()) |
203 | | - } |
204 | | - |
205 | | - // Check statuscode |
206 | | - if status > 299 || status < 200 { |
207 | | - return NewRequestError("Non HTTP OK response: "+strconv.Itoa(status), http.StatusBadRequest) |
208 | | - } |
209 | | - } |
210 | | - } |
211 | | - |
212 | | - // Detect mime type |
213 | | - mime, err := mimetype.DetectFile(handlerData.Config.GetStorageFile(file.LocalName)) |
214 | | - if err != nil { |
215 | | - log.Info("Can't detect mime: ", err.Error()) |
216 | | - } else { |
217 | | - file.FileType = strings.Split(mime.String(), ";")[0] |
218 | | - } |
219 | | - |
220 | | - if replaceMode { |
221 | | - // Update file |
222 | | - err = file.Save(handlerData.Db) |
223 | | - } else { |
224 | | - // Insert file to DB |
225 | | - err = file.Insert(handlerData.Db, handlerData.User) |
226 | | - } |
227 | | - |
228 | | - if err != nil { |
229 | | - return err |
230 | | - } |
231 | | - |
232 | | - sendResponse(w, libdm.ResponseSuccess, "", libdm.UploadResponse{ |
233 | | - FileID: file.ID, |
234 | | - Filename: file.Name, |
235 | | - PublicFilename: file.PublicFilename.String, |
236 | | - Checksum: file.Checksum, |
237 | | - FileSize: file.FileSize, |
238 | | - Namespace: namespace.Name, |
239 | | - }) |
240 | | - |
241 | | - return nil |
242 | | -} |
243 | | - |
244 | 18 | // ListFilesHandler handler for listing files |
245 | 19 | func ListFilesHandler(handlerData web.HandlerData, w http.ResponseWriter, r *http.Request) error { |
246 | 20 | var request libdm.FileListRequest |
|
0 commit comments