github.com/cs3org/reva/v2@v2.27.7/pkg/siteacc/data/filestorage.go (about) 1 // Copyright 2018-2020 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this filePath except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package data 20 21 import ( 22 "encoding/json" 23 "os" 24 "path/filepath" 25 26 "github.com/cs3org/reva/v2/pkg/siteacc/config" 27 "github.com/pkg/errors" 28 "github.com/rs/zerolog" 29 ) 30 31 // FileStorage implements a filePath-based storage. 32 type FileStorage struct { 33 Storage 34 35 conf *config.Configuration 36 log *zerolog.Logger 37 38 sitesFilePath string 39 accountsFilePath string 40 } 41 42 func (storage *FileStorage) initialize(conf *config.Configuration, log *zerolog.Logger) error { 43 if conf == nil { 44 return errors.Errorf("no configuration provided") 45 } 46 storage.conf = conf 47 48 if log == nil { 49 return errors.Errorf("no logger provided") 50 } 51 storage.log = log 52 53 if conf.Storage.File.SitesFile == "" { 54 return errors.Errorf("no sites file set in the configuration") 55 } 56 storage.sitesFilePath = conf.Storage.File.SitesFile 57 58 if conf.Storage.File.AccountsFile == "" { 59 return errors.Errorf("no accounts file set in the configuration") 60 } 61 storage.accountsFilePath = conf.Storage.File.AccountsFile 62 63 // Create the file directories if necessary 64 _ = os.MkdirAll(filepath.Dir(storage.sitesFilePath), 0755) 65 _ = os.MkdirAll(filepath.Dir(storage.accountsFilePath), 0755) 66 67 return nil 68 } 69 70 func (storage *FileStorage) readData(file string, obj interface{}) error { 71 // Read the data from the specified file 72 jsonData, err := os.ReadFile(file) 73 if err != nil { 74 return errors.Wrapf(err, "unable to read file %v", file) 75 } 76 77 if err := json.Unmarshal(jsonData, obj); err != nil { 78 return errors.Wrapf(err, "invalid file %v", file) 79 } 80 81 return nil 82 } 83 84 // ReadSites reads all stored sites into the given data object. 85 func (storage *FileStorage) ReadSites() (*Sites, error) { 86 sites := &Sites{} 87 if err := storage.readData(storage.sitesFilePath, sites); err != nil { 88 return nil, errors.Wrap(err, "error reading sites") 89 } 90 return sites, nil 91 } 92 93 // ReadAccounts reads all stored accounts into the given data object. 94 func (storage *FileStorage) ReadAccounts() (*Accounts, error) { 95 accounts := &Accounts{} 96 if err := storage.readData(storage.accountsFilePath, accounts); err != nil { 97 return nil, errors.Wrap(err, "error reading accounts") 98 } 99 return accounts, nil 100 } 101 102 func (storage *FileStorage) writeData(file string, obj interface{}) error { 103 // Write the data to the specified file 104 jsonData, _ := json.MarshalIndent(obj, "", "\t") 105 if err := os.WriteFile(file, jsonData, 0755); err != nil { 106 return errors.Wrapf(err, "unable to write file %v", file) 107 } 108 return nil 109 } 110 111 // WriteSites writes all stored sites from the given data object. 112 func (storage *FileStorage) WriteSites(sites *Sites) error { 113 if err := storage.writeData(storage.sitesFilePath, sites); err != nil { 114 return errors.Wrap(err, "error writing sites") 115 } 116 return nil 117 } 118 119 // WriteAccounts writes all stored accounts from the given data object. 120 func (storage *FileStorage) WriteAccounts(accounts *Accounts) error { 121 if err := storage.writeData(storage.accountsFilePath, accounts); err != nil { 122 return errors.Wrap(err, "error writing accounts") 123 } 124 return nil 125 } 126 127 // SiteAdded is called when a site has been added. 128 func (storage *FileStorage) SiteAdded(site *Site) { 129 // Simply skip this action; all data is saved solely in WriteSites 130 } 131 132 // SiteUpdated is called when a site has been updated. 133 func (storage *FileStorage) SiteUpdated(site *Site) { 134 // Simply skip this action; all data is saved solely in WriteSites 135 } 136 137 // SiteRemoved is called when a site has been removed. 138 func (storage *FileStorage) SiteRemoved(site *Site) { 139 // Simply skip this action; all data is saved solely in WriteSites 140 } 141 142 // AccountAdded is called when an account has been added. 143 func (storage *FileStorage) AccountAdded(account *Account) { 144 // Simply skip this action; all data is saved solely in WriteAccounts 145 } 146 147 // AccountUpdated is called when an account has been updated. 148 func (storage *FileStorage) AccountUpdated(account *Account) { 149 // Simply skip this action; all data is saved solely in WriteAccounts 150 } 151 152 // AccountRemoved is called when an account has been removed. 153 func (storage *FileStorage) AccountRemoved(account *Account) { 154 // Simply skip this action; all data is saved solely in WriteAccounts 155 } 156 157 // NewFileStorage creates a new file storage. 158 func NewFileStorage(conf *config.Configuration, log *zerolog.Logger) (*FileStorage, error) { 159 storage := &FileStorage{} 160 if err := storage.initialize(conf, log); err != nil { 161 return nil, errors.Wrap(err, "unable to initialize the file storage") 162 } 163 return storage, nil 164 }