router.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. package router
  2. import (
  3. "net/http"
  4. "os"
  5. "github.com/go-chi/chi"
  6. "github.com/gorilla/sessions"
  7. "github.com/porter-dev/porter/internal/repository"
  8. "github.com/porter-dev/porter/server/api"
  9. "github.com/porter-dev/porter/server/requestlog"
  10. mw "github.com/porter-dev/porter/server/router/middleware"
  11. )
  12. // New creates a new Chi router instance
  13. func New(
  14. a *api.App,
  15. store sessions.Store,
  16. cookieName string,
  17. staticFilePath string,
  18. repo *repository.Repository,
  19. ) *chi.Mux {
  20. l := a.Logger()
  21. r := chi.NewRouter()
  22. auth := mw.NewAuth(store, cookieName, repo)
  23. r.Route("/api", func(r chi.Router) {
  24. r.Use(mw.ContentTypeJSON)
  25. // health checks
  26. r.Method("GET", "/livez", http.HandlerFunc(a.HandleLive))
  27. r.Method("GET", "/readyz", http.HandlerFunc(a.HandleReady))
  28. // /api/users routes
  29. r.Method("GET", "/users/{user_id}", auth.DoesUserIDMatch(requestlog.NewHandler(a.HandleReadUser, l), mw.URLParam))
  30. r.Method("GET", "/users/{user_id}/projects", auth.DoesUserIDMatch(requestlog.NewHandler(a.HandleListUserProjects, l), mw.URLParam))
  31. r.Method("POST", "/users", requestlog.NewHandler(a.HandleCreateUser, l))
  32. r.Method("DELETE", "/users/{user_id}", auth.DoesUserIDMatch(requestlog.NewHandler(a.HandleDeleteUser, l), mw.URLParam))
  33. r.Method("POST", "/login", requestlog.NewHandler(a.HandleLoginUser, l))
  34. r.Method("GET", "/auth/check", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleAuthCheck, l)))
  35. r.Method("POST", "/logout", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleLogoutUser, l)))
  36. // /integrations routes
  37. r.Method(
  38. "GET",
  39. "/integrations/cluster",
  40. auth.BasicAuthenticate(
  41. requestlog.NewHandler(a.HandleListClusterIntegrations, l),
  42. ),
  43. )
  44. r.Method(
  45. "GET",
  46. "/integrations/registry",
  47. auth.BasicAuthenticate(
  48. requestlog.NewHandler(a.HandleListRegistryIntegrations, l),
  49. ),
  50. )
  51. r.Method(
  52. "GET",
  53. "/integrations/repo",
  54. auth.BasicAuthenticate(
  55. requestlog.NewHandler(a.HandleListRepoIntegrations, l),
  56. ),
  57. )
  58. // /api/oauth routes
  59. // r.Method(
  60. // "GET",
  61. // "/oauth/projects/{project_id}/github",
  62. // auth.DoesUserHaveProjectAccess(
  63. // requestlog.NewHandler(a.HandleGithubOAuthStartProject, l),
  64. // mw.URLParam,
  65. // mw.WriteAccess,
  66. // ),
  67. // )
  68. // r.Method(
  69. // "GET",
  70. // "/oauth/github/callback",
  71. // requestlog.NewHandler(a.HandleGithubOAuthCallback, l),
  72. // )
  73. // /api/projects routes
  74. r.Method(
  75. "GET",
  76. "/projects/{project_id}",
  77. auth.DoesUserHaveProjectAccess(
  78. requestlog.NewHandler(a.HandleReadProject, l),
  79. mw.URLParam,
  80. mw.ReadAccess,
  81. ),
  82. )
  83. r.Method(
  84. "GET",
  85. "/projects/{project_id}/clusters/{cluster_id}",
  86. auth.DoesUserHaveProjectAccess(
  87. auth.DoesUserHaveClusterAccess(
  88. requestlog.NewHandler(a.HandleReadProjectCluster, l),
  89. mw.URLParam,
  90. mw.URLParam,
  91. ),
  92. mw.URLParam,
  93. mw.ReadAccess,
  94. ),
  95. )
  96. r.Method(
  97. "GET",
  98. "/projects/{project_id}/clusters",
  99. auth.DoesUserHaveProjectAccess(
  100. requestlog.NewHandler(a.HandleListProjectClusters, l),
  101. mw.URLParam,
  102. mw.ReadAccess,
  103. ),
  104. )
  105. r.Method("POST", "/projects", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleCreateProject, l)))
  106. r.Method(
  107. "POST",
  108. "/projects/{project_id}/clusters/candidates",
  109. auth.DoesUserHaveProjectAccess(
  110. requestlog.NewHandler(a.HandleCreateProjectClusterCandidates, l),
  111. mw.URLParam,
  112. mw.WriteAccess,
  113. ),
  114. )
  115. r.Method(
  116. "GET",
  117. "/projects/{project_id}/clusters/candidates",
  118. auth.DoesUserHaveProjectAccess(
  119. requestlog.NewHandler(a.HandleListProjectClusterCandidates, l),
  120. mw.URLParam,
  121. mw.WriteAccess,
  122. ),
  123. )
  124. r.Method(
  125. "POST",
  126. "/projects/{project_id}/clusters/candidates/{candidate_id}/resolve",
  127. auth.DoesUserHaveProjectAccess(
  128. requestlog.NewHandler(a.HandleResolveClusterCandidate, l),
  129. mw.URLParam,
  130. mw.WriteAccess,
  131. ),
  132. )
  133. r.Method(
  134. "DELETE",
  135. "/projects/{project_id}",
  136. auth.DoesUserHaveProjectAccess(
  137. requestlog.NewHandler(a.HandleDeleteProject, l),
  138. mw.URLParam,
  139. mw.WriteAccess,
  140. ),
  141. )
  142. // /api/projects/{project_id}/integrations routes
  143. r.Method(
  144. "POST",
  145. "/projects/{project_id}/integrations/gcp",
  146. auth.DoesUserHaveProjectAccess(
  147. requestlog.NewHandler(a.HandleCreateGCPIntegration, l),
  148. mw.URLParam,
  149. mw.WriteAccess,
  150. ),
  151. )
  152. r.Method(
  153. "POST",
  154. "/projects/{project_id}/integrations/aws",
  155. auth.DoesUserHaveProjectAccess(
  156. requestlog.NewHandler(a.HandleCreateAWSIntegration, l),
  157. mw.URLParam,
  158. mw.WriteAccess,
  159. ),
  160. )
  161. // /api/projects/{project_id}/registries routes
  162. r.Method(
  163. "POST",
  164. "/projects/{project_id}/registries",
  165. auth.DoesUserHaveProjectAccess(
  166. requestlog.NewHandler(a.HandleCreateRegistry, l),
  167. mw.URLParam,
  168. mw.WriteAccess,
  169. ),
  170. )
  171. r.Method(
  172. "GET",
  173. "/projects/{project_id}/registries",
  174. auth.DoesUserHaveProjectAccess(
  175. requestlog.NewHandler(a.HandleListProjectRegistries, l),
  176. mw.URLParam,
  177. mw.WriteAccess,
  178. ),
  179. )
  180. r.Method(
  181. "GET",
  182. "/projects/{project_id}/registries/{registry_id}/repositories",
  183. auth.DoesUserHaveProjectAccess(
  184. auth.DoesUserHaveRegistryAccess(
  185. requestlog.NewHandler(a.HandleListRepositories, l),
  186. mw.URLParam,
  187. mw.URLParam,
  188. ),
  189. mw.URLParam,
  190. mw.WriteAccess,
  191. ),
  192. )
  193. // /api/projects/{project_id}/releases routes
  194. r.Method(
  195. "GET",
  196. "/projects/{project_id}/releases",
  197. auth.DoesUserHaveProjectAccess(
  198. auth.DoesUserHaveClusterAccess(
  199. requestlog.NewHandler(a.HandleListReleases, l),
  200. mw.URLParam,
  201. mw.QueryParam,
  202. ),
  203. mw.URLParam,
  204. mw.ReadAccess,
  205. ),
  206. )
  207. r.Method(
  208. "GET",
  209. "/projects/{project_id}/releases/{name}/{revision}/components",
  210. auth.DoesUserHaveProjectAccess(
  211. auth.DoesUserHaveClusterAccess(
  212. requestlog.NewHandler(a.HandleGetReleaseComponents, l),
  213. mw.URLParam,
  214. mw.QueryParam,
  215. ),
  216. mw.URLParam,
  217. mw.ReadAccess,
  218. ),
  219. )
  220. r.Method(
  221. "GET",
  222. "/projects/{project_id}/releases/{name}/{revision}/controllers",
  223. auth.DoesUserHaveProjectAccess(
  224. auth.DoesUserHaveClusterAccess(
  225. requestlog.NewHandler(a.HandleGetReleaseControllers, l),
  226. mw.URLParam,
  227. mw.QueryParam,
  228. ),
  229. mw.URLParam,
  230. mw.ReadAccess,
  231. ),
  232. )
  233. r.Method(
  234. "GET",
  235. "/projects/{project_id}/releases/{name}/history",
  236. auth.DoesUserHaveProjectAccess(
  237. auth.DoesUserHaveClusterAccess(
  238. requestlog.NewHandler(a.HandleListReleaseHistory, l),
  239. mw.URLParam,
  240. mw.QueryParam,
  241. ),
  242. mw.URLParam,
  243. mw.ReadAccess,
  244. ),
  245. )
  246. r.Method(
  247. "POST",
  248. "/projects/{project_id}/releases/{name}/upgrade",
  249. auth.DoesUserHaveProjectAccess(
  250. auth.DoesUserHaveClusterAccess(
  251. requestlog.NewHandler(a.HandleUpgradeRelease, l),
  252. mw.URLParam,
  253. mw.QueryParam,
  254. ),
  255. mw.URLParam,
  256. mw.ReadAccess,
  257. ),
  258. )
  259. r.Method(
  260. "GET",
  261. "/projects/{project_id}/releases/{name}/{revision}",
  262. auth.DoesUserHaveProjectAccess(
  263. auth.DoesUserHaveClusterAccess(
  264. requestlog.NewHandler(a.HandleGetRelease, l),
  265. mw.URLParam,
  266. mw.QueryParam,
  267. ),
  268. mw.URLParam,
  269. mw.ReadAccess,
  270. ),
  271. )
  272. r.Method(
  273. "POST",
  274. "/projects/{project_id}/releases/{name}/rollback",
  275. auth.DoesUserHaveProjectAccess(
  276. auth.DoesUserHaveClusterAccess(
  277. requestlog.NewHandler(a.HandleRollbackRelease, l),
  278. mw.URLParam,
  279. mw.QueryParam,
  280. ),
  281. mw.URLParam,
  282. mw.ReadAccess,
  283. ),
  284. )
  285. // /api/projects/{project_id}/repos routes
  286. // r.Method(
  287. // "GET",
  288. // "/projects/{project_id}/repos",
  289. // auth.DoesUserHaveProjectAccess(
  290. // requestlog.NewHandler(a.HandleListRepos, l),
  291. // mw.URLParam,
  292. // mw.ReadAccess,
  293. // ),
  294. // )
  295. // r.Method(
  296. // "GET",
  297. // "/projects/{project_id}/repos/{kind}/{name}/branches",
  298. // auth.DoesUserHaveProjectAccess(
  299. // requestlog.NewHandler(a.HandleGetBranches, l),
  300. // mw.URLParam,
  301. // mw.ReadAccess,
  302. // ),
  303. // )
  304. // r.Method(
  305. // "GET",
  306. // "/projects/{project_id}/repos/{kind}/{name}/{branch}/contents",
  307. // auth.DoesUserHaveProjectAccess(
  308. // requestlog.NewHandler(a.HandleGetBranchContents, l),
  309. // mw.URLParam,
  310. // mw.ReadAccess,
  311. // ),
  312. // )
  313. // /api/projects/{project_id}/images routes
  314. // TODO: add back project access check
  315. r.Method(
  316. "GET",
  317. "/projects/{project_id}/images",
  318. auth.BasicAuthenticate(requestlog.NewHandler(a.HandleListImages, l)),
  319. )
  320. r.Method(
  321. "POST",
  322. "/projects/{project_id}/deploy",
  323. auth.DoesUserHaveProjectAccess(
  324. auth.DoesUserHaveClusterAccess(
  325. requestlog.NewHandler(a.HandleDeployTemplate, l),
  326. mw.URLParam,
  327. mw.QueryParam,
  328. ),
  329. mw.URLParam,
  330. mw.ReadAccess,
  331. ),
  332. )
  333. // /api/templates routes
  334. r.Method(
  335. "GET",
  336. "/templates",
  337. auth.BasicAuthenticate(
  338. requestlog.NewHandler(a.HandleListTemplates, l),
  339. ),
  340. )
  341. // /api/projects/{project_id}/k8s routes
  342. r.Method(
  343. "GET",
  344. "/projects/{project_id}/k8s/namespaces",
  345. auth.DoesUserHaveProjectAccess(
  346. auth.DoesUserHaveClusterAccess(
  347. requestlog.NewHandler(a.HandleListNamespaces, l),
  348. mw.URLParam,
  349. mw.QueryParam,
  350. ),
  351. mw.URLParam,
  352. mw.ReadAccess,
  353. ),
  354. )
  355. r.Method(
  356. "GET",
  357. "/projects/{project_id}/k8s/{namespace}/pod/{name}/logs",
  358. auth.DoesUserHaveProjectAccess(
  359. auth.DoesUserHaveClusterAccess(
  360. requestlog.NewHandler(a.HandleGetPodLogs, l),
  361. mw.URLParam,
  362. mw.QueryParam,
  363. ),
  364. mw.URLParam,
  365. mw.ReadAccess,
  366. ),
  367. )
  368. r.Method(
  369. "GET",
  370. "/projects/{project_id}/k8s/{kind}/status",
  371. auth.DoesUserHaveProjectAccess(
  372. auth.DoesUserHaveClusterAccess(
  373. requestlog.NewHandler(a.HandleStreamControllerStatus, l),
  374. mw.URLParam,
  375. mw.QueryParam,
  376. ),
  377. mw.URLParam,
  378. mw.ReadAccess,
  379. ),
  380. )
  381. r.Method(
  382. "GET",
  383. "/projects/{project_id}/k8s/pods",
  384. auth.DoesUserHaveProjectAccess(
  385. auth.DoesUserHaveClusterAccess(
  386. requestlog.NewHandler(a.HandleListPods, l),
  387. mw.URLParam,
  388. mw.QueryParam,
  389. ),
  390. mw.URLParam,
  391. mw.ReadAccess,
  392. ),
  393. )
  394. })
  395. fs := http.FileServer(http.Dir(staticFilePath))
  396. r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
  397. if _, err := os.Stat(staticFilePath + r.RequestURI); os.IsNotExist(err) {
  398. http.StripPrefix(r.URL.Path, fs).ServeHTTP(w, r)
  399. } else {
  400. fs.ServeHTTP(w, r)
  401. }
  402. })
  403. return r
  404. }