github.com/cs3org/reva/v2@v2.27.7/pkg/siteacc/manager/sitesmanager.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 file 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 manager 20 21 import ( 22 "strings" 23 "sync" 24 25 "github.com/cs3org/reva/v2/pkg/siteacc/config" 26 "github.com/cs3org/reva/v2/pkg/siteacc/data" 27 "github.com/pkg/errors" 28 "github.com/rs/zerolog" 29 ) 30 31 // SitesManager is responsible for all sites related tasks. 32 type SitesManager struct { 33 conf *config.Configuration 34 log *zerolog.Logger 35 36 storage data.Storage 37 38 sites data.Sites 39 40 mutex sync.RWMutex 41 } 42 43 func (mngr *SitesManager) initialize(storage data.Storage, conf *config.Configuration, log *zerolog.Logger) error { 44 if conf == nil { 45 return errors.Errorf("no configuration provided") 46 } 47 mngr.conf = conf 48 49 if log == nil { 50 return errors.Errorf("no logger provided") 51 } 52 mngr.log = log 53 54 if storage == nil { 55 return errors.Errorf("no storage provided") 56 } 57 mngr.storage = storage 58 59 mngr.sites = make(data.Sites, 0, 32) // Reserve some space for sites 60 mngr.readAllSites() 61 62 return nil 63 } 64 65 func (mngr *SitesManager) readAllSites() { 66 if sites, err := mngr.storage.ReadSites(); err == nil { 67 mngr.sites = *sites 68 } else { 69 // Just warn when not being able to read sites 70 mngr.log.Warn().Err(err).Msg("error while reading sites") 71 } 72 } 73 74 func (mngr *SitesManager) writeAllSites() { 75 if err := mngr.storage.WriteSites(&mngr.sites); err != nil { 76 // Just warn when not being able to write sites 77 mngr.log.Warn().Err(err).Msg("error while writing sites") 78 } 79 } 80 81 // GetSite retrieves the site with the given ID, creating it first if necessary. 82 func (mngr *SitesManager) GetSite(id string, cloneSite bool) (*data.Site, error) { 83 mngr.mutex.RLock() 84 defer mngr.mutex.RUnlock() 85 86 site, err := mngr.getSite(id) 87 if err != nil { 88 return nil, err 89 } 90 91 if cloneSite { 92 site = site.Clone(false) 93 } 94 95 return site, nil 96 } 97 98 // FindSite returns the site specified by the ID if one exists. 99 func (mngr *SitesManager) FindSite(id string) *data.Site { 100 site, _ := mngr.findSite(id) 101 return site 102 } 103 104 // UpdateSite updates the site identified by the site ID; if no such site exists, one will be created first. 105 func (mngr *SitesManager) UpdateSite(siteData *data.Site) error { 106 mngr.mutex.Lock() 107 defer mngr.mutex.Unlock() 108 109 site, err := mngr.getSite(siteData.ID) 110 if err != nil { 111 return errors.Wrap(err, "site to update not found") 112 } 113 114 if err := site.Update(siteData, mngr.conf.Security.CredentialsPassphrase); err == nil { 115 mngr.storage.SiteUpdated(site) 116 mngr.writeAllSites() 117 } else { 118 return errors.Wrap(err, "error while updating site") 119 } 120 121 return nil 122 } 123 124 // CloneSites retrieves all sites currently stored by cloning the data, thus avoiding race conflicts and making outside modifications impossible. 125 func (mngr *SitesManager) CloneSites(eraseCredentials bool) data.Sites { 126 mngr.mutex.RLock() 127 defer mngr.mutex.RUnlock() 128 129 clones := make(data.Sites, 0, len(mngr.sites)) 130 for _, site := range mngr.sites { 131 clones = append(clones, site.Clone(eraseCredentials)) 132 } 133 134 return clones 135 } 136 137 func (mngr *SitesManager) getSite(id string) (*data.Site, error) { 138 site, err := mngr.findSite(id) 139 if site == nil { 140 site, err = mngr.createSite(id) 141 } 142 return site, err 143 } 144 145 func (mngr *SitesManager) createSite(id string) (*data.Site, error) { 146 site, err := data.NewSite(id) 147 if err != nil { 148 return nil, errors.Wrap(err, "error while creating site") 149 } 150 mngr.sites = append(mngr.sites, site) 151 mngr.storage.SiteAdded(site) 152 mngr.writeAllSites() 153 return site, nil 154 } 155 156 func (mngr *SitesManager) findSite(id string) (*data.Site, error) { 157 if len(id) == 0 { 158 return nil, errors.Errorf("no search ID specified") 159 } 160 161 site := mngr.findSiteByPredicate(func(site *data.Site) bool { return strings.EqualFold(site.ID, id) }) 162 if site != nil { 163 return site, nil 164 } 165 166 return nil, errors.Errorf("no site found matching the specified ID") 167 } 168 169 func (mngr *SitesManager) findSiteByPredicate(predicate func(*data.Site) bool) *data.Site { 170 for _, site := range mngr.sites { 171 if predicate(site) { 172 return site 173 } 174 } 175 return nil 176 } 177 178 // NewSitesManager creates a new sites manager instance. 179 func NewSitesManager(storage data.Storage, conf *config.Configuration, log *zerolog.Logger) (*SitesManager, error) { 180 mngr := &SitesManager{} 181 if err := mngr.initialize(storage, conf, log); err != nil { 182 return nil, errors.Wrap(err, "unable to initialize the sites manager") 183 } 184 return mngr, nil 185 }