sqlcommon.go 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502
  1. // Copyright (C) 2019-2022 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package dataprovider
  15. import (
  16. "context"
  17. "crypto/x509"
  18. "database/sql"
  19. "encoding/json"
  20. "errors"
  21. "fmt"
  22. "runtime/debug"
  23. "strings"
  24. "time"
  25. "github.com/cockroachdb/cockroach-go/v2/crdb"
  26. "github.com/sftpgo/sdk"
  27. "github.com/drakkan/sftpgo/v2/internal/logger"
  28. "github.com/drakkan/sftpgo/v2/internal/util"
  29. "github.com/drakkan/sftpgo/v2/internal/vfs"
  30. )
  31. const (
  32. sqlDatabaseVersion = 23
  33. defaultSQLQueryTimeout = 10 * time.Second
  34. longSQLQueryTimeout = 60 * time.Second
  35. )
  36. var (
  37. errSQLFoldersAssociation = errors.New("unable to associate virtual folders to user")
  38. errSQLGroupsAssociation = errors.New("unable to associate groups to user")
  39. errSQLUsersAssociation = errors.New("unable to associate users to group")
  40. errSchemaVersionEmpty = errors.New("we can't determine schema version because the schema_migration table is empty. The SFTPGo database might be corrupted. Consider using the \"resetprovider\" sub-command")
  41. )
  42. type sqlQuerier interface {
  43. QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
  44. QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
  45. ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
  46. PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
  47. }
  48. type sqlScanner interface {
  49. Scan(dest ...any) error
  50. }
  51. func sqlReplaceAll(sql string) string {
  52. sql = strings.ReplaceAll(sql, "{{schema_version}}", sqlTableSchemaVersion)
  53. sql = strings.ReplaceAll(sql, "{{admins}}", sqlTableAdmins)
  54. sql = strings.ReplaceAll(sql, "{{folders}}", sqlTableFolders)
  55. sql = strings.ReplaceAll(sql, "{{users}}", sqlTableUsers)
  56. sql = strings.ReplaceAll(sql, "{{groups}}", sqlTableGroups)
  57. sql = strings.ReplaceAll(sql, "{{users_folders_mapping}}", sqlTableUsersFoldersMapping)
  58. sql = strings.ReplaceAll(sql, "{{users_groups_mapping}}", sqlTableUsersGroupsMapping)
  59. sql = strings.ReplaceAll(sql, "{{admins_groups_mapping}}", sqlTableAdminsGroupsMapping)
  60. sql = strings.ReplaceAll(sql, "{{groups_folders_mapping}}", sqlTableGroupsFoldersMapping)
  61. sql = strings.ReplaceAll(sql, "{{api_keys}}", sqlTableAPIKeys)
  62. sql = strings.ReplaceAll(sql, "{{shares}}", sqlTableShares)
  63. sql = strings.ReplaceAll(sql, "{{defender_events}}", sqlTableDefenderEvents)
  64. sql = strings.ReplaceAll(sql, "{{defender_hosts}}", sqlTableDefenderHosts)
  65. sql = strings.ReplaceAll(sql, "{{active_transfers}}", sqlTableActiveTransfers)
  66. sql = strings.ReplaceAll(sql, "{{shared_sessions}}", sqlTableSharedSessions)
  67. sql = strings.ReplaceAll(sql, "{{events_actions}}", sqlTableEventsActions)
  68. sql = strings.ReplaceAll(sql, "{{events_rules}}", sqlTableEventsRules)
  69. sql = strings.ReplaceAll(sql, "{{rules_actions_mapping}}", sqlTableRulesActionsMapping)
  70. sql = strings.ReplaceAll(sql, "{{tasks}}", sqlTableTasks)
  71. sql = strings.ReplaceAll(sql, "{{nodes}}", sqlTableNodes)
  72. sql = strings.ReplaceAll(sql, "{{prefix}}", config.SQLTablesPrefix)
  73. return sql
  74. }
  75. func sqlCommonGetShareByID(shareID, username string, dbHandle sqlQuerier) (Share, error) {
  76. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  77. defer cancel()
  78. filterUser := username != ""
  79. q := getShareByIDQuery(filterUser)
  80. var row *sql.Row
  81. if filterUser {
  82. row = dbHandle.QueryRowContext(ctx, q, shareID, username)
  83. } else {
  84. row = dbHandle.QueryRowContext(ctx, q, shareID)
  85. }
  86. return getShareFromDbRow(row)
  87. }
  88. func sqlCommonAddShare(share *Share, dbHandle *sql.DB) error {
  89. err := share.validate()
  90. if err != nil {
  91. return err
  92. }
  93. user, err := provider.userExists(share.Username)
  94. if err != nil {
  95. return util.NewValidationError(fmt.Sprintf("unable to validate user %#v", share.Username))
  96. }
  97. paths, err := json.Marshal(share.Paths)
  98. if err != nil {
  99. return err
  100. }
  101. allowFrom := ""
  102. if len(share.AllowFrom) > 0 {
  103. res, err := json.Marshal(share.AllowFrom)
  104. if err == nil {
  105. allowFrom = string(res)
  106. }
  107. }
  108. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  109. defer cancel()
  110. q := getAddShareQuery()
  111. usedTokens := 0
  112. createdAt := util.GetTimeAsMsSinceEpoch(time.Now())
  113. updatedAt := createdAt
  114. lastUseAt := int64(0)
  115. if share.IsRestore {
  116. usedTokens = share.UsedTokens
  117. if share.CreatedAt > 0 {
  118. createdAt = share.CreatedAt
  119. }
  120. if share.UpdatedAt > 0 {
  121. updatedAt = share.UpdatedAt
  122. }
  123. lastUseAt = share.LastUseAt
  124. }
  125. _, err = dbHandle.ExecContext(ctx, q, share.ShareID, share.Name, share.Description, share.Scope,
  126. string(paths), createdAt, updatedAt, lastUseAt, share.ExpiresAt, share.Password,
  127. share.MaxTokens, usedTokens, allowFrom, user.ID)
  128. return err
  129. }
  130. func sqlCommonUpdateShare(share *Share, dbHandle *sql.DB) error {
  131. err := share.validate()
  132. if err != nil {
  133. return err
  134. }
  135. paths, err := json.Marshal(share.Paths)
  136. if err != nil {
  137. return err
  138. }
  139. allowFrom := ""
  140. if len(share.AllowFrom) > 0 {
  141. res, err := json.Marshal(share.AllowFrom)
  142. if err == nil {
  143. allowFrom = string(res)
  144. }
  145. }
  146. user, err := provider.userExists(share.Username)
  147. if err != nil {
  148. return util.NewValidationError(fmt.Sprintf("unable to validate user %#v", share.Username))
  149. }
  150. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  151. defer cancel()
  152. var q string
  153. if share.IsRestore {
  154. q = getUpdateShareRestoreQuery()
  155. } else {
  156. q = getUpdateShareQuery()
  157. }
  158. if share.IsRestore {
  159. if share.CreatedAt == 0 {
  160. share.CreatedAt = util.GetTimeAsMsSinceEpoch(time.Now())
  161. }
  162. if share.UpdatedAt == 0 {
  163. share.UpdatedAt = share.CreatedAt
  164. }
  165. _, err = dbHandle.ExecContext(ctx, q, share.Name, share.Description, share.Scope, string(paths),
  166. share.CreatedAt, share.UpdatedAt, share.LastUseAt, share.ExpiresAt, share.Password, share.MaxTokens,
  167. share.UsedTokens, allowFrom, user.ID, share.ShareID)
  168. } else {
  169. _, err = dbHandle.ExecContext(ctx, q, share.Name, share.Description, share.Scope, string(paths),
  170. util.GetTimeAsMsSinceEpoch(time.Now()), share.ExpiresAt, share.Password, share.MaxTokens,
  171. allowFrom, user.ID, share.ShareID)
  172. }
  173. return err
  174. }
  175. func sqlCommonDeleteShare(share Share, dbHandle *sql.DB) error {
  176. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  177. defer cancel()
  178. q := getDeleteShareQuery()
  179. res, err := dbHandle.ExecContext(ctx, q, share.ShareID)
  180. if err != nil {
  181. return err
  182. }
  183. return sqlCommonRequireRowAffected(res)
  184. }
  185. func sqlCommonGetShares(limit, offset int, order, username string, dbHandle sqlQuerier) ([]Share, error) {
  186. shares := make([]Share, 0, limit)
  187. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  188. defer cancel()
  189. q := getSharesQuery(order)
  190. rows, err := dbHandle.QueryContext(ctx, q, username, limit, offset)
  191. if err != nil {
  192. return shares, err
  193. }
  194. defer rows.Close()
  195. for rows.Next() {
  196. s, err := getShareFromDbRow(rows)
  197. if err != nil {
  198. return shares, err
  199. }
  200. s.HideConfidentialData()
  201. shares = append(shares, s)
  202. }
  203. return shares, rows.Err()
  204. }
  205. func sqlCommonDumpShares(dbHandle sqlQuerier) ([]Share, error) {
  206. shares := make([]Share, 0, 30)
  207. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  208. defer cancel()
  209. q := getDumpSharesQuery()
  210. rows, err := dbHandle.QueryContext(ctx, q)
  211. if err != nil {
  212. return shares, err
  213. }
  214. defer rows.Close()
  215. for rows.Next() {
  216. s, err := getShareFromDbRow(rows)
  217. if err != nil {
  218. return shares, err
  219. }
  220. shares = append(shares, s)
  221. }
  222. return shares, rows.Err()
  223. }
  224. func sqlCommonGetAPIKeyByID(keyID string, dbHandle sqlQuerier) (APIKey, error) {
  225. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  226. defer cancel()
  227. q := getAPIKeyByIDQuery()
  228. row := dbHandle.QueryRowContext(ctx, q, keyID)
  229. apiKey, err := getAPIKeyFromDbRow(row)
  230. if err != nil {
  231. return apiKey, err
  232. }
  233. return getAPIKeyWithRelatedFields(ctx, apiKey, dbHandle)
  234. }
  235. func sqlCommonAddAPIKey(apiKey *APIKey, dbHandle *sql.DB) error {
  236. err := apiKey.validate()
  237. if err != nil {
  238. return err
  239. }
  240. userID, adminID, err := sqlCommonGetAPIKeyRelatedIDs(apiKey)
  241. if err != nil {
  242. return err
  243. }
  244. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  245. defer cancel()
  246. q := getAddAPIKeyQuery()
  247. _, err = dbHandle.ExecContext(ctx, q, apiKey.KeyID, apiKey.Name, apiKey.Key, apiKey.Scope,
  248. util.GetTimeAsMsSinceEpoch(time.Now()), util.GetTimeAsMsSinceEpoch(time.Now()), apiKey.LastUseAt,
  249. apiKey.ExpiresAt, apiKey.Description, userID, adminID)
  250. return err
  251. }
  252. func sqlCommonUpdateAPIKey(apiKey *APIKey, dbHandle *sql.DB) error {
  253. err := apiKey.validate()
  254. if err != nil {
  255. return err
  256. }
  257. userID, adminID, err := sqlCommonGetAPIKeyRelatedIDs(apiKey)
  258. if err != nil {
  259. return err
  260. }
  261. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  262. defer cancel()
  263. q := getUpdateAPIKeyQuery()
  264. _, err = dbHandle.ExecContext(ctx, q, apiKey.Name, apiKey.Scope, apiKey.ExpiresAt, userID, adminID,
  265. apiKey.Description, util.GetTimeAsMsSinceEpoch(time.Now()), apiKey.KeyID)
  266. return err
  267. }
  268. func sqlCommonDeleteAPIKey(apiKey APIKey, dbHandle *sql.DB) error {
  269. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  270. defer cancel()
  271. q := getDeleteAPIKeyQuery()
  272. res, err := dbHandle.ExecContext(ctx, q, apiKey.KeyID)
  273. if err != nil {
  274. return err
  275. }
  276. return sqlCommonRequireRowAffected(res)
  277. }
  278. func sqlCommonGetAPIKeys(limit, offset int, order string, dbHandle sqlQuerier) ([]APIKey, error) {
  279. apiKeys := make([]APIKey, 0, limit)
  280. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  281. defer cancel()
  282. q := getAPIKeysQuery(order)
  283. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  284. if err != nil {
  285. return apiKeys, err
  286. }
  287. defer rows.Close()
  288. for rows.Next() {
  289. k, err := getAPIKeyFromDbRow(rows)
  290. if err != nil {
  291. return apiKeys, err
  292. }
  293. k.HideConfidentialData()
  294. apiKeys = append(apiKeys, k)
  295. }
  296. err = rows.Err()
  297. if err != nil {
  298. return apiKeys, err
  299. }
  300. apiKeys, err = getRelatedValuesForAPIKeys(ctx, apiKeys, dbHandle, APIKeyScopeAdmin)
  301. if err != nil {
  302. return apiKeys, err
  303. }
  304. return getRelatedValuesForAPIKeys(ctx, apiKeys, dbHandle, APIKeyScopeUser)
  305. }
  306. func sqlCommonDumpAPIKeys(dbHandle sqlQuerier) ([]APIKey, error) {
  307. apiKeys := make([]APIKey, 0, 30)
  308. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  309. defer cancel()
  310. q := getDumpAPIKeysQuery()
  311. rows, err := dbHandle.QueryContext(ctx, q)
  312. if err != nil {
  313. return apiKeys, err
  314. }
  315. defer rows.Close()
  316. for rows.Next() {
  317. k, err := getAPIKeyFromDbRow(rows)
  318. if err != nil {
  319. return apiKeys, err
  320. }
  321. apiKeys = append(apiKeys, k)
  322. }
  323. err = rows.Err()
  324. if err != nil {
  325. return apiKeys, err
  326. }
  327. apiKeys, err = getRelatedValuesForAPIKeys(ctx, apiKeys, dbHandle, APIKeyScopeAdmin)
  328. if err != nil {
  329. return apiKeys, err
  330. }
  331. return getRelatedValuesForAPIKeys(ctx, apiKeys, dbHandle, APIKeyScopeUser)
  332. }
  333. func sqlCommonGetAdminByUsername(username string, dbHandle sqlQuerier) (Admin, error) {
  334. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  335. defer cancel()
  336. q := getAdminByUsernameQuery()
  337. row := dbHandle.QueryRowContext(ctx, q, username)
  338. admin, err := getAdminFromDbRow(row)
  339. if err != nil {
  340. return admin, err
  341. }
  342. return getAdminWithGroups(ctx, admin, dbHandle)
  343. }
  344. func sqlCommonValidateAdminAndPass(username, password, ip string, dbHandle *sql.DB) (Admin, error) {
  345. admin, err := sqlCommonGetAdminByUsername(username, dbHandle)
  346. if err != nil {
  347. providerLog(logger.LevelWarn, "error authenticating admin %#v: %v", username, err)
  348. return admin, ErrInvalidCredentials
  349. }
  350. err = admin.checkUserAndPass(password, ip)
  351. return admin, err
  352. }
  353. func sqlCommonAddAdmin(admin *Admin, dbHandle *sql.DB) error {
  354. err := admin.validate()
  355. if err != nil {
  356. return err
  357. }
  358. perms, err := json.Marshal(admin.Permissions)
  359. if err != nil {
  360. return err
  361. }
  362. filters, err := json.Marshal(admin.Filters)
  363. if err != nil {
  364. return err
  365. }
  366. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  367. defer cancel()
  368. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  369. q := getAddAdminQuery()
  370. _, err = tx.ExecContext(ctx, q, admin.Username, admin.Password, admin.Status, admin.Email, string(perms),
  371. string(filters), admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
  372. util.GetTimeAsMsSinceEpoch(time.Now()))
  373. if err != nil {
  374. return err
  375. }
  376. return generateAdminGroupMapping(ctx, admin, tx)
  377. })
  378. }
  379. func sqlCommonUpdateAdmin(admin *Admin, dbHandle *sql.DB) error {
  380. err := admin.validate()
  381. if err != nil {
  382. return err
  383. }
  384. perms, err := json.Marshal(admin.Permissions)
  385. if err != nil {
  386. return err
  387. }
  388. filters, err := json.Marshal(admin.Filters)
  389. if err != nil {
  390. return err
  391. }
  392. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  393. defer cancel()
  394. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  395. q := getUpdateAdminQuery()
  396. _, err = tx.ExecContext(ctx, q, admin.Password, admin.Status, admin.Email, string(perms), string(filters),
  397. admin.AdditionalInfo, admin.Description, util.GetTimeAsMsSinceEpoch(time.Now()), admin.Username)
  398. if err != nil {
  399. return err
  400. }
  401. return generateAdminGroupMapping(ctx, admin, tx)
  402. })
  403. }
  404. func sqlCommonDeleteAdmin(admin Admin, dbHandle *sql.DB) error {
  405. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  406. defer cancel()
  407. q := getDeleteAdminQuery()
  408. res, err := dbHandle.ExecContext(ctx, q, admin.Username)
  409. if err != nil {
  410. return err
  411. }
  412. return sqlCommonRequireRowAffected(res)
  413. }
  414. func sqlCommonGetAdmins(limit, offset int, order string, dbHandle sqlQuerier) ([]Admin, error) {
  415. admins := make([]Admin, 0, limit)
  416. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  417. defer cancel()
  418. q := getAdminsQuery(order)
  419. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  420. if err != nil {
  421. return admins, err
  422. }
  423. defer rows.Close()
  424. for rows.Next() {
  425. a, err := getAdminFromDbRow(rows)
  426. if err != nil {
  427. return admins, err
  428. }
  429. a.HideConfidentialData()
  430. admins = append(admins, a)
  431. }
  432. err = rows.Err()
  433. if err != nil {
  434. return admins, err
  435. }
  436. return getAdminsWithGroups(ctx, admins, dbHandle)
  437. }
  438. func sqlCommonDumpAdmins(dbHandle sqlQuerier) ([]Admin, error) {
  439. admins := make([]Admin, 0, 30)
  440. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  441. defer cancel()
  442. q := getDumpAdminsQuery()
  443. rows, err := dbHandle.QueryContext(ctx, q)
  444. if err != nil {
  445. return admins, err
  446. }
  447. defer rows.Close()
  448. for rows.Next() {
  449. a, err := getAdminFromDbRow(rows)
  450. if err != nil {
  451. return admins, err
  452. }
  453. admins = append(admins, a)
  454. }
  455. err = rows.Err()
  456. if err != nil {
  457. return admins, err
  458. }
  459. return getAdminsWithGroups(ctx, admins, dbHandle)
  460. }
  461. func sqlCommonGetGroupByName(name string, dbHandle sqlQuerier) (Group, error) {
  462. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  463. defer cancel()
  464. q := getGroupByNameQuery()
  465. row := dbHandle.QueryRowContext(ctx, q, name)
  466. group, err := getGroupFromDbRow(row)
  467. if err != nil {
  468. return group, err
  469. }
  470. group, err = getGroupWithVirtualFolders(ctx, group, dbHandle)
  471. if err != nil {
  472. return group, err
  473. }
  474. group, err = getGroupWithUsers(ctx, group, dbHandle)
  475. if err != nil {
  476. return group, err
  477. }
  478. return getGroupWithAdmins(ctx, group, dbHandle)
  479. }
  480. func sqlCommonDumpGroups(dbHandle sqlQuerier) ([]Group, error) {
  481. groups := make([]Group, 0, 50)
  482. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  483. defer cancel()
  484. q := getDumpGroupsQuery()
  485. rows, err := dbHandle.QueryContext(ctx, q)
  486. if err != nil {
  487. return groups, err
  488. }
  489. defer rows.Close()
  490. for rows.Next() {
  491. group, err := getGroupFromDbRow(rows)
  492. if err != nil {
  493. return groups, err
  494. }
  495. groups = append(groups, group)
  496. }
  497. err = rows.Err()
  498. if err != nil {
  499. return groups, err
  500. }
  501. return getGroupsWithVirtualFolders(ctx, groups, dbHandle)
  502. }
  503. func sqlCommonGetUsersInGroups(names []string, dbHandle sqlQuerier) ([]string, error) {
  504. if len(names) == 0 {
  505. return nil, nil
  506. }
  507. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  508. defer cancel()
  509. q := getUsersInGroupsQuery(len(names))
  510. args := make([]any, 0, len(names))
  511. for _, name := range names {
  512. args = append(args, name)
  513. }
  514. usernames := make([]string, 0, len(names))
  515. rows, err := dbHandle.QueryContext(ctx, q, args...)
  516. if err != nil {
  517. return nil, err
  518. }
  519. defer rows.Close()
  520. for rows.Next() {
  521. var username string
  522. err = rows.Scan(&username)
  523. if err != nil {
  524. return usernames, err
  525. }
  526. usernames = append(usernames, username)
  527. }
  528. return usernames, rows.Err()
  529. }
  530. func sqlCommonGetGroupsWithNames(names []string, dbHandle sqlQuerier) ([]Group, error) {
  531. if len(names) == 0 {
  532. return nil, nil
  533. }
  534. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  535. defer cancel()
  536. q := getGroupsWithNamesQuery(len(names))
  537. args := make([]any, 0, len(names))
  538. for _, name := range names {
  539. args = append(args, name)
  540. }
  541. groups := make([]Group, 0, len(names))
  542. rows, err := dbHandle.QueryContext(ctx, q, args...)
  543. if err != nil {
  544. return groups, err
  545. }
  546. defer rows.Close()
  547. for rows.Next() {
  548. group, err := getGroupFromDbRow(rows)
  549. if err != nil {
  550. return groups, err
  551. }
  552. groups = append(groups, group)
  553. }
  554. err = rows.Err()
  555. if err != nil {
  556. return groups, err
  557. }
  558. return getGroupsWithVirtualFolders(ctx, groups, dbHandle)
  559. }
  560. func sqlCommonGetGroups(limit int, offset int, order string, minimal bool, dbHandle sqlQuerier) ([]Group, error) {
  561. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  562. defer cancel()
  563. q := getGroupsQuery(order, minimal)
  564. groups := make([]Group, 0, limit)
  565. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  566. if err != nil {
  567. return groups, err
  568. }
  569. defer rows.Close()
  570. for rows.Next() {
  571. var group Group
  572. if minimal {
  573. err = rows.Scan(&group.ID, &group.Name)
  574. } else {
  575. group, err = getGroupFromDbRow(rows)
  576. }
  577. if err != nil {
  578. return groups, err
  579. }
  580. groups = append(groups, group)
  581. }
  582. err = rows.Err()
  583. if err != nil {
  584. return groups, err
  585. }
  586. if minimal {
  587. return groups, nil
  588. }
  589. groups, err = getGroupsWithVirtualFolders(ctx, groups, dbHandle)
  590. if err != nil {
  591. return groups, err
  592. }
  593. groups, err = getGroupsWithUsers(ctx, groups, dbHandle)
  594. if err != nil {
  595. return groups, err
  596. }
  597. groups, err = getGroupsWithAdmins(ctx, groups, dbHandle)
  598. if err != nil {
  599. return groups, err
  600. }
  601. for idx := range groups {
  602. groups[idx].PrepareForRendering()
  603. }
  604. return groups, nil
  605. }
  606. func sqlCommonAddGroup(group *Group, dbHandle *sql.DB) error {
  607. if err := group.validate(); err != nil {
  608. return err
  609. }
  610. settings, err := json.Marshal(group.UserSettings)
  611. if err != nil {
  612. return err
  613. }
  614. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  615. defer cancel()
  616. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  617. q := getAddGroupQuery()
  618. _, err := tx.ExecContext(ctx, q, group.Name, group.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
  619. util.GetTimeAsMsSinceEpoch(time.Now()), string(settings))
  620. if err != nil {
  621. return err
  622. }
  623. return generateGroupVirtualFoldersMapping(ctx, group, tx)
  624. })
  625. }
  626. func sqlCommonUpdateGroup(group *Group, dbHandle *sql.DB) error {
  627. if err := group.validate(); err != nil {
  628. return err
  629. }
  630. settings, err := json.Marshal(group.UserSettings)
  631. if err != nil {
  632. return err
  633. }
  634. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  635. defer cancel()
  636. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  637. q := getUpdateGroupQuery()
  638. _, err := tx.ExecContext(ctx, q, group.Description, settings, util.GetTimeAsMsSinceEpoch(time.Now()), group.Name)
  639. if err != nil {
  640. return err
  641. }
  642. return generateGroupVirtualFoldersMapping(ctx, group, tx)
  643. })
  644. }
  645. func sqlCommonDeleteGroup(group Group, dbHandle *sql.DB) error {
  646. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  647. defer cancel()
  648. q := getDeleteGroupQuery()
  649. res, err := dbHandle.ExecContext(ctx, q, group.Name)
  650. if err != nil {
  651. return err
  652. }
  653. return sqlCommonRequireRowAffected(res)
  654. }
  655. func sqlCommonGetUserByUsername(username string, dbHandle sqlQuerier) (User, error) {
  656. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  657. defer cancel()
  658. q := getUserByUsernameQuery()
  659. row := dbHandle.QueryRowContext(ctx, q, username)
  660. user, err := getUserFromDbRow(row)
  661. if err != nil {
  662. return user, err
  663. }
  664. user, err = getUserWithVirtualFolders(ctx, user, dbHandle)
  665. if err != nil {
  666. return user, err
  667. }
  668. return getUserWithGroups(ctx, user, dbHandle)
  669. }
  670. func sqlCommonValidateUserAndPass(username, password, ip, protocol string, dbHandle *sql.DB) (User, error) {
  671. user, err := sqlCommonGetUserByUsername(username, dbHandle)
  672. if err != nil {
  673. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  674. return user, err
  675. }
  676. return checkUserAndPass(&user, password, ip, protocol)
  677. }
  678. func sqlCommonValidateUserAndTLSCertificate(username, protocol string, tlsCert *x509.Certificate, dbHandle *sql.DB) (User, error) {
  679. var user User
  680. if tlsCert == nil {
  681. return user, errors.New("TLS certificate cannot be null or empty")
  682. }
  683. user, err := sqlCommonGetUserByUsername(username, dbHandle)
  684. if err != nil {
  685. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  686. return user, err
  687. }
  688. return checkUserAndTLSCertificate(&user, protocol, tlsCert)
  689. }
  690. func sqlCommonValidateUserAndPubKey(username string, pubKey []byte, isSSHCert bool, dbHandle *sql.DB) (User, string, error) {
  691. var user User
  692. if len(pubKey) == 0 {
  693. return user, "", errors.New("credentials cannot be null or empty")
  694. }
  695. user, err := sqlCommonGetUserByUsername(username, dbHandle)
  696. if err != nil {
  697. providerLog(logger.LevelWarn, "error authenticating user %#v: %v", username, err)
  698. return user, "", err
  699. }
  700. return checkUserAndPubKey(&user, pubKey, isSSHCert)
  701. }
  702. func sqlCommonCheckAvailability(dbHandle *sql.DB) (err error) {
  703. defer func() {
  704. if r := recover(); r != nil {
  705. providerLog(logger.LevelError, "panic in check provider availability, stack trace: %v", string(debug.Stack()))
  706. err = errors.New("unable to check provider status")
  707. }
  708. }()
  709. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  710. defer cancel()
  711. err = dbHandle.PingContext(ctx)
  712. return
  713. }
  714. func sqlCommonUpdateTransferQuota(username string, uploadSize, downloadSize int64, reset bool, dbHandle *sql.DB) error {
  715. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  716. defer cancel()
  717. q := getUpdateTransferQuotaQuery(reset)
  718. _, err := dbHandle.ExecContext(ctx, q, uploadSize, downloadSize, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  719. if err == nil {
  720. providerLog(logger.LevelDebug, "transfer quota updated for user %#v, ul increment: %v dl increment: %v is reset? %v",
  721. username, uploadSize, downloadSize, reset)
  722. } else {
  723. providerLog(logger.LevelError, "error updating quota for user %#v: %v", username, err)
  724. }
  725. return err
  726. }
  727. func sqlCommonUpdateQuota(username string, filesAdd int, sizeAdd int64, reset bool, dbHandle *sql.DB) error {
  728. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  729. defer cancel()
  730. q := getUpdateQuotaQuery(reset)
  731. _, err := dbHandle.ExecContext(ctx, q, sizeAdd, filesAdd, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  732. if err == nil {
  733. providerLog(logger.LevelDebug, "quota updated for user %#v, files increment: %v size increment: %v is reset? %v",
  734. username, filesAdd, sizeAdd, reset)
  735. } else {
  736. providerLog(logger.LevelError, "error updating quota for user %#v: %v", username, err)
  737. }
  738. return err
  739. }
  740. func sqlCommonGetUsedQuota(username string, dbHandle *sql.DB) (int, int64, int64, int64, error) {
  741. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  742. defer cancel()
  743. q := getQuotaQuery()
  744. var usedFiles int
  745. var usedSize, usedUploadSize, usedDownloadSize int64
  746. err := dbHandle.QueryRowContext(ctx, q, username).Scan(&usedSize, &usedFiles, &usedUploadSize, &usedDownloadSize)
  747. if err != nil {
  748. providerLog(logger.LevelError, "error getting quota for user: %v, error: %v", username, err)
  749. return 0, 0, 0, 0, err
  750. }
  751. return usedFiles, usedSize, usedUploadSize, usedDownloadSize, err
  752. }
  753. func sqlCommonUpdateShareLastUse(shareID string, numTokens int, dbHandle *sql.DB) error {
  754. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  755. defer cancel()
  756. q := getUpdateShareLastUseQuery()
  757. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), numTokens, shareID)
  758. if err == nil {
  759. providerLog(logger.LevelDebug, "last use updated for shared object %#v", shareID)
  760. } else {
  761. providerLog(logger.LevelWarn, "error updating last use for shared object %#v: %v", shareID, err)
  762. }
  763. return err
  764. }
  765. func sqlCommonUpdateAPIKeyLastUse(keyID string, dbHandle *sql.DB) error {
  766. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  767. defer cancel()
  768. q := getUpdateAPIKeyLastUseQuery()
  769. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), keyID)
  770. if err == nil {
  771. providerLog(logger.LevelDebug, "last use updated for key %#v", keyID)
  772. } else {
  773. providerLog(logger.LevelWarn, "error updating last use for key %#v: %v", keyID, err)
  774. }
  775. return err
  776. }
  777. func sqlCommonUpdateAdminLastLogin(username string, dbHandle *sql.DB) error {
  778. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  779. defer cancel()
  780. q := getUpdateAdminLastLoginQuery()
  781. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  782. if err == nil {
  783. providerLog(logger.LevelDebug, "last login updated for admin %#v", username)
  784. } else {
  785. providerLog(logger.LevelWarn, "error updating last login for admin %#v: %v", username, err)
  786. }
  787. return err
  788. }
  789. func sqlCommonSetUpdatedAt(username string, dbHandle *sql.DB) {
  790. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  791. defer cancel()
  792. q := getSetUpdateAtQuery()
  793. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  794. if err == nil {
  795. providerLog(logger.LevelDebug, "updated_at set for user %#v", username)
  796. } else {
  797. providerLog(logger.LevelWarn, "error setting updated_at for user %#v: %v", username, err)
  798. }
  799. }
  800. func sqlCommonSetFirstDownloadTimestamp(username string, dbHandle *sql.DB) error {
  801. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  802. defer cancel()
  803. q := getSetFirstDownloadQuery()
  804. res, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  805. if err != nil {
  806. return err
  807. }
  808. return sqlCommonRequireRowAffected(res)
  809. }
  810. func sqlCommonSetFirstUploadTimestamp(username string, dbHandle *sql.DB) error {
  811. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  812. defer cancel()
  813. q := getSetFirstUploadQuery()
  814. res, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  815. if err != nil {
  816. return err
  817. }
  818. return sqlCommonRequireRowAffected(res)
  819. }
  820. func sqlCommonUpdateLastLogin(username string, dbHandle *sql.DB) error {
  821. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  822. defer cancel()
  823. q := getUpdateLastLoginQuery()
  824. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), username)
  825. if err == nil {
  826. providerLog(logger.LevelDebug, "last login updated for user %#v", username)
  827. } else {
  828. providerLog(logger.LevelWarn, "error updating last login for user %#v: %v", username, err)
  829. }
  830. return err
  831. }
  832. func sqlCommonAddUser(user *User, dbHandle *sql.DB) error {
  833. err := ValidateUser(user)
  834. if err != nil {
  835. return err
  836. }
  837. permissions, err := user.GetPermissionsAsJSON()
  838. if err != nil {
  839. return err
  840. }
  841. publicKeys, err := user.GetPublicKeysAsJSON()
  842. if err != nil {
  843. return err
  844. }
  845. filters, err := user.GetFiltersAsJSON()
  846. if err != nil {
  847. return err
  848. }
  849. fsConfig, err := user.GetFsConfigAsJSON()
  850. if err != nil {
  851. return err
  852. }
  853. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  854. defer cancel()
  855. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  856. if config.IsShared == 1 {
  857. _, err := tx.ExecContext(ctx, getRemoveSoftDeletedUserQuery(), user.Username)
  858. if err != nil {
  859. return err
  860. }
  861. }
  862. q := getAddUserQuery()
  863. _, err := tx.ExecContext(ctx, q, user.Username, user.Password, string(publicKeys), user.HomeDir, user.UID, user.GID,
  864. user.MaxSessions, user.QuotaSize, user.QuotaFiles, string(permissions), user.UploadBandwidth,
  865. user.DownloadBandwidth, user.Status, user.ExpirationDate, string(filters), string(fsConfig), user.AdditionalInfo,
  866. user.Description, user.Email, util.GetTimeAsMsSinceEpoch(time.Now()), util.GetTimeAsMsSinceEpoch(time.Now()),
  867. user.UploadDataTransfer, user.DownloadDataTransfer, user.TotalDataTransfer)
  868. if err != nil {
  869. return err
  870. }
  871. if err := generateUserVirtualFoldersMapping(ctx, user, tx); err != nil {
  872. return err
  873. }
  874. return generateUserGroupMapping(ctx, user, tx)
  875. })
  876. }
  877. func sqlCommonUpdateUserPassword(username, password string, dbHandle *sql.DB) error {
  878. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  879. defer cancel()
  880. q := getUpdateUserPasswordQuery()
  881. _, err := dbHandle.ExecContext(ctx, q, password, username)
  882. return err
  883. }
  884. func sqlCommonUpdateUser(user *User, dbHandle *sql.DB) error {
  885. err := ValidateUser(user)
  886. if err != nil {
  887. return err
  888. }
  889. permissions, err := user.GetPermissionsAsJSON()
  890. if err != nil {
  891. return err
  892. }
  893. publicKeys, err := user.GetPublicKeysAsJSON()
  894. if err != nil {
  895. return err
  896. }
  897. filters, err := user.GetFiltersAsJSON()
  898. if err != nil {
  899. return err
  900. }
  901. fsConfig, err := user.GetFsConfigAsJSON()
  902. if err != nil {
  903. return err
  904. }
  905. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  906. defer cancel()
  907. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  908. q := getUpdateUserQuery()
  909. _, err := tx.ExecContext(ctx, q, user.Password, string(publicKeys), user.HomeDir, user.UID, user.GID, user.MaxSessions,
  910. user.QuotaSize, user.QuotaFiles, string(permissions), user.UploadBandwidth, user.DownloadBandwidth, user.Status,
  911. user.ExpirationDate, string(filters), string(fsConfig), user.AdditionalInfo, user.Description, user.Email,
  912. util.GetTimeAsMsSinceEpoch(time.Now()), user.UploadDataTransfer, user.DownloadDataTransfer, user.TotalDataTransfer,
  913. user.ID)
  914. if err != nil {
  915. return err
  916. }
  917. if err := generateUserVirtualFoldersMapping(ctx, user, tx); err != nil {
  918. return err
  919. }
  920. return generateUserGroupMapping(ctx, user, tx)
  921. })
  922. }
  923. func sqlCommonDeleteUser(user User, softDelete bool, dbHandle *sql.DB) error {
  924. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  925. defer cancel()
  926. q := getDeleteUserQuery(softDelete)
  927. if softDelete {
  928. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  929. if err := sqlCommonClearUserFolderMapping(ctx, &user, tx); err != nil {
  930. return err
  931. }
  932. if err := sqlCommonClearUserGroupMapping(ctx, &user, tx); err != nil {
  933. return err
  934. }
  935. ts := util.GetTimeAsMsSinceEpoch(time.Now())
  936. res, err := tx.ExecContext(ctx, q, ts, ts, user.Username)
  937. if err != nil {
  938. return err
  939. }
  940. return sqlCommonRequireRowAffected(res)
  941. })
  942. }
  943. res, err := dbHandle.ExecContext(ctx, q, user.ID)
  944. if err != nil {
  945. return err
  946. }
  947. return sqlCommonRequireRowAffected(res)
  948. }
  949. func sqlCommonDumpUsers(dbHandle sqlQuerier) ([]User, error) {
  950. users := make([]User, 0, 100)
  951. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  952. defer cancel()
  953. q := getDumpUsersQuery()
  954. rows, err := dbHandle.QueryContext(ctx, q)
  955. if err != nil {
  956. return users, err
  957. }
  958. defer rows.Close()
  959. for rows.Next() {
  960. u, err := getUserFromDbRow(rows)
  961. if err != nil {
  962. return users, err
  963. }
  964. users = append(users, u)
  965. }
  966. err = rows.Err()
  967. if err != nil {
  968. return users, err
  969. }
  970. users, err = getUsersWithVirtualFolders(ctx, users, dbHandle)
  971. if err != nil {
  972. return users, err
  973. }
  974. return getUsersWithGroups(ctx, users, dbHandle)
  975. }
  976. func sqlCommonGetRecentlyUpdatedUsers(after int64, dbHandle sqlQuerier) ([]User, error) {
  977. users := make([]User, 0, 10)
  978. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  979. defer cancel()
  980. q := getRecentlyUpdatedUsersQuery()
  981. rows, err := dbHandle.QueryContext(ctx, q, after)
  982. if err != nil {
  983. return users, err
  984. }
  985. defer rows.Close()
  986. for rows.Next() {
  987. u, err := getUserFromDbRow(rows)
  988. if err != nil {
  989. return users, err
  990. }
  991. users = append(users, u)
  992. }
  993. err = rows.Err()
  994. if err != nil {
  995. return users, err
  996. }
  997. users, err = getUsersWithVirtualFolders(ctx, users, dbHandle)
  998. if err != nil {
  999. return users, err
  1000. }
  1001. users, err = getUsersWithGroups(ctx, users, dbHandle)
  1002. if err != nil {
  1003. return users, err
  1004. }
  1005. var groupNames []string
  1006. for _, u := range users {
  1007. for _, g := range u.Groups {
  1008. groupNames = append(groupNames, g.Name)
  1009. }
  1010. }
  1011. groupNames = util.RemoveDuplicates(groupNames, false)
  1012. groups, err := sqlCommonGetGroupsWithNames(groupNames, dbHandle)
  1013. if err != nil {
  1014. return users, err
  1015. }
  1016. if len(groups) == 0 {
  1017. return users, nil
  1018. }
  1019. groupsMapping := make(map[string]Group)
  1020. for idx := range groups {
  1021. groupsMapping[groups[idx].Name] = groups[idx]
  1022. }
  1023. for idx := range users {
  1024. ref := &users[idx]
  1025. ref.applyGroupSettings(groupsMapping)
  1026. }
  1027. return users, nil
  1028. }
  1029. func sqlCommonGetUsersForQuotaCheck(toFetch map[string]bool, dbHandle sqlQuerier) ([]User, error) {
  1030. users := make([]User, 0, 30)
  1031. usernames := make([]string, 0, len(toFetch))
  1032. for k := range toFetch {
  1033. usernames = append(usernames, k)
  1034. }
  1035. maxUsers := 30
  1036. for len(usernames) > 0 {
  1037. if maxUsers > len(usernames) {
  1038. maxUsers = len(usernames)
  1039. }
  1040. usersRange, err := sqlCommonGetUsersRangeForQuotaCheck(usernames[:maxUsers], dbHandle)
  1041. if err != nil {
  1042. return users, err
  1043. }
  1044. users = append(users, usersRange...)
  1045. usernames = usernames[maxUsers:]
  1046. }
  1047. var usersWithFolders []User
  1048. validIdx := 0
  1049. for _, user := range users {
  1050. if toFetch[user.Username] {
  1051. usersWithFolders = append(usersWithFolders, user)
  1052. } else {
  1053. users[validIdx] = user
  1054. validIdx++
  1055. }
  1056. }
  1057. users = users[:validIdx]
  1058. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1059. defer cancel()
  1060. usersWithFolders, err := getUsersWithVirtualFolders(ctx, usersWithFolders, dbHandle)
  1061. if err != nil {
  1062. return users, err
  1063. }
  1064. users = append(users, usersWithFolders...)
  1065. users, err = getUsersWithGroups(ctx, users, dbHandle)
  1066. if err != nil {
  1067. return users, err
  1068. }
  1069. var groupNames []string
  1070. for _, u := range users {
  1071. for _, g := range u.Groups {
  1072. groupNames = append(groupNames, g.Name)
  1073. }
  1074. }
  1075. groupNames = util.RemoveDuplicates(groupNames, false)
  1076. if len(groupNames) == 0 {
  1077. return users, nil
  1078. }
  1079. groups, err := sqlCommonGetGroupsWithNames(groupNames, dbHandle)
  1080. if err != nil {
  1081. return users, err
  1082. }
  1083. groupsMapping := make(map[string]Group)
  1084. for idx := range groups {
  1085. groupsMapping[groups[idx].Name] = groups[idx]
  1086. }
  1087. for idx := range users {
  1088. ref := &users[idx]
  1089. ref.applyGroupSettings(groupsMapping)
  1090. }
  1091. return users, nil
  1092. }
  1093. func sqlCommonGetUsersRangeForQuotaCheck(usernames []string, dbHandle sqlQuerier) ([]User, error) {
  1094. users := make([]User, 0, len(usernames))
  1095. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1096. defer cancel()
  1097. q := getUsersForQuotaCheckQuery(len(usernames))
  1098. queryArgs := make([]any, 0, len(usernames))
  1099. for idx := range usernames {
  1100. queryArgs = append(queryArgs, usernames[idx])
  1101. }
  1102. rows, err := dbHandle.QueryContext(ctx, q, queryArgs...)
  1103. if err != nil {
  1104. return nil, err
  1105. }
  1106. defer rows.Close()
  1107. for rows.Next() {
  1108. var user User
  1109. var filters sql.NullString
  1110. err = rows.Scan(&user.ID, &user.Username, &user.QuotaSize, &user.UsedQuotaSize, &user.TotalDataTransfer,
  1111. &user.UploadDataTransfer, &user.DownloadDataTransfer, &user.UsedUploadDataTransfer,
  1112. &user.UsedDownloadDataTransfer, &filters)
  1113. if err != nil {
  1114. return users, err
  1115. }
  1116. if filters.Valid {
  1117. var userFilters UserFilters
  1118. err = json.Unmarshal([]byte(filters.String), &userFilters)
  1119. if err == nil {
  1120. user.Filters = userFilters
  1121. }
  1122. }
  1123. users = append(users, user)
  1124. }
  1125. return users, rows.Err()
  1126. }
  1127. func sqlCommonAddActiveTransfer(transfer ActiveTransfer, dbHandle *sql.DB) error {
  1128. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1129. defer cancel()
  1130. q := getAddActiveTransferQuery()
  1131. now := util.GetTimeAsMsSinceEpoch(time.Now())
  1132. _, err := dbHandle.ExecContext(ctx, q, transfer.ID, transfer.ConnID, transfer.Type, transfer.Username,
  1133. transfer.FolderName, transfer.IP, transfer.TruncatedSize, transfer.CurrentULSize, transfer.CurrentDLSize,
  1134. now, now)
  1135. return err
  1136. }
  1137. func sqlCommonUpdateActiveTransferSizes(ulSize, dlSize, transferID int64, connectionID string, dbHandle *sql.DB) error {
  1138. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1139. defer cancel()
  1140. q := getUpdateActiveTransferSizesQuery()
  1141. _, err := dbHandle.ExecContext(ctx, q, ulSize, dlSize, util.GetTimeAsMsSinceEpoch(time.Now()), connectionID, transferID)
  1142. return err
  1143. }
  1144. func sqlCommonRemoveActiveTransfer(transferID int64, connectionID string, dbHandle *sql.DB) error {
  1145. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1146. defer cancel()
  1147. q := getRemoveActiveTransferQuery()
  1148. _, err := dbHandle.ExecContext(ctx, q, connectionID, transferID)
  1149. return err
  1150. }
  1151. func sqlCommonCleanupActiveTransfers(before time.Time, dbHandle *sql.DB) error {
  1152. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1153. defer cancel()
  1154. q := getCleanupActiveTransfersQuery()
  1155. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(before))
  1156. return err
  1157. }
  1158. func sqlCommonGetActiveTransfers(from time.Time, dbHandle sqlQuerier) ([]ActiveTransfer, error) {
  1159. transfers := make([]ActiveTransfer, 0, 30)
  1160. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  1161. defer cancel()
  1162. q := getActiveTransfersQuery()
  1163. rows, err := dbHandle.QueryContext(ctx, q, util.GetTimeAsMsSinceEpoch(from))
  1164. if err != nil {
  1165. return nil, err
  1166. }
  1167. defer rows.Close()
  1168. for rows.Next() {
  1169. var transfer ActiveTransfer
  1170. var folderName sql.NullString
  1171. err = rows.Scan(&transfer.ID, &transfer.ConnID, &transfer.Type, &transfer.Username, &folderName, &transfer.IP,
  1172. &transfer.TruncatedSize, &transfer.CurrentULSize, &transfer.CurrentDLSize, &transfer.CreatedAt,
  1173. &transfer.UpdatedAt)
  1174. if err != nil {
  1175. return transfers, err
  1176. }
  1177. if folderName.Valid {
  1178. transfer.FolderName = folderName.String
  1179. }
  1180. transfers = append(transfers, transfer)
  1181. }
  1182. return transfers, rows.Err()
  1183. }
  1184. func sqlCommonGetUsers(limit int, offset int, order string, dbHandle sqlQuerier) ([]User, error) {
  1185. users := make([]User, 0, limit)
  1186. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1187. defer cancel()
  1188. q := getUsersQuery(order)
  1189. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  1190. if err != nil {
  1191. return users, err
  1192. }
  1193. defer rows.Close()
  1194. for rows.Next() {
  1195. u, err := getUserFromDbRow(rows)
  1196. if err != nil {
  1197. return users, err
  1198. }
  1199. users = append(users, u)
  1200. }
  1201. err = rows.Err()
  1202. if err != nil {
  1203. return users, err
  1204. }
  1205. users, err = getUsersWithVirtualFolders(ctx, users, dbHandle)
  1206. if err != nil {
  1207. return users, err
  1208. }
  1209. users, err = getUsersWithGroups(ctx, users, dbHandle)
  1210. if err != nil {
  1211. return users, err
  1212. }
  1213. for idx := range users {
  1214. users[idx].PrepareForRendering()
  1215. }
  1216. return users, nil
  1217. }
  1218. func sqlCommonGetDefenderHosts(from int64, limit int, dbHandle sqlQuerier) ([]DefenderEntry, error) {
  1219. hosts := make([]DefenderEntry, 0, 100)
  1220. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1221. defer cancel()
  1222. q := getDefenderHostsQuery()
  1223. rows, err := dbHandle.QueryContext(ctx, q, from, limit)
  1224. if err != nil {
  1225. providerLog(logger.LevelError, "unable to get defender hosts: %v", err)
  1226. return hosts, err
  1227. }
  1228. defer rows.Close()
  1229. var idForScores []int64
  1230. for rows.Next() {
  1231. var banTime sql.NullInt64
  1232. host := DefenderEntry{}
  1233. err = rows.Scan(&host.ID, &host.IP, &banTime)
  1234. if err != nil {
  1235. providerLog(logger.LevelError, "unable to scan defender host row: %v", err)
  1236. return hosts, err
  1237. }
  1238. var hostBanTime time.Time
  1239. if banTime.Valid && banTime.Int64 > 0 {
  1240. hostBanTime = util.GetTimeFromMsecSinceEpoch(banTime.Int64)
  1241. }
  1242. if hostBanTime.IsZero() || hostBanTime.Before(time.Now()) {
  1243. idForScores = append(idForScores, host.ID)
  1244. } else {
  1245. host.BanTime = hostBanTime
  1246. }
  1247. hosts = append(hosts, host)
  1248. }
  1249. err = rows.Err()
  1250. if err != nil {
  1251. providerLog(logger.LevelError, "unable to iterate over defender host rows: %v", err)
  1252. return hosts, err
  1253. }
  1254. return getDefenderHostsWithScores(ctx, hosts, from, idForScores, dbHandle)
  1255. }
  1256. func sqlCommonIsDefenderHostBanned(ip string, dbHandle sqlQuerier) (DefenderEntry, error) {
  1257. var host DefenderEntry
  1258. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1259. defer cancel()
  1260. q := getDefenderIsHostBannedQuery()
  1261. row := dbHandle.QueryRowContext(ctx, q, ip, util.GetTimeAsMsSinceEpoch(time.Now()))
  1262. err := row.Scan(&host.ID)
  1263. if err != nil {
  1264. if errors.Is(err, sql.ErrNoRows) {
  1265. return host, util.NewRecordNotFoundError("host not found")
  1266. }
  1267. providerLog(logger.LevelError, "unable to check ban status for host %#v: %v", ip, err)
  1268. return host, err
  1269. }
  1270. return host, nil
  1271. }
  1272. func sqlCommonGetDefenderHostByIP(ip string, from int64, dbHandle sqlQuerier) (DefenderEntry, error) {
  1273. var host DefenderEntry
  1274. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1275. defer cancel()
  1276. q := getDefenderHostQuery()
  1277. row := dbHandle.QueryRowContext(ctx, q, ip, from)
  1278. var banTime sql.NullInt64
  1279. err := row.Scan(&host.ID, &host.IP, &banTime)
  1280. if err != nil {
  1281. if errors.Is(err, sql.ErrNoRows) {
  1282. return host, util.NewRecordNotFoundError("host not found")
  1283. }
  1284. providerLog(logger.LevelError, "unable to get host for ip %#v: %v", ip, err)
  1285. return host, err
  1286. }
  1287. if banTime.Valid && banTime.Int64 > 0 {
  1288. hostBanTime := util.GetTimeFromMsecSinceEpoch(banTime.Int64)
  1289. if !hostBanTime.IsZero() && hostBanTime.After(time.Now()) {
  1290. host.BanTime = hostBanTime
  1291. return host, nil
  1292. }
  1293. }
  1294. hosts, err := getDefenderHostsWithScores(ctx, []DefenderEntry{host}, from, []int64{host.ID}, dbHandle)
  1295. if err != nil {
  1296. return host, err
  1297. }
  1298. if len(hosts) == 0 {
  1299. return host, util.NewRecordNotFoundError("host not found")
  1300. }
  1301. return hosts[0], nil
  1302. }
  1303. func sqlCommonDefenderIncrementBanTime(ip string, minutesToAdd int, dbHandle *sql.DB) error {
  1304. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1305. defer cancel()
  1306. q := getDefenderIncrementBanTimeQuery()
  1307. _, err := dbHandle.ExecContext(ctx, q, minutesToAdd*60000, ip)
  1308. if err == nil {
  1309. providerLog(logger.LevelDebug, "ban time updated for ip %#v, increment (minutes): %v",
  1310. ip, minutesToAdd)
  1311. } else {
  1312. providerLog(logger.LevelError, "error updating ban time for ip %#v: %v", ip, err)
  1313. }
  1314. return err
  1315. }
  1316. func sqlCommonSetDefenderBanTime(ip string, banTime int64, dbHandle *sql.DB) error {
  1317. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1318. defer cancel()
  1319. q := getDefenderSetBanTimeQuery()
  1320. _, err := dbHandle.ExecContext(ctx, q, banTime, ip)
  1321. if err == nil {
  1322. providerLog(logger.LevelDebug, "ip %#v banned until %v", ip, util.GetTimeFromMsecSinceEpoch(banTime))
  1323. } else {
  1324. providerLog(logger.LevelError, "error setting ban time for ip %#v: %v", ip, err)
  1325. }
  1326. return err
  1327. }
  1328. func sqlCommonDeleteDefenderHost(ip string, dbHandle sqlQuerier) error {
  1329. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1330. defer cancel()
  1331. q := getDeleteDefenderHostQuery()
  1332. res, err := dbHandle.ExecContext(ctx, q, ip)
  1333. if err != nil {
  1334. providerLog(logger.LevelError, "unable to delete defender host %#v: %v", ip, err)
  1335. return err
  1336. }
  1337. return sqlCommonRequireRowAffected(res)
  1338. }
  1339. func sqlCommonAddDefenderHostAndEvent(ip string, score int, dbHandle *sql.DB) error {
  1340. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1341. defer cancel()
  1342. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  1343. if err := sqlCommonAddDefenderHost(ctx, ip, tx); err != nil {
  1344. return err
  1345. }
  1346. return sqlCommonAddDefenderEvent(ctx, ip, score, tx)
  1347. })
  1348. }
  1349. func sqlCommonDefenderCleanup(from int64, dbHandler *sql.DB) error {
  1350. if err := sqlCommonCleanupDefenderEvents(from, dbHandler); err != nil {
  1351. return err
  1352. }
  1353. return sqlCommonCleanupDefenderHosts(from, dbHandler)
  1354. }
  1355. func sqlCommonAddDefenderHost(ctx context.Context, ip string, tx *sql.Tx) error {
  1356. q := getAddDefenderHostQuery()
  1357. _, err := tx.ExecContext(ctx, q, ip, util.GetTimeAsMsSinceEpoch(time.Now()))
  1358. if err != nil {
  1359. providerLog(logger.LevelError, "unable to add defender host %#v: %v", ip, err)
  1360. }
  1361. return err
  1362. }
  1363. func sqlCommonAddDefenderEvent(ctx context.Context, ip string, score int, tx *sql.Tx) error {
  1364. q := getAddDefenderEventQuery()
  1365. _, err := tx.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), score, ip)
  1366. if err != nil {
  1367. providerLog(logger.LevelError, "unable to add defender event for %#v: %v", ip, err)
  1368. }
  1369. return err
  1370. }
  1371. func sqlCommonCleanupDefenderHosts(from int64, dbHandle *sql.DB) error {
  1372. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1373. defer cancel()
  1374. q := getDefenderHostsCleanupQuery()
  1375. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), from)
  1376. if err != nil {
  1377. providerLog(logger.LevelError, "unable to cleanup defender hosts: %v", err)
  1378. }
  1379. return err
  1380. }
  1381. func sqlCommonCleanupDefenderEvents(from int64, dbHandle *sql.DB) error {
  1382. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1383. defer cancel()
  1384. q := getDefenderEventsCleanupQuery()
  1385. _, err := dbHandle.ExecContext(ctx, q, from)
  1386. if err != nil {
  1387. providerLog(logger.LevelError, "unable to cleanup defender events: %v", err)
  1388. }
  1389. return err
  1390. }
  1391. func getShareFromDbRow(row sqlScanner) (Share, error) {
  1392. var share Share
  1393. var description, password, allowFrom, paths sql.NullString
  1394. err := row.Scan(&share.ShareID, &share.Name, &description, &share.Scope,
  1395. &paths, &share.Username, &share.CreatedAt, &share.UpdatedAt,
  1396. &share.LastUseAt, &share.ExpiresAt, &password, &share.MaxTokens,
  1397. &share.UsedTokens, &allowFrom)
  1398. if err != nil {
  1399. if errors.Is(err, sql.ErrNoRows) {
  1400. return share, util.NewRecordNotFoundError(err.Error())
  1401. }
  1402. return share, err
  1403. }
  1404. if paths.Valid {
  1405. var list []string
  1406. err = json.Unmarshal([]byte(paths.String), &list)
  1407. if err != nil {
  1408. return share, err
  1409. }
  1410. share.Paths = list
  1411. } else {
  1412. return share, errors.New("unable to decode shared paths")
  1413. }
  1414. if description.Valid {
  1415. share.Description = description.String
  1416. }
  1417. if password.Valid {
  1418. share.Password = password.String
  1419. }
  1420. if allowFrom.Valid {
  1421. var list []string
  1422. err = json.Unmarshal([]byte(allowFrom.String), &list)
  1423. if err == nil {
  1424. share.AllowFrom = list
  1425. }
  1426. }
  1427. return share, nil
  1428. }
  1429. func getAPIKeyFromDbRow(row sqlScanner) (APIKey, error) {
  1430. var apiKey APIKey
  1431. var userID, adminID sql.NullInt64
  1432. var description sql.NullString
  1433. err := row.Scan(&apiKey.KeyID, &apiKey.Name, &apiKey.Key, &apiKey.Scope, &apiKey.CreatedAt, &apiKey.UpdatedAt,
  1434. &apiKey.LastUseAt, &apiKey.ExpiresAt, &description, &userID, &adminID)
  1435. if err != nil {
  1436. if errors.Is(err, sql.ErrNoRows) {
  1437. return apiKey, util.NewRecordNotFoundError(err.Error())
  1438. }
  1439. return apiKey, err
  1440. }
  1441. if userID.Valid {
  1442. apiKey.userID = userID.Int64
  1443. }
  1444. if adminID.Valid {
  1445. apiKey.adminID = adminID.Int64
  1446. }
  1447. if description.Valid {
  1448. apiKey.Description = description.String
  1449. }
  1450. return apiKey, nil
  1451. }
  1452. func getAdminFromDbRow(row sqlScanner) (Admin, error) {
  1453. var admin Admin
  1454. var email, filters, additionalInfo, permissions, description sql.NullString
  1455. err := row.Scan(&admin.ID, &admin.Username, &admin.Password, &admin.Status, &email, &permissions,
  1456. &filters, &additionalInfo, &description, &admin.CreatedAt, &admin.UpdatedAt, &admin.LastLogin)
  1457. if err != nil {
  1458. if errors.Is(err, sql.ErrNoRows) {
  1459. return admin, util.NewRecordNotFoundError(err.Error())
  1460. }
  1461. return admin, err
  1462. }
  1463. if permissions.Valid {
  1464. var perms []string
  1465. err = json.Unmarshal([]byte(permissions.String), &perms)
  1466. if err != nil {
  1467. return admin, err
  1468. }
  1469. admin.Permissions = perms
  1470. }
  1471. if email.Valid {
  1472. admin.Email = email.String
  1473. }
  1474. if filters.Valid {
  1475. var adminFilters AdminFilters
  1476. err = json.Unmarshal([]byte(filters.String), &adminFilters)
  1477. if err == nil {
  1478. admin.Filters = adminFilters
  1479. }
  1480. }
  1481. if additionalInfo.Valid {
  1482. admin.AdditionalInfo = additionalInfo.String
  1483. }
  1484. if description.Valid {
  1485. admin.Description = description.String
  1486. }
  1487. admin.SetEmptySecretsIfNil()
  1488. return admin, nil
  1489. }
  1490. func getEventActionFromDbRow(row sqlScanner) (BaseEventAction, error) {
  1491. var action BaseEventAction
  1492. var description sql.NullString
  1493. var options []byte
  1494. err := row.Scan(&action.ID, &action.Name, &description, &action.Type, &options)
  1495. if err != nil {
  1496. if errors.Is(err, sql.ErrNoRows) {
  1497. return action, util.NewRecordNotFoundError(err.Error())
  1498. }
  1499. return action, err
  1500. }
  1501. if description.Valid {
  1502. action.Description = description.String
  1503. }
  1504. if len(options) > 0 {
  1505. err = json.Unmarshal(options, &action.Options)
  1506. if err != nil {
  1507. return action, err
  1508. }
  1509. }
  1510. return action, nil
  1511. }
  1512. func getEventRuleFromDbRow(row sqlScanner) (EventRule, error) {
  1513. var rule EventRule
  1514. var description sql.NullString
  1515. var conditions []byte
  1516. err := row.Scan(&rule.ID, &rule.Name, &description, &rule.CreatedAt, &rule.UpdatedAt, &rule.Trigger,
  1517. &conditions, &rule.DeletedAt)
  1518. if err != nil {
  1519. if errors.Is(err, sql.ErrNoRows) {
  1520. return rule, util.NewRecordNotFoundError(err.Error())
  1521. }
  1522. return rule, err
  1523. }
  1524. if len(conditions) > 0 {
  1525. err = json.Unmarshal(conditions, &rule.Conditions)
  1526. if err != nil {
  1527. return rule, err
  1528. }
  1529. }
  1530. if description.Valid {
  1531. rule.Description = description.String
  1532. }
  1533. return rule, nil
  1534. }
  1535. func getGroupFromDbRow(row sqlScanner) (Group, error) {
  1536. var group Group
  1537. var userSettings, description sql.NullString
  1538. err := row.Scan(&group.ID, &group.Name, &description, &group.CreatedAt, &group.UpdatedAt, &userSettings)
  1539. if err != nil {
  1540. if errors.Is(err, sql.ErrNoRows) {
  1541. return group, util.NewRecordNotFoundError(err.Error())
  1542. }
  1543. return group, err
  1544. }
  1545. if description.Valid {
  1546. group.Description = description.String
  1547. }
  1548. if userSettings.Valid {
  1549. var settings GroupUserSettings
  1550. err = json.Unmarshal([]byte(userSettings.String), &settings)
  1551. if err == nil {
  1552. group.UserSettings = settings
  1553. }
  1554. }
  1555. return group, nil
  1556. }
  1557. func getUserFromDbRow(row sqlScanner) (User, error) {
  1558. var user User
  1559. var permissions sql.NullString
  1560. var password sql.NullString
  1561. var publicKey sql.NullString
  1562. var filters sql.NullString
  1563. var fsConfig sql.NullString
  1564. var additionalInfo, description, email sql.NullString
  1565. err := row.Scan(&user.ID, &user.Username, &password, &publicKey, &user.HomeDir, &user.UID, &user.GID, &user.MaxSessions,
  1566. &user.QuotaSize, &user.QuotaFiles, &permissions, &user.UsedQuotaSize, &user.UsedQuotaFiles, &user.LastQuotaUpdate,
  1567. &user.UploadBandwidth, &user.DownloadBandwidth, &user.ExpirationDate, &user.LastLogin, &user.Status, &filters, &fsConfig,
  1568. &additionalInfo, &description, &email, &user.CreatedAt, &user.UpdatedAt, &user.UploadDataTransfer, &user.DownloadDataTransfer,
  1569. &user.TotalDataTransfer, &user.UsedUploadDataTransfer, &user.UsedDownloadDataTransfer, &user.DeletedAt, &user.FirstDownload,
  1570. &user.FirstUpload)
  1571. if err != nil {
  1572. if errors.Is(err, sql.ErrNoRows) {
  1573. return user, util.NewRecordNotFoundError(err.Error())
  1574. }
  1575. return user, err
  1576. }
  1577. if password.Valid {
  1578. user.Password = password.String
  1579. }
  1580. // we can have a empty string or an invalid json in null string
  1581. // so we do a relaxed test if the field is optional, for example we
  1582. // populate public keys only if unmarshal does not return an error
  1583. if publicKey.Valid {
  1584. var list []string
  1585. err = json.Unmarshal([]byte(publicKey.String), &list)
  1586. if err == nil {
  1587. user.PublicKeys = list
  1588. }
  1589. }
  1590. if permissions.Valid {
  1591. perms := make(map[string][]string)
  1592. err = json.Unmarshal([]byte(permissions.String), &perms)
  1593. if err != nil {
  1594. providerLog(logger.LevelError, "unable to deserialize permissions for user %#v: %v", user.Username, err)
  1595. return user, fmt.Errorf("unable to deserialize permissions for user %#v: %v", user.Username, err)
  1596. }
  1597. user.Permissions = perms
  1598. }
  1599. if filters.Valid {
  1600. var userFilters UserFilters
  1601. err = json.Unmarshal([]byte(filters.String), &userFilters)
  1602. if err == nil {
  1603. user.Filters = userFilters
  1604. }
  1605. }
  1606. if fsConfig.Valid {
  1607. var fs vfs.Filesystem
  1608. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  1609. if err == nil {
  1610. user.FsConfig = fs
  1611. }
  1612. }
  1613. if additionalInfo.Valid {
  1614. user.AdditionalInfo = additionalInfo.String
  1615. }
  1616. if description.Valid {
  1617. user.Description = description.String
  1618. }
  1619. if email.Valid {
  1620. user.Email = email.String
  1621. }
  1622. user.SetEmptySecretsIfNil()
  1623. return user, nil
  1624. }
  1625. func sqlCommonGetFolder(ctx context.Context, name string, dbHandle sqlQuerier) (vfs.BaseVirtualFolder, error) {
  1626. var folder vfs.BaseVirtualFolder
  1627. q := getFolderByNameQuery()
  1628. row := dbHandle.QueryRowContext(ctx, q, name)
  1629. var mappedPath, description, fsConfig sql.NullString
  1630. err := row.Scan(&folder.ID, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles, &folder.LastQuotaUpdate,
  1631. &folder.Name, &description, &fsConfig)
  1632. if err != nil {
  1633. if errors.Is(err, sql.ErrNoRows) {
  1634. return folder, util.NewRecordNotFoundError(err.Error())
  1635. }
  1636. return folder, err
  1637. }
  1638. if mappedPath.Valid {
  1639. folder.MappedPath = mappedPath.String
  1640. }
  1641. if description.Valid {
  1642. folder.Description = description.String
  1643. }
  1644. if fsConfig.Valid {
  1645. var fs vfs.Filesystem
  1646. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  1647. if err == nil {
  1648. folder.FsConfig = fs
  1649. }
  1650. }
  1651. return folder, err
  1652. }
  1653. func sqlCommonGetFolderByName(ctx context.Context, name string, dbHandle sqlQuerier) (vfs.BaseVirtualFolder, error) {
  1654. folder, err := sqlCommonGetFolder(ctx, name, dbHandle)
  1655. if err != nil {
  1656. return folder, err
  1657. }
  1658. folders, err := getVirtualFoldersWithUsers([]vfs.BaseVirtualFolder{folder}, dbHandle)
  1659. if err != nil {
  1660. return folder, err
  1661. }
  1662. if len(folders) != 1 {
  1663. return folder, fmt.Errorf("unable to associate users with folder %#v", name)
  1664. }
  1665. folders, err = getVirtualFoldersWithGroups([]vfs.BaseVirtualFolder{folders[0]}, dbHandle)
  1666. if err != nil {
  1667. return folder, err
  1668. }
  1669. if len(folders) != 1 {
  1670. return folder, fmt.Errorf("unable to associate groups with folder %#v", name)
  1671. }
  1672. return folders[0], nil
  1673. }
  1674. func sqlCommonAddOrUpdateFolder(ctx context.Context, baseFolder *vfs.BaseVirtualFolder, usedQuotaSize int64,
  1675. usedQuotaFiles int, lastQuotaUpdate int64, dbHandle sqlQuerier,
  1676. ) error {
  1677. fsConfig, err := json.Marshal(baseFolder.FsConfig)
  1678. if err != nil {
  1679. return err
  1680. }
  1681. q := getUpsertFolderQuery()
  1682. _, err = dbHandle.ExecContext(ctx, q, baseFolder.MappedPath, usedQuotaSize, usedQuotaFiles,
  1683. lastQuotaUpdate, baseFolder.Name, baseFolder.Description, string(fsConfig))
  1684. return err
  1685. }
  1686. func sqlCommonAddFolder(folder *vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
  1687. err := ValidateFolder(folder)
  1688. if err != nil {
  1689. return err
  1690. }
  1691. fsConfig, err := json.Marshal(folder.FsConfig)
  1692. if err != nil {
  1693. return err
  1694. }
  1695. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1696. defer cancel()
  1697. q := getAddFolderQuery()
  1698. _, err = dbHandle.ExecContext(ctx, q, folder.MappedPath, folder.UsedQuotaSize, folder.UsedQuotaFiles,
  1699. folder.LastQuotaUpdate, folder.Name, folder.Description, string(fsConfig))
  1700. return err
  1701. }
  1702. func sqlCommonUpdateFolder(folder *vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
  1703. err := ValidateFolder(folder)
  1704. if err != nil {
  1705. return err
  1706. }
  1707. fsConfig, err := json.Marshal(folder.FsConfig)
  1708. if err != nil {
  1709. return err
  1710. }
  1711. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1712. defer cancel()
  1713. q := getUpdateFolderQuery()
  1714. _, err = dbHandle.ExecContext(ctx, q, folder.MappedPath, folder.Description, string(fsConfig), folder.Name)
  1715. return err
  1716. }
  1717. func sqlCommonDeleteFolder(folder vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
  1718. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1719. defer cancel()
  1720. q := getDeleteFolderQuery()
  1721. res, err := dbHandle.ExecContext(ctx, q, folder.ID)
  1722. if err != nil {
  1723. return err
  1724. }
  1725. return sqlCommonRequireRowAffected(res)
  1726. }
  1727. func sqlCommonDumpFolders(dbHandle sqlQuerier) ([]vfs.BaseVirtualFolder, error) {
  1728. folders := make([]vfs.BaseVirtualFolder, 0, 50)
  1729. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  1730. defer cancel()
  1731. q := getDumpFoldersQuery()
  1732. rows, err := dbHandle.QueryContext(ctx, q)
  1733. if err != nil {
  1734. return folders, err
  1735. }
  1736. defer rows.Close()
  1737. for rows.Next() {
  1738. var folder vfs.BaseVirtualFolder
  1739. var mappedPath, description, fsConfig sql.NullString
  1740. err = rows.Scan(&folder.ID, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles,
  1741. &folder.LastQuotaUpdate, &folder.Name, &description, &fsConfig)
  1742. if err != nil {
  1743. return folders, err
  1744. }
  1745. if mappedPath.Valid {
  1746. folder.MappedPath = mappedPath.String
  1747. }
  1748. if description.Valid {
  1749. folder.Description = description.String
  1750. }
  1751. if fsConfig.Valid {
  1752. var fs vfs.Filesystem
  1753. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  1754. if err == nil {
  1755. folder.FsConfig = fs
  1756. }
  1757. }
  1758. folders = append(folders, folder)
  1759. }
  1760. return folders, rows.Err()
  1761. }
  1762. func sqlCommonGetFolders(limit, offset int, order string, minimal bool, dbHandle sqlQuerier) ([]vfs.BaseVirtualFolder, error) {
  1763. folders := make([]vfs.BaseVirtualFolder, 0, limit)
  1764. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  1765. defer cancel()
  1766. q := getFoldersQuery(order, minimal)
  1767. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  1768. if err != nil {
  1769. return folders, err
  1770. }
  1771. defer rows.Close()
  1772. for rows.Next() {
  1773. var folder vfs.BaseVirtualFolder
  1774. if minimal {
  1775. err = rows.Scan(&folder.ID, &folder.Name)
  1776. if err != nil {
  1777. return folders, err
  1778. }
  1779. } else {
  1780. var mappedPath, description, fsConfig sql.NullString
  1781. err = rows.Scan(&folder.ID, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles,
  1782. &folder.LastQuotaUpdate, &folder.Name, &description, &fsConfig)
  1783. if err != nil {
  1784. return folders, err
  1785. }
  1786. if mappedPath.Valid {
  1787. folder.MappedPath = mappedPath.String
  1788. }
  1789. if description.Valid {
  1790. folder.Description = description.String
  1791. }
  1792. if fsConfig.Valid {
  1793. var fs vfs.Filesystem
  1794. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  1795. if err == nil {
  1796. folder.FsConfig = fs
  1797. }
  1798. }
  1799. }
  1800. folder.PrepareForRendering()
  1801. folders = append(folders, folder)
  1802. }
  1803. err = rows.Err()
  1804. if err != nil {
  1805. return folders, err
  1806. }
  1807. if minimal {
  1808. return folders, nil
  1809. }
  1810. folders, err = getVirtualFoldersWithUsers(folders, dbHandle)
  1811. if err != nil {
  1812. return folders, err
  1813. }
  1814. return getVirtualFoldersWithGroups(folders, dbHandle)
  1815. }
  1816. func sqlCommonClearUserFolderMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
  1817. q := getClearUserFolderMappingQuery()
  1818. _, err := dbHandle.ExecContext(ctx, q, user.Username)
  1819. return err
  1820. }
  1821. func sqlCommonClearGroupFolderMapping(ctx context.Context, group *Group, dbHandle sqlQuerier) error {
  1822. q := getClearGroupFolderMappingQuery()
  1823. _, err := dbHandle.ExecContext(ctx, q, group.Name)
  1824. return err
  1825. }
  1826. func sqlCommonClearUserGroupMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
  1827. q := getClearUserGroupMappingQuery()
  1828. _, err := dbHandle.ExecContext(ctx, q, user.Username)
  1829. return err
  1830. }
  1831. func sqlCommonAddUserFolderMapping(ctx context.Context, user *User, folder *vfs.VirtualFolder, dbHandle sqlQuerier) error {
  1832. q := getAddUserFolderMappingQuery()
  1833. _, err := dbHandle.ExecContext(ctx, q, folder.VirtualPath, folder.QuotaSize, folder.QuotaFiles, folder.Name, user.Username)
  1834. return err
  1835. }
  1836. func sqlCommonClearAdminGroupMapping(ctx context.Context, admin *Admin, dbHandle sqlQuerier) error {
  1837. q := getClearAdminGroupMappingQuery()
  1838. _, err := dbHandle.ExecContext(ctx, q, admin.Username)
  1839. return err
  1840. }
  1841. func sqlCommonAddGroupFolderMapping(ctx context.Context, group *Group, folder *vfs.VirtualFolder, dbHandle sqlQuerier) error {
  1842. q := getAddGroupFolderMappingQuery()
  1843. _, err := dbHandle.ExecContext(ctx, q, folder.VirtualPath, folder.QuotaSize, folder.QuotaFiles, folder.Name, group.Name)
  1844. return err
  1845. }
  1846. func sqlCommonAddUserGroupMapping(ctx context.Context, username, groupName string, groupType int, dbHandle sqlQuerier) error {
  1847. q := getAddUserGroupMappingQuery()
  1848. _, err := dbHandle.ExecContext(ctx, q, username, groupName, groupType)
  1849. return err
  1850. }
  1851. func sqlCommonAddAdminGroupMapping(ctx context.Context, username, groupName string, mappingOptions AdminGroupMappingOptions,
  1852. dbHandle sqlQuerier,
  1853. ) error {
  1854. options, err := json.Marshal(mappingOptions)
  1855. if err != nil {
  1856. return err
  1857. }
  1858. q := getAddAdminGroupMappingQuery()
  1859. _, err = dbHandle.ExecContext(ctx, q, username, groupName, string(options))
  1860. return err
  1861. }
  1862. func generateGroupVirtualFoldersMapping(ctx context.Context, group *Group, dbHandle sqlQuerier) error {
  1863. err := sqlCommonClearGroupFolderMapping(ctx, group, dbHandle)
  1864. if err != nil {
  1865. return err
  1866. }
  1867. for idx := range group.VirtualFolders {
  1868. vfolder := &group.VirtualFolders[idx]
  1869. err = sqlCommonAddOrUpdateFolder(ctx, &vfolder.BaseVirtualFolder, 0, 0, 0, dbHandle)
  1870. if err != nil {
  1871. return err
  1872. }
  1873. err = sqlCommonAddGroupFolderMapping(ctx, group, vfolder, dbHandle)
  1874. if err != nil {
  1875. return err
  1876. }
  1877. }
  1878. return err
  1879. }
  1880. func generateUserVirtualFoldersMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
  1881. err := sqlCommonClearUserFolderMapping(ctx, user, dbHandle)
  1882. if err != nil {
  1883. return err
  1884. }
  1885. for idx := range user.VirtualFolders {
  1886. vfolder := &user.VirtualFolders[idx]
  1887. err := sqlCommonAddOrUpdateFolder(ctx, &vfolder.BaseVirtualFolder, 0, 0, 0, dbHandle)
  1888. if err != nil {
  1889. return err
  1890. }
  1891. err = sqlCommonAddUserFolderMapping(ctx, user, vfolder, dbHandle)
  1892. if err != nil {
  1893. return err
  1894. }
  1895. }
  1896. return err
  1897. }
  1898. func generateUserGroupMapping(ctx context.Context, user *User, dbHandle sqlQuerier) error {
  1899. err := sqlCommonClearUserGroupMapping(ctx, user, dbHandle)
  1900. if err != nil {
  1901. return err
  1902. }
  1903. for _, group := range user.Groups {
  1904. err = sqlCommonAddUserGroupMapping(ctx, user.Username, group.Name, group.Type, dbHandle)
  1905. if err != nil {
  1906. return err
  1907. }
  1908. }
  1909. return err
  1910. }
  1911. func generateAdminGroupMapping(ctx context.Context, admin *Admin, dbHandle sqlQuerier) error {
  1912. err := sqlCommonClearAdminGroupMapping(ctx, admin, dbHandle)
  1913. if err != nil {
  1914. return err
  1915. }
  1916. for _, group := range admin.Groups {
  1917. err = sqlCommonAddAdminGroupMapping(ctx, admin.Username, group.Name, group.Options, dbHandle)
  1918. if err != nil {
  1919. return err
  1920. }
  1921. }
  1922. return err
  1923. }
  1924. func getDefenderHostsWithScores(ctx context.Context, hosts []DefenderEntry, from int64, idForScores []int64,
  1925. dbHandle sqlQuerier) (
  1926. []DefenderEntry,
  1927. error,
  1928. ) {
  1929. if len(idForScores) == 0 {
  1930. return hosts, nil
  1931. }
  1932. hostsWithScores := make(map[int64]int)
  1933. q := getDefenderEventsQuery(idForScores)
  1934. rows, err := dbHandle.QueryContext(ctx, q, from)
  1935. if err != nil {
  1936. providerLog(logger.LevelError, "unable to get score for hosts with id %+v: %v", idForScores, err)
  1937. return nil, err
  1938. }
  1939. defer rows.Close()
  1940. for rows.Next() {
  1941. var hostID int64
  1942. var score int
  1943. err = rows.Scan(&hostID, &score)
  1944. if err != nil {
  1945. providerLog(logger.LevelError, "error scanning host score row: %v", err)
  1946. return hosts, err
  1947. }
  1948. if score > 0 {
  1949. hostsWithScores[hostID] = score
  1950. }
  1951. }
  1952. err = rows.Err()
  1953. if err != nil {
  1954. return hosts, err
  1955. }
  1956. result := make([]DefenderEntry, 0, len(hosts))
  1957. for idx := range hosts {
  1958. hosts[idx].Score = hostsWithScores[hosts[idx].ID]
  1959. if hosts[idx].Score > 0 || !hosts[idx].BanTime.IsZero() {
  1960. result = append(result, hosts[idx])
  1961. }
  1962. }
  1963. return result, nil
  1964. }
  1965. func getAdminWithGroups(ctx context.Context, admin Admin, dbHandle sqlQuerier) (Admin, error) {
  1966. admins, err := getAdminsWithGroups(ctx, []Admin{admin}, dbHandle)
  1967. if err != nil {
  1968. return admin, err
  1969. }
  1970. if len(admins) == 0 {
  1971. return admin, errSQLGroupsAssociation
  1972. }
  1973. return admins[0], err
  1974. }
  1975. func getAdminsWithGroups(ctx context.Context, admins []Admin, dbHandle sqlQuerier) ([]Admin, error) {
  1976. if len(admins) == 0 {
  1977. return admins, nil
  1978. }
  1979. adminsGroups := make(map[int64][]AdminGroupMapping)
  1980. q := getRelatedGroupsForAdminsQuery(admins)
  1981. rows, err := dbHandle.QueryContext(ctx, q)
  1982. if err != nil {
  1983. return nil, err
  1984. }
  1985. defer rows.Close()
  1986. for rows.Next() {
  1987. var group AdminGroupMapping
  1988. var adminID int64
  1989. var options []byte
  1990. err = rows.Scan(&group.Name, &options, &adminID)
  1991. if err != nil {
  1992. return admins, err
  1993. }
  1994. err = json.Unmarshal(options, &group.Options)
  1995. if err != nil {
  1996. return admins, err
  1997. }
  1998. adminsGroups[adminID] = append(adminsGroups[adminID], group)
  1999. }
  2000. err = rows.Err()
  2001. if err != nil {
  2002. return admins, err
  2003. }
  2004. if len(adminsGroups) == 0 {
  2005. return admins, err
  2006. }
  2007. for idx := range admins {
  2008. ref := &admins[idx]
  2009. ref.Groups = adminsGroups[ref.ID]
  2010. }
  2011. return admins, err
  2012. }
  2013. func getUserWithVirtualFolders(ctx context.Context, user User, dbHandle sqlQuerier) (User, error) {
  2014. users, err := getUsersWithVirtualFolders(ctx, []User{user}, dbHandle)
  2015. if err != nil {
  2016. return user, err
  2017. }
  2018. if len(users) == 0 {
  2019. return user, errSQLFoldersAssociation
  2020. }
  2021. return users[0], err
  2022. }
  2023. func getUsersWithVirtualFolders(ctx context.Context, users []User, dbHandle sqlQuerier) ([]User, error) {
  2024. if len(users) == 0 {
  2025. return users, nil
  2026. }
  2027. usersVirtualFolders := make(map[int64][]vfs.VirtualFolder)
  2028. q := getRelatedFoldersForUsersQuery(users)
  2029. rows, err := dbHandle.QueryContext(ctx, q)
  2030. if err != nil {
  2031. return nil, err
  2032. }
  2033. defer rows.Close()
  2034. for rows.Next() {
  2035. var folder vfs.VirtualFolder
  2036. var userID int64
  2037. var mappedPath, fsConfig, description sql.NullString
  2038. err = rows.Scan(&folder.ID, &folder.Name, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles,
  2039. &folder.LastQuotaUpdate, &folder.VirtualPath, &folder.QuotaSize, &folder.QuotaFiles, &userID, &fsConfig,
  2040. &description)
  2041. if err != nil {
  2042. return users, err
  2043. }
  2044. if mappedPath.Valid {
  2045. folder.MappedPath = mappedPath.String
  2046. }
  2047. if description.Valid {
  2048. folder.Description = description.String
  2049. }
  2050. if fsConfig.Valid {
  2051. var fs vfs.Filesystem
  2052. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  2053. if err == nil {
  2054. folder.FsConfig = fs
  2055. }
  2056. }
  2057. usersVirtualFolders[userID] = append(usersVirtualFolders[userID], folder)
  2058. }
  2059. err = rows.Err()
  2060. if err != nil {
  2061. return users, err
  2062. }
  2063. if len(usersVirtualFolders) == 0 {
  2064. return users, err
  2065. }
  2066. for idx := range users {
  2067. ref := &users[idx]
  2068. ref.VirtualFolders = usersVirtualFolders[ref.ID]
  2069. }
  2070. return users, err
  2071. }
  2072. func getUserWithGroups(ctx context.Context, user User, dbHandle sqlQuerier) (User, error) {
  2073. users, err := getUsersWithGroups(ctx, []User{user}, dbHandle)
  2074. if err != nil {
  2075. return user, err
  2076. }
  2077. if len(users) == 0 {
  2078. return user, errSQLGroupsAssociation
  2079. }
  2080. return users[0], err
  2081. }
  2082. func getUsersWithGroups(ctx context.Context, users []User, dbHandle sqlQuerier) ([]User, error) {
  2083. if len(users) == 0 {
  2084. return users, nil
  2085. }
  2086. usersGroups := make(map[int64][]sdk.GroupMapping)
  2087. q := getRelatedGroupsForUsersQuery(users)
  2088. rows, err := dbHandle.QueryContext(ctx, q)
  2089. if err != nil {
  2090. return nil, err
  2091. }
  2092. defer rows.Close()
  2093. for rows.Next() {
  2094. var group sdk.GroupMapping
  2095. var userID int64
  2096. err = rows.Scan(&group.Name, &group.Type, &userID)
  2097. if err != nil {
  2098. return users, err
  2099. }
  2100. usersGroups[userID] = append(usersGroups[userID], group)
  2101. }
  2102. err = rows.Err()
  2103. if err != nil {
  2104. return users, err
  2105. }
  2106. if len(usersGroups) == 0 {
  2107. return users, err
  2108. }
  2109. for idx := range users {
  2110. ref := &users[idx]
  2111. ref.Groups = usersGroups[ref.ID]
  2112. }
  2113. return users, err
  2114. }
  2115. func getGroupWithUsers(ctx context.Context, group Group, dbHandle sqlQuerier) (Group, error) {
  2116. groups, err := getGroupsWithUsers(ctx, []Group{group}, dbHandle)
  2117. if err != nil {
  2118. return group, err
  2119. }
  2120. if len(groups) == 0 {
  2121. return group, errSQLUsersAssociation
  2122. }
  2123. return groups[0], err
  2124. }
  2125. func getGroupWithAdmins(ctx context.Context, group Group, dbHandle sqlQuerier) (Group, error) {
  2126. groups, err := getGroupsWithAdmins(ctx, []Group{group}, dbHandle)
  2127. if err != nil {
  2128. return group, err
  2129. }
  2130. if len(groups) == 0 {
  2131. return group, errSQLUsersAssociation
  2132. }
  2133. return groups[0], err
  2134. }
  2135. func getGroupWithVirtualFolders(ctx context.Context, group Group, dbHandle sqlQuerier) (Group, error) {
  2136. groups, err := getGroupsWithVirtualFolders(ctx, []Group{group}, dbHandle)
  2137. if err != nil {
  2138. return group, err
  2139. }
  2140. if len(groups) == 0 {
  2141. return group, errSQLFoldersAssociation
  2142. }
  2143. return groups[0], err
  2144. }
  2145. func getGroupsWithVirtualFolders(ctx context.Context, groups []Group, dbHandle sqlQuerier) ([]Group, error) {
  2146. if len(groups) == 0 {
  2147. return groups, nil
  2148. }
  2149. q := getRelatedFoldersForGroupsQuery(groups)
  2150. rows, err := dbHandle.QueryContext(ctx, q)
  2151. if err != nil {
  2152. return nil, err
  2153. }
  2154. defer rows.Close()
  2155. groupsVirtualFolders := make(map[int64][]vfs.VirtualFolder)
  2156. for rows.Next() {
  2157. var groupID int64
  2158. var folder vfs.VirtualFolder
  2159. var mappedPath, fsConfig, description sql.NullString
  2160. err = rows.Scan(&folder.ID, &folder.Name, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles,
  2161. &folder.LastQuotaUpdate, &folder.VirtualPath, &folder.QuotaSize, &folder.QuotaFiles, &groupID, &fsConfig,
  2162. &description)
  2163. if err != nil {
  2164. return groups, err
  2165. }
  2166. if mappedPath.Valid {
  2167. folder.MappedPath = mappedPath.String
  2168. }
  2169. if description.Valid {
  2170. folder.Description = description.String
  2171. }
  2172. if fsConfig.Valid {
  2173. var fs vfs.Filesystem
  2174. err = json.Unmarshal([]byte(fsConfig.String), &fs)
  2175. if err == nil {
  2176. folder.FsConfig = fs
  2177. }
  2178. }
  2179. groupsVirtualFolders[groupID] = append(groupsVirtualFolders[groupID], folder)
  2180. }
  2181. err = rows.Err()
  2182. if err != nil {
  2183. return groups, err
  2184. }
  2185. if len(groupsVirtualFolders) == 0 {
  2186. return groups, err
  2187. }
  2188. for idx := range groups {
  2189. ref := &groups[idx]
  2190. ref.VirtualFolders = groupsVirtualFolders[ref.ID]
  2191. }
  2192. return groups, err
  2193. }
  2194. func getGroupsWithUsers(ctx context.Context, groups []Group, dbHandle sqlQuerier) ([]Group, error) {
  2195. if len(groups) == 0 {
  2196. return groups, nil
  2197. }
  2198. q := getRelatedUsersForGroupsQuery(groups)
  2199. rows, err := dbHandle.QueryContext(ctx, q)
  2200. if err != nil {
  2201. return nil, err
  2202. }
  2203. defer rows.Close()
  2204. groupsUsers := make(map[int64][]string)
  2205. for rows.Next() {
  2206. var username string
  2207. var groupID int64
  2208. err = rows.Scan(&groupID, &username)
  2209. if err != nil {
  2210. return groups, err
  2211. }
  2212. groupsUsers[groupID] = append(groupsUsers[groupID], username)
  2213. }
  2214. err = rows.Err()
  2215. if err != nil {
  2216. return groups, err
  2217. }
  2218. if len(groupsUsers) == 0 {
  2219. return groups, err
  2220. }
  2221. for idx := range groups {
  2222. ref := &groups[idx]
  2223. ref.Users = groupsUsers[ref.ID]
  2224. }
  2225. return groups, err
  2226. }
  2227. func getGroupsWithAdmins(ctx context.Context, groups []Group, dbHandle sqlQuerier) ([]Group, error) {
  2228. if len(groups) == 0 {
  2229. return groups, nil
  2230. }
  2231. q := getRelatedAdminsForGroupsQuery(groups)
  2232. rows, err := dbHandle.QueryContext(ctx, q)
  2233. if err != nil {
  2234. return nil, err
  2235. }
  2236. defer rows.Close()
  2237. groupsAdmins := make(map[int64][]string)
  2238. for rows.Next() {
  2239. var groupID int64
  2240. var username string
  2241. err = rows.Scan(&groupID, &username)
  2242. if err != nil {
  2243. return groups, err
  2244. }
  2245. groupsAdmins[groupID] = append(groupsAdmins[groupID], username)
  2246. }
  2247. err = rows.Err()
  2248. if err != nil {
  2249. return groups, err
  2250. }
  2251. if len(groupsAdmins) > 0 {
  2252. for idx := range groups {
  2253. ref := &groups[idx]
  2254. ref.Admins = groupsAdmins[ref.ID]
  2255. }
  2256. }
  2257. return groups, nil
  2258. }
  2259. func getVirtualFoldersWithGroups(folders []vfs.BaseVirtualFolder, dbHandle sqlQuerier) ([]vfs.BaseVirtualFolder, error) {
  2260. if len(folders) == 0 {
  2261. return folders, nil
  2262. }
  2263. vFoldersGroups := make(map[int64][]string)
  2264. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2265. defer cancel()
  2266. q := getRelatedGroupsForFoldersQuery(folders)
  2267. rows, err := dbHandle.QueryContext(ctx, q)
  2268. if err != nil {
  2269. return nil, err
  2270. }
  2271. defer rows.Close()
  2272. for rows.Next() {
  2273. var name string
  2274. var folderID int64
  2275. err = rows.Scan(&folderID, &name)
  2276. if err != nil {
  2277. return folders, err
  2278. }
  2279. vFoldersGroups[folderID] = append(vFoldersGroups[folderID], name)
  2280. }
  2281. err = rows.Err()
  2282. if err != nil {
  2283. return folders, err
  2284. }
  2285. if len(vFoldersGroups) == 0 {
  2286. return folders, err
  2287. }
  2288. for idx := range folders {
  2289. ref := &folders[idx]
  2290. ref.Groups = vFoldersGroups[ref.ID]
  2291. }
  2292. return folders, err
  2293. }
  2294. func getVirtualFoldersWithUsers(folders []vfs.BaseVirtualFolder, dbHandle sqlQuerier) ([]vfs.BaseVirtualFolder, error) {
  2295. if len(folders) == 0 {
  2296. return folders, nil
  2297. }
  2298. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2299. defer cancel()
  2300. q := getRelatedUsersForFoldersQuery(folders)
  2301. rows, err := dbHandle.QueryContext(ctx, q)
  2302. if err != nil {
  2303. return nil, err
  2304. }
  2305. defer rows.Close()
  2306. vFoldersUsers := make(map[int64][]string)
  2307. for rows.Next() {
  2308. var username string
  2309. var folderID int64
  2310. err = rows.Scan(&folderID, &username)
  2311. if err != nil {
  2312. return folders, err
  2313. }
  2314. vFoldersUsers[folderID] = append(vFoldersUsers[folderID], username)
  2315. }
  2316. err = rows.Err()
  2317. if err != nil {
  2318. return folders, err
  2319. }
  2320. if len(vFoldersUsers) == 0 {
  2321. return folders, err
  2322. }
  2323. for idx := range folders {
  2324. ref := &folders[idx]
  2325. ref.Users = vFoldersUsers[ref.ID]
  2326. }
  2327. return folders, err
  2328. }
  2329. func sqlCommonUpdateFolderQuota(name string, filesAdd int, sizeAdd int64, reset bool, dbHandle *sql.DB) error {
  2330. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2331. defer cancel()
  2332. q := getUpdateFolderQuotaQuery(reset)
  2333. _, err := dbHandle.ExecContext(ctx, q, sizeAdd, filesAdd, util.GetTimeAsMsSinceEpoch(time.Now()), name)
  2334. if err == nil {
  2335. providerLog(logger.LevelDebug, "quota updated for folder %#v, files increment: %v size increment: %v is reset? %v",
  2336. name, filesAdd, sizeAdd, reset)
  2337. } else {
  2338. providerLog(logger.LevelWarn, "error updating quota for folder %#v: %v", name, err)
  2339. }
  2340. return err
  2341. }
  2342. func sqlCommonGetFolderUsedQuota(mappedPath string, dbHandle *sql.DB) (int, int64, error) {
  2343. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2344. defer cancel()
  2345. q := getQuotaFolderQuery()
  2346. var usedFiles int
  2347. var usedSize int64
  2348. err := dbHandle.QueryRowContext(ctx, q, mappedPath).Scan(&usedSize, &usedFiles)
  2349. if err != nil {
  2350. providerLog(logger.LevelError, "error getting quota for folder: %v, error: %v", mappedPath, err)
  2351. return 0, 0, err
  2352. }
  2353. return usedFiles, usedSize, err
  2354. }
  2355. func getAPIKeyWithRelatedFields(ctx context.Context, apiKey APIKey, dbHandle sqlQuerier) (APIKey, error) {
  2356. var apiKeys []APIKey
  2357. var err error
  2358. scope := APIKeyScopeAdmin
  2359. if apiKey.userID > 0 {
  2360. scope = APIKeyScopeUser
  2361. }
  2362. apiKeys, err = getRelatedValuesForAPIKeys(ctx, []APIKey{apiKey}, dbHandle, scope)
  2363. if err != nil {
  2364. return apiKey, err
  2365. }
  2366. if len(apiKeys) > 0 {
  2367. apiKey = apiKeys[0]
  2368. }
  2369. return apiKey, nil
  2370. }
  2371. func getRelatedValuesForAPIKeys(ctx context.Context, apiKeys []APIKey, dbHandle sqlQuerier, scope APIKeyScope) ([]APIKey, error) {
  2372. if len(apiKeys) == 0 {
  2373. return apiKeys, nil
  2374. }
  2375. values := make(map[int64]string)
  2376. var q string
  2377. if scope == APIKeyScopeUser {
  2378. q = getRelatedUsersForAPIKeysQuery(apiKeys)
  2379. } else {
  2380. q = getRelatedAdminsForAPIKeysQuery(apiKeys)
  2381. }
  2382. rows, err := dbHandle.QueryContext(ctx, q)
  2383. if err != nil {
  2384. return nil, err
  2385. }
  2386. defer rows.Close()
  2387. for rows.Next() {
  2388. var valueID int64
  2389. var valueName string
  2390. err = rows.Scan(&valueID, &valueName)
  2391. if err != nil {
  2392. return apiKeys, err
  2393. }
  2394. values[valueID] = valueName
  2395. }
  2396. err = rows.Err()
  2397. if err != nil {
  2398. return apiKeys, err
  2399. }
  2400. if len(values) == 0 {
  2401. return apiKeys, nil
  2402. }
  2403. for idx := range apiKeys {
  2404. ref := &apiKeys[idx]
  2405. if scope == APIKeyScopeUser {
  2406. ref.User = values[ref.userID]
  2407. } else {
  2408. ref.Admin = values[ref.adminID]
  2409. }
  2410. }
  2411. return apiKeys, nil
  2412. }
  2413. func sqlCommonGetAPIKeyRelatedIDs(apiKey *APIKey) (sql.NullInt64, sql.NullInt64, error) {
  2414. var userID, adminID sql.NullInt64
  2415. if apiKey.User != "" {
  2416. u, err := provider.userExists(apiKey.User)
  2417. if err != nil {
  2418. return userID, adminID, util.NewValidationError(fmt.Sprintf("unable to validate user %v", apiKey.User))
  2419. }
  2420. userID.Valid = true
  2421. userID.Int64 = u.ID
  2422. }
  2423. if apiKey.Admin != "" {
  2424. a, err := provider.adminExists(apiKey.Admin)
  2425. if err != nil {
  2426. return userID, adminID, util.NewValidationError(fmt.Sprintf("unable to validate admin %v", apiKey.Admin))
  2427. }
  2428. adminID.Valid = true
  2429. adminID.Int64 = a.ID
  2430. }
  2431. return userID, adminID, nil
  2432. }
  2433. func sqlCommonAddSession(session Session, dbHandle *sql.DB) error {
  2434. if err := session.validate(); err != nil {
  2435. return err
  2436. }
  2437. data, err := json.Marshal(session.Data)
  2438. if err != nil {
  2439. return err
  2440. }
  2441. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2442. defer cancel()
  2443. q := getAddSessionQuery()
  2444. _, err = dbHandle.ExecContext(ctx, q, session.Key, data, session.Type, session.Timestamp)
  2445. return err
  2446. }
  2447. func sqlCommonGetSession(key string, dbHandle sqlQuerier) (Session, error) {
  2448. var session Session
  2449. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2450. defer cancel()
  2451. q := getSessionQuery()
  2452. var data []byte // type hint, some driver will use string instead of []byte if the type is any
  2453. err := dbHandle.QueryRowContext(ctx, q, key).Scan(&session.Key, &data, &session.Type, &session.Timestamp)
  2454. if err != nil {
  2455. return session, err
  2456. }
  2457. session.Data = data
  2458. return session, nil
  2459. }
  2460. func sqlCommonDeleteSession(key string, dbHandle *sql.DB) error {
  2461. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2462. defer cancel()
  2463. q := getDeleteSessionQuery()
  2464. res, err := dbHandle.ExecContext(ctx, q, key)
  2465. if err != nil {
  2466. return err
  2467. }
  2468. return sqlCommonRequireRowAffected(res)
  2469. }
  2470. func sqlCommonCleanupSessions(sessionType SessionType, before int64, dbHandle *sql.DB) error {
  2471. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2472. defer cancel()
  2473. q := getCleanupSessionsQuery()
  2474. _, err := dbHandle.ExecContext(ctx, q, sessionType, before)
  2475. return err
  2476. }
  2477. func getActionsWithRuleNames(ctx context.Context, actions []BaseEventAction, dbHandle sqlQuerier,
  2478. ) ([]BaseEventAction, error) {
  2479. if len(actions) == 0 {
  2480. return actions, nil
  2481. }
  2482. q := getRelatedRulesForActionsQuery(actions)
  2483. rows, err := dbHandle.QueryContext(ctx, q)
  2484. if err != nil {
  2485. return nil, err
  2486. }
  2487. defer rows.Close()
  2488. actionsRules := make(map[int64][]string)
  2489. for rows.Next() {
  2490. var name string
  2491. var actionID int64
  2492. if err = rows.Scan(&actionID, &name); err != nil {
  2493. return nil, err
  2494. }
  2495. actionsRules[actionID] = append(actionsRules[actionID], name)
  2496. }
  2497. err = rows.Err()
  2498. if err != nil {
  2499. return nil, err
  2500. }
  2501. if len(actionsRules) == 0 {
  2502. return actions, nil
  2503. }
  2504. for idx := range actions {
  2505. ref := &actions[idx]
  2506. ref.Rules = actionsRules[ref.ID]
  2507. }
  2508. return actions, nil
  2509. }
  2510. func getRulesWithActions(ctx context.Context, rules []EventRule, dbHandle sqlQuerier) ([]EventRule, error) {
  2511. if len(rules) == 0 {
  2512. return rules, nil
  2513. }
  2514. rulesActions := make(map[int64][]EventAction)
  2515. q := getRelatedActionsForRulesQuery(rules)
  2516. rows, err := dbHandle.QueryContext(ctx, q)
  2517. if err != nil {
  2518. return nil, err
  2519. }
  2520. defer rows.Close()
  2521. for rows.Next() {
  2522. var action EventAction
  2523. var ruleID int64
  2524. var description sql.NullString
  2525. var baseOptions, options []byte
  2526. err = rows.Scan(&action.ID, &action.Name, &description, &action.Type, &baseOptions, &options,
  2527. &action.Order, &ruleID)
  2528. if err != nil {
  2529. return rules, err
  2530. }
  2531. if len(baseOptions) > 0 {
  2532. err = json.Unmarshal(baseOptions, &action.BaseEventAction.Options)
  2533. if err != nil {
  2534. return rules, err
  2535. }
  2536. }
  2537. if len(options) > 0 {
  2538. err = json.Unmarshal(options, &action.Options)
  2539. if err != nil {
  2540. return rules, err
  2541. }
  2542. }
  2543. action.BaseEventAction.Options.SetEmptySecretsIfNil()
  2544. rulesActions[ruleID] = append(rulesActions[ruleID], action)
  2545. }
  2546. err = rows.Err()
  2547. if err != nil {
  2548. return rules, err
  2549. }
  2550. if len(rulesActions) == 0 {
  2551. return rules, nil
  2552. }
  2553. for idx := range rules {
  2554. ref := &rules[idx]
  2555. ref.Actions = rulesActions[ref.ID]
  2556. }
  2557. return rules, nil
  2558. }
  2559. func generateEventRuleActionsMapping(ctx context.Context, rule *EventRule, dbHandle sqlQuerier) error {
  2560. q := getClearRuleActionMappingQuery()
  2561. _, err := dbHandle.ExecContext(ctx, q, rule.Name)
  2562. if err != nil {
  2563. return err
  2564. }
  2565. for _, action := range rule.Actions {
  2566. options, err := json.Marshal(action.Options)
  2567. if err != nil {
  2568. return err
  2569. }
  2570. q = getAddRuleActionMappingQuery()
  2571. _, err = dbHandle.ExecContext(ctx, q, rule.Name, action.Name, action.Order, string(options))
  2572. if err != nil {
  2573. return err
  2574. }
  2575. }
  2576. return nil
  2577. }
  2578. func sqlCommonGetEventActionByName(name string, dbHandle sqlQuerier) (BaseEventAction, error) {
  2579. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2580. defer cancel()
  2581. q := getEventActionByNameQuery()
  2582. row := dbHandle.QueryRowContext(ctx, q, name)
  2583. action, err := getEventActionFromDbRow(row)
  2584. if err != nil {
  2585. return action, err
  2586. }
  2587. actions, err := getActionsWithRuleNames(ctx, []BaseEventAction{action}, dbHandle)
  2588. if err != nil {
  2589. return action, err
  2590. }
  2591. if len(actions) != 1 {
  2592. return action, fmt.Errorf("unable to associate rules with action %q", name)
  2593. }
  2594. return actions[0], nil
  2595. }
  2596. func sqlCommonDumpEventActions(dbHandle sqlQuerier) ([]BaseEventAction, error) {
  2597. actions := make([]BaseEventAction, 0, 10)
  2598. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  2599. defer cancel()
  2600. q := getDumpEventActionsQuery()
  2601. rows, err := dbHandle.QueryContext(ctx, q)
  2602. if err != nil {
  2603. return actions, err
  2604. }
  2605. defer rows.Close()
  2606. for rows.Next() {
  2607. action, err := getEventActionFromDbRow(rows)
  2608. if err != nil {
  2609. return actions, err
  2610. }
  2611. actions = append(actions, action)
  2612. }
  2613. return actions, rows.Err()
  2614. }
  2615. func sqlCommonGetEventActions(limit int, offset int, order string, minimal bool,
  2616. dbHandle sqlQuerier,
  2617. ) ([]BaseEventAction, error) {
  2618. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2619. defer cancel()
  2620. q := getEventsActionsQuery(order, minimal)
  2621. actions := make([]BaseEventAction, 0, limit)
  2622. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  2623. if err != nil {
  2624. return actions, err
  2625. }
  2626. defer rows.Close()
  2627. for rows.Next() {
  2628. var action BaseEventAction
  2629. if minimal {
  2630. err = rows.Scan(&action.ID, &action.Name)
  2631. } else {
  2632. action, err = getEventActionFromDbRow(rows)
  2633. }
  2634. if err != nil {
  2635. return actions, err
  2636. }
  2637. actions = append(actions, action)
  2638. }
  2639. err = rows.Err()
  2640. if err != nil {
  2641. return nil, err
  2642. }
  2643. if minimal {
  2644. return actions, nil
  2645. }
  2646. actions, err = getActionsWithRuleNames(ctx, actions, dbHandle)
  2647. if err != nil {
  2648. return nil, err
  2649. }
  2650. for idx := range actions {
  2651. actions[idx].PrepareForRendering()
  2652. }
  2653. return actions, nil
  2654. }
  2655. func sqlCommonAddEventAction(action *BaseEventAction, dbHandle *sql.DB) error {
  2656. if err := action.validate(); err != nil {
  2657. return err
  2658. }
  2659. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2660. defer cancel()
  2661. q := getAddEventActionQuery()
  2662. options, err := json.Marshal(action.Options)
  2663. if err != nil {
  2664. return err
  2665. }
  2666. _, err = dbHandle.ExecContext(ctx, q, action.Name, action.Description, action.Type, string(options))
  2667. return err
  2668. }
  2669. func sqlCommonUpdateEventAction(action *BaseEventAction, dbHandle *sql.DB) error {
  2670. if err := action.validate(); err != nil {
  2671. return err
  2672. }
  2673. options, err := json.Marshal(action.Options)
  2674. if err != nil {
  2675. return err
  2676. }
  2677. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2678. defer cancel()
  2679. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  2680. q := getUpdateEventActionQuery()
  2681. _, err = tx.ExecContext(ctx, q, action.Description, action.Type, string(options), action.Name)
  2682. if err != nil {
  2683. return err
  2684. }
  2685. q = getUpdateRulesTimestampQuery()
  2686. _, err = tx.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), action.ID)
  2687. return err
  2688. })
  2689. }
  2690. func sqlCommonDeleteEventAction(action BaseEventAction, dbHandle *sql.DB) error {
  2691. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2692. defer cancel()
  2693. q := getDeleteEventActionQuery()
  2694. res, err := dbHandle.ExecContext(ctx, q, action.Name)
  2695. if err != nil {
  2696. return err
  2697. }
  2698. return sqlCommonRequireRowAffected(res)
  2699. }
  2700. func sqlCommonGetEventRuleByName(name string, dbHandle sqlQuerier) (EventRule, error) {
  2701. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2702. defer cancel()
  2703. q := getEventRulesByNameQuery()
  2704. row := dbHandle.QueryRowContext(ctx, q, name)
  2705. rule, err := getEventRuleFromDbRow(row)
  2706. if err != nil {
  2707. return rule, err
  2708. }
  2709. rules, err := getRulesWithActions(ctx, []EventRule{rule}, dbHandle)
  2710. if err != nil {
  2711. return rule, err
  2712. }
  2713. if len(rules) != 1 {
  2714. return rule, fmt.Errorf("unable to associate rule %q with actions", name)
  2715. }
  2716. return rules[0], nil
  2717. }
  2718. func sqlCommonDumpEventRules(dbHandle sqlQuerier) ([]EventRule, error) {
  2719. rules := make([]EventRule, 0, 10)
  2720. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  2721. defer cancel()
  2722. q := getDumpEventRulesQuery()
  2723. rows, err := dbHandle.QueryContext(ctx, q)
  2724. if err != nil {
  2725. return rules, err
  2726. }
  2727. defer rows.Close()
  2728. for rows.Next() {
  2729. rule, err := getEventRuleFromDbRow(rows)
  2730. if err != nil {
  2731. return rules, err
  2732. }
  2733. rules = append(rules, rule)
  2734. }
  2735. err = rows.Err()
  2736. if err != nil {
  2737. return rules, err
  2738. }
  2739. return getRulesWithActions(ctx, rules, dbHandle)
  2740. }
  2741. func sqlCommonGetRecentlyUpdatedRules(after int64, dbHandle sqlQuerier) ([]EventRule, error) {
  2742. rules := make([]EventRule, 0, 10)
  2743. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  2744. defer cancel()
  2745. q := getRecentlyUpdatedRulesQuery()
  2746. rows, err := dbHandle.QueryContext(ctx, q, after)
  2747. if err != nil {
  2748. return rules, err
  2749. }
  2750. defer rows.Close()
  2751. for rows.Next() {
  2752. rule, err := getEventRuleFromDbRow(rows)
  2753. if err != nil {
  2754. return rules, err
  2755. }
  2756. rules = append(rules, rule)
  2757. }
  2758. err = rows.Err()
  2759. if err != nil {
  2760. return rules, err
  2761. }
  2762. return getRulesWithActions(ctx, rules, dbHandle)
  2763. }
  2764. func sqlCommonGetEventRules(limit int, offset int, order string, dbHandle sqlQuerier) ([]EventRule, error) {
  2765. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2766. defer cancel()
  2767. q := getEventRulesQuery(order)
  2768. rules := make([]EventRule, 0, limit)
  2769. rows, err := dbHandle.QueryContext(ctx, q, limit, offset)
  2770. if err != nil {
  2771. return rules, err
  2772. }
  2773. defer rows.Close()
  2774. for rows.Next() {
  2775. rule, err := getEventRuleFromDbRow(rows)
  2776. if err != nil {
  2777. return rules, err
  2778. }
  2779. rules = append(rules, rule)
  2780. }
  2781. err = rows.Err()
  2782. if err != nil {
  2783. return rules, err
  2784. }
  2785. rules, err = getRulesWithActions(ctx, rules, dbHandle)
  2786. if err != nil {
  2787. return rules, err
  2788. }
  2789. for idx := range rules {
  2790. rules[idx].PrepareForRendering()
  2791. }
  2792. return rules, nil
  2793. }
  2794. func sqlCommonAddEventRule(rule *EventRule, dbHandle *sql.DB) error {
  2795. if err := rule.validate(); err != nil {
  2796. return err
  2797. }
  2798. conditions, err := json.Marshal(rule.Conditions)
  2799. if err != nil {
  2800. return err
  2801. }
  2802. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2803. defer cancel()
  2804. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  2805. if config.IsShared == 1 {
  2806. _, err := tx.ExecContext(ctx, getRemoveSoftDeletedRuleQuery(), rule.Name)
  2807. if err != nil {
  2808. return err
  2809. }
  2810. }
  2811. q := getAddEventRuleQuery()
  2812. _, err := tx.ExecContext(ctx, q, rule.Name, rule.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
  2813. util.GetTimeAsMsSinceEpoch(time.Now()), rule.Trigger, string(conditions))
  2814. if err != nil {
  2815. return err
  2816. }
  2817. return generateEventRuleActionsMapping(ctx, rule, tx)
  2818. })
  2819. }
  2820. func sqlCommonUpdateEventRule(rule *EventRule, dbHandle *sql.DB) error {
  2821. if err := rule.validate(); err != nil {
  2822. return err
  2823. }
  2824. conditions, err := json.Marshal(rule.Conditions)
  2825. if err != nil {
  2826. return err
  2827. }
  2828. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2829. defer cancel()
  2830. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  2831. q := getUpdateEventRuleQuery()
  2832. _, err := tx.ExecContext(ctx, q, rule.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
  2833. rule.Trigger, string(conditions), rule.Name)
  2834. if err != nil {
  2835. return err
  2836. }
  2837. return generateEventRuleActionsMapping(ctx, rule, tx)
  2838. })
  2839. }
  2840. func sqlCommonDeleteEventRule(rule EventRule, softDelete bool, dbHandle *sql.DB) error {
  2841. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2842. defer cancel()
  2843. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  2844. if softDelete {
  2845. q := getClearRuleActionMappingQuery()
  2846. _, err := tx.ExecContext(ctx, q, rule.Name)
  2847. if err != nil {
  2848. return err
  2849. }
  2850. }
  2851. q := getDeleteEventRuleQuery(softDelete)
  2852. if softDelete {
  2853. ts := util.GetTimeAsMsSinceEpoch(time.Now())
  2854. res, err := tx.ExecContext(ctx, q, ts, ts, rule.Name)
  2855. if err != nil {
  2856. return err
  2857. }
  2858. return sqlCommonRequireRowAffected(res)
  2859. }
  2860. res, err := tx.ExecContext(ctx, q, rule.Name)
  2861. if err != nil {
  2862. return err
  2863. }
  2864. if err = sqlCommonRequireRowAffected(res); err != nil {
  2865. return err
  2866. }
  2867. return sqlCommonDeleteTask(rule.Name, tx)
  2868. })
  2869. }
  2870. func sqlCommonGetTaskByName(name string, dbHandle sqlQuerier) (Task, error) {
  2871. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2872. defer cancel()
  2873. task := Task{
  2874. Name: name,
  2875. }
  2876. q := getTaskByNameQuery()
  2877. row := dbHandle.QueryRowContext(ctx, q, name)
  2878. err := row.Scan(&task.UpdateAt, &task.Version)
  2879. if err != nil {
  2880. if errors.Is(err, sql.ErrNoRows) {
  2881. return task, util.NewRecordNotFoundError(err.Error())
  2882. }
  2883. }
  2884. return task, err
  2885. }
  2886. func sqlCommonAddTask(name string, dbHandle *sql.DB) error {
  2887. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2888. defer cancel()
  2889. q := getAddTaskQuery()
  2890. _, err := dbHandle.ExecContext(ctx, q, name, util.GetTimeAsMsSinceEpoch(time.Now()))
  2891. return err
  2892. }
  2893. func sqlCommonUpdateTask(name string, version int64, dbHandle *sql.DB) error {
  2894. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2895. defer cancel()
  2896. q := getUpdateTaskQuery()
  2897. res, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), name, version)
  2898. if err != nil {
  2899. return err
  2900. }
  2901. return sqlCommonRequireRowAffected(res)
  2902. }
  2903. func sqlCommonUpdateTaskTimestamp(name string, dbHandle *sql.DB) error {
  2904. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2905. defer cancel()
  2906. q := getUpdateTaskTimestampQuery()
  2907. res, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), name)
  2908. if err != nil {
  2909. return err
  2910. }
  2911. return sqlCommonRequireRowAffected(res)
  2912. }
  2913. func sqlCommonDeleteTask(name string, dbHandle sqlQuerier) error {
  2914. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2915. defer cancel()
  2916. q := getDeleteTaskQuery()
  2917. _, err := dbHandle.ExecContext(ctx, q, name)
  2918. return err
  2919. }
  2920. func sqlCommonAddNode(dbHandle *sql.DB) error {
  2921. if err := currentNode.validate(); err != nil {
  2922. return fmt.Errorf("unable to register cluster node: %w", err)
  2923. }
  2924. data, err := json.Marshal(currentNode.Data)
  2925. if err != nil {
  2926. return err
  2927. }
  2928. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2929. defer cancel()
  2930. q := getAddNodeQuery()
  2931. _, err = dbHandle.ExecContext(ctx, q, currentNode.Name, string(data), util.GetTimeAsMsSinceEpoch(time.Now()),
  2932. util.GetTimeAsMsSinceEpoch(time.Now()))
  2933. if err != nil {
  2934. return fmt.Errorf("unable to register cluster node: %w", err)
  2935. }
  2936. providerLog(logger.LevelInfo, "registered as cluster node %q, port: %d, proto: %s",
  2937. currentNode.Name, currentNode.Data.Port, currentNode.Data.Proto)
  2938. return nil
  2939. }
  2940. func sqlCommonGetNodeByName(name string, dbHandle *sql.DB) (Node, error) {
  2941. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2942. defer cancel()
  2943. var data []byte
  2944. var node Node
  2945. q := getNodeByNameQuery()
  2946. row := dbHandle.QueryRowContext(ctx, q, name, util.GetTimeAsMsSinceEpoch(time.Now().Add(activeNodeTimeDiff)))
  2947. err := row.Scan(&node.Name, &data, &node.CreatedAt, &node.UpdatedAt)
  2948. if err != nil {
  2949. if errors.Is(err, sql.ErrNoRows) {
  2950. return node, util.NewRecordNotFoundError(err.Error())
  2951. }
  2952. return node, err
  2953. }
  2954. err = json.Unmarshal(data, &node.Data)
  2955. return node, err
  2956. }
  2957. func sqlCommonGetNodes(dbHandle *sql.DB) ([]Node, error) {
  2958. var nodes []Node
  2959. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2960. defer cancel()
  2961. q := getNodesQuery()
  2962. rows, err := dbHandle.QueryContext(ctx, q, currentNode.Name,
  2963. util.GetTimeAsMsSinceEpoch(time.Now().Add(activeNodeTimeDiff)))
  2964. if err != nil {
  2965. return nodes, err
  2966. }
  2967. defer rows.Close()
  2968. for rows.Next() {
  2969. var node Node
  2970. var data []byte
  2971. err = rows.Scan(&node.Name, &data, &node.CreatedAt, &node.UpdatedAt)
  2972. if err != nil {
  2973. return nodes, err
  2974. }
  2975. err = json.Unmarshal(data, &node.Data)
  2976. if err != nil {
  2977. return nodes, err
  2978. }
  2979. nodes = append(nodes, node)
  2980. }
  2981. return nodes, rows.Err()
  2982. }
  2983. func sqlCommonUpdateNodeTimestamp(dbHandle *sql.DB) error {
  2984. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2985. defer cancel()
  2986. q := getUpdateNodeTimestampQuery()
  2987. res, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now()), currentNode.Name)
  2988. if err != nil {
  2989. return err
  2990. }
  2991. return sqlCommonRequireRowAffected(res)
  2992. }
  2993. func sqlCommonCleanupNodes(dbHandle *sql.DB) error {
  2994. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  2995. defer cancel()
  2996. q := getCleanupNodesQuery()
  2997. _, err := dbHandle.ExecContext(ctx, q, util.GetTimeAsMsSinceEpoch(time.Now().Add(10*activeNodeTimeDiff)))
  2998. return err
  2999. }
  3000. func sqlCommonGetDatabaseVersion(dbHandle sqlQuerier, showInitWarn bool) (schemaVersion, error) {
  3001. var result schemaVersion
  3002. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  3003. defer cancel()
  3004. q := getDatabaseVersionQuery()
  3005. stmt, err := dbHandle.PrepareContext(ctx, q)
  3006. if err != nil {
  3007. providerLog(logger.LevelError, "error preparing database query %#v: %v", q, err)
  3008. if showInitWarn && strings.Contains(err.Error(), sqlTableSchemaVersion) {
  3009. logger.WarnToConsole("database query error, did you forgot to run the \"initprovider\" command?")
  3010. }
  3011. return result, err
  3012. }
  3013. defer stmt.Close()
  3014. row := stmt.QueryRowContext(ctx)
  3015. err = row.Scan(&result.Version)
  3016. return result, err
  3017. }
  3018. func sqlCommonRequireRowAffected(res sql.Result) error {
  3019. // MariaDB/MySQL returns 0 rows affected for updates that don't change anything
  3020. // so we don't check rows affected for updates
  3021. affected, err := res.RowsAffected()
  3022. if err == nil && affected == 0 {
  3023. return util.NewRecordNotFoundError(sql.ErrNoRows.Error())
  3024. }
  3025. return nil
  3026. }
  3027. func sqlCommonUpdateDatabaseVersion(ctx context.Context, dbHandle sqlQuerier, version int) error {
  3028. q := getUpdateDBVersionQuery()
  3029. _, err := dbHandle.ExecContext(ctx, q, version)
  3030. return err
  3031. }
  3032. func sqlCommonExecSQLAndUpdateDBVersion(dbHandle *sql.DB, sqlQueries []string, newVersion int, isUp bool) error {
  3033. if err := sqlAcquireLock(dbHandle); err != nil {
  3034. return err
  3035. }
  3036. defer sqlReleaseLock(dbHandle)
  3037. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  3038. defer cancel()
  3039. if newVersion > 0 {
  3040. currentVersion, err := sqlCommonGetDatabaseVersion(dbHandle, false)
  3041. if err == nil {
  3042. if (isUp && currentVersion.Version >= newVersion) || (!isUp && currentVersion.Version <= newVersion) {
  3043. providerLog(logger.LevelInfo, "current schema version: %v, requested: %v, did you execute simultaneous migrations?",
  3044. currentVersion.Version, newVersion)
  3045. return nil
  3046. }
  3047. }
  3048. }
  3049. return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
  3050. for _, q := range sqlQueries {
  3051. if strings.TrimSpace(q) == "" {
  3052. continue
  3053. }
  3054. _, err := tx.ExecContext(ctx, q)
  3055. if err != nil {
  3056. return err
  3057. }
  3058. }
  3059. if newVersion == 0 {
  3060. return nil
  3061. }
  3062. return sqlCommonUpdateDatabaseVersion(ctx, tx, newVersion)
  3063. })
  3064. }
  3065. func sqlAcquireLock(dbHandle *sql.DB) error {
  3066. ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
  3067. defer cancel()
  3068. switch config.Driver {
  3069. case PGSQLDataProviderName:
  3070. _, err := dbHandle.ExecContext(ctx, `SELECT pg_advisory_lock(101,1)`)
  3071. if err != nil {
  3072. return fmt.Errorf("unable to get advisory lock: %w", err)
  3073. }
  3074. providerLog(logger.LevelInfo, "acquired database lock")
  3075. case MySQLDataProviderName:
  3076. var lockResult sql.NullInt64
  3077. err := dbHandle.QueryRowContext(ctx, `SELECT GET_LOCK('sftpgo.migration',30)`).Scan(&lockResult)
  3078. if err != nil {
  3079. return fmt.Errorf("unable to get lock: %w", err)
  3080. }
  3081. if !lockResult.Valid {
  3082. return errors.New("unable to get lock: null value returned")
  3083. }
  3084. if lockResult.Int64 != 1 {
  3085. return fmt.Errorf("unable to get lock, result: %d", lockResult.Int64)
  3086. }
  3087. providerLog(logger.LevelInfo, "acquired database lock")
  3088. }
  3089. return nil
  3090. }
  3091. func sqlReleaseLock(dbHandle *sql.DB) {
  3092. ctx, cancel := context.WithTimeout(context.Background(), defaultSQLQueryTimeout)
  3093. defer cancel()
  3094. switch config.Driver {
  3095. case PGSQLDataProviderName:
  3096. _, err := dbHandle.ExecContext(ctx, `SELECT pg_advisory_unlock(101,1)`)
  3097. if err != nil {
  3098. providerLog(logger.LevelWarn, "unable to release lock: %v", err)
  3099. } else {
  3100. providerLog(logger.LevelInfo, "released database lock")
  3101. }
  3102. case MySQLDataProviderName:
  3103. _, err := dbHandle.ExecContext(ctx, `SELECT RELEASE_LOCK('sftpgo.migration')`)
  3104. if err != nil {
  3105. providerLog(logger.LevelWarn, "unable to release lock: %v", err)
  3106. } else {
  3107. providerLog(logger.LevelInfo, "released database lock")
  3108. }
  3109. }
  3110. }
  3111. func sqlCommonExecuteTx(ctx context.Context, dbHandle *sql.DB, txFn func(*sql.Tx) error) error {
  3112. if config.Driver == CockroachDataProviderName {
  3113. return crdb.ExecuteTx(ctx, dbHandle, nil, txFn)
  3114. }
  3115. tx, err := dbHandle.BeginTx(ctx, nil)
  3116. if err != nil {
  3117. return err
  3118. }
  3119. err = txFn(tx)
  3120. if err != nil {
  3121. // we don't change the returned error
  3122. tx.Rollback() //nolint:errcheck
  3123. return err
  3124. }
  3125. return tx.Commit()
  3126. }