github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/file_test.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package api4 5 6 import ( 7 "fmt" 8 "net/http" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/store" 15 ) 16 17 func TestUploadFileAsMultipart(t *testing.T) { 18 th := Setup().InitBasic().InitSystemAdmin() 19 defer th.TearDown() 20 Client := th.Client 21 22 user := th.BasicUser 23 channel := th.BasicChannel 24 25 var uploadInfo *model.FileInfo 26 var data []byte 27 var err error 28 if data, err = readTestFile("test.png"); err != nil { 29 t.Fatal(err) 30 } else if fileResp, resp := Client.UploadFile(data, channel.Id, "test.png"); resp.Error != nil { 31 t.Fatal(resp.Error) 32 } else if len(fileResp.FileInfos) != 1 { 33 t.Fatal("should've returned a single file infos") 34 } else { 35 uploadInfo = fileResp.FileInfos[0] 36 } 37 38 // The returned file info from the upload call will be missing some fields that will be stored in the database 39 if uploadInfo.CreatorId != user.Id { 40 t.Fatal("file should be assigned to user") 41 } else if uploadInfo.PostId != "" { 42 t.Fatal("file shouldn't have a post") 43 } else if uploadInfo.Path != "" { 44 t.Fatal("file path should not be set on returned info") 45 } else if uploadInfo.ThumbnailPath != "" { 46 t.Fatal("file thumbnail path should not be set on returned info") 47 } else if uploadInfo.PreviewPath != "" { 48 t.Fatal("file preview path should not be set on returned info") 49 } 50 51 var info *model.FileInfo 52 if result := <-th.App.Srv.Store.FileInfo().Get(uploadInfo.Id); result.Err != nil { 53 t.Fatal(result.Err) 54 } else { 55 info = result.Data.(*model.FileInfo) 56 } 57 58 if info.Id != uploadInfo.Id { 59 t.Fatal("file id from response should match one stored in database") 60 } else if info.CreatorId != user.Id { 61 t.Fatal("file should be assigned to user") 62 } else if info.PostId != "" { 63 t.Fatal("file shouldn't have a post") 64 } else if info.Path == "" { 65 t.Fatal("file path should be set in database") 66 } else if info.ThumbnailPath == "" { 67 t.Fatal("file thumbnail path should be set in database") 68 } else if info.PreviewPath == "" { 69 t.Fatal("file preview path should be set in database") 70 } 71 72 date := time.Now().Format("20060102") 73 74 // This also makes sure that the relative path provided above is sanitized out 75 expectedPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test.png", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 76 if info.Path != expectedPath { 77 t.Logf("file is saved in %v", info.Path) 78 t.Fatalf("file should've been saved in %v", expectedPath) 79 } 80 81 expectedThumbnailPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_thumb.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 82 if info.ThumbnailPath != expectedThumbnailPath { 83 t.Logf("file thumbnail is saved in %v", info.ThumbnailPath) 84 t.Fatalf("file thumbnail should've been saved in %v", expectedThumbnailPath) 85 } 86 87 expectedPreviewPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_preview.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 88 if info.PreviewPath != expectedPreviewPath { 89 t.Logf("file preview is saved in %v", info.PreviewPath) 90 t.Fatalf("file preview should've been saved in %v", expectedPreviewPath) 91 } 92 93 // Wait a bit for files to ready 94 time.Sleep(2 * time.Second) 95 96 if err := th.cleanupTestFile(info); err != nil { 97 t.Fatal(err) 98 } 99 100 _, resp := Client.UploadFile(data, model.NewId(), "test.png") 101 CheckForbiddenStatus(t, resp) 102 103 _, resp = Client.UploadFile(data, "../../junk", "test.png") 104 CheckForbiddenStatus(t, resp) 105 106 _, resp = th.SystemAdminClient.UploadFile(data, model.NewId(), "test.png") 107 CheckForbiddenStatus(t, resp) 108 109 _, resp = th.SystemAdminClient.UploadFile(data, "../../junk", "test.png") 110 CheckForbiddenStatus(t, resp) 111 112 _, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png") 113 CheckNoError(t, resp) 114 115 enableFileAttachments := *th.App.Config().FileSettings.EnableFileAttachments 116 defer func() { 117 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = enableFileAttachments }) 118 }() 119 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) 120 121 _, resp = th.SystemAdminClient.UploadFile(data, channel.Id, "test.png") 122 if resp.StatusCode == 0 { 123 t.Log("file upload request failed completely") 124 } else if resp.StatusCode != http.StatusNotImplemented { 125 // This should return an HTTP 501, but it occasionally causes the http client itself to error 126 t.Fatalf("should've returned HTTP 501 or failed completely, got %v instead", resp.StatusCode) 127 } 128 } 129 130 func TestUploadFileAsRequestBody(t *testing.T) { 131 th := Setup().InitBasic().InitSystemAdmin() 132 defer th.TearDown() 133 Client := th.Client 134 135 user := th.BasicUser 136 channel := th.BasicChannel 137 138 var uploadInfo *model.FileInfo 139 var data []byte 140 var err error 141 if data, err = readTestFile("test.png"); err != nil { 142 t.Fatal(err) 143 } else if fileResp, resp := Client.UploadFileAsRequestBody(data, channel.Id, "test.png"); resp.Error != nil { 144 t.Fatal(resp.Error) 145 } else if len(fileResp.FileInfos) != 1 { 146 t.Fatal("should've returned a single file infos") 147 } else { 148 uploadInfo = fileResp.FileInfos[0] 149 } 150 151 // The returned file info from the upload call will be missing some fields that will be stored in the database 152 if uploadInfo.CreatorId != user.Id { 153 t.Fatal("file should be assigned to user") 154 } else if uploadInfo.PostId != "" { 155 t.Fatal("file shouldn't have a post") 156 } else if uploadInfo.Path != "" { 157 t.Fatal("file path should not be set on returned info") 158 } else if uploadInfo.ThumbnailPath != "" { 159 t.Fatal("file thumbnail path should not be set on returned info") 160 } else if uploadInfo.PreviewPath != "" { 161 t.Fatal("file preview path should not be set on returned info") 162 } 163 164 var info *model.FileInfo 165 if result := <-th.App.Srv.Store.FileInfo().Get(uploadInfo.Id); result.Err != nil { 166 t.Fatal(result.Err) 167 } else { 168 info = result.Data.(*model.FileInfo) 169 } 170 171 if info.Id != uploadInfo.Id { 172 t.Fatal("file id from response should match one stored in database") 173 } else if info.CreatorId != user.Id { 174 t.Fatal("file should be assigned to user") 175 } else if info.PostId != "" { 176 t.Fatal("file shouldn't have a post") 177 } else if info.Path == "" { 178 t.Fatal("file path should be set in database") 179 } else if info.ThumbnailPath == "" { 180 t.Fatal("file thumbnail path should be set in database") 181 } else if info.PreviewPath == "" { 182 t.Fatal("file preview path should be set in database") 183 } 184 185 date := time.Now().Format("20060102") 186 187 // This also makes sure that the relative path provided above is sanitized out 188 expectedPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test.png", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 189 if info.Path != expectedPath { 190 t.Logf("file is saved in %v", info.Path) 191 t.Fatalf("file should've been saved in %v", expectedPath) 192 } 193 194 expectedThumbnailPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_thumb.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 195 if info.ThumbnailPath != expectedThumbnailPath { 196 t.Logf("file thumbnail is saved in %v", info.ThumbnailPath) 197 t.Fatalf("file thumbnail should've been saved in %v", expectedThumbnailPath) 198 } 199 200 expectedPreviewPath := fmt.Sprintf("%v/teams/%v/channels/%v/users/%v/%v/test_preview.jpg", date, FILE_TEAM_ID, channel.Id, user.Id, info.Id) 201 if info.PreviewPath != expectedPreviewPath { 202 t.Logf("file preview is saved in %v", info.PreviewPath) 203 t.Fatalf("file preview should've been saved in %v", expectedPreviewPath) 204 } 205 206 // Wait a bit for files to ready 207 time.Sleep(2 * time.Second) 208 209 if err := th.cleanupTestFile(info); err != nil { 210 t.Fatal(err) 211 } 212 213 _, resp := Client.UploadFileAsRequestBody(data, model.NewId(), "test.png") 214 CheckForbiddenStatus(t, resp) 215 216 _, resp = Client.UploadFileAsRequestBody(data, "../../junk", "test.png") 217 if resp.StatusCode == 0 { 218 t.Log("file upload request failed completely") 219 } else if resp.StatusCode != http.StatusBadRequest { 220 // This should return an HTTP 400, but it occasionally causes the http client itself to error 221 t.Fatalf("should've returned HTTP 400 or failed completely, got %v instead", resp.StatusCode) 222 } 223 224 _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, model.NewId(), "test.png") 225 CheckForbiddenStatus(t, resp) 226 227 _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, "../../junk", "test.png") 228 if resp.StatusCode == 0 { 229 t.Log("file upload request failed completely") 230 } else if resp.StatusCode != http.StatusBadRequest { 231 // This should return an HTTP 400, but it occasionally causes the http client itself to error 232 t.Fatalf("should've returned HTTP 400 or failed completely, got %v instead", resp.StatusCode) 233 } 234 235 _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, channel.Id, "test.png") 236 CheckNoError(t, resp) 237 238 enableFileAttachments := *th.App.Config().FileSettings.EnableFileAttachments 239 defer func() { 240 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = enableFileAttachments }) 241 }() 242 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) 243 244 _, resp = th.SystemAdminClient.UploadFileAsRequestBody(data, channel.Id, "test.png") 245 if resp.StatusCode == 0 { 246 t.Log("file upload request failed completely") 247 } else if resp.StatusCode != http.StatusNotImplemented { 248 // This should return an HTTP 501, but it occasionally causes the http client itself to error 249 t.Fatalf("should've returned HTTP 501 or failed completely, got %v instead", resp.StatusCode) 250 } 251 } 252 253 func TestGetFile(t *testing.T) { 254 th := Setup().InitBasic().InitSystemAdmin() 255 defer th.TearDown() 256 Client := th.Client 257 channel := th.BasicChannel 258 259 if *th.App.Config().FileSettings.DriverName == "" { 260 t.Skip("skipping because no file driver is enabled") 261 } 262 263 fileId := "" 264 var sent []byte 265 var err error 266 if sent, err = readTestFile("test.png"); err != nil { 267 t.Fatal(err) 268 } else { 269 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 270 CheckNoError(t, resp) 271 272 fileId = fileResp.FileInfos[0].Id 273 } 274 275 data, resp := Client.GetFile(fileId) 276 CheckNoError(t, resp) 277 278 if len(data) == 0 { 279 t.Fatal("should not be empty") 280 } 281 282 for i := range data { 283 if data[i] != sent[i] { 284 t.Fatal("received file didn't match sent one") 285 } 286 } 287 288 _, resp = Client.GetFile("junk") 289 CheckBadRequestStatus(t, resp) 290 291 _, resp = Client.GetFile(model.NewId()) 292 CheckNotFoundStatus(t, resp) 293 294 Client.Logout() 295 _, resp = Client.GetFile(fileId) 296 CheckUnauthorizedStatus(t, resp) 297 298 _, resp = th.SystemAdminClient.GetFile(fileId) 299 CheckNoError(t, resp) 300 } 301 302 func TestGetFileHeaders(t *testing.T) { 303 th := Setup().InitBasic() 304 defer th.TearDown() 305 306 Client := th.Client 307 channel := th.BasicChannel 308 309 if *th.App.Config().FileSettings.DriverName == "" { 310 t.Skip("skipping because no file driver is enabled") 311 } 312 313 testHeaders := func(data []byte, filename string, expectedContentType string, getInline bool) func(*testing.T) { 314 return func(t *testing.T) { 315 fileResp, resp := Client.UploadFile(data, channel.Id, filename) 316 CheckNoError(t, resp) 317 318 fileId := fileResp.FileInfos[0].Id 319 320 _, resp = Client.GetFile(fileId) 321 CheckNoError(t, resp) 322 323 if contentType := resp.Header.Get("Content-Type"); !strings.HasPrefix(contentType, expectedContentType) { 324 t.Fatal("returned incorrect Content-Type", contentType) 325 } 326 327 if getInline { 328 if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "inline") { 329 t.Fatal("returned incorrect Content-Disposition", contentDisposition) 330 } 331 } else { 332 if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "attachment") { 333 t.Fatal("returned incorrect Content-Disposition", contentDisposition) 334 } 335 } 336 337 _, resp = Client.DownloadFile(fileId, true) 338 CheckNoError(t, resp) 339 340 if contentType := resp.Header.Get("Content-Type"); !strings.HasPrefix(contentType, expectedContentType) { 341 t.Fatal("returned incorrect Content-Type", contentType) 342 } 343 344 if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "attachment") { 345 t.Fatal("returned incorrect Content-Disposition", contentDisposition) 346 } 347 } 348 } 349 350 data := []byte("ABC") 351 352 t.Run("png", testHeaders(data, "test.png", "image/png", true)) 353 t.Run("gif", testHeaders(data, "test.gif", "image/gif", true)) 354 t.Run("mp4", testHeaders(data, "test.mp4", "video/mp4", true)) 355 t.Run("mp3", testHeaders(data, "test.mp3", "audio/mpeg", true)) 356 t.Run("pdf", testHeaders(data, "test.pdf", "application/pdf", false)) 357 t.Run("txt", testHeaders(data, "test.txt", "text/plain", false)) 358 t.Run("html", testHeaders(data, "test.html", "text/plain", false)) 359 t.Run("js", testHeaders(data, "test.js", "text/plain", false)) 360 t.Run("go", testHeaders(data, "test.go", "application/octet-stream", false)) 361 t.Run("zip", testHeaders(data, "test.zip", "application/zip", false)) 362 // Not every platform can recognize these 363 //t.Run("exe", testHeaders(data, "test.exe", "application/x-ms", false)) 364 t.Run("no extension", testHeaders(data, "test", "application/octet-stream", false)) 365 t.Run("no extension 2", testHeaders([]byte("<html></html>"), "test", "application/octet-stream", false)) 366 } 367 368 func TestGetFileThumbnail(t *testing.T) { 369 th := Setup().InitBasic().InitSystemAdmin() 370 defer th.TearDown() 371 Client := th.Client 372 channel := th.BasicChannel 373 374 if *th.App.Config().FileSettings.DriverName == "" { 375 t.Skip("skipping because no file driver is enabled") 376 } 377 378 fileId := "" 379 var sent []byte 380 var err error 381 if sent, err = readTestFile("test.png"); err != nil { 382 t.Fatal(err) 383 } else { 384 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 385 CheckNoError(t, resp) 386 387 fileId = fileResp.FileInfos[0].Id 388 } 389 390 // Wait a bit for files to ready 391 time.Sleep(2 * time.Second) 392 393 data, resp := Client.GetFileThumbnail(fileId) 394 CheckNoError(t, resp) 395 396 if len(data) == 0 { 397 t.Fatal("should not be empty") 398 } 399 400 _, resp = Client.GetFileThumbnail("junk") 401 CheckBadRequestStatus(t, resp) 402 403 _, resp = Client.GetFileThumbnail(model.NewId()) 404 CheckNotFoundStatus(t, resp) 405 406 Client.Logout() 407 _, resp = Client.GetFileThumbnail(fileId) 408 CheckUnauthorizedStatus(t, resp) 409 410 otherUser := th.CreateUser() 411 Client.Login(otherUser.Email, otherUser.Password) 412 _, resp = Client.GetFileThumbnail(fileId) 413 CheckForbiddenStatus(t, resp) 414 415 Client.Logout() 416 _, resp = th.SystemAdminClient.GetFileThumbnail(fileId) 417 CheckNoError(t, resp) 418 } 419 420 func TestGetFileLink(t *testing.T) { 421 th := Setup().InitBasic().InitSystemAdmin() 422 defer th.TearDown() 423 Client := th.Client 424 channel := th.BasicChannel 425 426 if *th.App.Config().FileSettings.DriverName == "" { 427 t.Skip("skipping because no file driver is enabled") 428 } 429 430 enablePublicLink := th.App.Config().FileSettings.EnablePublicLink 431 publicLinkSalt := *th.App.Config().FileSettings.PublicLinkSalt 432 defer func() { 433 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = enablePublicLink }) 434 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = publicLinkSalt }) 435 }() 436 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 437 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = model.NewId() }) 438 439 fileId := "" 440 if data, err := readTestFile("test.png"); err != nil { 441 t.Fatal(err) 442 } else { 443 fileResp, resp := Client.UploadFile(data, channel.Id, "test.png") 444 CheckNoError(t, resp) 445 446 fileId = fileResp.FileInfos[0].Id 447 } 448 449 _, resp := Client.GetFileLink(fileId) 450 CheckBadRequestStatus(t, resp) 451 452 // Hacky way to assign file to a post (usually would be done by CreatePost call) 453 store.Must(th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id)) 454 455 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = false }) 456 _, resp = Client.GetFileLink(fileId) 457 CheckNotImplementedStatus(t, resp) 458 459 // Wait a bit for files to ready 460 time.Sleep(2 * time.Second) 461 462 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 463 link, resp := Client.GetFileLink(fileId) 464 CheckNoError(t, resp) 465 466 if link == "" { 467 t.Fatal("should've received public link") 468 } 469 470 _, resp = Client.GetFileLink("junk") 471 CheckBadRequestStatus(t, resp) 472 473 _, resp = Client.GetFileLink(model.NewId()) 474 CheckNotFoundStatus(t, resp) 475 476 Client.Logout() 477 _, resp = Client.GetFileLink(fileId) 478 CheckUnauthorizedStatus(t, resp) 479 480 otherUser := th.CreateUser() 481 Client.Login(otherUser.Email, otherUser.Password) 482 _, resp = Client.GetFileLink(fileId) 483 CheckForbiddenStatus(t, resp) 484 485 Client.Logout() 486 _, resp = th.SystemAdminClient.GetFileLink(fileId) 487 CheckNoError(t, resp) 488 489 if result := <-th.App.Srv.Store.FileInfo().Get(fileId); result.Err != nil { 490 t.Fatal(result.Err) 491 } else { 492 th.cleanupTestFile(result.Data.(*model.FileInfo)) 493 } 494 } 495 496 func TestGetFilePreview(t *testing.T) { 497 th := Setup().InitBasic().InitSystemAdmin() 498 defer th.TearDown() 499 Client := th.Client 500 channel := th.BasicChannel 501 502 if *th.App.Config().FileSettings.DriverName == "" { 503 t.Skip("skipping because no file driver is enabled") 504 } 505 506 fileId := "" 507 var sent []byte 508 var err error 509 if sent, err = readTestFile("test.png"); err != nil { 510 t.Fatal(err) 511 } else { 512 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 513 CheckNoError(t, resp) 514 515 fileId = fileResp.FileInfos[0].Id 516 } 517 518 // Wait a bit for files to ready 519 time.Sleep(2 * time.Second) 520 521 data, resp := Client.GetFilePreview(fileId) 522 CheckNoError(t, resp) 523 524 if len(data) == 0 { 525 t.Fatal("should not be empty") 526 } 527 528 _, resp = Client.GetFilePreview("junk") 529 CheckBadRequestStatus(t, resp) 530 531 _, resp = Client.GetFilePreview(model.NewId()) 532 CheckNotFoundStatus(t, resp) 533 534 Client.Logout() 535 _, resp = Client.GetFilePreview(fileId) 536 CheckUnauthorizedStatus(t, resp) 537 538 otherUser := th.CreateUser() 539 Client.Login(otherUser.Email, otherUser.Password) 540 _, resp = Client.GetFilePreview(fileId) 541 CheckForbiddenStatus(t, resp) 542 543 Client.Logout() 544 _, resp = th.SystemAdminClient.GetFilePreview(fileId) 545 CheckNoError(t, resp) 546 } 547 548 func TestGetFileInfo(t *testing.T) { 549 th := Setup().InitBasic().InitSystemAdmin() 550 defer th.TearDown() 551 Client := th.Client 552 user := th.BasicUser 553 channel := th.BasicChannel 554 555 if *th.App.Config().FileSettings.DriverName == "" { 556 t.Skip("skipping because no file driver is enabled") 557 } 558 559 fileId := "" 560 var sent []byte 561 var err error 562 if sent, err = readTestFile("test.png"); err != nil { 563 t.Fatal(err) 564 } else { 565 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 566 CheckNoError(t, resp) 567 568 fileId = fileResp.FileInfos[0].Id 569 } 570 571 // Wait a bit for files to ready 572 time.Sleep(2 * time.Second) 573 574 info, resp := Client.GetFileInfo(fileId) 575 CheckNoError(t, resp) 576 577 if err != nil { 578 t.Fatal(err) 579 } else if info.Id != fileId { 580 t.Fatal("got incorrect file") 581 } else if info.CreatorId != user.Id { 582 t.Fatal("file should be assigned to user") 583 } else if info.PostId != "" { 584 t.Fatal("file shouldn't have a post") 585 } else if info.Path != "" { 586 t.Fatal("file path shouldn't have been returned to client") 587 } else if info.ThumbnailPath != "" { 588 t.Fatal("file thumbnail path shouldn't have been returned to client") 589 } else if info.PreviewPath != "" { 590 t.Fatal("file preview path shouldn't have been returned to client") 591 } else if info.MimeType != "image/png" { 592 t.Fatal("mime type should've been image/png") 593 } 594 595 _, resp = Client.GetFileInfo("junk") 596 CheckBadRequestStatus(t, resp) 597 598 _, resp = Client.GetFileInfo(model.NewId()) 599 CheckNotFoundStatus(t, resp) 600 601 Client.Logout() 602 _, resp = Client.GetFileInfo(fileId) 603 CheckUnauthorizedStatus(t, resp) 604 605 otherUser := th.CreateUser() 606 Client.Login(otherUser.Email, otherUser.Password) 607 _, resp = Client.GetFileInfo(fileId) 608 CheckForbiddenStatus(t, resp) 609 610 Client.Logout() 611 _, resp = th.SystemAdminClient.GetFileInfo(fileId) 612 CheckNoError(t, resp) 613 } 614 615 func TestGetPublicFile(t *testing.T) { 616 th := Setup().InitBasic().InitSystemAdmin() 617 defer th.TearDown() 618 Client := th.Client 619 channel := th.BasicChannel 620 621 if *th.App.Config().FileSettings.DriverName == "" { 622 t.Skip("skipping because no file driver is enabled") 623 } 624 625 enablePublicLink := th.App.Config().FileSettings.EnablePublicLink 626 publicLinkSalt := *th.App.Config().FileSettings.PublicLinkSalt 627 defer func() { 628 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = enablePublicLink }) 629 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = publicLinkSalt }) 630 }() 631 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 632 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 633 634 fileId := "" 635 if data, err := readTestFile("test.png"); err != nil { 636 t.Fatal(err) 637 } else { 638 fileResp, resp := Client.UploadFile(data, channel.Id, "test.png") 639 CheckNoError(t, resp) 640 641 fileId = fileResp.FileInfos[0].Id 642 } 643 644 // Hacky way to assign file to a post (usually would be done by CreatePost call) 645 store.Must(th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id)) 646 647 result := <-th.App.Srv.Store.FileInfo().Get(fileId) 648 info := result.Data.(*model.FileInfo) 649 link := th.App.GeneratePublicLink(Client.Url, info) 650 651 // Wait a bit for files to ready 652 time.Sleep(2 * time.Second) 653 654 if resp, err := http.Get(link); err != nil || resp.StatusCode != http.StatusOK { 655 t.Log(link) 656 t.Fatal("failed to get image with public link", err) 657 } 658 659 if resp, err := http.Get(link[:strings.LastIndex(link, "?")]); err == nil && resp.StatusCode != http.StatusBadRequest { 660 t.Fatal("should've failed to get image with public link without hash", resp.Status) 661 } 662 663 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = false }) 664 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusNotImplemented { 665 t.Fatal("should've failed to get image with disabled public link") 666 } 667 668 // test after the salt has changed 669 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 670 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 671 672 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 673 t.Fatal("should've failed to get image with public link after salt changed") 674 } 675 676 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 677 t.Fatal("should've failed to get image with public link after salt changed") 678 } 679 680 if err := th.cleanupTestFile(store.Must(th.App.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil { 681 t.Fatal(err) 682 } 683 684 th.cleanupTestFile(info) 685 }