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  }