memory.go 19 KB

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