router.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  1. package router
  2. import (
  3. "net/http"
  4. "os"
  5. "path"
  6. "strings"
  7. "time"
  8. "github.com/go-chi/chi"
  9. "github.com/go-chi/chi/middleware"
  10. "github.com/porter-dev/porter/internal/auth/token"
  11. "github.com/porter-dev/porter/server/api"
  12. mw "github.com/porter-dev/porter/server/middleware"
  13. "github.com/porter-dev/porter/server/middleware/requestlog"
  14. )
  15. // New creates a new Chi router instance and registers all routes supported by the
  16. // API
  17. func New(a *api.App) *chi.Mux {
  18. l := a.Logger
  19. r := chi.NewRouter()
  20. auth := mw.NewAuth(a.Store, a.ServerConf.CookieName, &token.TokenGeneratorConf{
  21. TokenSecret: a.ServerConf.TokenGeneratorSecret,
  22. }, a.Repo)
  23. r.Route("/api", func(r chi.Router) {
  24. r.Use(mw.ContentTypeJSON)
  25. // Group for default operations with 10s timeout
  26. r.Group(func(r chi.Router) {
  27. r.Use(middleware.Timeout(10 * time.Second))
  28. // health checks
  29. r.Method("GET", "/livez", http.HandlerFunc(a.HandleLive))
  30. r.Method("GET", "/readyz", http.HandlerFunc(a.HandleReady))
  31. // /api/users routes
  32. r.Method(
  33. "GET",
  34. "/users/{user_id}",
  35. auth.DoesUserIDMatch(
  36. requestlog.NewHandler(a.HandleReadUser, l),
  37. mw.URLParam,
  38. ),
  39. )
  40. r.Method(
  41. "GET",
  42. "/users/{user_id}/projects",
  43. auth.DoesUserIDMatch(
  44. requestlog.NewHandler(a.HandleListUserProjects, l),
  45. mw.URLParam,
  46. ),
  47. )
  48. r.Method(
  49. "POST",
  50. "/users",
  51. requestlog.NewHandler(a.HandleCreateUser, l),
  52. )
  53. r.Method(
  54. "DELETE",
  55. "/users/{user_id}",
  56. auth.DoesUserIDMatch(
  57. requestlog.NewHandler(a.HandleDeleteUser, l),
  58. mw.URLParam,
  59. ),
  60. )
  61. r.Method(
  62. "GET",
  63. "/cli/login",
  64. auth.BasicAuthenticateWithRedirect(
  65. requestlog.NewHandler(a.HandleCLILoginUser, l),
  66. ),
  67. )
  68. r.Method(
  69. "GET",
  70. "/cli/login/exchange",
  71. requestlog.NewHandler(a.HandleCLILoginExchangeToken, l),
  72. )
  73. r.Method(
  74. "POST",
  75. "/login",
  76. requestlog.NewHandler(a.HandleLoginUser, l),
  77. )
  78. r.Method(
  79. "GET",
  80. "/auth/check",
  81. auth.BasicAuthenticate(
  82. requestlog.NewHandler(a.HandleAuthCheck, l),
  83. ),
  84. )
  85. r.Method(
  86. "POST",
  87. "/logout",
  88. auth.BasicAuthenticate(
  89. requestlog.NewHandler(a.HandleLogoutUser, l),
  90. ),
  91. )
  92. r.Method(
  93. "POST",
  94. "/email/verify/initiate",
  95. auth.BasicAuthenticate(
  96. requestlog.NewHandler(a.InitiateEmailVerifyUser, l),
  97. ),
  98. )
  99. r.Method(
  100. "GET",
  101. "/email/verify/finalize",
  102. auth.BasicAuthenticateWithRedirect(
  103. requestlog.NewHandler(a.FinalizEmailVerifyUser, l),
  104. ),
  105. )
  106. r.Method(
  107. "POST",
  108. "/password/reset/initiate",
  109. requestlog.NewHandler(a.InitiatePWResetUser, l),
  110. )
  111. r.Method(
  112. "POST",
  113. "/password/reset/verify",
  114. requestlog.NewHandler(a.VerifyPWResetUser, l),
  115. )
  116. r.Method(
  117. "POST",
  118. "/password/reset/finalize",
  119. requestlog.NewHandler(a.FinalizPWResetUser, l),
  120. )
  121. // /api/integrations routes
  122. r.Method(
  123. "GET",
  124. "/integrations/cluster",
  125. auth.BasicAuthenticate(
  126. requestlog.NewHandler(a.HandleListClusterIntegrations, l),
  127. ),
  128. )
  129. r.Method(
  130. "GET",
  131. "/integrations/registry",
  132. auth.BasicAuthenticate(
  133. requestlog.NewHandler(a.HandleListRegistryIntegrations, l),
  134. ),
  135. )
  136. r.Method(
  137. "GET",
  138. "/integrations/helm",
  139. auth.BasicAuthenticate(
  140. requestlog.NewHandler(a.HandleListHelmRepoIntegrations, l),
  141. ),
  142. )
  143. r.Method(
  144. "GET",
  145. "/integrations/repo",
  146. auth.BasicAuthenticate(
  147. requestlog.NewHandler(a.HandleListRepoIntegrations, l),
  148. ),
  149. )
  150. // /api/templates routes
  151. r.Method(
  152. "GET",
  153. "/templates",
  154. auth.BasicAuthenticate(
  155. requestlog.NewHandler(a.HandleListTemplates, l),
  156. ),
  157. )
  158. r.Method(
  159. "GET",
  160. "/templates/{name}/{version}",
  161. auth.BasicAuthenticate(
  162. requestlog.NewHandler(a.HandleReadTemplate, l),
  163. ),
  164. )
  165. // /api/oauth routes
  166. r.Method(
  167. "GET",
  168. "/oauth/projects/{project_id}/github",
  169. auth.DoesUserHaveProjectAccess(
  170. requestlog.NewHandler(a.HandleGithubOAuthStartProject, l),
  171. mw.URLParam,
  172. mw.WriteAccess,
  173. ),
  174. )
  175. r.Method(
  176. "GET",
  177. "/oauth/login/github",
  178. requestlog.NewHandler(a.HandleGithubOAuthStartUser, l),
  179. )
  180. r.Method(
  181. "GET",
  182. "/oauth/github/callback",
  183. requestlog.NewHandler(a.HandleGithubOAuthCallback, l),
  184. )
  185. r.Method(
  186. "GET",
  187. "/oauth/login/google",
  188. requestlog.NewHandler(a.HandleGoogleStartUser, l),
  189. )
  190. r.Method(
  191. "GET",
  192. "/oauth/google/callback",
  193. requestlog.NewHandler(a.HandleGoogleOAuthCallback, l),
  194. )
  195. r.Method(
  196. "GET",
  197. "/oauth/projects/{project_id}/digitalocean",
  198. auth.DoesUserHaveProjectAccess(
  199. requestlog.NewHandler(a.HandleDOOAuthStartProject, l),
  200. mw.URLParam,
  201. mw.WriteAccess,
  202. ),
  203. )
  204. r.Method(
  205. "GET",
  206. "/oauth/digitalocean/callback",
  207. requestlog.NewHandler(a.HandleDOOAuthCallback, l),
  208. )
  209. // /api/projects routes
  210. r.Method(
  211. "GET",
  212. "/projects/{project_id}",
  213. auth.DoesUserHaveProjectAccess(
  214. requestlog.NewHandler(a.HandleReadProject, l),
  215. mw.URLParam,
  216. mw.ReadAccess,
  217. ),
  218. )
  219. r.Method(
  220. "POST",
  221. "/projects",
  222. auth.BasicAuthenticate(
  223. requestlog.NewHandler(a.HandleCreateProject, l),
  224. ),
  225. )
  226. r.Method(
  227. "DELETE",
  228. "/projects/{project_id}",
  229. auth.DoesUserHaveProjectAccess(
  230. requestlog.NewHandler(a.HandleDeleteProject, l),
  231. mw.URLParam,
  232. mw.WriteAccess,
  233. ),
  234. )
  235. // /api/projects/{project_id}/ci routes
  236. r.Method(
  237. "POST",
  238. "/projects/{project_id}/ci/actions",
  239. auth.DoesUserHaveProjectAccess(
  240. auth.DoesUserHaveClusterAccess(
  241. requestlog.NewHandler(a.HandleCreateGitAction, l),
  242. mw.URLParam,
  243. mw.QueryParam,
  244. ),
  245. mw.URLParam,
  246. mw.ReadAccess,
  247. ),
  248. )
  249. // /api/projects/{project_id}/invites routes
  250. r.Method(
  251. "POST",
  252. "/projects/{project_id}/invites",
  253. auth.DoesUserHaveProjectAccess(
  254. requestlog.NewHandler(a.HandleCreateInvite, l),
  255. mw.URLParam,
  256. mw.WriteAccess,
  257. ),
  258. )
  259. r.Method(
  260. "GET",
  261. "/projects/{project_id}/invites",
  262. auth.DoesUserHaveProjectAccess(
  263. requestlog.NewHandler(a.HandleListProjectInvites, l),
  264. mw.URLParam,
  265. mw.ReadAccess,
  266. ),
  267. )
  268. r.Method(
  269. "GET",
  270. "/projects/{project_id}/invites/{token}",
  271. auth.BasicAuthenticateWithRedirect(
  272. requestlog.NewHandler(a.HandleAcceptInvite, l),
  273. ),
  274. )
  275. r.Method(
  276. "DELETE",
  277. "/projects/{project_id}/invites/{invite_id}",
  278. auth.DoesUserHaveProjectAccess(
  279. auth.DoesUserHaveInviteAccess(
  280. requestlog.NewHandler(a.HandleDeleteProjectInvite, l),
  281. mw.URLParam,
  282. mw.URLParam,
  283. ),
  284. mw.URLParam,
  285. mw.WriteAccess,
  286. ),
  287. )
  288. // /api/projects/{project_id}/infra routes
  289. r.Method(
  290. "GET",
  291. "/projects/{project_id}/infra",
  292. auth.DoesUserHaveProjectAccess(
  293. requestlog.NewHandler(a.HandleListProjectInfra, l),
  294. mw.URLParam,
  295. mw.ReadAccess,
  296. ),
  297. )
  298. // /api/projects/{project_id}/provision routes
  299. r.Method(
  300. "POST",
  301. "/projects/{project_id}/provision/test",
  302. auth.DoesUserHaveProjectAccess(
  303. requestlog.NewHandler(a.HandleProvisionTestInfra, l),
  304. mw.URLParam,
  305. mw.ReadAccess,
  306. ),
  307. )
  308. r.Method(
  309. "POST",
  310. "/projects/{project_id}/provision/ecr",
  311. auth.DoesUserHaveProjectAccess(
  312. auth.DoesUserHaveAWSIntegrationAccess(
  313. requestlog.NewHandler(a.HandleProvisionAWSECRInfra, l),
  314. mw.URLParam,
  315. mw.BodyParam,
  316. false,
  317. ),
  318. mw.URLParam,
  319. mw.ReadAccess,
  320. ),
  321. )
  322. r.Method(
  323. "POST",
  324. "/projects/{project_id}/provision/eks",
  325. auth.DoesUserHaveProjectAccess(
  326. auth.DoesUserHaveAWSIntegrationAccess(
  327. requestlog.NewHandler(a.HandleProvisionAWSEKSInfra, l),
  328. mw.URLParam,
  329. mw.BodyParam,
  330. false,
  331. ),
  332. mw.URLParam,
  333. mw.ReadAccess,
  334. ),
  335. )
  336. r.Method(
  337. "POST",
  338. "/projects/{project_id}/provision/gcr",
  339. auth.DoesUserHaveProjectAccess(
  340. auth.DoesUserHaveGCPIntegrationAccess(
  341. requestlog.NewHandler(a.HandleProvisionGCPGCRInfra, l),
  342. mw.URLParam,
  343. mw.BodyParam,
  344. false,
  345. ),
  346. mw.URLParam,
  347. mw.ReadAccess,
  348. ),
  349. )
  350. r.Method(
  351. "POST",
  352. "/projects/{project_id}/provision/gke",
  353. auth.DoesUserHaveProjectAccess(
  354. auth.DoesUserHaveGCPIntegrationAccess(
  355. requestlog.NewHandler(a.HandleProvisionGCPGKEInfra, l),
  356. mw.URLParam,
  357. mw.BodyParam,
  358. false,
  359. ),
  360. mw.URLParam,
  361. mw.ReadAccess,
  362. ),
  363. )
  364. r.Method(
  365. "POST",
  366. "/projects/{project_id}/provision/docr",
  367. auth.DoesUserHaveProjectAccess(
  368. auth.DoesUserHaveDOIntegrationAccess(
  369. requestlog.NewHandler(a.HandleProvisionDODOCRInfra, l),
  370. mw.URLParam,
  371. mw.BodyParam,
  372. false,
  373. ),
  374. mw.URLParam,
  375. mw.ReadAccess,
  376. ),
  377. )
  378. r.Method(
  379. "POST",
  380. "/projects/{project_id}/provision/doks",
  381. auth.DoesUserHaveProjectAccess(
  382. auth.DoesUserHaveDOIntegrationAccess(
  383. requestlog.NewHandler(a.HandleProvisionDODOKSInfra, l),
  384. mw.URLParam,
  385. mw.BodyParam,
  386. false,
  387. ),
  388. mw.URLParam,
  389. mw.ReadAccess,
  390. ),
  391. )
  392. r.Method(
  393. "GET",
  394. "/projects/{project_id}/provision/{kind}/{infra_id}/logs",
  395. auth.DoesUserHaveProjectAccess(
  396. auth.DoesUserHaveInfraAccess(
  397. requestlog.NewHandler(a.HandleGetProvisioningLogs, l),
  398. mw.URLParam,
  399. mw.URLParam,
  400. ),
  401. mw.URLParam,
  402. mw.ReadAccess,
  403. ),
  404. )
  405. r.Method(
  406. "POST",
  407. "/projects/{project_id}/provision/{kind}/{infra_id}/logs",
  408. auth.DoesUserHaveProjectAccess(
  409. auth.DoesUserHaveInfraAccess(
  410. requestlog.NewHandler(a.HandleGetProvisioningLogs, l),
  411. mw.URLParam,
  412. mw.URLParam,
  413. ),
  414. mw.URLParam,
  415. mw.ReadAccess,
  416. ),
  417. )
  418. r.Method(
  419. "POST",
  420. "/projects/{project_id}/infra/{infra_id}/ecr/destroy",
  421. auth.DoesUserHaveProjectAccess(
  422. auth.DoesUserHaveInfraAccess(
  423. requestlog.NewHandler(a.HandleDestroyAWSECRInfra, l),
  424. mw.URLParam,
  425. mw.URLParam,
  426. ),
  427. mw.URLParam,
  428. mw.ReadAccess,
  429. ),
  430. )
  431. r.Method(
  432. "POST",
  433. "/projects/{project_id}/infra/{infra_id}/test/destroy",
  434. auth.DoesUserHaveProjectAccess(
  435. auth.DoesUserHaveInfraAccess(
  436. requestlog.NewHandler(a.HandleDestroyTestInfra, l),
  437. mw.URLParam,
  438. mw.URLParam,
  439. ),
  440. mw.URLParam,
  441. mw.ReadAccess,
  442. ),
  443. )
  444. r.Method(
  445. "POST",
  446. "/projects/{project_id}/infra/{infra_id}/eks/destroy",
  447. auth.DoesUserHaveProjectAccess(
  448. auth.DoesUserHaveInfraAccess(
  449. requestlog.NewHandler(a.HandleDestroyAWSEKSInfra, l),
  450. mw.URLParam,
  451. mw.URLParam,
  452. ),
  453. mw.URLParam,
  454. mw.ReadAccess,
  455. ),
  456. )
  457. r.Method(
  458. "POST",
  459. "/projects/{project_id}/infra/{infra_id}/gke/destroy",
  460. auth.DoesUserHaveProjectAccess(
  461. auth.DoesUserHaveInfraAccess(
  462. requestlog.NewHandler(a.HandleDestroyGCPGKEInfra, l),
  463. mw.URLParam,
  464. mw.URLParam,
  465. ),
  466. mw.URLParam,
  467. mw.ReadAccess,
  468. ),
  469. )
  470. r.Method(
  471. "POST",
  472. "/projects/{project_id}/infra/{infra_id}/docr/destroy",
  473. auth.DoesUserHaveProjectAccess(
  474. auth.DoesUserHaveInfraAccess(
  475. requestlog.NewHandler(a.HandleDestroyDODOCRInfra, l),
  476. mw.URLParam,
  477. mw.URLParam,
  478. ),
  479. mw.URLParam,
  480. mw.ReadAccess,
  481. ),
  482. )
  483. r.Method(
  484. "POST",
  485. "/projects/{project_id}/infra/{infra_id}/doks/destroy",
  486. auth.DoesUserHaveProjectAccess(
  487. auth.DoesUserHaveInfraAccess(
  488. requestlog.NewHandler(a.HandleDestroyDODOKSInfra, l),
  489. mw.URLParam,
  490. mw.URLParam,
  491. ),
  492. mw.URLParam,
  493. mw.ReadAccess,
  494. ),
  495. )
  496. // /api/projects/{project_id}/clusters routes
  497. r.Method(
  498. "GET",
  499. "/projects/{project_id}/clusters",
  500. auth.DoesUserHaveProjectAccess(
  501. requestlog.NewHandler(a.HandleListProjectClusters, l),
  502. mw.URLParam,
  503. mw.ReadAccess,
  504. ),
  505. )
  506. r.Method(
  507. "POST",
  508. "/projects/{project_id}/clusters",
  509. auth.DoesUserHaveProjectAccess(
  510. auth.DoesUserHaveAWSIntegrationAccess(
  511. auth.DoesUserHaveGCPIntegrationAccess(
  512. requestlog.NewHandler(a.HandleCreateProjectCluster, l),
  513. mw.URLParam,
  514. mw.BodyParam,
  515. true,
  516. ),
  517. mw.URLParam,
  518. mw.BodyParam,
  519. true,
  520. ),
  521. mw.URLParam,
  522. mw.WriteAccess,
  523. ),
  524. )
  525. r.Method(
  526. "GET",
  527. "/projects/{project_id}/clusters/{cluster_id}",
  528. auth.DoesUserHaveProjectAccess(
  529. auth.DoesUserHaveClusterAccess(
  530. requestlog.NewHandler(a.HandleReadProjectCluster, l),
  531. mw.URLParam,
  532. mw.URLParam,
  533. ),
  534. mw.URLParam,
  535. mw.ReadAccess,
  536. ),
  537. )
  538. r.Method(
  539. "POST",
  540. "/projects/{project_id}/clusters/{cluster_id}",
  541. auth.DoesUserHaveProjectAccess(
  542. auth.DoesUserHaveClusterAccess(
  543. requestlog.NewHandler(a.HandleUpdateProjectCluster, l),
  544. mw.URLParam,
  545. mw.URLParam,
  546. ),
  547. mw.URLParam,
  548. mw.WriteAccess,
  549. ),
  550. )
  551. r.Method(
  552. "DELETE",
  553. "/projects/{project_id}/clusters/{cluster_id}",
  554. auth.DoesUserHaveProjectAccess(
  555. auth.DoesUserHaveClusterAccess(
  556. requestlog.NewHandler(a.HandleDeleteProjectCluster, l),
  557. mw.URLParam,
  558. mw.URLParam,
  559. ),
  560. mw.URLParam,
  561. mw.WriteAccess,
  562. ),
  563. )
  564. // /api/projects/{project_id}/clusters/candidates routes
  565. r.Method(
  566. "POST",
  567. "/projects/{project_id}/clusters/candidates",
  568. auth.DoesUserHaveProjectAccess(
  569. requestlog.NewHandler(a.HandleCreateProjectClusterCandidates, l),
  570. mw.URLParam,
  571. mw.WriteAccess,
  572. ),
  573. )
  574. r.Method(
  575. "GET",
  576. "/projects/{project_id}/clusters/candidates",
  577. auth.DoesUserHaveProjectAccess(
  578. requestlog.NewHandler(a.HandleListProjectClusterCandidates, l),
  579. mw.URLParam,
  580. mw.WriteAccess,
  581. ),
  582. )
  583. r.Method(
  584. "POST",
  585. "/projects/{project_id}/clusters/candidates/{candidate_id}/resolve",
  586. auth.DoesUserHaveProjectAccess(
  587. requestlog.NewHandler(a.HandleResolveClusterCandidate, l),
  588. mw.URLParam,
  589. mw.WriteAccess,
  590. ),
  591. )
  592. // /api/projects/{project_id}/integrations routes
  593. r.Method(
  594. "POST",
  595. "/projects/{project_id}/integrations/gcp",
  596. auth.DoesUserHaveProjectAccess(
  597. requestlog.NewHandler(a.HandleCreateGCPIntegration, l),
  598. mw.URLParam,
  599. mw.WriteAccess,
  600. ),
  601. )
  602. r.Method(
  603. "POST",
  604. "/projects/{project_id}/integrations/aws",
  605. auth.DoesUserHaveProjectAccess(
  606. requestlog.NewHandler(a.HandleCreateAWSIntegration, l),
  607. mw.URLParam,
  608. mw.WriteAccess,
  609. ),
  610. )
  611. r.Method(
  612. "POST",
  613. "/projects/{project_id}/integrations/basic",
  614. auth.DoesUserHaveProjectAccess(
  615. requestlog.NewHandler(a.HandleCreateBasicAuthIntegration, l),
  616. mw.URLParam,
  617. mw.WriteAccess,
  618. ),
  619. )
  620. r.Method(
  621. "GET",
  622. "/projects/{project_id}/integrations/oauth",
  623. auth.DoesUserHaveProjectAccess(
  624. requestlog.NewHandler(a.HandleListProjectOAuthIntegrations, l),
  625. mw.URLParam,
  626. mw.WriteAccess,
  627. ),
  628. )
  629. // /api/projects/{project_id}/helmrepos routes
  630. r.Method(
  631. "POST",
  632. "/projects/{project_id}/helmrepos",
  633. auth.DoesUserHaveProjectAccess(
  634. auth.DoesUserHaveAWSIntegrationAccess(
  635. auth.DoesUserHaveGCPIntegrationAccess(
  636. requestlog.NewHandler(a.HandleCreateHelmRepo, l),
  637. mw.URLParam,
  638. mw.BodyParam,
  639. true,
  640. ),
  641. mw.URLParam,
  642. mw.BodyParam,
  643. true,
  644. ),
  645. mw.URLParam,
  646. mw.WriteAccess,
  647. ),
  648. )
  649. r.Method(
  650. "GET",
  651. "/projects/{project_id}/helmrepos",
  652. auth.DoesUserHaveProjectAccess(
  653. requestlog.NewHandler(a.HandleListProjectHelmRepos, l),
  654. mw.URLParam,
  655. mw.WriteAccess,
  656. ),
  657. )
  658. r.Method(
  659. "GET",
  660. "/projects/{project_id}/helmrepos/{helm_id}/charts",
  661. auth.DoesUserHaveProjectAccess(
  662. requestlog.NewHandler(a.HandleListHelmRepoCharts, l),
  663. mw.URLParam,
  664. mw.WriteAccess,
  665. ),
  666. )
  667. // /api/projects/{project_id}/registries routes
  668. r.Method(
  669. "POST",
  670. "/projects/{project_id}/registries",
  671. auth.DoesUserHaveProjectAccess(
  672. auth.DoesUserHaveAWSIntegrationAccess(
  673. auth.DoesUserHaveGCPIntegrationAccess(
  674. auth.DoesUserHaveDOIntegrationAccess(
  675. requestlog.NewHandler(a.HandleCreateRegistry, l),
  676. mw.URLParam,
  677. mw.BodyParam,
  678. true,
  679. ),
  680. mw.URLParam,
  681. mw.BodyParam,
  682. true,
  683. ),
  684. mw.URLParam,
  685. mw.BodyParam,
  686. true,
  687. ),
  688. mw.URLParam,
  689. mw.WriteAccess,
  690. ),
  691. )
  692. r.Method(
  693. "GET",
  694. "/projects/{project_id}/registries",
  695. auth.DoesUserHaveProjectAccess(
  696. requestlog.NewHandler(a.HandleListProjectRegistries, l),
  697. mw.URLParam,
  698. mw.WriteAccess,
  699. ),
  700. )
  701. r.Method(
  702. "POST",
  703. "/projects/{project_id}/registries/{registry_id}",
  704. auth.DoesUserHaveProjectAccess(
  705. auth.DoesUserHaveRegistryAccess(
  706. requestlog.NewHandler(a.HandleUpdateProjectRegistry, l),
  707. mw.URLParam,
  708. mw.URLParam,
  709. ),
  710. mw.URLParam,
  711. mw.WriteAccess,
  712. ),
  713. )
  714. r.Method(
  715. "GET",
  716. "/projects/{project_id}/registries/ecr/{region}/token",
  717. auth.DoesUserHaveProjectAccess(
  718. requestlog.NewHandler(a.HandleGetProjectRegistryECRToken, l),
  719. mw.URLParam,
  720. mw.WriteAccess,
  721. ),
  722. )
  723. r.Method(
  724. "GET",
  725. "/projects/{project_id}/registries/gcr/token",
  726. auth.DoesUserHaveProjectAccess(
  727. requestlog.NewHandler(a.HandleGetProjectRegistryGCRToken, l),
  728. mw.URLParam,
  729. mw.WriteAccess,
  730. ),
  731. )
  732. r.Method(
  733. "GET",
  734. "/projects/{project_id}/registries/dockerhub/token",
  735. auth.DoesUserHaveProjectAccess(
  736. requestlog.NewHandler(a.HandleGetProjectRegistryDockerhubToken, l),
  737. mw.URLParam,
  738. mw.WriteAccess,
  739. ),
  740. )
  741. r.Method(
  742. "GET",
  743. "/projects/{project_id}/registries/docr/token",
  744. auth.DoesUserHaveProjectAccess(
  745. requestlog.NewHandler(a.HandleGetProjectRegistryDOCRToken, l),
  746. mw.URLParam,
  747. mw.WriteAccess,
  748. ),
  749. )
  750. r.Method(
  751. "DELETE",
  752. "/projects/{project_id}/registries/{registry_id}",
  753. auth.DoesUserHaveProjectAccess(
  754. auth.DoesUserHaveRegistryAccess(
  755. requestlog.NewHandler(a.HandleDeleteProjectRegistry, l),
  756. mw.URLParam,
  757. mw.URLParam,
  758. ),
  759. mw.URLParam,
  760. mw.WriteAccess,
  761. ),
  762. )
  763. // /api/projects/{project_id}/registries/{registry_id}/repositories routes
  764. r.Method(
  765. "GET",
  766. "/projects/{project_id}/registries/{registry_id}/repositories",
  767. auth.DoesUserHaveProjectAccess(
  768. auth.DoesUserHaveRegistryAccess(
  769. requestlog.NewHandler(a.HandleListRepositories, l),
  770. mw.URLParam,
  771. mw.URLParam,
  772. ),
  773. mw.URLParam,
  774. mw.WriteAccess,
  775. ),
  776. )
  777. r.Method(
  778. "GET",
  779. // * is the repo name, which can itself be nested
  780. // for example, for GCR this is project-id/repo
  781. // need to use wildcard, see https://github.com/go-chi/chi/issues/243
  782. "/projects/{project_id}/registries/{registry_id}/repositories/*",
  783. auth.DoesUserHaveProjectAccess(
  784. auth.DoesUserHaveRegistryAccess(
  785. requestlog.NewHandler(a.HandleListImages, l),
  786. mw.URLParam,
  787. mw.URLParam,
  788. ),
  789. mw.URLParam,
  790. mw.WriteAccess,
  791. ),
  792. )
  793. // /api/projects/{project_id}/releases routes
  794. r.Method(
  795. "GET",
  796. "/projects/{project_id}/releases",
  797. auth.DoesUserHaveProjectAccess(
  798. auth.DoesUserHaveClusterAccess(
  799. requestlog.NewHandler(a.HandleListReleases, l),
  800. mw.URLParam,
  801. mw.QueryParam,
  802. ),
  803. mw.URLParam,
  804. mw.ReadAccess,
  805. ),
  806. )
  807. r.Method(
  808. "GET",
  809. "/projects/{project_id}/releases/{name}/{revision}/components",
  810. auth.DoesUserHaveProjectAccess(
  811. auth.DoesUserHaveClusterAccess(
  812. requestlog.NewHandler(a.HandleGetReleaseComponents, l),
  813. mw.URLParam,
  814. mw.QueryParam,
  815. ),
  816. mw.URLParam,
  817. mw.ReadAccess,
  818. ),
  819. )
  820. r.Method(
  821. "GET",
  822. "/projects/{project_id}/releases/{name}/{revision}/controllers",
  823. auth.DoesUserHaveProjectAccess(
  824. auth.DoesUserHaveClusterAccess(
  825. requestlog.NewHandler(a.HandleGetReleaseControllers, l),
  826. mw.URLParam,
  827. mw.QueryParam,
  828. ),
  829. mw.URLParam,
  830. mw.ReadAccess,
  831. ),
  832. )
  833. r.Method(
  834. "GET",
  835. "/projects/{project_id}/releases/{name}/{revision}/pods/all",
  836. auth.DoesUserHaveProjectAccess(
  837. auth.DoesUserHaveClusterAccess(
  838. requestlog.NewHandler(a.HandleGetReleaseAllPods, l),
  839. mw.URLParam,
  840. mw.QueryParam,
  841. ),
  842. mw.URLParam,
  843. mw.ReadAccess,
  844. ),
  845. )
  846. r.Method(
  847. "GET",
  848. "/projects/{project_id}/releases/{name}/history",
  849. auth.DoesUserHaveProjectAccess(
  850. auth.DoesUserHaveClusterAccess(
  851. requestlog.NewHandler(a.HandleListReleaseHistory, l),
  852. mw.URLParam,
  853. mw.QueryParam,
  854. ),
  855. mw.URLParam,
  856. mw.ReadAccess,
  857. ),
  858. )
  859. r.Method(
  860. "GET",
  861. "/projects/{project_id}/releases/{name}/webhook_token",
  862. auth.DoesUserHaveProjectAccess(
  863. auth.DoesUserHaveClusterAccess(
  864. requestlog.NewHandler(a.HandleGetReleaseToken, l),
  865. mw.URLParam,
  866. mw.QueryParam,
  867. ),
  868. mw.URLParam,
  869. mw.ReadAccess,
  870. ),
  871. )
  872. r.Method(
  873. "GET",
  874. "/projects/{project_id}/releases/{name}/{revision}",
  875. auth.DoesUserHaveProjectAccess(
  876. auth.DoesUserHaveClusterAccess(
  877. requestlog.NewHandler(a.HandleGetRelease, l),
  878. mw.URLParam,
  879. mw.QueryParam,
  880. ),
  881. mw.URLParam,
  882. mw.ReadAccess,
  883. ),
  884. )
  885. // /api/projects/{project_id}/gitrepos routes
  886. r.Method(
  887. "GET",
  888. "/projects/{project_id}/gitrepos",
  889. auth.DoesUserHaveProjectAccess(
  890. requestlog.NewHandler(a.HandleListProjectGitRepos, l),
  891. mw.URLParam,
  892. mw.ReadAccess,
  893. ),
  894. )
  895. r.Method(
  896. "DELETE",
  897. "/projects/{project_id}/gitrepos/{git_repo_id}",
  898. auth.DoesUserHaveProjectAccess(
  899. auth.DoesUserHaveGitRepoAccess(
  900. requestlog.NewHandler(a.HandleDeleteProjectGitRepo, l),
  901. mw.URLParam,
  902. mw.URLParam,
  903. ),
  904. mw.URLParam,
  905. mw.WriteAccess,
  906. ),
  907. )
  908. r.Method(
  909. "GET",
  910. "/projects/{project_id}/gitrepos/{git_repo_id}/repos",
  911. auth.DoesUserHaveProjectAccess(
  912. auth.DoesUserHaveGitRepoAccess(
  913. requestlog.NewHandler(a.HandleListRepos, l),
  914. mw.URLParam,
  915. mw.URLParam,
  916. ),
  917. mw.URLParam,
  918. mw.ReadAccess,
  919. ),
  920. )
  921. r.Method(
  922. "GET",
  923. "/projects/{project_id}/gitrepos/{git_repo_id}/repos/{kind}/{owner}/{name}/branches",
  924. auth.DoesUserHaveProjectAccess(
  925. auth.DoesUserHaveGitRepoAccess(
  926. requestlog.NewHandler(a.HandleGetBranches, l),
  927. mw.URLParam,
  928. mw.URLParam,
  929. ),
  930. mw.URLParam,
  931. mw.ReadAccess,
  932. ),
  933. )
  934. r.Method(
  935. "GET",
  936. "/projects/{project_id}/gitrepos/{git_repo_id}/repos/{kind}/{owner}/{name}/{branch}/contents",
  937. auth.DoesUserHaveProjectAccess(
  938. auth.DoesUserHaveGitRepoAccess(
  939. requestlog.NewHandler(a.HandleGetBranchContents, l),
  940. mw.URLParam,
  941. mw.URLParam,
  942. ),
  943. mw.URLParam,
  944. mw.ReadAccess,
  945. ),
  946. )
  947. r.Method(
  948. "GET",
  949. "/projects/{project_id}/gitrepos/{git_repo_id}/repos/{kind}/{owner}/{name}/{branch}/procfile",
  950. auth.DoesUserHaveProjectAccess(
  951. auth.DoesUserHaveGitRepoAccess(
  952. requestlog.NewHandler(a.HandleGetProcfileContents, l),
  953. mw.URLParam,
  954. mw.URLParam,
  955. ),
  956. mw.URLParam,
  957. mw.ReadAccess,
  958. ),
  959. )
  960. // /api/projects/{project_id}/k8s routes
  961. r.Method(
  962. "GET",
  963. "/projects/{project_id}/k8s/namespaces",
  964. auth.DoesUserHaveProjectAccess(
  965. auth.DoesUserHaveClusterAccess(
  966. requestlog.NewHandler(a.HandleListNamespaces, l),
  967. mw.URLParam,
  968. mw.QueryParam,
  969. ),
  970. mw.URLParam,
  971. mw.ReadAccess,
  972. ),
  973. )
  974. r.Method(
  975. "GET",
  976. "/projects/{project_id}/k8s/kubeconfig",
  977. auth.DoesUserHaveProjectAccess(
  978. auth.DoesUserHaveClusterAccess(
  979. requestlog.NewHandler(a.HandleGetTemporaryKubeconfig, l),
  980. mw.URLParam,
  981. mw.QueryParam,
  982. ),
  983. mw.URLParam,
  984. mw.WriteAccess,
  985. ),
  986. )
  987. r.Method(
  988. "GET",
  989. "/projects/{project_id}/k8s/prometheus/detect",
  990. auth.DoesUserHaveProjectAccess(
  991. auth.DoesUserHaveClusterAccess(
  992. requestlog.NewHandler(a.HandleDetectPrometheusInstalled, l),
  993. mw.URLParam,
  994. mw.QueryParam,
  995. ),
  996. mw.URLParam,
  997. mw.ReadAccess,
  998. ),
  999. )
  1000. r.Method(
  1001. "GET",
  1002. "/projects/{project_id}/k8s/prometheus/ingresses",
  1003. auth.DoesUserHaveProjectAccess(
  1004. auth.DoesUserHaveClusterAccess(
  1005. requestlog.NewHandler(a.HandleListNGINXIngresses, l),
  1006. mw.URLParam,
  1007. mw.QueryParam,
  1008. ),
  1009. mw.URLParam,
  1010. mw.ReadAccess,
  1011. ),
  1012. )
  1013. r.Method(
  1014. "GET",
  1015. "/projects/{project_id}/k8s/metrics",
  1016. auth.DoesUserHaveProjectAccess(
  1017. auth.DoesUserHaveClusterAccess(
  1018. requestlog.NewHandler(a.HandleGetPodMetrics, l),
  1019. mw.URLParam,
  1020. mw.QueryParam,
  1021. ),
  1022. mw.URLParam,
  1023. mw.ReadAccess,
  1024. ),
  1025. )
  1026. r.Method(
  1027. "GET",
  1028. "/projects/{project_id}/k8s/{namespace}/pod/{name}/logs",
  1029. auth.DoesUserHaveProjectAccess(
  1030. auth.DoesUserHaveClusterAccess(
  1031. requestlog.NewHandler(a.HandleGetPodLogs, l),
  1032. mw.URLParam,
  1033. mw.QueryParam,
  1034. ),
  1035. mw.URLParam,
  1036. mw.ReadAccess,
  1037. ),
  1038. )
  1039. r.Method(
  1040. "GET",
  1041. "/projects/{project_id}/k8s/{namespace}/{chart}/{release_name}/jobs",
  1042. auth.DoesUserHaveProjectAccess(
  1043. auth.DoesUserHaveClusterAccess(
  1044. requestlog.NewHandler(a.HandleListJobsByChart, l),
  1045. mw.URLParam,
  1046. mw.QueryParam,
  1047. ),
  1048. mw.URLParam,
  1049. mw.ReadAccess,
  1050. ),
  1051. )
  1052. r.Method(
  1053. "GET",
  1054. "/projects/{project_id}/k8s/jobs/{namespace}/{name}/pods",
  1055. auth.DoesUserHaveProjectAccess(
  1056. auth.DoesUserHaveClusterAccess(
  1057. requestlog.NewHandler(a.HandleListJobPods, l),
  1058. mw.URLParam,
  1059. mw.QueryParam,
  1060. ),
  1061. mw.URLParam,
  1062. mw.ReadAccess,
  1063. ),
  1064. )
  1065. r.Method(
  1066. "GET",
  1067. "/projects/{project_id}/k8s/{namespace}/ingress/{name}",
  1068. auth.DoesUserHaveProjectAccess(
  1069. auth.DoesUserHaveClusterAccess(
  1070. requestlog.NewHandler(a.HandleGetIngress, l),
  1071. mw.URLParam,
  1072. mw.QueryParam,
  1073. ),
  1074. mw.URLParam,
  1075. mw.ReadAccess,
  1076. ),
  1077. )
  1078. r.Method(
  1079. "GET",
  1080. "/projects/{project_id}/k8s/{kind}/status",
  1081. auth.DoesUserHaveProjectAccess(
  1082. auth.DoesUserHaveClusterAccess(
  1083. requestlog.NewHandler(a.HandleStreamControllerStatus, l),
  1084. mw.URLParam,
  1085. mw.QueryParam,
  1086. ),
  1087. mw.URLParam,
  1088. mw.ReadAccess,
  1089. ),
  1090. )
  1091. r.Method(
  1092. "GET",
  1093. "/projects/{project_id}/k8s/pods",
  1094. auth.DoesUserHaveProjectAccess(
  1095. auth.DoesUserHaveClusterAccess(
  1096. requestlog.NewHandler(a.HandleListPods, l),
  1097. mw.URLParam,
  1098. mw.QueryParam,
  1099. ),
  1100. mw.URLParam,
  1101. mw.ReadAccess,
  1102. ),
  1103. )
  1104. r.Method(
  1105. "DELETE",
  1106. "/projects/{project_id}/k8s/pods/{namespace}/{name}",
  1107. auth.DoesUserHaveProjectAccess(
  1108. auth.DoesUserHaveClusterAccess(
  1109. requestlog.NewHandler(a.HandleDeletePod, l),
  1110. mw.URLParam,
  1111. mw.QueryParam,
  1112. ),
  1113. mw.URLParam,
  1114. mw.ReadAccess,
  1115. ),
  1116. )
  1117. r.Method(
  1118. "GET",
  1119. "/projects/{project_id}/k8s/pods/{namespace}/{name}/events/list",
  1120. auth.DoesUserHaveProjectAccess(
  1121. auth.DoesUserHaveClusterAccess(
  1122. requestlog.NewHandler(a.HandleListPodEvents, l),
  1123. mw.URLParam,
  1124. mw.QueryParam,
  1125. ),
  1126. mw.URLParam,
  1127. mw.ReadAccess,
  1128. ),
  1129. )
  1130. r.Method(
  1131. "POST",
  1132. "/projects/{project_id}/k8s/configmap/create",
  1133. auth.DoesUserHaveProjectAccess(
  1134. auth.DoesUserHaveClusterAccess(
  1135. requestlog.NewHandler(a.HandleCreateConfigMap, l),
  1136. mw.URLParam,
  1137. mw.QueryParam,
  1138. ),
  1139. mw.URLParam,
  1140. mw.ReadAccess,
  1141. ),
  1142. )
  1143. r.Method(
  1144. "DELETE",
  1145. "/projects/{project_id}/k8s/configmap/delete",
  1146. auth.DoesUserHaveProjectAccess(
  1147. auth.DoesUserHaveClusterAccess(
  1148. requestlog.NewHandler(a.HandleDeleteConfigMap, l),
  1149. mw.URLParam,
  1150. mw.QueryParam,
  1151. ),
  1152. mw.URLParam,
  1153. mw.ReadAccess,
  1154. ),
  1155. )
  1156. r.Method(
  1157. "GET",
  1158. "/projects/{project_id}/k8s/configmap",
  1159. auth.DoesUserHaveProjectAccess(
  1160. auth.DoesUserHaveClusterAccess(
  1161. requestlog.NewHandler(a.HandleGetConfigMap, l),
  1162. mw.URLParam,
  1163. mw.QueryParam,
  1164. ),
  1165. mw.URLParam,
  1166. mw.ReadAccess,
  1167. ),
  1168. )
  1169. r.Method(
  1170. "GET",
  1171. "/projects/{project_id}/k8s/configmap/list",
  1172. auth.DoesUserHaveProjectAccess(
  1173. auth.DoesUserHaveClusterAccess(
  1174. requestlog.NewHandler(a.HandleListConfigMaps, l),
  1175. mw.URLParam,
  1176. mw.QueryParam,
  1177. ),
  1178. mw.URLParam,
  1179. mw.ReadAccess,
  1180. ),
  1181. )
  1182. r.Method(
  1183. "POST",
  1184. "/projects/{project_id}/k8s/configmap/update",
  1185. auth.DoesUserHaveProjectAccess(
  1186. auth.DoesUserHaveClusterAccess(
  1187. requestlog.NewHandler(a.HandleUpdateConfigMap, l),
  1188. mw.URLParam,
  1189. mw.QueryParam,
  1190. ),
  1191. mw.URLParam,
  1192. mw.ReadAccess,
  1193. ),
  1194. )
  1195. r.Method(
  1196. "POST",
  1197. "/projects/{project_id}/k8s/jobs/{namespace}/{name}/stop",
  1198. auth.DoesUserHaveProjectAccess(
  1199. auth.DoesUserHaveClusterAccess(
  1200. requestlog.NewHandler(a.HandleStopJob, l),
  1201. mw.URLParam,
  1202. mw.QueryParam,
  1203. ),
  1204. mw.URLParam,
  1205. mw.ReadAccess,
  1206. ),
  1207. )
  1208. // /api/projects/{project_id}/subdomain routes
  1209. r.Method(
  1210. "POST",
  1211. "/projects/{project_id}/k8s/subdomain",
  1212. auth.DoesUserHaveProjectAccess(
  1213. auth.DoesUserHaveClusterAccess(
  1214. requestlog.NewHandler(a.HandleCreateDNSRecord, l),
  1215. mw.URLParam,
  1216. mw.QueryParam,
  1217. ),
  1218. mw.URLParam,
  1219. mw.ReadAccess,
  1220. ),
  1221. )
  1222. // capabilities
  1223. r.Method(
  1224. "GET",
  1225. "/capabilities",
  1226. http.HandlerFunc(a.HandleGetCapabilities),
  1227. )
  1228. // /api/projects/{project_id}/deploy routes
  1229. r.Method(
  1230. "POST",
  1231. "/projects/{project_id}/deploy/{name}/{version}",
  1232. auth.DoesUserHaveProjectAccess(
  1233. auth.DoesUserHaveClusterAccess(
  1234. requestlog.NewHandler(a.HandleDeployTemplate, l),
  1235. mw.URLParam,
  1236. mw.QueryParam,
  1237. ),
  1238. mw.URLParam,
  1239. mw.ReadAccess,
  1240. ),
  1241. )
  1242. })
  1243. // Create group for long-running Helm operations
  1244. r.Group(func(r chi.Router) {
  1245. r.Use(middleware.Timeout(300 * time.Second))
  1246. r.Method(
  1247. "POST",
  1248. "/projects/{project_id}/releases/{name}/rollback",
  1249. auth.DoesUserHaveProjectAccess(
  1250. auth.DoesUserHaveClusterAccess(
  1251. requestlog.NewHandler(a.HandleRollbackRelease, l),
  1252. mw.URLParam,
  1253. mw.QueryParam,
  1254. ),
  1255. mw.URLParam,
  1256. mw.ReadAccess,
  1257. ),
  1258. )
  1259. r.Method(
  1260. "POST",
  1261. "/webhooks/deploy/{token}",
  1262. requestlog.NewHandler(a.HandleReleaseDeployWebhook, l),
  1263. )
  1264. r.Method(
  1265. "POST",
  1266. "/projects/{project_id}/delete/{name}",
  1267. auth.DoesUserHaveProjectAccess(
  1268. auth.DoesUserHaveClusterAccess(
  1269. requestlog.NewHandler(a.HandleUninstallTemplate, l),
  1270. mw.URLParam,
  1271. mw.QueryParam,
  1272. ),
  1273. mw.URLParam,
  1274. mw.ReadAccess,
  1275. ),
  1276. )
  1277. r.Method(
  1278. "POST",
  1279. "/projects/{project_id}/releases/{name}/upgrade",
  1280. auth.DoesUserHaveProjectAccess(
  1281. auth.DoesUserHaveClusterAccess(
  1282. requestlog.NewHandler(a.HandleUpgradeRelease, l),
  1283. mw.URLParam,
  1284. mw.QueryParam,
  1285. ),
  1286. mw.URLParam,
  1287. mw.ReadAccess,
  1288. ),
  1289. )
  1290. })
  1291. })
  1292. staticFilePath := a.ServerConf.StaticFilePath
  1293. fs := http.FileServer(http.Dir(staticFilePath))
  1294. r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
  1295. if _, err := os.Stat(staticFilePath + r.RequestURI); os.IsNotExist(err) {
  1296. w.Header().Set("Cache-Control", "no-cache")
  1297. http.StripPrefix(r.URL.Path, fs).ServeHTTP(w, r)
  1298. } else {
  1299. // Set static files involving html, js, or empty cache to "no-cache", which means they must be validated
  1300. // for changes before the browser uses the cache
  1301. if base := path.Base(r.URL.Path); strings.Contains(base, "html") || strings.Contains(base, "js") || base == "." || base == "/" {
  1302. w.Header().Set("Cache-Control", "no-cache")
  1303. }
  1304. fs.ServeHTTP(w, r)
  1305. }
  1306. })
  1307. return r
  1308. }