memory.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. package dataprovider
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "sort"
  10. "sync"
  11. "time"
  12. "github.com/drakkan/sftpgo/logger"
  13. "github.com/drakkan/sftpgo/utils"
  14. "github.com/drakkan/sftpgo/vfs"
  15. )
  16. var (
  17. errMemoryProviderClosed = errors.New("memory provider is closed")
  18. )
  19. type memoryProviderHandle struct {
  20. // configuration file to use for loading users
  21. configFile string
  22. sync.Mutex
  23. isClosed bool
  24. // slice with ordered usernames
  25. usernames []string
  26. // mapping between ID and username
  27. usersIdx map[int64]string
  28. // map for users, username is the key
  29. users map[string]User
  30. // map for virtual folders, MappedPath is the key
  31. vfolders map[string]vfs.BaseVirtualFolder
  32. // slice with ordered folders mapped path
  33. vfoldersPaths []string
  34. }
  35. // MemoryProvider auth provider for a memory store
  36. type MemoryProvider struct {
  37. dbHandle *memoryProviderHandle
  38. }
  39. func initializeMemoryProvider(basePath string) error {
  40. logSender = fmt.Sprintf("dataprovider_%v", MemoryDataProviderName)
  41. configFile := ""
  42. if utils.IsFileInputValid(config.Name) {
  43. configFile = config.Name
  44. if !filepath.IsAbs(configFile) {
  45. configFile = filepath.Join(basePath, configFile)
  46. }
  47. }
  48. provider = MemoryProvider{
  49. dbHandle: &memoryProviderHandle{
  50. isClosed: false,
  51. usernames: []string{},
  52. usersIdx: make(map[int64]string),
  53. users: make(map[string]User),
  54. vfolders: make(map[string]vfs.BaseVirtualFolder),
  55. vfoldersPaths: []string{},
  56. configFile: configFile,
  57. },
  58. }
  59. return provider.reloadConfig()
  60. }
  61. func (p MemoryProvider) checkAvailability() error {
  62. p.dbHandle.Lock()
  63. defer p.dbHandle.Unlock()
  64. if p.dbHandle.isClosed {
  65. return errMemoryProviderClosed
  66. }
  67. return nil
  68. }
  69. func (p MemoryProvider) close() error {
  70. p.dbHandle.Lock()
  71. defer p.dbHandle.Unlock()
  72. if p.dbHandle.isClosed {
  73. return errMemoryProviderClosed
  74. }
  75. p.dbHandle.isClosed = true
  76. return nil
  77. }
  78. func (p MemoryProvider) validateUserAndPass(username, password, ip, protocol string) (User, error) {
  79. var user User
  80. if len(password) == 0 {
  81. return user, errors.New("Credentials cannot be null or empty")
  82. }
  83. user, err := p.userExists(username)
  84. if err != nil {
  85. providerLog(logger.LevelWarn, "error authenticating user %#v, error: %v", username, err)
  86. return user, err
  87. }
  88. return checkUserAndPass(user, password, ip, protocol)
  89. }
  90. func (p MemoryProvider) validateUserAndPubKey(username string, pubKey []byte) (User, string, error) {
  91. var user User
  92. if len(pubKey) == 0 {
  93. return user, "", errors.New("Credentials cannot be null or empty")
  94. }
  95. user, err := p.userExists(username)
  96. if err != nil {
  97. providerLog(logger.LevelWarn, "error authenticating user %#v, error: %v", username, err)
  98. return user, "", err
  99. }
  100. return checkUserAndPubKey(user, pubKey)
  101. }
  102. func (p MemoryProvider) getUserByID(ID int64) (User, error) {
  103. p.dbHandle.Lock()
  104. defer p.dbHandle.Unlock()
  105. if p.dbHandle.isClosed {
  106. return User{}, errMemoryProviderClosed
  107. }
  108. if val, ok := p.dbHandle.usersIdx[ID]; ok {
  109. return p.userExistsInternal(val)
  110. }
  111. return User{}, &RecordNotFoundError{err: fmt.Sprintf("user with ID %v does not exist", ID)}
  112. }
  113. func (p MemoryProvider) updateLastLogin(username string) error {
  114. p.dbHandle.Lock()
  115. defer p.dbHandle.Unlock()
  116. if p.dbHandle.isClosed {
  117. return errMemoryProviderClosed
  118. }
  119. user, err := p.userExistsInternal(username)
  120. if err != nil {
  121. return err
  122. }
  123. user.LastLogin = utils.GetTimeAsMsSinceEpoch(time.Now())
  124. p.dbHandle.users[user.Username] = user
  125. return nil
  126. }
  127. func (p MemoryProvider) updateQuota(username string, filesAdd int, sizeAdd int64, reset bool) error {
  128. p.dbHandle.Lock()
  129. defer p.dbHandle.Unlock()
  130. if p.dbHandle.isClosed {
  131. return errMemoryProviderClosed
  132. }
  133. user, err := p.userExistsInternal(username)
  134. if err != nil {
  135. providerLog(logger.LevelWarn, "unable to update quota for user %#v error: %v", username, err)
  136. return err
  137. }
  138. if reset {
  139. user.UsedQuotaSize = sizeAdd
  140. user.UsedQuotaFiles = filesAdd
  141. } else {
  142. user.UsedQuotaSize += sizeAdd
  143. user.UsedQuotaFiles += filesAdd
  144. }
  145. user.LastQuotaUpdate = utils.GetTimeAsMsSinceEpoch(time.Now())
  146. providerLog(logger.LevelDebug, "quota updated for user %#v, files increment: %v size increment: %v is reset? %v",
  147. username, filesAdd, sizeAdd, reset)
  148. p.dbHandle.users[user.Username] = user
  149. return nil
  150. }
  151. func (p MemoryProvider) getUsedQuota(username string) (int, int64, error) {
  152. p.dbHandle.Lock()
  153. defer p.dbHandle.Unlock()
  154. if p.dbHandle.isClosed {
  155. return 0, 0, errMemoryProviderClosed
  156. }
  157. user, err := p.userExistsInternal(username)
  158. if err != nil {
  159. providerLog(logger.LevelWarn, "unable to get quota for user %#v error: %v", username, err)
  160. return 0, 0, err
  161. }
  162. return user.UsedQuotaFiles, user.UsedQuotaSize, err
  163. }
  164. func (p MemoryProvider) addUser(user User) error {
  165. p.dbHandle.Lock()
  166. defer p.dbHandle.Unlock()
  167. if p.dbHandle.isClosed {
  168. return errMemoryProviderClosed
  169. }
  170. err := validateUser(&user)
  171. if err != nil {
  172. return err
  173. }
  174. _, err = p.userExistsInternal(user.Username)
  175. if err == nil {
  176. return fmt.Errorf("username %#v already exists", user.Username)
  177. }
  178. user.ID = p.getNextID()
  179. user.LastQuotaUpdate = 0
  180. user.UsedQuotaSize = 0
  181. user.UsedQuotaFiles = 0
  182. user.LastLogin = 0
  183. user.VirtualFolders = p.joinVirtualFoldersFields(user)
  184. p.dbHandle.users[user.Username] = user
  185. p.dbHandle.usersIdx[user.ID] = user.Username
  186. p.dbHandle.usernames = append(p.dbHandle.usernames, user.Username)
  187. sort.Strings(p.dbHandle.usernames)
  188. return nil
  189. }
  190. func (p MemoryProvider) updateUser(user User) error {
  191. p.dbHandle.Lock()
  192. defer p.dbHandle.Unlock()
  193. if p.dbHandle.isClosed {
  194. return errMemoryProviderClosed
  195. }
  196. err := validateUser(&user)
  197. if err != nil {
  198. return err
  199. }
  200. u, err := p.userExistsInternal(user.Username)
  201. if err != nil {
  202. return err
  203. }
  204. for _, oldFolder := range u.VirtualFolders {
  205. p.removeUserFromFolderMapping(oldFolder.MappedPath, u.Username)
  206. }
  207. user.VirtualFolders = p.joinVirtualFoldersFields(user)
  208. user.LastQuotaUpdate = u.LastQuotaUpdate
  209. user.UsedQuotaSize = u.UsedQuotaSize
  210. user.UsedQuotaFiles = u.UsedQuotaFiles
  211. user.LastLogin = u.LastLogin
  212. p.dbHandle.users[user.Username] = user
  213. return nil
  214. }
  215. func (p MemoryProvider) deleteUser(user User) error {
  216. p.dbHandle.Lock()
  217. defer p.dbHandle.Unlock()
  218. if p.dbHandle.isClosed {
  219. return errMemoryProviderClosed
  220. }
  221. u, err := p.userExistsInternal(user.Username)
  222. if err != nil {
  223. return err
  224. }
  225. for _, oldFolder := range u.VirtualFolders {
  226. p.removeUserFromFolderMapping(oldFolder.MappedPath, u.Username)
  227. }
  228. delete(p.dbHandle.users, user.Username)
  229. delete(p.dbHandle.usersIdx, user.ID)
  230. // this could be more efficient
  231. p.dbHandle.usernames = []string{}
  232. for username := range p.dbHandle.users {
  233. p.dbHandle.usernames = append(p.dbHandle.usernames, username)
  234. }
  235. sort.Strings(p.dbHandle.usernames)
  236. return nil
  237. }
  238. func (p MemoryProvider) dumpUsers() ([]User, error) {
  239. p.dbHandle.Lock()
  240. defer p.dbHandle.Unlock()
  241. users := make([]User, 0, len(p.dbHandle.usernames))
  242. var err error
  243. if p.dbHandle.isClosed {
  244. return users, errMemoryProviderClosed
  245. }
  246. for _, username := range p.dbHandle.usernames {
  247. user := p.dbHandle.users[username]
  248. err = addCredentialsToUser(&user)
  249. if err != nil {
  250. return users, err
  251. }
  252. users = append(users, user)
  253. }
  254. return users, err
  255. }
  256. func (p MemoryProvider) dumpFolders() ([]vfs.BaseVirtualFolder, error) {
  257. p.dbHandle.Lock()
  258. defer p.dbHandle.Unlock()
  259. folders := make([]vfs.BaseVirtualFolder, 0, len(p.dbHandle.vfoldersPaths))
  260. if p.dbHandle.isClosed {
  261. return folders, errMemoryProviderClosed
  262. }
  263. for _, f := range p.dbHandle.vfolders {
  264. folders = append(folders, f)
  265. }
  266. return folders, nil
  267. }
  268. func (p MemoryProvider) getUsers(limit int, offset int, order string, username string) ([]User, error) {
  269. users := make([]User, 0, limit)
  270. var err error
  271. p.dbHandle.Lock()
  272. defer p.dbHandle.Unlock()
  273. if p.dbHandle.isClosed {
  274. return users, errMemoryProviderClosed
  275. }
  276. if limit <= 0 {
  277. return users, err
  278. }
  279. if len(username) > 0 {
  280. if offset == 0 {
  281. user, err := p.userExistsInternal(username)
  282. if err == nil {
  283. users = append(users, HideUserSensitiveData(&user))
  284. }
  285. }
  286. return users, err
  287. }
  288. itNum := 0
  289. if order == OrderASC {
  290. for _, username := range p.dbHandle.usernames {
  291. itNum++
  292. if itNum <= offset {
  293. continue
  294. }
  295. user := p.dbHandle.users[username]
  296. users = append(users, HideUserSensitiveData(&user))
  297. if len(users) >= limit {
  298. break
  299. }
  300. }
  301. } else {
  302. for i := len(p.dbHandle.usernames) - 1; i >= 0; i-- {
  303. itNum++
  304. if itNum <= offset {
  305. continue
  306. }
  307. username := p.dbHandle.usernames[i]
  308. user := p.dbHandle.users[username]
  309. users = append(users, HideUserSensitiveData(&user))
  310. if len(users) >= limit {
  311. break
  312. }
  313. }
  314. }
  315. return users, err
  316. }
  317. func (p MemoryProvider) userExists(username string) (User, error) {
  318. p.dbHandle.Lock()
  319. defer p.dbHandle.Unlock()
  320. if p.dbHandle.isClosed {
  321. return User{}, errMemoryProviderClosed
  322. }
  323. return p.userExistsInternal(username)
  324. }
  325. func (p MemoryProvider) userExistsInternal(username string) (User, error) {
  326. if val, ok := p.dbHandle.users[username]; ok {
  327. return val.getACopy(), nil
  328. }
  329. return User{}, &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", username)}
  330. }
  331. func (p MemoryProvider) updateFolderQuota(mappedPath string, filesAdd int, sizeAdd int64, reset bool) error {
  332. p.dbHandle.Lock()
  333. defer p.dbHandle.Unlock()
  334. if p.dbHandle.isClosed {
  335. return errMemoryProviderClosed
  336. }
  337. folder, err := p.folderExistsInternal(mappedPath)
  338. if err != nil {
  339. providerLog(logger.LevelWarn, "unable to update quota for folder %#v error: %v", mappedPath, err)
  340. return err
  341. }
  342. if reset {
  343. folder.UsedQuotaSize = sizeAdd
  344. folder.UsedQuotaFiles = filesAdd
  345. } else {
  346. folder.UsedQuotaSize += sizeAdd
  347. folder.UsedQuotaFiles += filesAdd
  348. }
  349. folder.LastQuotaUpdate = utils.GetTimeAsMsSinceEpoch(time.Now())
  350. p.dbHandle.vfolders[mappedPath] = folder
  351. return nil
  352. }
  353. func (p MemoryProvider) getUsedFolderQuota(mappedPath string) (int, int64, error) {
  354. p.dbHandle.Lock()
  355. defer p.dbHandle.Unlock()
  356. if p.dbHandle.isClosed {
  357. return 0, 0, errMemoryProviderClosed
  358. }
  359. folder, err := p.folderExistsInternal(mappedPath)
  360. if err != nil {
  361. providerLog(logger.LevelWarn, "unable to get quota for folder %#v error: %v", mappedPath, err)
  362. return 0, 0, err
  363. }
  364. return folder.UsedQuotaFiles, folder.UsedQuotaSize, err
  365. }
  366. func (p MemoryProvider) joinVirtualFoldersFields(user User) []vfs.VirtualFolder {
  367. var folders []vfs.VirtualFolder
  368. for _, folder := range user.VirtualFolders {
  369. f, err := p.addOrGetFolderInternal(folder.MappedPath, user.Username, folder.UsedQuotaSize, folder.UsedQuotaFiles,
  370. folder.LastQuotaUpdate)
  371. if err == nil {
  372. folder.UsedQuotaFiles = f.UsedQuotaFiles
  373. folder.UsedQuotaSize = f.UsedQuotaSize
  374. folder.LastQuotaUpdate = f.LastQuotaUpdate
  375. folder.ID = f.ID
  376. folders = append(folders, folder)
  377. }
  378. }
  379. return folders
  380. }
  381. func (p MemoryProvider) removeUserFromFolderMapping(mappedPath, username string) {
  382. folder, err := p.folderExistsInternal(mappedPath)
  383. if err == nil {
  384. var usernames []string
  385. for _, user := range folder.Users {
  386. if user != username {
  387. usernames = append(usernames, user)
  388. }
  389. }
  390. folder.Users = usernames
  391. p.dbHandle.vfolders[folder.MappedPath] = folder
  392. }
  393. }
  394. func (p MemoryProvider) updateFoldersMappingInternal(folder vfs.BaseVirtualFolder) {
  395. p.dbHandle.vfolders[folder.MappedPath] = folder
  396. if !utils.IsStringInSlice(folder.MappedPath, p.dbHandle.vfoldersPaths) {
  397. p.dbHandle.vfoldersPaths = append(p.dbHandle.vfoldersPaths, folder.MappedPath)
  398. sort.Strings(p.dbHandle.vfoldersPaths)
  399. }
  400. }
  401. func (p MemoryProvider) addOrGetFolderInternal(mappedPath, username string, usedQuotaSize int64, usedQuotaFiles int, lastQuotaUpdate int64) (vfs.BaseVirtualFolder, error) {
  402. folder, err := p.folderExistsInternal(mappedPath)
  403. if _, ok := err.(*RecordNotFoundError); ok {
  404. folder := vfs.BaseVirtualFolder{
  405. ID: p.getNextFolderID(),
  406. MappedPath: mappedPath,
  407. UsedQuotaSize: usedQuotaSize,
  408. UsedQuotaFiles: usedQuotaFiles,
  409. LastQuotaUpdate: lastQuotaUpdate,
  410. Users: []string{username},
  411. }
  412. p.updateFoldersMappingInternal(folder)
  413. return folder, nil
  414. }
  415. if err == nil && !utils.IsStringInSlice(username, folder.Users) {
  416. folder.Users = append(folder.Users, username)
  417. p.updateFoldersMappingInternal(folder)
  418. }
  419. return folder, err
  420. }
  421. func (p MemoryProvider) folderExistsInternal(mappedPath string) (vfs.BaseVirtualFolder, error) {
  422. if val, ok := p.dbHandle.vfolders[mappedPath]; ok {
  423. return val, nil
  424. }
  425. return vfs.BaseVirtualFolder{}, &RecordNotFoundError{err: fmt.Sprintf("folder %#v does not exist", mappedPath)}
  426. }
  427. func (p MemoryProvider) getFolders(limit, offset int, order, folderPath string) ([]vfs.BaseVirtualFolder, error) {
  428. folders := make([]vfs.BaseVirtualFolder, 0, limit)
  429. var err error
  430. p.dbHandle.Lock()
  431. defer p.dbHandle.Unlock()
  432. if p.dbHandle.isClosed {
  433. return folders, errMemoryProviderClosed
  434. }
  435. if limit <= 0 {
  436. return folders, err
  437. }
  438. if len(folderPath) > 0 {
  439. if offset == 0 {
  440. var folder vfs.BaseVirtualFolder
  441. folder, err = p.folderExistsInternal(folderPath)
  442. if err == nil {
  443. folders = append(folders, folder)
  444. }
  445. }
  446. return folders, err
  447. }
  448. itNum := 0
  449. if order == OrderASC {
  450. for _, mappedPath := range p.dbHandle.vfoldersPaths {
  451. itNum++
  452. if itNum <= offset {
  453. continue
  454. }
  455. folder := p.dbHandle.vfolders[mappedPath]
  456. folders = append(folders, folder)
  457. if len(folders) >= limit {
  458. break
  459. }
  460. }
  461. } else {
  462. for i := len(p.dbHandle.vfoldersPaths) - 1; i >= 0; i-- {
  463. itNum++
  464. if itNum <= offset {
  465. continue
  466. }
  467. mappedPath := p.dbHandle.vfoldersPaths[i]
  468. folder := p.dbHandle.vfolders[mappedPath]
  469. folders = append(folders, folder)
  470. if len(folders) >= limit {
  471. break
  472. }
  473. }
  474. }
  475. return folders, err
  476. }
  477. func (p MemoryProvider) getFolderByPath(mappedPath string) (vfs.BaseVirtualFolder, error) {
  478. p.dbHandle.Lock()
  479. defer p.dbHandle.Unlock()
  480. if p.dbHandle.isClosed {
  481. return vfs.BaseVirtualFolder{}, errMemoryProviderClosed
  482. }
  483. return p.folderExistsInternal(mappedPath)
  484. }
  485. func (p MemoryProvider) addFolder(folder vfs.BaseVirtualFolder) error {
  486. p.dbHandle.Lock()
  487. defer p.dbHandle.Unlock()
  488. if p.dbHandle.isClosed {
  489. return errMemoryProviderClosed
  490. }
  491. err := validateFolder(&folder)
  492. if err != nil {
  493. return err
  494. }
  495. _, err = p.folderExistsInternal(folder.MappedPath)
  496. if err == nil {
  497. return fmt.Errorf("folder %#v already exists", folder.MappedPath)
  498. }
  499. folder.ID = p.getNextFolderID()
  500. p.dbHandle.vfolders[folder.MappedPath] = folder
  501. p.dbHandle.vfoldersPaths = append(p.dbHandle.vfoldersPaths, folder.MappedPath)
  502. sort.Strings(p.dbHandle.vfoldersPaths)
  503. return nil
  504. }
  505. func (p MemoryProvider) deleteFolder(folder vfs.BaseVirtualFolder) error {
  506. p.dbHandle.Lock()
  507. defer p.dbHandle.Unlock()
  508. if p.dbHandle.isClosed {
  509. return errMemoryProviderClosed
  510. }
  511. _, err := p.folderExistsInternal(folder.MappedPath)
  512. if err != nil {
  513. return err
  514. }
  515. for _, username := range folder.Users {
  516. user, err := p.userExistsInternal(username)
  517. if err == nil {
  518. var folders []vfs.VirtualFolder
  519. for _, userFolder := range user.VirtualFolders {
  520. if folder.MappedPath != userFolder.MappedPath {
  521. folders = append(folders, userFolder)
  522. }
  523. }
  524. user.VirtualFolders = folders
  525. p.dbHandle.users[user.Username] = user
  526. }
  527. }
  528. delete(p.dbHandle.vfolders, folder.MappedPath)
  529. p.dbHandle.vfoldersPaths = []string{}
  530. for mappedPath := range p.dbHandle.vfolders {
  531. p.dbHandle.vfoldersPaths = append(p.dbHandle.vfoldersPaths, mappedPath)
  532. }
  533. sort.Strings(p.dbHandle.vfoldersPaths)
  534. return nil
  535. }
  536. func (p MemoryProvider) getNextID() int64 {
  537. nextID := int64(1)
  538. for id := range p.dbHandle.usersIdx {
  539. if id >= nextID {
  540. nextID = id + 1
  541. }
  542. }
  543. return nextID
  544. }
  545. func (p MemoryProvider) getNextFolderID() int64 {
  546. nextID := int64(1)
  547. for _, v := range p.dbHandle.vfolders {
  548. if v.ID >= nextID {
  549. nextID = v.ID + 1
  550. }
  551. }
  552. return nextID
  553. }
  554. func (p MemoryProvider) clear() {
  555. p.dbHandle.Lock()
  556. defer p.dbHandle.Unlock()
  557. p.dbHandle.usernames = []string{}
  558. p.dbHandle.usersIdx = make(map[int64]string)
  559. p.dbHandle.users = make(map[string]User)
  560. p.dbHandle.vfoldersPaths = []string{}
  561. p.dbHandle.vfolders = make(map[string]vfs.BaseVirtualFolder)
  562. }
  563. func (p MemoryProvider) reloadConfig() error {
  564. if len(p.dbHandle.configFile) == 0 {
  565. providerLog(logger.LevelDebug, "no users configuration file defined")
  566. return nil
  567. }
  568. providerLog(logger.LevelDebug, "loading users from file: %#v", p.dbHandle.configFile)
  569. fi, err := os.Stat(p.dbHandle.configFile)
  570. if err != nil {
  571. providerLog(logger.LevelWarn, "error loading users: %v", err)
  572. return err
  573. }
  574. if fi.Size() == 0 {
  575. err = errors.New("users configuration file is invalid, its size must be > 0")
  576. providerLog(logger.LevelWarn, "error loading users: %v", err)
  577. return err
  578. }
  579. if fi.Size() > 10485760 {
  580. err = errors.New("users configuration file is invalid, its size must be <= 10485760 bytes")
  581. providerLog(logger.LevelWarn, "error loading users: %v", err)
  582. return err
  583. }
  584. content, err := ioutil.ReadFile(p.dbHandle.configFile)
  585. if err != nil {
  586. providerLog(logger.LevelWarn, "error loading users: %v", err)
  587. return err
  588. }
  589. var dump BackupData
  590. err = json.Unmarshal(content, &dump)
  591. if err != nil {
  592. providerLog(logger.LevelWarn, "error loading users: %v", err)
  593. return err
  594. }
  595. p.clear()
  596. for _, folder := range dump.Folders {
  597. _, err := p.getFolderByPath(folder.MappedPath)
  598. if err == nil {
  599. logger.Debug(logSender, "", "folder %#v already exists, restore not needed", folder.MappedPath)
  600. continue
  601. }
  602. folder.Users = nil
  603. err = p.addFolder(folder)
  604. if err != nil {
  605. providerLog(logger.LevelWarn, "error adding folder %#v: %v", folder.MappedPath, err)
  606. return err
  607. }
  608. }
  609. for _, user := range dump.Users {
  610. u, err := p.userExists(user.Username)
  611. if err == nil {
  612. user.ID = u.ID
  613. err = p.updateUser(user)
  614. if err != nil {
  615. providerLog(logger.LevelWarn, "error updating user %#v: %v", user.Username, err)
  616. return err
  617. }
  618. } else {
  619. err = p.addUser(user)
  620. if err != nil {
  621. providerLog(logger.LevelWarn, "error adding user %#v: %v", user.Username, err)
  622. return err
  623. }
  624. }
  625. }
  626. providerLog(logger.LevelDebug, "user and folders loaded from file: %#v", p.dbHandle.configFile)
  627. return nil
  628. }
  629. // initializeDatabase does nothing, no initilization is needed for memory provider
  630. func (p MemoryProvider) initializeDatabase() error {
  631. return ErrNoInitRequired
  632. }
  633. func (p MemoryProvider) migrateDatabase() error {
  634. return ErrNoInitRequired
  635. }