sqlcommon.go 89 KB

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