sqlite.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. //go:build !nosqlite
  2. // +build !nosqlite
  3. package dataprovider
  4. import (
  5. "context"
  6. "crypto/x509"
  7. "database/sql"
  8. "errors"
  9. "fmt"
  10. "path/filepath"
  11. "strings"
  12. // we import go-sqlite3 here to be able to disable SQLite support using a build tag
  13. _ "github.com/mattn/go-sqlite3"
  14. "github.com/drakkan/sftpgo/v2/logger"
  15. "github.com/drakkan/sftpgo/v2/util"
  16. "github.com/drakkan/sftpgo/v2/version"
  17. "github.com/drakkan/sftpgo/v2/vfs"
  18. )
  19. const (
  20. sqliteResetSQL = `DROP TABLE IF EXISTS "{{api_keys}}";
  21. DROP TABLE IF EXISTS "{{folders_mapping}}";
  22. DROP TABLE IF EXISTS "{{admins}}";
  23. DROP TABLE IF EXISTS "{{folders}}";
  24. DROP TABLE IF EXISTS "{{shares}}";
  25. DROP TABLE IF EXISTS "{{users}}";
  26. DROP TABLE IF EXISTS "{{defender_events}}";
  27. DROP TABLE IF EXISTS "{{defender_hosts}}";
  28. DROP TABLE IF EXISTS "{{schema_version}}";
  29. `
  30. sqliteInitialSQL = `CREATE TABLE "{{schema_version}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "version" integer NOT NULL);
  31. CREATE TABLE "{{admins}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE,
  32. "description" varchar(512) NULL, "password" varchar(255) NOT NULL, "email" varchar(255) NULL, "status" integer NOT NULL,
  33. "permissions" text NOT NULL, "filters" text NULL, "additional_info" text NULL);
  34. CREATE TABLE "{{folders}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL UNIQUE,
  35. "description" varchar(512) NULL, "path" varchar(512) NULL, "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL,
  36. "last_quota_update" bigint NOT NULL, "filesystem" text NULL);
  37. CREATE TABLE "{{users}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE,
  38. "status" integer NOT NULL, "expiration_date" bigint NOT NULL, "description" varchar(512) NULL, "password" text NULL,
  39. "public_keys" text NULL, "home_dir" varchar(512) NOT NULL, "uid" integer NOT NULL, "gid" integer NOT NULL,
  40. "max_sessions" integer NOT NULL, "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "permissions" text NOT NULL,
  41. "used_quota_size" bigint NOT NULL, "used_quota_files" integer NOT NULL, "last_quota_update" bigint NOT NULL,
  42. "upload_bandwidth" integer NOT NULL, "download_bandwidth" integer NOT NULL, "last_login" bigint NOT NULL, "filters" text NULL,
  43. "filesystem" text NULL, "additional_info" text NULL);
  44. CREATE TABLE "{{folders_mapping}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "virtual_path" varchar(512) NOT NULL,
  45. "quota_size" bigint NOT NULL, "quota_files" integer NOT NULL, "folder_id" integer NOT NULL REFERENCES "{{folders}}" ("id")
  46. ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, "user_id" integer NOT NULL REFERENCES "{{users}}" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
  47. CONSTRAINT "{{prefix}}unique_mapping" UNIQUE ("user_id", "folder_id"));
  48. CREATE INDEX "{{prefix}}folders_mapping_folder_id_idx" ON "{{folders_mapping}}" ("folder_id");
  49. CREATE INDEX "{{prefix}}folders_mapping_user_id_idx" ON "{{folders_mapping}}" ("user_id");
  50. INSERT INTO {{schema_version}} (version) VALUES (10);
  51. `
  52. sqliteV11SQL = `CREATE TABLE "{{api_keys}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL,
  53. "key_id" varchar(50) NOT NULL UNIQUE, "api_key" varchar(255) NOT NULL UNIQUE, "scope" integer NOT NULL, "created_at" bigint NOT NULL,
  54. "updated_at" bigint NOT NULL, "last_use_at" bigint NOT NULL, "expires_at" bigint NOT NULL, "description" text NULL,
  55. "admin_id" integer NULL REFERENCES "{{admins}}" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
  56. "user_id" integer NULL REFERENCES "{{users}}" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED);
  57. CREATE INDEX "{{prefix}}api_keys_admin_id_idx" ON "api_keys" ("admin_id");
  58. CREATE INDEX "{{prefix}}api_keys_user_id_idx" ON "api_keys" ("user_id");
  59. `
  60. sqliteV11DownSQL = `DROP TABLE "{{api_keys}}";`
  61. sqliteV12SQL = `ALTER TABLE "{{admins}}" ADD COLUMN "created_at" bigint DEFAULT 0 NOT NULL;
  62. ALTER TABLE "{{admins}}" ADD COLUMN "updated_at" bigint DEFAULT 0 NOT NULL;
  63. ALTER TABLE "{{admins}}" ADD COLUMN "last_login" bigint DEFAULT 0 NOT NULL;
  64. ALTER TABLE "{{users}}" ADD COLUMN "created_at" bigint DEFAULT 0 NOT NULL;
  65. ALTER TABLE "{{users}}" ADD COLUMN "updated_at" bigint DEFAULT 0 NOT NULL;
  66. CREATE INDEX "{{prefix}}users_updated_at_idx" ON "{{users}}" ("updated_at");
  67. `
  68. sqliteV12DownSQL = `DROP INDEX "{{prefix}}users_updated_at_idx";
  69. ALTER TABLE "{{users}}" DROP COLUMN "updated_at";
  70. ALTER TABLE "{{users}}" DROP COLUMN "created_at";
  71. ALTER TABLE "{{admins}}" DROP COLUMN "created_at";
  72. ALTER TABLE "{{admins}}" DROP COLUMN "updated_at";
  73. ALTER TABLE "{{admins}}" DROP COLUMN "last_login";
  74. `
  75. sqliteV13SQL = `ALTER TABLE "{{users}}" ADD COLUMN "email" varchar(255) NULL;`
  76. sqliteV13DownSQL = `ALTER TABLE "{{users}}" DROP COLUMN "email";`
  77. sqliteV14SQL = `CREATE TABLE "{{shares}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
  78. "share_id" varchar(60) NOT NULL UNIQUE, "name" varchar(255) NOT NULL, "description" varchar(512) NULL,
  79. "scope" integer NOT NULL, "paths" text NOT NULL, "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL,
  80. "last_use_at" bigint NOT NULL, "expires_at" bigint NOT NULL, "password" text NULL, "max_tokens" integer NOT NULL,
  81. "used_tokens" integer NOT NULL, "allow_from" text NULL,
  82. "user_id" integer NOT NULL REFERENCES "{{users}}" ("id") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED);
  83. CREATE INDEX "{{prefix}}shares_user_id_idx" ON "{{shares}}" ("user_id");
  84. `
  85. sqliteV14DownSQL = `DROP TABLE "{{shares}}";`
  86. sqliteV15SQL = `CREATE TABLE "{{defender_hosts}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
  87. "ip" varchar(50) NOT NULL UNIQUE, "ban_time" bigint NOT NULL, "updated_at" bigint NOT NULL);
  88. CREATE TABLE "{{defender_events}}" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "date_time" bigint NOT NULL,
  89. "score" integer NOT NULL, "host_id" integer NOT NULL REFERENCES "{{defender_hosts}}" ("id") ON DELETE CASCADE
  90. DEFERRABLE INITIALLY DEFERRED);
  91. CREATE INDEX "{{prefix}}defender_hosts_updated_at_idx" ON "{{defender_hosts}}" ("updated_at");
  92. CREATE INDEX "{{prefix}}defender_hosts_ban_time_idx" ON "{{defender_hosts}}" ("ban_time");
  93. CREATE INDEX "{{prefix}}defender_events_date_time_idx" ON "{{defender_events}}" ("date_time");
  94. CREATE INDEX "{{prefix}}defender_events_host_id_idx" ON "{{defender_events}}" ("host_id");
  95. `
  96. sqliteV15DownSQL = `DROP TABLE "{{defender_events}}";
  97. DROP TABLE "{{defender_hosts}}";
  98. `
  99. )
  100. // SQLiteProvider auth provider for SQLite database
  101. type SQLiteProvider struct {
  102. dbHandle *sql.DB
  103. }
  104. func init() {
  105. version.AddFeature("+sqlite")
  106. }
  107. func initializeSQLiteProvider(basePath string) error {
  108. var err error
  109. var connectionString string
  110. if config.ConnectionString == "" {
  111. dbPath := config.Name
  112. if !util.IsFileInputValid(dbPath) {
  113. return fmt.Errorf("invalid database path: %#v", dbPath)
  114. }
  115. if !filepath.IsAbs(dbPath) {
  116. dbPath = filepath.Join(basePath, dbPath)
  117. }
  118. connectionString = fmt.Sprintf("file:%v?cache=shared&_foreign_keys=1", dbPath)
  119. } else {
  120. connectionString = config.ConnectionString
  121. }
  122. dbHandle, err := sql.Open("sqlite3", connectionString)
  123. if err == nil {
  124. providerLog(logger.LevelDebug, "sqlite database handle created, connection string: %#v", connectionString)
  125. dbHandle.SetMaxOpenConns(1)
  126. provider = &SQLiteProvider{dbHandle: dbHandle}
  127. } else {
  128. providerLog(logger.LevelError, "error creating sqlite database handler, connection string: %#v, error: %v",
  129. connectionString, err)
  130. }
  131. return err
  132. }
  133. func (p *SQLiteProvider) checkAvailability() error {
  134. return sqlCommonCheckAvailability(p.dbHandle)
  135. }
  136. func (p *SQLiteProvider) validateUserAndPass(username, password, ip, protocol string) (User, error) {
  137. return sqlCommonValidateUserAndPass(username, password, ip, protocol, p.dbHandle)
  138. }
  139. func (p *SQLiteProvider) validateUserAndTLSCert(username, protocol string, tlsCert *x509.Certificate) (User, error) {
  140. return sqlCommonValidateUserAndTLSCertificate(username, protocol, tlsCert, p.dbHandle)
  141. }
  142. func (p *SQLiteProvider) validateUserAndPubKey(username string, publicKey []byte) (User, string, error) {
  143. return sqlCommonValidateUserAndPubKey(username, publicKey, p.dbHandle)
  144. }
  145. func (p *SQLiteProvider) updateQuota(username string, filesAdd int, sizeAdd int64, reset bool) error {
  146. return sqlCommonUpdateQuota(username, filesAdd, sizeAdd, reset, p.dbHandle)
  147. }
  148. func (p *SQLiteProvider) getUsedQuota(username string) (int, int64, error) {
  149. return sqlCommonGetUsedQuota(username, p.dbHandle)
  150. }
  151. func (p *SQLiteProvider) setUpdatedAt(username string) {
  152. sqlCommonSetUpdatedAt(username, p.dbHandle)
  153. }
  154. func (p *SQLiteProvider) updateLastLogin(username string) error {
  155. return sqlCommonUpdateLastLogin(username, p.dbHandle)
  156. }
  157. func (p *SQLiteProvider) updateAdminLastLogin(username string) error {
  158. return sqlCommonUpdateAdminLastLogin(username, p.dbHandle)
  159. }
  160. func (p *SQLiteProvider) userExists(username string) (User, error) {
  161. return sqlCommonGetUserByUsername(username, p.dbHandle)
  162. }
  163. func (p *SQLiteProvider) addUser(user *User) error {
  164. return sqlCommonAddUser(user, p.dbHandle)
  165. }
  166. func (p *SQLiteProvider) updateUser(user *User) error {
  167. return sqlCommonUpdateUser(user, p.dbHandle)
  168. }
  169. func (p *SQLiteProvider) deleteUser(user *User) error {
  170. return sqlCommonDeleteUser(user, p.dbHandle)
  171. }
  172. func (p *SQLiteProvider) dumpUsers() ([]User, error) {
  173. return sqlCommonDumpUsers(p.dbHandle)
  174. }
  175. // SQLite provider cannot be shared, so we always return no recently updated users
  176. func (p *SQLiteProvider) getRecentlyUpdatedUsers(after int64) ([]User, error) {
  177. return nil, nil
  178. }
  179. func (p *SQLiteProvider) getUsers(limit int, offset int, order string) ([]User, error) {
  180. return sqlCommonGetUsers(limit, offset, order, p.dbHandle)
  181. }
  182. func (p *SQLiteProvider) dumpFolders() ([]vfs.BaseVirtualFolder, error) {
  183. return sqlCommonDumpFolders(p.dbHandle)
  184. }
  185. func (p *SQLiteProvider) getFolders(limit, offset int, order string) ([]vfs.BaseVirtualFolder, error) {
  186. return sqlCommonGetFolders(limit, offset, order, p.dbHandle)
  187. }
  188. func (p *SQLiteProvider) getFolderByName(name string) (vfs.BaseVirtualFolder, error) {
  189. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  190. defer cancel()
  191. return sqlCommonGetFolderByName(ctx, name, p.dbHandle)
  192. }
  193. func (p *SQLiteProvider) addFolder(folder *vfs.BaseVirtualFolder) error {
  194. return sqlCommonAddFolder(folder, p.dbHandle)
  195. }
  196. func (p *SQLiteProvider) updateFolder(folder *vfs.BaseVirtualFolder) error {
  197. return sqlCommonUpdateFolder(folder, p.dbHandle)
  198. }
  199. func (p *SQLiteProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error {
  200. return sqlCommonDeleteFolder(folder, p.dbHandle)
  201. }
  202. func (p *SQLiteProvider) updateFolderQuota(name string, filesAdd int, sizeAdd int64, reset bool) error {
  203. return sqlCommonUpdateFolderQuota(name, filesAdd, sizeAdd, reset, p.dbHandle)
  204. }
  205. func (p *SQLiteProvider) getUsedFolderQuota(name string) (int, int64, error) {
  206. return sqlCommonGetFolderUsedQuota(name, p.dbHandle)
  207. }
  208. func (p *SQLiteProvider) adminExists(username string) (Admin, error) {
  209. return sqlCommonGetAdminByUsername(username, p.dbHandle)
  210. }
  211. func (p *SQLiteProvider) addAdmin(admin *Admin) error {
  212. return sqlCommonAddAdmin(admin, p.dbHandle)
  213. }
  214. func (p *SQLiteProvider) updateAdmin(admin *Admin) error {
  215. return sqlCommonUpdateAdmin(admin, p.dbHandle)
  216. }
  217. func (p *SQLiteProvider) deleteAdmin(admin *Admin) error {
  218. return sqlCommonDeleteAdmin(admin, p.dbHandle)
  219. }
  220. func (p *SQLiteProvider) getAdmins(limit int, offset int, order string) ([]Admin, error) {
  221. return sqlCommonGetAdmins(limit, offset, order, p.dbHandle)
  222. }
  223. func (p *SQLiteProvider) dumpAdmins() ([]Admin, error) {
  224. return sqlCommonDumpAdmins(p.dbHandle)
  225. }
  226. func (p *SQLiteProvider) validateAdminAndPass(username, password, ip string) (Admin, error) {
  227. return sqlCommonValidateAdminAndPass(username, password, ip, p.dbHandle)
  228. }
  229. func (p *SQLiteProvider) apiKeyExists(keyID string) (APIKey, error) {
  230. return sqlCommonGetAPIKeyByID(keyID, p.dbHandle)
  231. }
  232. func (p *SQLiteProvider) addAPIKey(apiKey *APIKey) error {
  233. return sqlCommonAddAPIKey(apiKey, p.dbHandle)
  234. }
  235. func (p *SQLiteProvider) updateAPIKey(apiKey *APIKey) error {
  236. return sqlCommonUpdateAPIKey(apiKey, p.dbHandle)
  237. }
  238. func (p *SQLiteProvider) deleteAPIKey(apiKey *APIKey) error {
  239. return sqlCommonDeleteAPIKey(apiKey, p.dbHandle)
  240. }
  241. func (p *SQLiteProvider) getAPIKeys(limit int, offset int, order string) ([]APIKey, error) {
  242. return sqlCommonGetAPIKeys(limit, offset, order, p.dbHandle)
  243. }
  244. func (p *SQLiteProvider) dumpAPIKeys() ([]APIKey, error) {
  245. return sqlCommonDumpAPIKeys(p.dbHandle)
  246. }
  247. func (p *SQLiteProvider) updateAPIKeyLastUse(keyID string) error {
  248. return sqlCommonUpdateAPIKeyLastUse(keyID, p.dbHandle)
  249. }
  250. func (p *SQLiteProvider) shareExists(shareID, username string) (Share, error) {
  251. return sqlCommonGetShareByID(shareID, username, p.dbHandle)
  252. }
  253. func (p *SQLiteProvider) addShare(share *Share) error {
  254. return sqlCommonAddShare(share, p.dbHandle)
  255. }
  256. func (p *SQLiteProvider) updateShare(share *Share) error {
  257. return sqlCommonUpdateShare(share, p.dbHandle)
  258. }
  259. func (p *SQLiteProvider) deleteShare(share *Share) error {
  260. return sqlCommonDeleteShare(share, p.dbHandle)
  261. }
  262. func (p *SQLiteProvider) getShares(limit int, offset int, order, username string) ([]Share, error) {
  263. return sqlCommonGetShares(limit, offset, order, username, p.dbHandle)
  264. }
  265. func (p *SQLiteProvider) dumpShares() ([]Share, error) {
  266. return sqlCommonDumpShares(p.dbHandle)
  267. }
  268. func (p *SQLiteProvider) updateShareLastUse(shareID string, numTokens int) error {
  269. return sqlCommonUpdateShareLastUse(shareID, numTokens, p.dbHandle)
  270. }
  271. func (p *SQLiteProvider) getDefenderHosts(from int64, limit int) ([]*DefenderEntry, error) {
  272. return sqlCommonGetDefenderHosts(from, limit, p.dbHandle)
  273. }
  274. func (p *SQLiteProvider) getDefenderHostByIP(ip string, from int64) (*DefenderEntry, error) {
  275. return sqlCommonGetDefenderHostByIP(ip, from, p.dbHandle)
  276. }
  277. func (p *SQLiteProvider) isDefenderHostBanned(ip string) (*DefenderEntry, error) {
  278. return sqlCommonIsDefenderHostBanned(ip, p.dbHandle)
  279. }
  280. func (p *SQLiteProvider) updateDefenderBanTime(ip string, minutes int) error {
  281. return sqlCommonDefenderIncrementBanTime(ip, minutes, p.dbHandle)
  282. }
  283. func (p *SQLiteProvider) deleteDefenderHost(ip string) error {
  284. return sqlCommonDeleteDefenderHost(ip, p.dbHandle)
  285. }
  286. func (p *SQLiteProvider) addDefenderEvent(ip string, score int) error {
  287. return sqlCommonAddDefenderHostAndEvent(ip, score, p.dbHandle)
  288. }
  289. func (p *SQLiteProvider) setDefenderBanTime(ip string, banTime int64) error {
  290. return sqlCommonSetDefenderBanTime(ip, banTime, p.dbHandle)
  291. }
  292. func (p *SQLiteProvider) cleanupDefender(from int64) error {
  293. return sqlCommonDefenderCleanup(from, p.dbHandle)
  294. }
  295. func (p *SQLiteProvider) close() error {
  296. return p.dbHandle.Close()
  297. }
  298. func (p *SQLiteProvider) reloadConfig() error {
  299. return nil
  300. }
  301. // initializeDatabase creates the initial database structure
  302. func (p *SQLiteProvider) initializeDatabase() error {
  303. dbVersion, err := sqlCommonGetDatabaseVersion(p.dbHandle, false)
  304. if err == nil && dbVersion.Version > 0 {
  305. return ErrNoInitRequired
  306. }
  307. if errors.Is(err, sql.ErrNoRows) {
  308. return errSchemaVersionEmpty
  309. }
  310. initialSQL := strings.ReplaceAll(sqliteInitialSQL, "{{schema_version}}", sqlTableSchemaVersion)
  311. initialSQL = strings.ReplaceAll(initialSQL, "{{admins}}", sqlTableAdmins)
  312. initialSQL = strings.ReplaceAll(initialSQL, "{{folders}}", sqlTableFolders)
  313. initialSQL = strings.ReplaceAll(initialSQL, "{{users}}", sqlTableUsers)
  314. initialSQL = strings.ReplaceAll(initialSQL, "{{folders_mapping}}", sqlTableFoldersMapping)
  315. initialSQL = strings.ReplaceAll(initialSQL, "{{prefix}}", config.SQLTablesPrefix)
  316. return sqlCommonExecSQLAndUpdateDBVersion(p.dbHandle, []string{initialSQL}, 10)
  317. }
  318. //nolint:dupl
  319. func (p *SQLiteProvider) migrateDatabase() error {
  320. dbVersion, err := sqlCommonGetDatabaseVersion(p.dbHandle, true)
  321. if err != nil {
  322. return err
  323. }
  324. switch version := dbVersion.Version; {
  325. case version == sqlDatabaseVersion:
  326. providerLog(logger.LevelDebug, "sql database is up to date, current version: %v", version)
  327. return ErrNoInitRequired
  328. case version < 10:
  329. err = fmt.Errorf("database version %v is too old, please see the upgrading docs", version)
  330. providerLog(logger.LevelError, "%v", err)
  331. logger.ErrorToConsole("%v", err)
  332. return err
  333. case version == 10:
  334. return updateSQLiteDatabaseFromV10(p.dbHandle)
  335. case version == 11:
  336. return updateSQLiteDatabaseFromV11(p.dbHandle)
  337. case version == 12:
  338. return updateSQLiteDatabaseFromV12(p.dbHandle)
  339. case version == 13:
  340. return updateSQLiteDatabaseFromV13(p.dbHandle)
  341. case version == 14:
  342. return updateSQLiteDatabaseFromV14(p.dbHandle)
  343. default:
  344. if version > sqlDatabaseVersion {
  345. providerLog(logger.LevelError, "database version %v is newer than the supported one: %v", version,
  346. sqlDatabaseVersion)
  347. logger.WarnToConsole("database version %v is newer than the supported one: %v", version,
  348. sqlDatabaseVersion)
  349. return nil
  350. }
  351. return fmt.Errorf("database version not handled: %v", version)
  352. }
  353. }
  354. func (p *SQLiteProvider) revertDatabase(targetVersion int) error {
  355. dbVersion, err := sqlCommonGetDatabaseVersion(p.dbHandle, true)
  356. if err != nil {
  357. return err
  358. }
  359. if dbVersion.Version == targetVersion {
  360. return errors.New("current version match target version, nothing to do")
  361. }
  362. switch dbVersion.Version {
  363. case 15:
  364. return downgradeSQLiteDatabaseFromV15(p.dbHandle)
  365. case 14:
  366. return downgradeSQLiteDatabaseFromV14(p.dbHandle)
  367. case 13:
  368. return downgradeSQLiteDatabaseFromV13(p.dbHandle)
  369. case 12:
  370. return downgradeSQLiteDatabaseFromV12(p.dbHandle)
  371. case 11:
  372. return downgradeSQLiteDatabaseFromV11(p.dbHandle)
  373. default:
  374. return fmt.Errorf("database version not handled: %v", dbVersion.Version)
  375. }
  376. }
  377. func (p *SQLiteProvider) resetDatabase() error {
  378. sql := strings.ReplaceAll(sqliteResetSQL, "{{schema_version}}", sqlTableSchemaVersion)
  379. sql = strings.ReplaceAll(sql, "{{admins}}", sqlTableAdmins)
  380. sql = strings.ReplaceAll(sql, "{{folders}}", sqlTableFolders)
  381. sql = strings.ReplaceAll(sql, "{{users}}", sqlTableUsers)
  382. sql = strings.ReplaceAll(sql, "{{folders_mapping}}", sqlTableFoldersMapping)
  383. sql = strings.ReplaceAll(sql, "{{api_keys}}", sqlTableAPIKeys)
  384. sql = strings.ReplaceAll(sql, "{{shares}}", sqlTableShares)
  385. sql = strings.ReplaceAll(sql, "{{defender_events}}", sqlTableDefenderEvents)
  386. sql = strings.ReplaceAll(sql, "{{defender_hosts}}", sqlTableDefenderHosts)
  387. return sqlCommonExecSQLAndUpdateDBVersion(p.dbHandle, []string{sql}, 0)
  388. }
  389. func updateSQLiteDatabaseFromV10(dbHandle *sql.DB) error {
  390. if err := updateSQLiteDatabaseFrom10To11(dbHandle); err != nil {
  391. return err
  392. }
  393. return updateSQLiteDatabaseFromV11(dbHandle)
  394. }
  395. func updateSQLiteDatabaseFromV11(dbHandle *sql.DB) error {
  396. if err := updateSQLiteDatabaseFrom11To12(dbHandle); err != nil {
  397. return err
  398. }
  399. return updateSQLiteDatabaseFromV12(dbHandle)
  400. }
  401. func updateSQLiteDatabaseFromV12(dbHandle *sql.DB) error {
  402. if err := updateSQLiteDatabaseFrom12To13(dbHandle); err != nil {
  403. return err
  404. }
  405. return updateSQLiteDatabaseFromV13(dbHandle)
  406. }
  407. func updateSQLiteDatabaseFromV13(dbHandle *sql.DB) error {
  408. if err := updateSQLiteDatabaseFrom13To14(dbHandle); err != nil {
  409. return err
  410. }
  411. return updateSQLiteDatabaseFromV14(dbHandle)
  412. }
  413. func updateSQLiteDatabaseFromV14(dbHandle *sql.DB) error {
  414. return updateSQLiteDatabaseFrom14To15(dbHandle)
  415. }
  416. func downgradeSQLiteDatabaseFromV15(dbHandle *sql.DB) error {
  417. if err := downgradeSQLiteDatabaseFrom15To14(dbHandle); err != nil {
  418. return err
  419. }
  420. return downgradeSQLiteDatabaseFromV14(dbHandle)
  421. }
  422. func downgradeSQLiteDatabaseFromV14(dbHandle *sql.DB) error {
  423. if err := downgradeSQLiteDatabaseFrom14To13(dbHandle); err != nil {
  424. return err
  425. }
  426. return downgradeSQLiteDatabaseFromV13(dbHandle)
  427. }
  428. func downgradeSQLiteDatabaseFromV13(dbHandle *sql.DB) error {
  429. if err := downgradeSQLiteDatabaseFrom13To12(dbHandle); err != nil {
  430. return err
  431. }
  432. return downgradeSQLiteDatabaseFromV12(dbHandle)
  433. }
  434. func downgradeSQLiteDatabaseFromV12(dbHandle *sql.DB) error {
  435. if err := downgradeSQLiteDatabaseFrom12To11(dbHandle); err != nil {
  436. return err
  437. }
  438. return downgradeSQLiteDatabaseFromV11(dbHandle)
  439. }
  440. func downgradeSQLiteDatabaseFromV11(dbHandle *sql.DB) error {
  441. return downgradeSQLiteDatabaseFrom11To10(dbHandle)
  442. }
  443. func updateSQLiteDatabaseFrom13To14(dbHandle *sql.DB) error {
  444. logger.InfoToConsole("updating database version: 13 -> 14")
  445. providerLog(logger.LevelInfo, "updating database version: 13 -> 14")
  446. sql := strings.ReplaceAll(sqliteV14SQL, "{{shares}}", sqlTableShares)
  447. sql = strings.ReplaceAll(sql, "{{users}}", sqlTableUsers)
  448. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  449. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 14)
  450. }
  451. func updateSQLiteDatabaseFrom14To15(dbHandle *sql.DB) error {
  452. logger.InfoToConsole("updating database version: 14 -> 15")
  453. providerLog(logger.LevelInfo, "updating database version: 14 -> 15")
  454. sql := strings.ReplaceAll(sqliteV15SQL, "{{defender_events}}", sqlTableDefenderEvents)
  455. sql = strings.ReplaceAll(sql, "{{defender_hosts}}", sqlTableDefenderHosts)
  456. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  457. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 15)
  458. }
  459. func downgradeSQLiteDatabaseFrom15To14(dbHandle *sql.DB) error {
  460. logger.InfoToConsole("downgrading database version: 15 -> 14")
  461. providerLog(logger.LevelInfo, "downgrading database version: 15 -> 14")
  462. sql := strings.ReplaceAll(sqliteV15DownSQL, "{{defender_events}}", sqlTableDefenderEvents)
  463. sql = strings.ReplaceAll(sql, "{{defender_hosts}}", sqlTableDefenderHosts)
  464. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 14)
  465. }
  466. func downgradeSQLiteDatabaseFrom14To13(dbHandle *sql.DB) error {
  467. logger.InfoToConsole("downgrading database version: 14 -> 13")
  468. providerLog(logger.LevelInfo, "downgrading database version: 14 -> 13")
  469. sql := strings.ReplaceAll(sqliteV14DownSQL, "{{shares}}", sqlTableShares)
  470. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 13)
  471. }
  472. func updateSQLiteDatabaseFrom12To13(dbHandle *sql.DB) error {
  473. logger.InfoToConsole("updating database version: 12 -> 13")
  474. providerLog(logger.LevelInfo, "updating database version: 12 -> 13")
  475. sql := strings.ReplaceAll(sqliteV13SQL, "{{users}}", sqlTableUsers)
  476. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 13)
  477. }
  478. func downgradeSQLiteDatabaseFrom13To12(dbHandle *sql.DB) error {
  479. logger.InfoToConsole("downgrading database version: 13 -> 12")
  480. providerLog(logger.LevelInfo, "downgrading database version: 13 -> 12")
  481. sql := strings.ReplaceAll(sqliteV13DownSQL, "{{users}}", sqlTableUsers)
  482. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 12)
  483. }
  484. func updateSQLiteDatabaseFrom11To12(dbHandle *sql.DB) error {
  485. logger.InfoToConsole("updating database version: 11 -> 12")
  486. providerLog(logger.LevelInfo, "updating database version: 11 -> 12")
  487. sql := strings.ReplaceAll(sqliteV12SQL, "{{users}}", sqlTableUsers)
  488. sql = strings.ReplaceAll(sql, "{{admins}}", sqlTableAdmins)
  489. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  490. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 12)
  491. }
  492. func downgradeSQLiteDatabaseFrom12To11(dbHandle *sql.DB) error {
  493. logger.InfoToConsole("downgrading database version: 12 -> 11")
  494. providerLog(logger.LevelInfo, "downgrading database version: 12 -> 11")
  495. sql := strings.ReplaceAll(sqliteV12DownSQL, "{{users}}", sqlTableUsers)
  496. sql = strings.ReplaceAll(sql, "{{admins}}", sqlTableAdmins)
  497. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  498. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 11)
  499. }
  500. func updateSQLiteDatabaseFrom10To11(dbHandle *sql.DB) error {
  501. logger.InfoToConsole("updating database version: 10 -> 11")
  502. providerLog(logger.LevelInfo, "updating database version: 10 -> 11")
  503. sql := strings.ReplaceAll(sqliteV11SQL, "{{users}}", sqlTableUsers)
  504. sql = strings.ReplaceAll(sql, "{{admins}}", sqlTableAdmins)
  505. sql = strings.ReplaceAll(sql, "{{api_keys}}", sqlTableAPIKeys)
  506. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  507. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 11)
  508. }
  509. func downgradeSQLiteDatabaseFrom11To10(dbHandle *sql.DB) error {
  510. logger.InfoToConsole("downgrading database version: 11 -> 10")
  511. providerLog(logger.LevelInfo, "downgrading database version: 11 -> 10")
  512. sql := strings.ReplaceAll(sqliteV11DownSQL, "{{api_keys}}", sqlTableAPIKeys)
  513. return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 10)
  514. }
  515. /*func setPragmaFK(dbHandle *sql.DB, value string) error {
  516. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  517. defer cancel()
  518. sql := fmt.Sprintf("PRAGMA foreign_keys=%v;", value)
  519. _, err := dbHandle.ExecContext(ctx, sql)
  520. return err
  521. }*/