github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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 link, 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 if link == "" { 466 t.Fatal("should've received public link") 467 } 468 469 _, resp = Client.GetFileLink("junk") 470 CheckBadRequestStatus(t, resp) 471 472 _, resp = Client.GetFileLink(model.NewId()) 473 CheckNotFoundStatus(t, resp) 474 475 Client.Logout() 476 _, resp = Client.GetFileLink(fileId) 477 CheckUnauthorizedStatus(t, resp) 478 479 otherUser := th.CreateUser() 480 Client.Login(otherUser.Email, otherUser.Password) 481 _, resp = Client.GetFileLink(fileId) 482 CheckForbiddenStatus(t, resp) 483 484 Client.Logout() 485 _, resp = th.SystemAdminClient.GetFileLink(fileId) 486 CheckNoError(t, resp) 487 488 if result := <-th.App.Srv.Store.FileInfo().Get(fileId); result.Err != nil { 489 t.Fatal(result.Err) 490 } else { 491 th.cleanupTestFile(result.Data.(*model.FileInfo)) 492 } 493 } 494 495 func TestGetFilePreview(t *testing.T) { 496 th := Setup().InitBasic().InitSystemAdmin() 497 defer th.TearDown() 498 Client := th.Client 499 channel := th.BasicChannel 500 501 if *th.App.Config().FileSettings.DriverName == "" { 502 t.Skip("skipping because no file driver is enabled") 503 } 504 505 fileId := "" 506 var sent []byte 507 var err error 508 if sent, err = readTestFile("test.png"); err != nil { 509 t.Fatal(err) 510 } else { 511 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 512 CheckNoError(t, resp) 513 514 fileId = fileResp.FileInfos[0].Id 515 } 516 517 // Wait a bit for files to ready 518 time.Sleep(2 * time.Second) 519 520 data, resp := Client.GetFilePreview(fileId) 521 CheckNoError(t, resp) 522 523 if len(data) == 0 { 524 t.Fatal("should not be empty") 525 } 526 527 _, resp = Client.GetFilePreview("junk") 528 CheckBadRequestStatus(t, resp) 529 530 _, resp = Client.GetFilePreview(model.NewId()) 531 CheckNotFoundStatus(t, resp) 532 533 Client.Logout() 534 _, resp = Client.GetFilePreview(fileId) 535 CheckUnauthorizedStatus(t, resp) 536 537 otherUser := th.CreateUser() 538 Client.Login(otherUser.Email, otherUser.Password) 539 _, resp = Client.GetFilePreview(fileId) 540 CheckForbiddenStatus(t, resp) 541 542 Client.Logout() 543 _, resp = th.SystemAdminClient.GetFilePreview(fileId) 544 CheckNoError(t, resp) 545 } 546 547 func TestGetFileInfo(t *testing.T) { 548 th := Setup().InitBasic().InitSystemAdmin() 549 defer th.TearDown() 550 Client := th.Client 551 user := th.BasicUser 552 channel := th.BasicChannel 553 554 if *th.App.Config().FileSettings.DriverName == "" { 555 t.Skip("skipping because no file driver is enabled") 556 } 557 558 fileId := "" 559 var sent []byte 560 var err error 561 if sent, err = readTestFile("test.png"); err != nil { 562 t.Fatal(err) 563 } else { 564 fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png") 565 CheckNoError(t, resp) 566 567 fileId = fileResp.FileInfos[0].Id 568 } 569 570 // Wait a bit for files to ready 571 time.Sleep(2 * time.Second) 572 573 info, resp := Client.GetFileInfo(fileId) 574 CheckNoError(t, resp) 575 576 if err != nil { 577 t.Fatal(err) 578 } else if info.Id != fileId { 579 t.Fatal("got incorrect file") 580 } else if info.CreatorId != user.Id { 581 t.Fatal("file should be assigned to user") 582 } else if info.PostId != "" { 583 t.Fatal("file shouldn't have a post") 584 } else if info.Path != "" { 585 t.Fatal("file path shouldn't have been returned to client") 586 } else if info.ThumbnailPath != "" { 587 t.Fatal("file thumbnail path shouldn't have been returned to client") 588 } else if info.PreviewPath != "" { 589 t.Fatal("file preview path shouldn't have been returned to client") 590 } else if info.MimeType != "image/png" { 591 t.Fatal("mime type should've been image/png") 592 } 593 594 _, resp = Client.GetFileInfo("junk") 595 CheckBadRequestStatus(t, resp) 596 597 _, resp = Client.GetFileInfo(model.NewId()) 598 CheckNotFoundStatus(t, resp) 599 600 Client.Logout() 601 _, resp = Client.GetFileInfo(fileId) 602 CheckUnauthorizedStatus(t, resp) 603 604 otherUser := th.CreateUser() 605 Client.Login(otherUser.Email, otherUser.Password) 606 _, resp = Client.GetFileInfo(fileId) 607 CheckForbiddenStatus(t, resp) 608 609 Client.Logout() 610 _, resp = th.SystemAdminClient.GetFileInfo(fileId) 611 CheckNoError(t, resp) 612 } 613 614 func TestGetPublicFile(t *testing.T) { 615 th := Setup().InitBasic().InitSystemAdmin() 616 defer th.TearDown() 617 Client := th.Client 618 channel := th.BasicChannel 619 620 if *th.App.Config().FileSettings.DriverName == "" { 621 t.Skip("skipping because no file driver is enabled") 622 } 623 624 enablePublicLink := th.App.Config().FileSettings.EnablePublicLink 625 publicLinkSalt := *th.App.Config().FileSettings.PublicLinkSalt 626 defer func() { 627 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = enablePublicLink }) 628 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = publicLinkSalt }) 629 }() 630 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 631 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 632 633 fileId := "" 634 if data, err := readTestFile("test.png"); err != nil { 635 t.Fatal(err) 636 } else { 637 fileResp, resp := Client.UploadFile(data, channel.Id, "test.png") 638 CheckNoError(t, resp) 639 640 fileId = fileResp.FileInfos[0].Id 641 } 642 643 // Hacky way to assign file to a post (usually would be done by CreatePost call) 644 store.Must(th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id)) 645 646 result := <-th.App.Srv.Store.FileInfo().Get(fileId) 647 info := result.Data.(*model.FileInfo) 648 link := th.App.GeneratePublicLink(Client.Url, info) 649 650 // Wait a bit for files to ready 651 time.Sleep(2 * time.Second) 652 653 if resp, err := http.Get(link); err != nil || resp.StatusCode != http.StatusOK { 654 t.Log(link) 655 t.Fatal("failed to get image with public link", err) 656 } 657 658 if resp, err := http.Get(link[:strings.LastIndex(link, "?")]); err == nil && resp.StatusCode != http.StatusBadRequest { 659 t.Fatal("should've failed to get image with public link without hash", resp.Status) 660 } 661 662 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = false }) 663 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusNotImplemented { 664 t.Fatal("should've failed to get image with disabled public link") 665 } 666 667 // test after the salt has changed 668 th.App.UpdateConfig(func(cfg *model.Config) { cfg.FileSettings.EnablePublicLink = true }) 669 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = GenerateTestId() }) 670 671 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 672 t.Fatal("should've failed to get image with public link after salt changed") 673 } 674 675 if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest { 676 t.Fatal("should've failed to get image with public link after salt changed") 677 } 678 679 if err := th.cleanupTestFile(store.Must(th.App.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil { 680 t.Fatal(err) 681 } 682 683 th.cleanupTestFile(info) 684 }