memory.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. package dataprovider
  2. import (
  3. "crypto/x509"
  4. "errors"
  5. "fmt"
  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. // map for users, username is the key
  26. users map[string]User
  27. // map for virtual folders, folder name is the key
  28. vfolders map[string]vfs.BaseVirtualFolder
  29. // slice with ordered folder names
  30. vfoldersNames []string
  31. // map for admins, username is the key
  32. admins map[string]Admin
  33. // slice with ordered admins
  34. adminsUsernames []string
  35. }
  36. // MemoryProvider auth provider for a memory store
  37. type MemoryProvider struct {
  38. dbHandle *memoryProviderHandle
  39. }
  40. func initializeMemoryProvider(basePath string) {
  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. users: make(map[string]User),
  53. vfolders: make(map[string]vfs.BaseVirtualFolder),
  54. vfoldersNames: []string{},
  55. admins: make(map[string]Admin),
  56. adminsUsernames: []string{},
  57. configFile: configFile,
  58. },
  59. }
  60. if err := provider.reloadConfig(); err != nil {
  61. logger.Error(logSender, "", "unable to load initial data: %v", err)
  62. logger.ErrorToConsole("unable to load initial data: %v", err)
  63. }
  64. }
  65. func (p *MemoryProvider) checkAvailability() error {
  66. p.dbHandle.Lock()
  67. defer p.dbHandle.Unlock()
  68. if p.dbHandle.isClosed {
  69. return errMemoryProviderClosed
  70. }
  71. return nil
  72. }
  73. func (p *MemoryProvider) close() error {
  74. p.dbHandle.Lock()
  75. defer p.dbHandle.Unlock()
  76. if p.dbHandle.isClosed {
  77. return errMemoryProviderClosed
  78. }
  79. p.dbHandle.isClosed = true
  80. return nil
  81. }
  82. func (p *MemoryProvider) validateUserAndTLSCert(username, protocol string, tlsCert *x509.Certificate) (User, error) {
  83. var user User
  84. if tlsCert == nil {
  85. return user, errors.New("TLS certificate cannot be null or empty")
  86. }
  87. user, err := p.userExists(username)
  88. if err != nil {
  89. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  90. return user, err
  91. }
  92. return checkUserAndTLSCertificate(&user, protocol, tlsCert)
  93. }
  94. func (p *MemoryProvider) validateUserAndPass(username, password, ip, protocol string) (User, error) {
  95. var user User
  96. if password == "" {
  97. return user, errors.New("credentials cannot be null or empty")
  98. }
  99. user, err := p.userExists(username)
  100. if err != nil {
  101. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  102. return user, err
  103. }
  104. return checkUserAndPass(&user, password, ip, protocol)
  105. }
  106. func (p *MemoryProvider) validateUserAndPubKey(username string, pubKey []byte) (User, string, error) {
  107. var user User
  108. if len(pubKey) == 0 {
  109. return user, "", errors.New("credentials cannot be null or empty")
  110. }
  111. user, err := p.userExists(username)
  112. if err != nil {
  113. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  114. return user, "", err
  115. }
  116. return checkUserAndPubKey(&user, pubKey)
  117. }
  118. func (p *MemoryProvider) validateAdminAndPass(username, password, ip string) (Admin, error) {
  119. admin, err := p.adminExists(username)
  120. if err != nil {
  121. providerLog(logger.LevelWarn, "error authenticating admin %#v: %v", username, err)
  122. return admin, ErrInvalidCredentials
  123. }
  124. err = admin.checkUserAndPass(password, ip)
  125. return admin, err
  126. }
  127. func (p *MemoryProvider) updateLastLogin(username string) 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. return err
  136. }
  137. user.LastLogin = utils.GetTimeAsMsSinceEpoch(time.Now())
  138. p.dbHandle.users[user.Username] = user
  139. return nil
  140. }
  141. func (p *MemoryProvider) updateQuota(username string, filesAdd int, sizeAdd int64, reset bool) error {
  142. p.dbHandle.Lock()
  143. defer p.dbHandle.Unlock()
  144. if p.dbHandle.isClosed {
  145. return errMemoryProviderClosed
  146. }
  147. user, err := p.userExistsInternal(username)
  148. if err != nil {
  149. providerLog(logger.LevelWarn, "unable to update quota for user %#v error: %v", username, err)
  150. return err
  151. }
  152. if reset {
  153. user.UsedQuotaSize = sizeAdd
  154. user.UsedQuotaFiles = filesAdd
  155. } else {
  156. user.UsedQuotaSize += sizeAdd
  157. user.UsedQuotaFiles += filesAdd
  158. }
  159. user.LastQuotaUpdate = utils.GetTimeAsMsSinceEpoch(time.Now())
  160. providerLog(logger.LevelDebug, "quota updated for user %#v, files increment: %v size increment: %v is reset? %v",
  161. username, filesAdd, sizeAdd, reset)
  162. p.dbHandle.users[user.Username] = user
  163. return nil
  164. }
  165. func (p *MemoryProvider) getUsedQuota(username string) (int, int64, error) {
  166. p.dbHandle.Lock()
  167. defer p.dbHandle.Unlock()
  168. if p.dbHandle.isClosed {
  169. return 0, 0, errMemoryProviderClosed
  170. }
  171. user, err := p.userExistsInternal(username)
  172. if err != nil {
  173. providerLog(logger.LevelWarn, "unable to get quota for user %#v error: %v", username, err)
  174. return 0, 0, err
  175. }
  176. return user.UsedQuotaFiles, user.UsedQuotaSize, err
  177. }
  178. func (p *MemoryProvider) addUser(user *User) error {
  179. // we can query virtual folder while validating a user
  180. // so we have to check without holding the lock
  181. err := ValidateUser(user)
  182. if err != nil {
  183. return err
  184. }
  185. p.dbHandle.Lock()
  186. defer p.dbHandle.Unlock()
  187. if p.dbHandle.isClosed {
  188. return errMemoryProviderClosed
  189. }
  190. _, err = p.userExistsInternal(user.Username)
  191. if err == nil {
  192. return fmt.Errorf("username %#v already exists", user.Username)
  193. }
  194. user.ID = p.getNextID()
  195. user.LastQuotaUpdate = 0
  196. user.UsedQuotaSize = 0
  197. user.UsedQuotaFiles = 0
  198. user.LastLogin = 0
  199. user.VirtualFolders = p.joinVirtualFoldersFields(user)
  200. p.dbHandle.users[user.Username] = user.getACopy()
  201. p.dbHandle.usernames = append(p.dbHandle.usernames, user.Username)
  202. sort.Strings(p.dbHandle.usernames)
  203. return nil
  204. }
  205. func (p *MemoryProvider) updateUser(user *User) error {
  206. // we can query virtual folder while validating a user
  207. // so we have to check without holding the lock
  208. err := ValidateUser(user)
  209. if err != nil {
  210. return err
  211. }
  212. p.dbHandle.Lock()
  213. defer p.dbHandle.Unlock()
  214. if p.dbHandle.isClosed {
  215. return errMemoryProviderClosed
  216. }
  217. u, err := p.userExistsInternal(user.Username)
  218. if err != nil {
  219. return err
  220. }
  221. for _, oldFolder := range u.VirtualFolders {
  222. p.removeUserFromFolderMapping(oldFolder.Name, u.Username)
  223. }
  224. user.VirtualFolders = p.joinVirtualFoldersFields(user)
  225. user.LastQuotaUpdate = u.LastQuotaUpdate
  226. user.UsedQuotaSize = u.UsedQuotaSize
  227. user.UsedQuotaFiles = u.UsedQuotaFiles
  228. user.LastLogin = u.LastLogin
  229. user.ID = u.ID
  230. // pre-login and external auth hook will use the passed *user so save a copy
  231. p.dbHandle.users[user.Username] = user.getACopy()
  232. return nil
  233. }
  234. func (p *MemoryProvider) deleteUser(user *User) error {
  235. p.dbHandle.Lock()
  236. defer p.dbHandle.Unlock()
  237. if p.dbHandle.isClosed {
  238. return errMemoryProviderClosed
  239. }
  240. u, err := p.userExistsInternal(user.Username)
  241. if err != nil {
  242. return err
  243. }
  244. for _, oldFolder := range u.VirtualFolders {
  245. p.removeUserFromFolderMapping(oldFolder.Name, u.Username)
  246. }
  247. delete(p.dbHandle.users, user.Username)
  248. // this could be more efficient
  249. p.dbHandle.usernames = make([]string, 0, len(p.dbHandle.users))
  250. for username := range p.dbHandle.users {
  251. p.dbHandle.usernames = append(p.dbHandle.usernames, username)
  252. }
  253. sort.Strings(p.dbHandle.usernames)
  254. return nil
  255. }
  256. func (p *MemoryProvider) dumpUsers() ([]User, error) {
  257. p.dbHandle.Lock()
  258. defer p.dbHandle.Unlock()
  259. users := make([]User, 0, len(p.dbHandle.usernames))
  260. var err error
  261. if p.dbHandle.isClosed {
  262. return users, errMemoryProviderClosed
  263. }
  264. for _, username := range p.dbHandle.usernames {
  265. u := p.dbHandle.users[username]
  266. user := u.getACopy()
  267. err = addCredentialsToUser(&user)
  268. if err != nil {
  269. return users, err
  270. }
  271. users = append(users, user)
  272. }
  273. return users, err
  274. }
  275. func (p *MemoryProvider) dumpFolders() ([]vfs.BaseVirtualFolder, error) {
  276. p.dbHandle.Lock()
  277. defer p.dbHandle.Unlock()
  278. folders := make([]vfs.BaseVirtualFolder, 0, len(p.dbHandle.vfoldersNames))
  279. if p.dbHandle.isClosed {
  280. return folders, errMemoryProviderClosed
  281. }
  282. for _, f := range p.dbHandle.vfolders {
  283. folders = append(folders, f)
  284. }
  285. return folders, nil
  286. }
  287. func (p *MemoryProvider) getUsers(limit int, offset int, order string) ([]User, error) {
  288. users := make([]User, 0, limit)
  289. var err error
  290. p.dbHandle.Lock()
  291. defer p.dbHandle.Unlock()
  292. if p.dbHandle.isClosed {
  293. return users, errMemoryProviderClosed
  294. }
  295. if limit <= 0 {
  296. return users, err
  297. }
  298. itNum := 0
  299. if order == OrderASC {
  300. for _, username := range p.dbHandle.usernames {
  301. itNum++
  302. if itNum <= offset {
  303. continue
  304. }
  305. u := p.dbHandle.users[username]
  306. user := u.getACopy()
  307. user.PrepareForRendering()
  308. users = append(users, user)
  309. if len(users) >= limit {
  310. break
  311. }
  312. }
  313. } else {
  314. for i := len(p.dbHandle.usernames) - 1; i >= 0; i-- {
  315. itNum++
  316. if itNum <= offset {
  317. continue
  318. }
  319. username := p.dbHandle.usernames[i]
  320. u := p.dbHandle.users[username]
  321. user := u.getACopy()
  322. user.PrepareForRendering()
  323. users = append(users, user)
  324. if len(users) >= limit {
  325. break
  326. }
  327. }
  328. }
  329. return users, err
  330. }
  331. func (p *MemoryProvider) userExists(username string) (User, error) {
  332. p.dbHandle.Lock()
  333. defer p.dbHandle.Unlock()
  334. if p.dbHandle.isClosed {
  335. return User{}, errMemoryProviderClosed
  336. }
  337. return p.userExistsInternal(username)
  338. }
  339. func (p *MemoryProvider) userExistsInternal(username string) (User, error) {
  340. if val, ok := p.dbHandle.users[username]; ok {
  341. return val.getACopy(), nil
  342. }
  343. return User{}, utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", username))
  344. }
  345. func (p *MemoryProvider) addAdmin(admin *Admin) error {
  346. p.dbHandle.Lock()
  347. defer p.dbHandle.Unlock()
  348. if p.dbHandle.isClosed {
  349. return errMemoryProviderClosed
  350. }
  351. err := admin.validate()
  352. if err != nil {
  353. return err
  354. }
  355. _, err = p.adminExistsInternal(admin.Username)
  356. if err == nil {
  357. return fmt.Errorf("admin %#v already exists", admin.Username)
  358. }
  359. admin.ID = p.getNextAdminID()
  360. p.dbHandle.admins[admin.Username] = admin.getACopy()
  361. p.dbHandle.adminsUsernames = append(p.dbHandle.adminsUsernames, admin.Username)
  362. sort.Strings(p.dbHandle.adminsUsernames)
  363. return nil
  364. }
  365. func (p *MemoryProvider) updateAdmin(admin *Admin) error {
  366. p.dbHandle.Lock()
  367. defer p.dbHandle.Unlock()
  368. if p.dbHandle.isClosed {
  369. return errMemoryProviderClosed
  370. }
  371. err := admin.validate()
  372. if err != nil {
  373. return err
  374. }
  375. a, err := p.adminExistsInternal(admin.Username)
  376. if err != nil {
  377. return err
  378. }
  379. admin.ID = a.ID
  380. p.dbHandle.admins[admin.Username] = admin.getACopy()
  381. return nil
  382. }
  383. func (p *MemoryProvider) deleteAdmin(admin *Admin) error {
  384. p.dbHandle.Lock()
  385. defer p.dbHandle.Unlock()
  386. if p.dbHandle.isClosed {
  387. return errMemoryProviderClosed
  388. }
  389. _, err := p.adminExistsInternal(admin.Username)
  390. if err != nil {
  391. return err
  392. }
  393. delete(p.dbHandle.admins, admin.Username)
  394. // this could be more efficient
  395. p.dbHandle.adminsUsernames = make([]string, 0, len(p.dbHandle.admins))
  396. for username := range p.dbHandle.admins {
  397. p.dbHandle.adminsUsernames = append(p.dbHandle.adminsUsernames, username)
  398. }
  399. sort.Strings(p.dbHandle.adminsUsernames)
  400. return nil
  401. }
  402. func (p *MemoryProvider) adminExists(username string) (Admin, error) {
  403. p.dbHandle.Lock()
  404. defer p.dbHandle.Unlock()
  405. if p.dbHandle.isClosed {
  406. return Admin{}, errMemoryProviderClosed
  407. }
  408. return p.adminExistsInternal(username)
  409. }
  410. func (p *MemoryProvider) adminExistsInternal(username string) (Admin, error) {
  411. if val, ok := p.dbHandle.admins[username]; ok {
  412. return val.getACopy(), nil
  413. }
  414. return Admin{}, utils.NewRecordNotFoundError(fmt.Sprintf("admin %#v does not exist", username))
  415. }
  416. func (p *MemoryProvider) dumpAdmins() ([]Admin, error) {
  417. p.dbHandle.Lock()
  418. defer p.dbHandle.Unlock()
  419. admins := make([]Admin, 0, len(p.dbHandle.admins))
  420. if p.dbHandle.isClosed {
  421. return admins, errMemoryProviderClosed
  422. }
  423. for _, admin := range p.dbHandle.admins {
  424. admins = append(admins, admin)
  425. }
  426. return admins, nil
  427. }
  428. func (p *MemoryProvider) getAdmins(limit int, offset int, order string) ([]Admin, error) {
  429. admins := make([]Admin, 0, limit)
  430. p.dbHandle.Lock()
  431. defer p.dbHandle.Unlock()
  432. if p.dbHandle.isClosed {
  433. return admins, errMemoryProviderClosed
  434. }
  435. if limit <= 0 {
  436. return admins, nil
  437. }
  438. itNum := 0
  439. if order == OrderASC {
  440. for _, username := range p.dbHandle.adminsUsernames {
  441. itNum++
  442. if itNum <= offset {
  443. continue
  444. }
  445. a := p.dbHandle.admins[username]
  446. admin := a.getACopy()
  447. admin.HideConfidentialData()
  448. admins = append(admins, admin)
  449. if len(admins) >= limit {
  450. break
  451. }
  452. }
  453. } else {
  454. for i := len(p.dbHandle.adminsUsernames) - 1; i >= 0; i-- {
  455. itNum++
  456. if itNum <= offset {
  457. continue
  458. }
  459. username := p.dbHandle.adminsUsernames[i]
  460. a := p.dbHandle.admins[username]
  461. admin := a.getACopy()
  462. admin.HideConfidentialData()
  463. admins = append(admins, admin)
  464. if len(admins) >= limit {
  465. break
  466. }
  467. }
  468. }
  469. return admins, nil
  470. }
  471. func (p *MemoryProvider) updateFolderQuota(name string, filesAdd int, sizeAdd int64, reset bool) error {
  472. p.dbHandle.Lock()
  473. defer p.dbHandle.Unlock()
  474. if p.dbHandle.isClosed {
  475. return errMemoryProviderClosed
  476. }
  477. folder, err := p.folderExistsInternal(name)
  478. if err != nil {
  479. providerLog(logger.LevelWarn, "unable to update quota for folder %#v error: %v", name, err)
  480. return err
  481. }
  482. if reset {
  483. folder.UsedQuotaSize = sizeAdd
  484. folder.UsedQuotaFiles = filesAdd
  485. } else {
  486. folder.UsedQuotaSize += sizeAdd
  487. folder.UsedQuotaFiles += filesAdd
  488. }
  489. folder.LastQuotaUpdate = utils.GetTimeAsMsSinceEpoch(time.Now())
  490. p.dbHandle.vfolders[name] = folder
  491. return nil
  492. }
  493. func (p *MemoryProvider) getUsedFolderQuota(name string) (int, int64, error) {
  494. p.dbHandle.Lock()
  495. defer p.dbHandle.Unlock()
  496. if p.dbHandle.isClosed {
  497. return 0, 0, errMemoryProviderClosed
  498. }
  499. folder, err := p.folderExistsInternal(name)
  500. if err != nil {
  501. providerLog(logger.LevelWarn, "unable to get quota for folder %#v error: %v", name, err)
  502. return 0, 0, err
  503. }
  504. return folder.UsedQuotaFiles, folder.UsedQuotaSize, err
  505. }
  506. func (p *MemoryProvider) joinVirtualFoldersFields(user *User) []vfs.VirtualFolder {
  507. var folders []vfs.VirtualFolder
  508. for idx := range user.VirtualFolders {
  509. folder := &user.VirtualFolders[idx]
  510. f, err := p.addOrUpdateFolderInternal(&folder.BaseVirtualFolder, user.Username, 0, 0, 0)
  511. if err == nil {
  512. folder.BaseVirtualFolder = f
  513. folders = append(folders, *folder)
  514. }
  515. }
  516. return folders
  517. }
  518. func (p *MemoryProvider) removeUserFromFolderMapping(folderName, username string) {
  519. folder, err := p.folderExistsInternal(folderName)
  520. if err == nil {
  521. var usernames []string
  522. for _, user := range folder.Users {
  523. if user != username {
  524. usernames = append(usernames, user)
  525. }
  526. }
  527. folder.Users = usernames
  528. p.dbHandle.vfolders[folder.Name] = folder
  529. }
  530. }
  531. func (p *MemoryProvider) updateFoldersMappingInternal(folder vfs.BaseVirtualFolder) {
  532. p.dbHandle.vfolders[folder.Name] = folder
  533. if !utils.IsStringInSlice(folder.Name, p.dbHandle.vfoldersNames) {
  534. p.dbHandle.vfoldersNames = append(p.dbHandle.vfoldersNames, folder.Name)
  535. sort.Strings(p.dbHandle.vfoldersNames)
  536. }
  537. }
  538. func (p *MemoryProvider) addOrUpdateFolderInternal(baseFolder *vfs.BaseVirtualFolder, username string, usedQuotaSize int64,
  539. usedQuotaFiles int, lastQuotaUpdate int64) (vfs.BaseVirtualFolder, error) {
  540. folder, err := p.folderExistsInternal(baseFolder.Name)
  541. if err == nil {
  542. // exists
  543. folder.MappedPath = baseFolder.MappedPath
  544. folder.Description = baseFolder.Description
  545. folder.FsConfig = baseFolder.FsConfig.GetACopy()
  546. if !utils.IsStringInSlice(username, folder.Users) {
  547. folder.Users = append(folder.Users, username)
  548. }
  549. p.updateFoldersMappingInternal(folder)
  550. return folder, nil
  551. }
  552. if _, ok := err.(*utils.RecordNotFoundError); ok {
  553. folder = baseFolder.GetACopy()
  554. folder.ID = p.getNextFolderID()
  555. folder.UsedQuotaSize = usedQuotaSize
  556. folder.UsedQuotaFiles = usedQuotaFiles
  557. folder.LastQuotaUpdate = lastQuotaUpdate
  558. folder.Users = []string{username}
  559. p.updateFoldersMappingInternal(folder)
  560. return folder, nil
  561. }
  562. return folder, err
  563. }
  564. func (p *MemoryProvider) folderExistsInternal(name string) (vfs.BaseVirtualFolder, error) {
  565. if val, ok := p.dbHandle.vfolders[name]; ok {
  566. return val, nil
  567. }
  568. return vfs.BaseVirtualFolder{}, utils.NewRecordNotFoundError(fmt.Sprintf("folder %#v does not exist", name))
  569. }
  570. func (p *MemoryProvider) getFolders(limit, offset int, order string) ([]vfs.BaseVirtualFolder, error) {
  571. folders := make([]vfs.BaseVirtualFolder, 0, limit)
  572. var err error
  573. p.dbHandle.Lock()
  574. defer p.dbHandle.Unlock()
  575. if p.dbHandle.isClosed {
  576. return folders, errMemoryProviderClosed
  577. }
  578. if limit <= 0 {
  579. return folders, err
  580. }
  581. itNum := 0
  582. if order == OrderASC {
  583. for _, name := range p.dbHandle.vfoldersNames {
  584. itNum++
  585. if itNum <= offset {
  586. continue
  587. }
  588. f := p.dbHandle.vfolders[name]
  589. folder := f.GetACopy()
  590. folder.PrepareForRendering()
  591. folders = append(folders, folder)
  592. if len(folders) >= limit {
  593. break
  594. }
  595. }
  596. } else {
  597. for i := len(p.dbHandle.vfoldersNames) - 1; i >= 0; i-- {
  598. itNum++
  599. if itNum <= offset {
  600. continue
  601. }
  602. name := p.dbHandle.vfoldersNames[i]
  603. f := p.dbHandle.vfolders[name]
  604. folder := f.GetACopy()
  605. folder.PrepareForRendering()
  606. folders = append(folders, folder)
  607. if len(folders) >= limit {
  608. break
  609. }
  610. }
  611. }
  612. return folders, err
  613. }
  614. func (p *MemoryProvider) getFolderByName(name string) (vfs.BaseVirtualFolder, error) {
  615. p.dbHandle.Lock()
  616. defer p.dbHandle.Unlock()
  617. if p.dbHandle.isClosed {
  618. return vfs.BaseVirtualFolder{}, errMemoryProviderClosed
  619. }
  620. folder, err := p.folderExistsInternal(name)
  621. if err != nil {
  622. return vfs.BaseVirtualFolder{}, err
  623. }
  624. return folder.GetACopy(), nil
  625. }
  626. func (p *MemoryProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
  627. err := ValidateFolder(folder)
  628. if err != nil {
  629. return err
  630. }
  631. p.dbHandle.Lock()
  632. defer p.dbHandle.Unlock()
  633. if p.dbHandle.isClosed {
  634. return errMemoryProviderClosed
  635. }
  636. _, err = p.folderExistsInternal(folder.Name)
  637. if err == nil {
  638. return fmt.Errorf("folder %#v already exists", folder.Name)
  639. }
  640. folder.ID = p.getNextFolderID()
  641. folder.Users = nil
  642. p.dbHandle.vfolders[folder.Name] = folder.GetACopy()
  643. p.dbHandle.vfoldersNames = append(p.dbHandle.vfoldersNames, folder.Name)
  644. sort.Strings(p.dbHandle.vfoldersNames)
  645. return nil
  646. }
  647. func (p *MemoryProvider) updateFolder(folder *vfs.BaseVirtualFolder) error {
  648. err := ValidateFolder(folder)
  649. if err != nil {
  650. return err
  651. }
  652. p.dbHandle.Lock()
  653. defer p.dbHandle.Unlock()
  654. if p.dbHandle.isClosed {
  655. return errMemoryProviderClosed
  656. }
  657. f, err := p.folderExistsInternal(folder.Name)
  658. if err != nil {
  659. return err
  660. }
  661. folder.ID = f.ID
  662. folder.LastQuotaUpdate = f.LastQuotaUpdate
  663. folder.UsedQuotaFiles = f.UsedQuotaFiles
  664. folder.UsedQuotaSize = f.UsedQuotaSize
  665. folder.Users = f.Users
  666. p.dbHandle.vfolders[folder.Name] = folder.GetACopy()
  667. // now update the related users
  668. for _, username := range folder.Users {
  669. user, err := p.userExistsInternal(username)
  670. if err == nil {
  671. var folders []vfs.VirtualFolder
  672. for idx := range user.VirtualFolders {
  673. userFolder := &user.VirtualFolders[idx]
  674. if folder.Name == userFolder.Name {
  675. userFolder.BaseVirtualFolder = folder.GetACopy()
  676. }
  677. folders = append(folders, *userFolder)
  678. }
  679. user.VirtualFolders = folders
  680. p.dbHandle.users[user.Username] = user
  681. }
  682. }
  683. return nil
  684. }
  685. func (p *MemoryProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
  686. p.dbHandle.Lock()
  687. defer p.dbHandle.Unlock()
  688. if p.dbHandle.isClosed {
  689. return errMemoryProviderClosed
  690. }
  691. _, err := p.folderExistsInternal(folder.Name)
  692. if err != nil {
  693. return err
  694. }
  695. for _, username := range folder.Users {
  696. user, err := p.userExistsInternal(username)
  697. if err == nil {
  698. var folders []vfs.VirtualFolder
  699. for idx := range user.VirtualFolders {
  700. userFolder := &user.VirtualFolders[idx]
  701. if folder.Name != userFolder.Name {
  702. folders = append(folders, *userFolder)
  703. }
  704. }
  705. user.VirtualFolders = folders
  706. p.dbHandle.users[user.Username] = user
  707. }
  708. }
  709. delete(p.dbHandle.vfolders, folder.Name)
  710. p.dbHandle.vfoldersNames = []string{}
  711. for name := range p.dbHandle.vfolders {
  712. p.dbHandle.vfoldersNames = append(p.dbHandle.vfoldersNames, name)
  713. }
  714. sort.Strings(p.dbHandle.vfoldersNames)
  715. return nil
  716. }
  717. func (p *MemoryProvider) getNextID() int64 {
  718. nextID := int64(1)
  719. for _, v := range p.dbHandle.users {
  720. if v.ID >= nextID {
  721. nextID = v.ID + 1
  722. }
  723. }
  724. return nextID
  725. }
  726. func (p *MemoryProvider) getNextFolderID() int64 {
  727. nextID := int64(1)
  728. for _, v := range p.dbHandle.vfolders {
  729. if v.ID >= nextID {
  730. nextID = v.ID + 1
  731. }
  732. }
  733. return nextID
  734. }
  735. func (p *MemoryProvider) getNextAdminID() int64 {
  736. nextID := int64(1)
  737. for _, a := range p.dbHandle.admins {
  738. if a.ID >= nextID {
  739. nextID = a.ID + 1
  740. }
  741. }
  742. return nextID
  743. }
  744. func (p *MemoryProvider) clear() {
  745. p.dbHandle.Lock()
  746. defer p.dbHandle.Unlock()
  747. p.dbHandle.usernames = []string{}
  748. p.dbHandle.users = make(map[string]User)
  749. p.dbHandle.vfoldersNames = []string{}
  750. p.dbHandle.vfolders = make(map[string]vfs.BaseVirtualFolder)
  751. p.dbHandle.admins = make(map[string]Admin)
  752. p.dbHandle.adminsUsernames = []string{}
  753. }
  754. func (p *MemoryProvider) reloadConfig() error {
  755. if p.dbHandle.configFile == "" {
  756. providerLog(logger.LevelDebug, "no dump configuration file defined")
  757. return nil
  758. }
  759. providerLog(logger.LevelDebug, "loading dump from file: %#v", p.dbHandle.configFile)
  760. fi, err := os.Stat(p.dbHandle.configFile)
  761. if err != nil {
  762. providerLog(logger.LevelWarn, "error loading dump: %v", err)
  763. return err
  764. }
  765. if fi.Size() == 0 {
  766. err = errors.New("dump configuration file is invalid, its size must be > 0")
  767. providerLog(logger.LevelWarn, "error loading dump: %v", err)
  768. return err
  769. }
  770. if fi.Size() > 10485760 {
  771. err = errors.New("dump configuration file is invalid, its size must be <= 10485760 bytes")
  772. providerLog(logger.LevelWarn, "error loading dump: %v", err)
  773. return err
  774. }
  775. content, err := os.ReadFile(p.dbHandle.configFile)
  776. if err != nil {
  777. providerLog(logger.LevelWarn, "error loading dump: %v", err)
  778. return err
  779. }
  780. dump, err := ParseDumpData(content)
  781. if err != nil {
  782. providerLog(logger.LevelWarn, "error loading dump: %v", err)
  783. return err
  784. }
  785. p.clear()
  786. if err := p.restoreFolders(&dump); err != nil {
  787. return err
  788. }
  789. if err := p.restoreUsers(&dump); err != nil {
  790. return err
  791. }
  792. if err := p.restoreAdmins(&dump); err != nil {
  793. return err
  794. }
  795. providerLog(logger.LevelDebug, "config loaded from file: %#v", p.dbHandle.configFile)
  796. return nil
  797. }
  798. func (p *MemoryProvider) restoreAdmins(dump *BackupData) error {
  799. for _, admin := range dump.Admins {
  800. a, err := p.adminExists(admin.Username)
  801. admin := admin // pin
  802. if err == nil {
  803. admin.ID = a.ID
  804. err = p.updateAdmin(&admin)
  805. if err != nil {
  806. providerLog(logger.LevelWarn, "error updating admin %#v: %v", admin.Username, err)
  807. return err
  808. }
  809. } else {
  810. err = p.addAdmin(&admin)
  811. if err != nil {
  812. providerLog(logger.LevelWarn, "error adding admin %#v: %v", admin.Username, err)
  813. return err
  814. }
  815. }
  816. }
  817. return nil
  818. }
  819. func (p *MemoryProvider) restoreFolders(dump *BackupData) error {
  820. for _, folder := range dump.Folders {
  821. folder := folder // pin
  822. f, err := p.getFolderByName(folder.Name)
  823. if err == nil {
  824. folder.ID = f.ID
  825. err = p.updateFolder(&folder)
  826. if err != nil {
  827. providerLog(logger.LevelWarn, "error updating folder %#v: %v", folder.Name, err)
  828. return err
  829. }
  830. } else {
  831. folder.Users = nil
  832. err = p.addFolder(&folder)
  833. if err != nil {
  834. providerLog(logger.LevelWarn, "error adding folder %#v: %v", folder.Name, err)
  835. return err
  836. }
  837. }
  838. }
  839. return nil
  840. }
  841. func (p *MemoryProvider) restoreUsers(dump *BackupData) error {
  842. for _, user := range dump.Users {
  843. user := user // pin
  844. u, err := p.userExists(user.Username)
  845. if err == nil {
  846. user.ID = u.ID
  847. err = p.updateUser(&user)
  848. if err != nil {
  849. providerLog(logger.LevelWarn, "error updating user %#v: %v", user.Username, err)
  850. return err
  851. }
  852. } else {
  853. err = p.addUser(&user)
  854. if err != nil {
  855. providerLog(logger.LevelWarn, "error adding user %#v: %v", user.Username, err)
  856. return err
  857. }
  858. }
  859. }
  860. return nil
  861. }
  862. // initializeDatabase does nothing, no initilization is needed for memory provider
  863. func (p *MemoryProvider) initializeDatabase() error {
  864. return ErrNoInitRequired
  865. }
  866. func (p *MemoryProvider) migrateDatabase() error {
  867. return ErrNoInitRequired
  868. }
  869. func (p *MemoryProvider) revertDatabase(targetVersion int) error {
  870. return errors.New("memory provider does not store data, revert not possible")
  871. }