github.com/levb/mattermost-server@v5.3.1+incompatible/utils/file_backend_local.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package utils 5 6 import ( 7 "bytes" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "os" 12 "path/filepath" 13 14 "github.com/mattermost/mattermost-server/mlog" 15 "github.com/mattermost/mattermost-server/model" 16 ) 17 18 const ( 19 TEST_FILE_PATH = "/testfile" 20 ) 21 22 type LocalFileBackend struct { 23 directory string 24 } 25 26 func (b *LocalFileBackend) TestConnection() *model.AppError { 27 f := bytes.NewReader([]byte("testingwrite")) 28 if _, err := writeFileLocally(f, filepath.Join(b.directory, TEST_FILE_PATH)); err != nil { 29 return model.NewAppError("TestFileConnection", "api.file.test_connection.local.connection.app_error", nil, err.Error(), http.StatusInternalServerError) 30 } 31 os.Remove(filepath.Join(b.directory, TEST_FILE_PATH)) 32 mlog.Info("Able to write files to local storage.") 33 return nil 34 } 35 36 func (b *LocalFileBackend) Reader(path string) (io.ReadCloser, *model.AppError) { 37 if f, err := os.Open(filepath.Join(b.directory, path)); err != nil { 38 return nil, model.NewAppError("Reader", "api.file.reader.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError) 39 } else { 40 return f, nil 41 } 42 } 43 44 func (b *LocalFileBackend) ReadFile(path string) ([]byte, *model.AppError) { 45 if f, err := ioutil.ReadFile(filepath.Join(b.directory, path)); err != nil { 46 return nil, model.NewAppError("ReadFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError) 47 } else { 48 return f, nil 49 } 50 } 51 52 func (b *LocalFileBackend) FileExists(path string) (bool, *model.AppError) { 53 _, err := os.Stat(filepath.Join(b.directory, path)) 54 55 if os.IsNotExist(err) { 56 return false, nil 57 } else if err == nil { 58 return true, nil 59 } 60 61 return false, model.NewAppError("ReadFile", "api.file.file_exists.exists_local.app_error", nil, err.Error(), http.StatusInternalServerError) 62 } 63 64 func (b *LocalFileBackend) CopyFile(oldPath, newPath string) *model.AppError { 65 if err := CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 66 return model.NewAppError("copyFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 67 } 68 return nil 69 } 70 71 func (b *LocalFileBackend) MoveFile(oldPath, newPath string) *model.AppError { 72 if err := os.MkdirAll(filepath.Dir(filepath.Join(b.directory, newPath)), 0774); err != nil { 73 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 74 } 75 76 if err := os.Rename(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 77 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 78 } 79 80 return nil 81 } 82 83 func (b *LocalFileBackend) WriteFile(fr io.Reader, path string) (int64, *model.AppError) { 84 return writeFileLocally(fr, filepath.Join(b.directory, path)) 85 } 86 87 func writeFileLocally(fr io.Reader, path string) (int64, *model.AppError) { 88 if err := os.MkdirAll(filepath.Dir(path), 0774); err != nil { 89 directory, _ := filepath.Abs(filepath.Dir(path)) 90 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.create_dir.app_error", nil, "directory="+directory+", err="+err.Error(), http.StatusInternalServerError) 91 } 92 fw, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 93 if err != nil { 94 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 95 } 96 defer fw.Close() 97 written, err := io.Copy(fw, fr) 98 if err != nil { 99 return written, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 100 } 101 return written, nil 102 } 103 104 func (b *LocalFileBackend) RemoveFile(path string) *model.AppError { 105 if err := os.Remove(filepath.Join(b.directory, path)); err != nil { 106 return model.NewAppError("RemoveFile", "utils.file.remove_file.local.app_error", nil, err.Error(), http.StatusInternalServerError) 107 } 108 return nil 109 } 110 111 func (b *LocalFileBackend) ListDirectory(path string) (*[]string, *model.AppError) { 112 var paths []string 113 if fileInfos, err := ioutil.ReadDir(filepath.Join(b.directory, path)); err != nil { 114 return nil, model.NewAppError("ListDirectory", "utils.file.list_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 115 } else { 116 for _, fileInfo := range fileInfos { 117 if fileInfo.IsDir() { 118 paths = append(paths, filepath.Join(path, fileInfo.Name())) 119 } 120 } 121 } 122 return &paths, nil 123 } 124 125 func (b *LocalFileBackend) RemoveDirectory(path string) *model.AppError { 126 if err := os.RemoveAll(filepath.Join(b.directory, path)); err != nil { 127 return model.NewAppError("RemoveDirectory", "utils.file.remove_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 128 } 129 return nil 130 }