server.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. package httpd
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "errors"
  7. "fmt"
  8. "log"
  9. "net"
  10. "net/http"
  11. "time"
  12. "github.com/go-chi/chi/v5"
  13. "github.com/go-chi/chi/v5/middleware"
  14. "github.com/go-chi/jwtauth/v5"
  15. "github.com/go-chi/render"
  16. "github.com/lestrrat-go/jwx/jwa"
  17. "github.com/rs/xid"
  18. "github.com/drakkan/sftpgo/common"
  19. "github.com/drakkan/sftpgo/dataprovider"
  20. "github.com/drakkan/sftpgo/logger"
  21. "github.com/drakkan/sftpgo/utils"
  22. "github.com/drakkan/sftpgo/version"
  23. )
  24. var (
  25. compressor = middleware.NewCompressor(5)
  26. xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Proto")
  27. )
  28. type httpdServer struct {
  29. binding Binding
  30. staticFilesPath string
  31. enableWebAdmin bool
  32. enableWebClient bool
  33. router *chi.Mux
  34. tokenAuth *jwtauth.JWTAuth
  35. }
  36. func newHttpdServer(b Binding, staticFilesPath string) *httpdServer {
  37. return &httpdServer{
  38. binding: b,
  39. staticFilesPath: staticFilesPath,
  40. enableWebAdmin: b.EnableWebAdmin,
  41. enableWebClient: b.EnableWebClient,
  42. }
  43. }
  44. func (s *httpdServer) listenAndServe() error {
  45. s.initializeRouter()
  46. httpServer := &http.Server{
  47. Handler: s.router,
  48. ReadHeaderTimeout: 30 * time.Second,
  49. ReadTimeout: 60 * time.Second,
  50. WriteTimeout: 60 * time.Second,
  51. IdleTimeout: 60 * time.Second,
  52. MaxHeaderBytes: 1 << 16, // 64KB
  53. ErrorLog: log.New(&logger.StdLoggerWrapper{Sender: logSender}, "", 0),
  54. }
  55. if certMgr != nil && s.binding.EnableHTTPS {
  56. config := &tls.Config{
  57. GetCertificate: certMgr.GetCertificateFunc(),
  58. MinVersion: tls.VersionTLS12,
  59. CipherSuites: utils.GetTLSCiphersFromNames(s.binding.TLSCipherSuites),
  60. PreferServerCipherSuites: true,
  61. }
  62. logger.Debug(logSender, "", "configured TLS cipher suites for binding %#v: %v", s.binding.GetAddress(),
  63. config.CipherSuites)
  64. httpServer.TLSConfig = config
  65. if s.binding.ClientAuthType == 1 {
  66. httpServer.TLSConfig.ClientCAs = certMgr.GetRootCAs()
  67. httpServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
  68. httpServer.TLSConfig.VerifyConnection = s.verifyTLSConnection
  69. }
  70. return utils.HTTPListenAndServe(httpServer, s.binding.Address, s.binding.Port, true, logSender)
  71. }
  72. return utils.HTTPListenAndServe(httpServer, s.binding.Address, s.binding.Port, false, logSender)
  73. }
  74. func (s *httpdServer) verifyTLSConnection(state tls.ConnectionState) error {
  75. if certMgr != nil {
  76. var clientCrt *x509.Certificate
  77. var clientCrtName string
  78. if len(state.PeerCertificates) > 0 {
  79. clientCrt = state.PeerCertificates[0]
  80. clientCrtName = clientCrt.Subject.String()
  81. }
  82. if len(state.VerifiedChains) == 0 {
  83. logger.Warn(logSender, "", "TLS connection cannot be verified: unable to get verification chain")
  84. return errors.New("TLS connection cannot be verified: unable to get verification chain")
  85. }
  86. for _, verifiedChain := range state.VerifiedChains {
  87. var caCrt *x509.Certificate
  88. if len(verifiedChain) > 0 {
  89. caCrt = verifiedChain[len(verifiedChain)-1]
  90. }
  91. if certMgr.IsRevoked(clientCrt, caCrt) {
  92. logger.Debug(logSender, "", "tls handshake error, client certificate %#v has been revoked", clientCrtName)
  93. return common.ErrCrtRevoked
  94. }
  95. }
  96. }
  97. return nil
  98. }
  99. func (s *httpdServer) refreshCookie(next http.Handler) http.Handler {
  100. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  101. s.checkCookieExpiration(w, r)
  102. next.ServeHTTP(w, r)
  103. })
  104. }
  105. func (s *httpdServer) handleWebClientLoginPost(w http.ResponseWriter, r *http.Request) {
  106. r.Body = http.MaxBytesReader(w, r.Body, maxLoginPostSize)
  107. if err := r.ParseForm(); err != nil {
  108. renderClientLoginPage(w, err.Error())
  109. return
  110. }
  111. username := r.Form.Get("username")
  112. password := r.Form.Get("password")
  113. if username == "" || password == "" {
  114. renderClientLoginPage(w, "Invalid credentials")
  115. return
  116. }
  117. if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
  118. renderClientLoginPage(w, err.Error())
  119. return
  120. }
  121. ipAddr := utils.GetIPFromRemoteAddress(r.RemoteAddr)
  122. if err := common.Config.ExecutePostConnectHook(ipAddr, common.ProtocolHTTP); err != nil {
  123. renderClientLoginPage(w, fmt.Sprintf("access denied by post connect hook: %v", err))
  124. return
  125. }
  126. user, err := dataprovider.CheckUserAndPass(username, password, ipAddr, common.ProtocolHTTP)
  127. if err != nil {
  128. updateLoginMetrics(&user, ipAddr, err)
  129. renderClientLoginPage(w, dataprovider.ErrInvalidCredentials.Error())
  130. return
  131. }
  132. connectionID := fmt.Sprintf("%v_%v", common.ProtocolHTTP, xid.New().String())
  133. if err := checkWebClientUser(&user, r, connectionID); err != nil {
  134. updateLoginMetrics(&user, ipAddr, err)
  135. renderClientLoginPage(w, err.Error())
  136. return
  137. }
  138. defer user.CloseFs() //nolint:errcheck
  139. err = user.CheckFsRoot(connectionID)
  140. if err != nil {
  141. logger.Warn(logSender, connectionID, "unable to check fs root: %v", err)
  142. updateLoginMetrics(&user, ipAddr, err)
  143. renderClientLoginPage(w, err.Error())
  144. return
  145. }
  146. c := jwtTokenClaims{
  147. Username: user.Username,
  148. Permissions: user.Filters.WebClient,
  149. Signature: user.GetSignature(),
  150. }
  151. err = c.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebClient)
  152. if err != nil {
  153. logger.Warn(logSender, connectionID, "unable to set client login cookie %v", err)
  154. updateLoginMetrics(&user, ipAddr, err)
  155. renderClientLoginPage(w, err.Error())
  156. return
  157. }
  158. updateLoginMetrics(&user, ipAddr, err)
  159. http.Redirect(w, r, webClientFilesPath, http.StatusFound)
  160. }
  161. func (s *httpdServer) handleWebAdminLoginPost(w http.ResponseWriter, r *http.Request) {
  162. r.Body = http.MaxBytesReader(w, r.Body, maxLoginPostSize)
  163. if err := r.ParseForm(); err != nil {
  164. renderLoginPage(w, err.Error())
  165. return
  166. }
  167. username := r.Form.Get("username")
  168. password := r.Form.Get("password")
  169. if username == "" || password == "" {
  170. renderLoginPage(w, "Invalid credentials")
  171. return
  172. }
  173. if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
  174. renderLoginPage(w, err.Error())
  175. return
  176. }
  177. admin, err := dataprovider.CheckAdminAndPass(username, password, utils.GetIPFromRemoteAddress(r.RemoteAddr))
  178. if err != nil {
  179. renderLoginPage(w, err.Error())
  180. return
  181. }
  182. s.loginAdmin(w, r, &admin)
  183. }
  184. func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Request) {
  185. r.Body = http.MaxBytesReader(w, r.Body, maxLoginPostSize)
  186. if dataprovider.HasAdmin() {
  187. renderBadRequestPage(w, r, errors.New("an admin user already exists"))
  188. return
  189. }
  190. err := r.ParseForm()
  191. if err != nil {
  192. renderAdminSetupPage(w, r, "", err.Error())
  193. return
  194. }
  195. if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
  196. renderForbiddenPage(w, r, err.Error())
  197. return
  198. }
  199. username := r.Form.Get("username")
  200. password := r.Form.Get("password")
  201. confirmPassword := r.Form.Get("confirm_password")
  202. if username == "" {
  203. renderAdminSetupPage(w, r, username, "Please set a username")
  204. return
  205. }
  206. if password == "" {
  207. renderAdminSetupPage(w, r, username, "Please set a password")
  208. return
  209. }
  210. if password != confirmPassword {
  211. renderAdminSetupPage(w, r, username, "Passwords mismatch")
  212. return
  213. }
  214. admin := dataprovider.Admin{
  215. Username: username,
  216. Password: password,
  217. Status: 1,
  218. Permissions: []string{dataprovider.PermAdminAny},
  219. }
  220. err = dataprovider.AddAdmin(&admin)
  221. if err != nil {
  222. renderAdminSetupPage(w, r, username, err.Error())
  223. return
  224. }
  225. s.loginAdmin(w, r, &admin)
  226. }
  227. func (s *httpdServer) loginAdmin(w http.ResponseWriter, r *http.Request, admin *dataprovider.Admin) {
  228. c := jwtTokenClaims{
  229. Username: admin.Username,
  230. Permissions: admin.Permissions,
  231. Signature: admin.GetSignature(),
  232. }
  233. err := c.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebAdmin)
  234. if err != nil {
  235. logger.Warn(logSender, "", "unable to set admin login cookie %v", err)
  236. renderLoginPage(w, err.Error())
  237. return
  238. }
  239. http.Redirect(w, r, webUsersPath, http.StatusFound)
  240. }
  241. func (s *httpdServer) logout(w http.ResponseWriter, r *http.Request) {
  242. invalidateToken(r)
  243. sendAPIResponse(w, r, nil, "Your token has been invalidated", http.StatusOK)
  244. }
  245. func (s *httpdServer) getToken(w http.ResponseWriter, r *http.Request) {
  246. username, password, ok := r.BasicAuth()
  247. if !ok {
  248. w.Header().Set(common.HTTPAuthenticationHeader, basicRealm)
  249. sendAPIResponse(w, r, nil, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
  250. return
  251. }
  252. admin, err := dataprovider.CheckAdminAndPass(username, password, utils.GetIPFromRemoteAddress(r.RemoteAddr))
  253. if err != nil {
  254. w.Header().Set(common.HTTPAuthenticationHeader, basicRealm)
  255. sendAPIResponse(w, r, err, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
  256. return
  257. }
  258. s.generateAndSendToken(w, r, admin)
  259. }
  260. func (s *httpdServer) generateAndSendToken(w http.ResponseWriter, r *http.Request, admin dataprovider.Admin) {
  261. c := jwtTokenClaims{
  262. Username: admin.Username,
  263. Permissions: admin.Permissions,
  264. Signature: admin.GetSignature(),
  265. }
  266. resp, err := c.createTokenResponse(s.tokenAuth, tokenAudienceAPI)
  267. if err != nil {
  268. sendAPIResponse(w, r, err, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  269. return
  270. }
  271. render.JSON(w, r, resp)
  272. }
  273. func (s *httpdServer) checkCookieExpiration(w http.ResponseWriter, r *http.Request) {
  274. token, claims, err := jwtauth.FromContext(r.Context())
  275. if err != nil {
  276. return
  277. }
  278. tokenClaims := jwtTokenClaims{}
  279. tokenClaims.Decode(claims)
  280. if tokenClaims.Username == "" || tokenClaims.Signature == "" {
  281. return
  282. }
  283. if time.Until(token.Expiration()) > tokenRefreshMin {
  284. return
  285. }
  286. if utils.IsStringInSlice(tokenAudienceWebClient, token.Audience()) {
  287. s.refreshClientToken(w, r, tokenClaims)
  288. } else {
  289. s.refreshAdminToken(w, r, tokenClaims)
  290. }
  291. }
  292. func (s *httpdServer) refreshClientToken(w http.ResponseWriter, r *http.Request, tokenClaims jwtTokenClaims) {
  293. user, err := dataprovider.UserExists(tokenClaims.Username)
  294. if err != nil {
  295. return
  296. }
  297. if user.GetSignature() != tokenClaims.Signature {
  298. logger.Debug(logSender, "", "signature mismatch for user %#v, unable to refresh cookie", user.Username)
  299. return
  300. }
  301. if err := checkWebClientUser(&user, r, xid.New().String()); err != nil {
  302. logger.Debug(logSender, "", "unable to refresh cookie for user %#v: %v", user.Username, err)
  303. return
  304. }
  305. logger.Debug(logSender, "", "cookie refreshed for user %#v", user.Username)
  306. tokenClaims.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebClient) //nolint:errcheck
  307. }
  308. func (s *httpdServer) refreshAdminToken(w http.ResponseWriter, r *http.Request, tokenClaims jwtTokenClaims) {
  309. admin, err := dataprovider.AdminExists(tokenClaims.Username)
  310. if err != nil {
  311. return
  312. }
  313. if admin.Status != 1 {
  314. logger.Debug(logSender, "", "admin %#v is disabled, unable to refresh cookie", admin.Username)
  315. return
  316. }
  317. if admin.GetSignature() != tokenClaims.Signature {
  318. logger.Debug(logSender, "", "signature mismatch for admin %#v, unable to refresh cookie", admin.Username)
  319. return
  320. }
  321. if !admin.CanLoginFromIP(utils.GetIPFromRemoteAddress(r.RemoteAddr)) {
  322. logger.Debug(logSender, "", "admin %#v cannot login from %v, unable to refresh cookie", admin.Username, r.RemoteAddr)
  323. return
  324. }
  325. logger.Debug(logSender, "", "cookie refreshed for admin %#v", admin.Username)
  326. tokenClaims.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebAdmin) //nolint:errcheck
  327. }
  328. func (s *httpdServer) updateContextFromCookie(r *http.Request) *http.Request {
  329. token, _, err := jwtauth.FromContext(r.Context())
  330. if token == nil || err != nil {
  331. _, err = r.Cookie("jwt")
  332. if err != nil {
  333. return r
  334. }
  335. token, err = jwtauth.VerifyRequest(s.tokenAuth, r, jwtauth.TokenFromCookie)
  336. ctx := jwtauth.NewContext(r.Context(), token, err)
  337. return r.WithContext(ctx)
  338. }
  339. return r
  340. }
  341. func (s *httpdServer) checkConnection(next http.Handler) http.Handler {
  342. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  343. ipAddr := utils.GetIPFromRemoteAddress(r.RemoteAddr)
  344. ip := net.ParseIP(ipAddr)
  345. if ip != nil {
  346. for _, allow := range s.binding.allowHeadersFrom {
  347. if allow(ip) {
  348. parsedIP := utils.GetRealIP(r)
  349. if parsedIP != "" {
  350. ipAddr = parsedIP
  351. r.RemoteAddr = ipAddr
  352. }
  353. if forwardedProto := r.Header.Get(xForwardedProto); forwardedProto != "" {
  354. ctx := context.WithValue(r.Context(), forwardedProtoKey, forwardedProto)
  355. r = r.WithContext(ctx)
  356. }
  357. break
  358. }
  359. }
  360. }
  361. common.Connections.AddClientConnection(ipAddr)
  362. defer common.Connections.RemoveClientConnection(ipAddr)
  363. if !common.Connections.IsNewConnectionAllowed(ipAddr) {
  364. logger.Log(logger.LevelDebug, common.ProtocolHTTP, "", "connection refused, configured limit reached")
  365. s.sendForbiddenResponse(w, r, "configured connections limit reached")
  366. return
  367. }
  368. if common.IsBanned(ipAddr) {
  369. s.sendForbiddenResponse(w, r, "your IP address is banned")
  370. return
  371. }
  372. if delay, err := common.LimitRate(common.ProtocolHTTP, ipAddr); err != nil {
  373. delay += 499999999 * time.Nanosecond
  374. w.Header().Set("Retry-After", fmt.Sprintf("%.0f", delay.Seconds()))
  375. w.Header().Set("X-Retry-In", delay.String())
  376. s.sendTooManyRequestResponse(w, r, err)
  377. return
  378. }
  379. next.ServeHTTP(w, r)
  380. })
  381. }
  382. func (s *httpdServer) sendTooManyRequestResponse(w http.ResponseWriter, r *http.Request, err error) {
  383. if (s.enableWebAdmin || s.enableWebClient) && isWebRequest(r) {
  384. r = s.updateContextFromCookie(r)
  385. if s.enableWebClient && (isWebClientRequest(r) || !s.enableWebAdmin) {
  386. renderClientMessagePage(w, r, http.StatusText(http.StatusTooManyRequests), "Rate limit exceeded",
  387. http.StatusTooManyRequests, err, "")
  388. return
  389. }
  390. renderMessagePage(w, r, http.StatusText(http.StatusTooManyRequests), "Rate limit exceeded", http.StatusTooManyRequests,
  391. err, "")
  392. return
  393. }
  394. sendAPIResponse(w, r, err, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
  395. }
  396. func (s *httpdServer) sendForbiddenResponse(w http.ResponseWriter, r *http.Request, message string) {
  397. if (s.enableWebAdmin || s.enableWebClient) && isWebRequest(r) {
  398. r = s.updateContextFromCookie(r)
  399. if s.enableWebClient && (isWebClientRequest(r) || !s.enableWebAdmin) {
  400. renderClientForbiddenPage(w, r, message)
  401. return
  402. }
  403. renderForbiddenPage(w, r, message)
  404. return
  405. }
  406. sendAPIResponse(w, r, errors.New(message), message, http.StatusForbidden)
  407. }
  408. func (s *httpdServer) redirectToWebPath(w http.ResponseWriter, r *http.Request, webPath string) {
  409. if dataprovider.HasAdmin() {
  410. http.Redirect(w, r, webPath, http.StatusMovedPermanently)
  411. return
  412. }
  413. if s.enableWebAdmin {
  414. http.Redirect(w, r, webAdminSetupPath, http.StatusFound)
  415. }
  416. }
  417. func (s *httpdServer) initializeRouter() {
  418. s.tokenAuth = jwtauth.New(jwa.HS256.String(), utils.GenerateRandomBytes(32), nil)
  419. s.router = chi.NewRouter()
  420. s.router.Use(middleware.RequestID)
  421. s.router.Use(logger.NewStructuredLogger(logger.GetLogger()))
  422. s.router.Use(recoverer)
  423. s.router.Use(s.checkConnection)
  424. s.router.Use(middleware.GetHead)
  425. s.router.Use(middleware.StripSlashes)
  426. s.router.NotFound(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  427. if (s.enableWebAdmin || s.enableWebClient) && isWebRequest(r) {
  428. r = s.updateContextFromCookie(r)
  429. if s.enableWebClient && (isWebClientRequest(r) || !s.enableWebAdmin) {
  430. renderClientNotFoundPage(w, r, nil)
  431. return
  432. }
  433. renderNotFoundPage(w, r, nil)
  434. return
  435. }
  436. sendAPIResponse(w, r, nil, http.StatusText(http.StatusNotFound), http.StatusNotFound)
  437. }))
  438. s.router.Get(healthzPath, func(w http.ResponseWriter, r *http.Request) {
  439. render.PlainText(w, r, "ok")
  440. })
  441. s.router.Get(tokenPath, s.getToken)
  442. s.router.Group(func(router chi.Router) {
  443. router.Use(jwtauth.Verify(s.tokenAuth, jwtauth.TokenFromHeader))
  444. router.Use(jwtAuthenticatorAPI)
  445. router.Get(versionPath, func(w http.ResponseWriter, r *http.Request) {
  446. render.JSON(w, r, version.Get())
  447. })
  448. router.Get(logoutPath, s.logout)
  449. router.Put(adminPwdPath, changeAdminPassword)
  450. router.With(checkPerm(dataprovider.PermAdminViewServerStatus)).
  451. Get(serverStatusPath, func(w http.ResponseWriter, r *http.Request) {
  452. render.JSON(w, r, getServicesStatus())
  453. })
  454. router.With(checkPerm(dataprovider.PermAdminViewConnections)).
  455. Get(activeConnectionsPath, func(w http.ResponseWriter, r *http.Request) {
  456. render.JSON(w, r, common.Connections.GetStats())
  457. })
  458. router.With(checkPerm(dataprovider.PermAdminCloseConnections)).
  459. Delete(activeConnectionsPath+"/{connectionID}", handleCloseConnection)
  460. router.With(checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotaScanPath, getQuotaScans)
  461. router.With(checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotaScanPath, startQuotaScan)
  462. router.With(checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotaScanVFolderPath, getVFolderQuotaScans)
  463. router.With(checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotaScanVFolderPath, startVFolderQuotaScan)
  464. router.With(checkPerm(dataprovider.PermAdminViewUsers)).Get(userPath, getUsers)
  465. router.With(checkPerm(dataprovider.PermAdminAddUsers)).Post(userPath, addUser)
  466. router.With(checkPerm(dataprovider.PermAdminViewUsers)).Get(userPath+"/{username}", getUserByUsername)
  467. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}", updateUser)
  468. router.With(checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(userPath+"/{username}", deleteUser)
  469. router.With(checkPerm(dataprovider.PermAdminViewUsers)).Get(folderPath, getFolders)
  470. router.With(checkPerm(dataprovider.PermAdminViewUsers)).Get(folderPath+"/{name}", getFolderByName)
  471. router.With(checkPerm(dataprovider.PermAdminAddUsers)).Post(folderPath, addFolder)
  472. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Put(folderPath+"/{name}", updateFolder)
  473. router.With(checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(folderPath+"/{name}", deleteFolder)
  474. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Get(dumpDataPath, dumpData)
  475. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Get(loadDataPath, loadData)
  476. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Post(loadDataPath, loadDataFromRequest)
  477. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Put(updateUsedQuotaPath, updateUserQuotaUsage)
  478. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Put(updateFolderUsedQuotaPath, updateVFolderQuotaUsage)
  479. router.With(checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderBanTime, getBanTime)
  480. router.With(checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderScore, getScore)
  481. router.With(checkPerm(dataprovider.PermAdminManageDefender)).Post(defenderUnban, unban)
  482. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath, getAdmins)
  483. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Post(adminPath, addAdmin)
  484. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath+"/{username}", getAdminByUsername)
  485. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Put(adminPath+"/{username}", updateAdmin)
  486. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Delete(adminPath+"/{username}", deleteAdmin)
  487. })
  488. if s.enableWebAdmin || s.enableWebClient {
  489. s.router.Group(func(router chi.Router) {
  490. router.Use(compressor.Handler)
  491. fileServer(router, webStaticFilesPath, http.Dir(s.staticFilesPath))
  492. })
  493. if s.enableWebClient {
  494. s.router.Get(webRootPath, func(w http.ResponseWriter, r *http.Request) {
  495. s.redirectToWebPath(w, r, webClientLoginPath)
  496. })
  497. s.router.Get(webBasePath, func(w http.ResponseWriter, r *http.Request) {
  498. s.redirectToWebPath(w, r, webClientLoginPath)
  499. })
  500. } else {
  501. s.router.Get(webRootPath, func(w http.ResponseWriter, r *http.Request) {
  502. s.redirectToWebPath(w, r, webLoginPath)
  503. })
  504. s.router.Get(webBasePath, func(w http.ResponseWriter, r *http.Request) {
  505. s.redirectToWebPath(w, r, webLoginPath)
  506. })
  507. }
  508. }
  509. if s.enableWebClient {
  510. s.router.Get(webBaseClientPath, func(w http.ResponseWriter, r *http.Request) {
  511. http.Redirect(w, r, webClientLoginPath, http.StatusMovedPermanently)
  512. })
  513. s.router.Get(webClientLoginPath, handleClientWebLogin)
  514. s.router.Post(webClientLoginPath, s.handleWebClientLoginPost)
  515. s.router.Group(func(router chi.Router) {
  516. router.Use(jwtauth.Verify(s.tokenAuth, jwtauth.TokenFromCookie))
  517. router.Use(jwtAuthenticatorWebClient)
  518. router.Get(webClientLogoutPath, handleWebClientLogout)
  519. router.With(s.refreshCookie).Get(webClientFilesPath, handleClientGetFiles)
  520. router.With(compressor.Handler, s.refreshCookie).Get(webClientDirContentsPath, handleClientGetDirContents)
  521. router.With(s.refreshCookie).Get(webClientDownloadPath, handleWebClientDownload)
  522. router.With(s.refreshCookie).Get(webClientCredentialsPath, handleClientGetCredentials)
  523. router.Post(webChangeClientPwdPath, handleWebClientChangePwdPost)
  524. router.With(checkClientPerm(dataprovider.WebClientPubKeyChangeDisabled)).
  525. Post(webChangeClientKeysPath, handleWebClientManageKeysPost)
  526. })
  527. }
  528. if s.enableWebAdmin {
  529. s.router.Get(webBaseAdminPath, func(w http.ResponseWriter, r *http.Request) {
  530. s.redirectToWebPath(w, r, webLoginPath)
  531. })
  532. s.router.Get(webLoginPath, handleWebLogin)
  533. s.router.Post(webLoginPath, s.handleWebAdminLoginPost)
  534. s.router.Get(webAdminSetupPath, handleWebAdminSetupGet)
  535. s.router.Post(webAdminSetupPath, s.handleWebAdminSetupPost)
  536. s.router.Group(func(router chi.Router) {
  537. router.Use(jwtauth.Verify(s.tokenAuth, jwtauth.TokenFromCookie))
  538. router.Use(jwtAuthenticatorWebAdmin)
  539. router.Get(webLogoutPath, handleWebLogout)
  540. router.With(s.refreshCookie).Get(webChangeAdminPwdPath, handleWebAdminChangePwd)
  541. router.Post(webChangeAdminPwdPath, handleWebAdminChangePwdPost)
  542. router.With(checkPerm(dataprovider.PermAdminViewUsers), s.refreshCookie).
  543. Get(webUsersPath, handleGetWebUsers)
  544. router.With(checkPerm(dataprovider.PermAdminAddUsers), s.refreshCookie).
  545. Get(webUserPath, handleWebAddUserGet)
  546. router.With(checkPerm(dataprovider.PermAdminChangeUsers), s.refreshCookie).
  547. Get(webUserPath+"/{username}", handleWebUpdateUserGet)
  548. router.With(checkPerm(dataprovider.PermAdminAddUsers)).Post(webUserPath, handleWebAddUserPost)
  549. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Post(webUserPath+"/{username}", handleWebUpdateUserPost)
  550. router.With(checkPerm(dataprovider.PermAdminViewConnections), s.refreshCookie).
  551. Get(webConnectionsPath, handleWebGetConnections)
  552. router.With(checkPerm(dataprovider.PermAdminViewUsers), s.refreshCookie).
  553. Get(webFoldersPath, handleWebGetFolders)
  554. router.With(checkPerm(dataprovider.PermAdminAddUsers), s.refreshCookie).
  555. Get(webFolderPath, handleWebAddFolderGet)
  556. router.With(checkPerm(dataprovider.PermAdminAddUsers)).Post(webFolderPath, handleWebAddFolderPost)
  557. router.With(checkPerm(dataprovider.PermAdminViewServerStatus), s.refreshCookie).
  558. Get(webStatusPath, handleWebGetStatus)
  559. router.With(checkPerm(dataprovider.PermAdminManageAdmins), s.refreshCookie).
  560. Get(webAdminsPath, handleGetWebAdmins)
  561. router.With(checkPerm(dataprovider.PermAdminManageAdmins), s.refreshCookie).
  562. Get(webAdminPath, handleWebAddAdminGet)
  563. router.With(checkPerm(dataprovider.PermAdminManageAdmins), s.refreshCookie).
  564. Get(webAdminPath+"/{username}", handleWebUpdateAdminGet)
  565. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Post(webAdminPath, handleWebAddAdminPost)
  566. router.With(checkPerm(dataprovider.PermAdminManageAdmins)).Post(webAdminPath+"/{username}", handleWebUpdateAdminPost)
  567. router.With(checkPerm(dataprovider.PermAdminManageAdmins), verifyCSRFHeader).
  568. Delete(webAdminPath+"/{username}", deleteAdmin)
  569. router.With(checkPerm(dataprovider.PermAdminCloseConnections), verifyCSRFHeader).
  570. Delete(webConnectionsPath+"/{connectionID}", handleCloseConnection)
  571. router.With(checkPerm(dataprovider.PermAdminChangeUsers), s.refreshCookie).
  572. Get(webFolderPath+"/{name}", handleWebUpdateFolderGet)
  573. router.With(checkPerm(dataprovider.PermAdminChangeUsers)).Post(webFolderPath+"/{name}", handleWebUpdateFolderPost)
  574. router.With(checkPerm(dataprovider.PermAdminDeleteUsers), verifyCSRFHeader).
  575. Delete(webFolderPath+"/{name}", deleteFolder)
  576. router.With(checkPerm(dataprovider.PermAdminQuotaScans), verifyCSRFHeader).
  577. Post(webScanVFolderPath, startVFolderQuotaScan)
  578. router.With(checkPerm(dataprovider.PermAdminDeleteUsers), verifyCSRFHeader).
  579. Delete(webUserPath+"/{username}", deleteUser)
  580. router.With(checkPerm(dataprovider.PermAdminQuotaScans), verifyCSRFHeader).
  581. Post(webQuotaScanPath, startQuotaScan)
  582. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Get(webMaintenancePath, handleWebMaintenance)
  583. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Get(webBackupPath, dumpData)
  584. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Post(webRestorePath, handleWebRestore)
  585. router.With(checkPerm(dataprovider.PermAdminManageSystem), s.refreshCookie).
  586. Get(webTemplateUser, handleWebTemplateUserGet)
  587. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Post(webTemplateUser, handleWebTemplateUserPost)
  588. router.With(checkPerm(dataprovider.PermAdminManageSystem), s.refreshCookie).
  589. Get(webTemplateFolder, handleWebTemplateFolderGet)
  590. router.With(checkPerm(dataprovider.PermAdminManageSystem)).Post(webTemplateFolder, handleWebTemplateFolderPost)
  591. })
  592. }
  593. }