github.com/wgh-/mattermost-server@v4.8.0-rc2+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 t.Run("exe", testHeaders(data, "test.exe", "application/x-ms", false)) 363 t.Run("no extension", testHeaders(data, "test", "application/octet-stream", false)) 364 t.Run("no extension 2", testHeaders([]byte("<html></html>"), "test", "application/octet-stream", false)) 365 } 366 367 func TestGetFileThumbnail(t *testing.T) { 368 th := Setup().InitBasic().InitSystemAdmin() 369 defer th.TearDown() 370 Client := th.Client 371 channel := th.BasicChannel 372 373 if *th.App.Config().FileSettings.DriverName == "" { 374 t.Skip("skipping because no file driver is enabled") 375 } 376 377 fileId := "" 378 var sent []byte 379 var err error 380 if sent, err = readTestFile("test.png"); err != nil { 381 t.Fatal(err) 382 } else { 383 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 384 CheckNoError(t, resp) 385 386 fileId = fileResp.FileInfos[0].Id 387 } 388 389 // Wait a bit for files to ready 390 time.Sleep(2 * time.Second) 391 392 data, resp := Client.GetFileThumbnail(fileId) 393 CheckNoError(t, resp) 394 395 if len(data) == 0 { 396 t.Fatal("should not be empty") 397 } 398 399 _, resp = Client.GetFileThumbnail("junk") 400 CheckBadRequestStatus(t, resp) 401 402 _, resp = Client.GetFileThumbnail(model.NewId()) 403 CheckNotFoundStatus(t, resp) 404 405 Client.Logout() 406 _, resp = Client.GetFileThumbnail(fileId) 407 CheckUnauthorizedStatus(t, resp) 408 409 otherUser := th.CreateUser() 410 Client.Login(otherUser.Email, otherUser.Password) 411 _, resp = Client.GetFileThumbnail(fileId) 412 CheckForbiddenStatus(t, resp) 413 414 Client.Logout() 415 _, resp = th.SystemAdminClient.GetFileThumbnail(fileId) 416 CheckNoError(t, resp) 417 } 418 419 func TestGetFileLink(t *testing.T) { 420 th := Setup().InitBasic().InitSystemAdmin() 421 defer th.TearDown() 422 Client := th.Client 423 channel := th.BasicChannel 424 425 if *th.App.Config().FileSettings.DriverName == "" { 426 t.Skip("skipping because no file driver is enabled") 427 } 428 429 enablePublicLink := th.App.Config().FileSettings.EnablePublicLink 430 publicLinkSalt := *th.App.Config().FileSettings.PublicLinkSalt 431 defer func() { 432 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = enablePublicLink }) 433 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = publicLinkSalt }) 434 }() 435 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 436 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = model.NewId() }) 437 438 fileId := "" 439 if data, err := readTestFile("test.png"); err != nil { 440 t.Fatal(err) 441 } else { 442 fileResp, resp := Client.UploadFile(data, channel.Id, "test.png") 443 CheckNoError(t, resp) 444 445 fileId = fileResp.FileInfos[0].Id 446 } 447 448 link, resp := Client.GetFileLink(fileId) 449 CheckBadRequestStatus(t, resp) 450 451 // Hacky way to assign file to a post (usually would be done by CreatePost call) 452 store.Must(th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id)) 453 454 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = false }) 455 _, resp = Client.GetFileLink(fileId) 456 CheckNotImplementedStatus(t, resp) 457 458 // Wait a bit for files to ready 459 time.Sleep(2 * time.Second) 460 461 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 462 link, resp = Client.GetFileLink(fileId) 463 CheckNoError(t, resp) 464 if link == "" { 465 t.Fatal("should've received public link") 466 } 467 468 _, resp = Client.GetFileLink("junk") 469 CheckBadRequestStatus(t, resp) 470 471 _, resp = Client.GetFileLink(model.NewId()) 472 CheckNotFoundStatus(t, resp) 473 474 Client.Logout() 475 _, resp = Client.GetFileLink(fileId) 476 CheckUnauthorizedStatus(t, resp) 477 478 otherUser := th.CreateUser() 479 Client.Login(otherUser.Email, otherUser.Password) 480 _, resp = Client.GetFileLink(fileId) 481 CheckForbiddenStatus(t, resp) 482 483 Client.Logout() 484 _, resp = th.SystemAdminClient.GetFileLink(fileId) 485 CheckNoError(t, resp) 486 487 if result := <-th.App.Srv.Store.FileInfo().Get(fileId); result.Err != nil { 488 t.Fatal(result.Err) 489 } else { 490 th.cleanupTestFile(result.Data.(*model.FileInfo)) 491 } 492 } 493 494 func TestGetFilePreview(t *testing.T) { 495 th := Setup().InitBasic().InitSystemAdmin() 496 defer th.TearDown() 497 Client := th.Client 498 channel := th.BasicChannel 499 500 if *th.App.Config().FileSettings.DriverName == "" { 501 t.Skip("skipping because no file driver is enabled") 502 } 503 504 fileId := "" 505 var sent []byte 506 var err error 507 if sent, err = readTestFile("test.png"); err != nil { 508 t.Fatal(err) 509 } else { 510 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 511 CheckNoError(t, resp) 512 513 fileId = fileResp.FileInfos[0].Id 514 } 515 516 // Wait a bit for files to ready 517 time.Sleep(2 * time.Second) 518 519 data, resp := Client.GetFilePreview(fileId) 520 CheckNoError(t, resp) 521 522 if len(data) == 0 { 523 t.Fatal("should not be empty") 524 } 525 526 _, resp = Client.GetFilePreview("junk") 527 CheckBadRequestStatus(t, resp) 528 529 _, resp = Client.GetFilePreview(model.NewId()) 530 CheckNotFoundStatus(t, resp) 531 532 Client.Logout() 533 _, resp = Client.GetFilePreview(fileId) 534 CheckUnauthorizedStatus(t, resp) 535 536 otherUser := th.CreateUser() 537 Client.Login(otherUser.Email, otherUser.Password) 538 _, resp = Client.GetFilePreview(fileId) 539 CheckForbiddenStatus(t, resp) 540 541 Client.Logout() 542 _, resp = th.SystemAdminClient.GetFilePreview(fileId) 543 CheckNoError(t, resp) 544 } 545 546 func TestGetFileInfo(t *testing.T) { 547 th := Setup().InitBasic().InitSystemAdmin() 548 defer th.TearDown() 549 Client := th.Client 550 user := th.BasicUser 551 channel := th.BasicChannel 552 553 if *th.App.Config().FileSettings.DriverName == "" { 554 t.Skip("skipping because no file driver is enabled") 555 } 556 557 fileId := "" 558 var sent []byte 559 var err error 560 if sent, err = readTestFile("test.png"); err != nil { 561 t.Fatal(err) 562 } else { 563 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 564 CheckNoError(t, resp) 565 566 fileId = fileResp.FileInfos[0].Id 567 } 568 569 // Wait a bit for files to ready 570 time.Sleep(2 * time.Second) 571 572 info, resp := Client.GetFileInfo(fileId) 573 CheckNoError(t, resp) 574 575 if err != nil { 576 t.Fatal(err) 577 } else if info.Id != fileId { 578 t.Fatal("got incorrect file") 579 } else if info.CreatorId != user.Id { 580 t.Fatal("file should be assigned to user") 581 } else if info.PostId != "" { 582 t.Fatal("file shouldn't have a post") 583 } else if info.Path != "" { 584 t.Fatal("file path shouldn't have been returned to client") 585 } else if info.ThumbnailPath != "" { 586 t.Fatal("file thumbnail path shouldn't have been returned to client") 587 } else if info.PreviewPath != "" { 588 t.Fatal("file preview path shouldn't have been returned to client") 589 } else if info.MimeType != "image/png" { 590 t.Fatal("mime type should've been image/png") 591 } 592 593 _, resp = Client.GetFileInfo("junk") 594 CheckBadRequestStatus(t, resp) 595 596 _, resp = Client.GetFileInfo(model.NewId()) 597 CheckNotFoundStatus(t, resp) 598 599 Client.Logout() 600 _, resp = Client.GetFileInfo(fileId) 601 CheckUnauthorizedStatus(t, resp) 602 603 otherUser := th.CreateUser() 604 Client.Login(otherUser.Email, otherUser.Password) 605 _, resp = Client.GetFileInfo(fileId) 606 CheckForbiddenStatus(t, resp) 607 608 Client.Logout() 609 _, resp = th.SystemAdminClient.GetFileInfo(fileId) 610 CheckNoError(t, resp) 611 } 612 613 func TestGetPublicFile(t *testing.T) { 614 th := Setup().InitBasic().InitSystemAdmin() 615 defer th.TearDown() 616 Client := th.Client 617 channel := th.BasicChannel 618 619 if *th.App.Config().FileSettings.DriverName == "" { 620 t.Skip("skipping because no file driver is enabled") 621 } 622 623 enablePublicLink := th.App.Config().FileSettings.EnablePublicLink 624 publicLinkSalt := *th.App.Config().FileSettings.PublicLinkSalt 625 defer func() { 626 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = enablePublicLink }) 627 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = publicLinkSalt }) 628 }() 629 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 630 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 631 632 fileId := "" 633 if data, err := readTestFile("test.png"); err != nil { 634 t.Fatal(err) 635 } else { 636 fileResp, resp := Client.UploadFile(data, channel.Id, "test.png") 637 CheckNoError(t, resp) 638 639 fileId = fileResp.FileInfos[0].Id 640 } 641 642 // Hacky way to assign file to a post (usually would be done by CreatePost call) 643 store.Must(th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id)) 644 645 result := <-th.App.Srv.Store.FileInfo().Get(fileId) 646 info := result.Data.(*model.FileInfo) 647 link := th.App.GeneratePublicLink(Client.Url, info) 648 649 // Wait a bit for files to ready 650 time.Sleep(2 * time.Second) 651 652 if resp, err := http.Get(link); err != nil || resp.StatusCode != http.StatusOK { 653 t.Log(link) 654 t.Fatal("failed to get image with public link", err) 655 } 656 657 if resp, err := http.Get(link[:strings.LastIndex(link, "?")]); err == nil && resp.StatusCode != http.StatusBadRequest { 658 t.Fatal("should've failed to get image with public link without hash", resp.Status) 659 } 660 661 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = false }) 662 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusNotImplemented { 663 t.Fatal("should've failed to get image with disabled public link") 664 } 665 666 // test after the salt has changed 667 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 668 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 669 670 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 671 t.Fatal("should've failed to get image with public link after salt changed") 672 } 673 674 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 675 t.Fatal("should've failed to get image with public link after salt changed") 676 } 677 678 if err := th.cleanupTestFile(store.Must(th.App.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil { 679 t.Fatal(err) 680 } 681 682 th.cleanupTestFile(info) 683 }