auth.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. package middleware
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "strconv"
  11. "github.com/go-chi/chi"
  12. "github.com/gorilla/sessions"
  13. "github.com/porter-dev/porter/internal/models"
  14. "github.com/porter-dev/porter/internal/repository"
  15. )
  16. // Auth implements the authorization functions
  17. type Auth struct {
  18. store sessions.Store
  19. cookieName string
  20. repo *repository.Repository
  21. }
  22. // NewAuth returns a new Auth instance
  23. func NewAuth(
  24. store sessions.Store,
  25. cookieName string,
  26. repo *repository.Repository,
  27. ) *Auth {
  28. return &Auth{store, cookieName, repo}
  29. }
  30. // BasicAuthenticate just checks that a user is logged in
  31. func (auth *Auth) BasicAuthenticate(next http.Handler) http.Handler {
  32. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  33. if auth.isLoggedIn(w, r) {
  34. next.ServeHTTP(w, r)
  35. } else {
  36. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  37. return
  38. }
  39. return
  40. })
  41. }
  42. // IDLocation represents the location of the ID to use for authentication
  43. type IDLocation uint
  44. const (
  45. // URLParam location looks for a parameter in the URL endpoint
  46. URLParam IDLocation = iota
  47. // BodyParam location looks for a parameter in the body
  48. BodyParam
  49. // QueryParam location looks for a parameter in the query string
  50. QueryParam
  51. )
  52. type bodyUserID struct {
  53. UserID uint64 `json:"user_id"`
  54. }
  55. type bodyProjectID struct {
  56. ProjectID uint64 `json:"project_id"`
  57. }
  58. type bodyClusterID struct {
  59. ClusterID uint64 `json:"cluster_id"`
  60. }
  61. type bodyRegistryID struct {
  62. RegistryID uint64 `json:"registry_id"`
  63. }
  64. type bodyGitRepoID struct {
  65. GitRepoID uint64 `json:"git_repo_id"`
  66. }
  67. type bodyInfraID struct {
  68. InfraID uint64 `json:"infra_id"`
  69. }
  70. type bodyAWSIntegrationID struct {
  71. AWSIntegrationID uint64 `json:"aws_integration_id"`
  72. }
  73. type bodyGCPIntegrationID struct {
  74. GCPIntegrationID uint64 `json:"gcp_integration_id"`
  75. }
  76. type bodyDOIntegrationID struct {
  77. DOIntegrationID uint64 `json:"do_integration_id"`
  78. }
  79. // DoesUserIDMatch checks the id URL parameter and verifies that it matches
  80. // the one stored in the session
  81. func (auth *Auth) DoesUserIDMatch(next http.Handler, loc IDLocation) http.Handler {
  82. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  83. var err error
  84. id, err := findUserIDInRequest(r, loc)
  85. if err == nil && auth.doesSessionMatchID(r, uint(id)) {
  86. next.ServeHTTP(w, r)
  87. } else {
  88. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  89. return
  90. }
  91. return
  92. })
  93. }
  94. // AccessType represents the various access types for a project
  95. type AccessType string
  96. // The various access types
  97. const (
  98. ReadAccess AccessType = "read"
  99. WriteAccess AccessType = "write"
  100. )
  101. // DoesUserHaveProjectAccess looks for a project_id parameter and checks that the
  102. // user has access via the specified accessType
  103. func (auth *Auth) DoesUserHaveProjectAccess(
  104. next http.Handler,
  105. projLoc IDLocation,
  106. accessType AccessType,
  107. ) http.Handler {
  108. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  109. var err error
  110. projID, err := findProjIDInRequest(r, projLoc)
  111. if err != nil {
  112. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  113. return
  114. }
  115. session, err := auth.store.Get(r, auth.cookieName)
  116. if err != nil {
  117. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  118. return
  119. }
  120. userID, ok := session.Values["user_id"].(uint)
  121. if !ok {
  122. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  123. return
  124. }
  125. // get the project
  126. proj, err := auth.repo.Project.ReadProject(uint(projID))
  127. if err != nil {
  128. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  129. return
  130. }
  131. // look for the user role in the project
  132. for _, role := range proj.Roles {
  133. if role.UserID == userID {
  134. if accessType == ReadAccess {
  135. next.ServeHTTP(w, r)
  136. return
  137. } else if accessType == WriteAccess {
  138. if role.Kind == models.RoleAdmin {
  139. next.ServeHTTP(w, r)
  140. return
  141. }
  142. }
  143. }
  144. }
  145. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  146. return
  147. })
  148. }
  149. // DoesUserHaveClusterAccess looks for a project_id parameter and a
  150. // cluster_id parameter, and verifies that the cluster belongs
  151. // to the project
  152. func (auth *Auth) DoesUserHaveClusterAccess(
  153. next http.Handler,
  154. projLoc IDLocation,
  155. clusterLoc IDLocation,
  156. ) http.Handler {
  157. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  158. clusterID, err := findClusterIDInRequest(r, clusterLoc)
  159. if err != nil {
  160. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  161. return
  162. }
  163. projID, err := findProjIDInRequest(r, projLoc)
  164. if err != nil {
  165. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  166. return
  167. }
  168. // get the service accounts belonging to the project
  169. clusters, err := auth.repo.Cluster.ListClustersByProjectID(uint(projID))
  170. if err != nil {
  171. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  172. return
  173. }
  174. doesExist := false
  175. for _, cluster := range clusters {
  176. if cluster.ID == uint(clusterID) {
  177. doesExist = true
  178. break
  179. }
  180. }
  181. if doesExist {
  182. next.ServeHTTP(w, r)
  183. return
  184. }
  185. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  186. return
  187. })
  188. }
  189. // DoesUserHaveRegistryAccess looks for a project_id parameter and a
  190. // registry_id parameter, and verifies that the registry belongs
  191. // to the project
  192. func (auth *Auth) DoesUserHaveRegistryAccess(
  193. next http.Handler,
  194. projLoc IDLocation,
  195. registryLoc IDLocation,
  196. ) http.Handler {
  197. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  198. regID, err := findRegistryIDInRequest(r, registryLoc)
  199. if err != nil {
  200. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  201. return
  202. }
  203. projID, err := findProjIDInRequest(r, projLoc)
  204. if err != nil {
  205. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  206. return
  207. }
  208. // get the service accounts belonging to the project
  209. regs, err := auth.repo.Registry.ListRegistriesByProjectID(uint(projID))
  210. if err != nil {
  211. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  212. return
  213. }
  214. doesExist := false
  215. for _, reg := range regs {
  216. if reg.ID == uint(regID) {
  217. doesExist = true
  218. break
  219. }
  220. }
  221. if doesExist {
  222. next.ServeHTTP(w, r)
  223. return
  224. }
  225. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  226. return
  227. })
  228. }
  229. // DoesUserHaveGitRepoAccess looks for a project_id parameter and a
  230. // git_repo_id parameter, and verifies that the git repo belongs
  231. // to the project
  232. func (auth *Auth) DoesUserHaveGitRepoAccess(
  233. next http.Handler,
  234. projLoc IDLocation,
  235. gitRepoLoc IDLocation,
  236. ) http.Handler {
  237. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  238. grID, err := findGitRepoIDInRequest(r, gitRepoLoc)
  239. if err != nil {
  240. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  241. return
  242. }
  243. projID, err := findProjIDInRequest(r, projLoc)
  244. if err != nil {
  245. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  246. return
  247. }
  248. // get the service accounts belonging to the project
  249. grs, err := auth.repo.GitRepo.ListGitReposByProjectID(uint(projID))
  250. if err != nil {
  251. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  252. return
  253. }
  254. doesExist := false
  255. for _, gr := range grs {
  256. if gr.ID == uint(grID) {
  257. doesExist = true
  258. break
  259. }
  260. }
  261. if doesExist {
  262. next.ServeHTTP(w, r)
  263. return
  264. }
  265. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  266. return
  267. })
  268. }
  269. // DoesUserHaveInfraAccess looks for a project_id parameter and an
  270. // infra_id parameter, and verifies that the infra belongs
  271. // to the project
  272. func (auth *Auth) DoesUserHaveInfraAccess(
  273. next http.Handler,
  274. projLoc IDLocation,
  275. infraLoc IDLocation,
  276. ) http.Handler {
  277. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  278. infraID, err := findInfraIDInRequest(r, infraLoc)
  279. if err != nil {
  280. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  281. return
  282. }
  283. projID, err := findProjIDInRequest(r, projLoc)
  284. if err != nil {
  285. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  286. return
  287. }
  288. infras, err := auth.repo.Infra.ListInfrasByProjectID(uint(projID))
  289. if err != nil {
  290. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  291. return
  292. }
  293. doesExist := false
  294. for _, infra := range infras {
  295. if infra.ID == uint(infraID) {
  296. doesExist = true
  297. break
  298. }
  299. }
  300. if doesExist {
  301. next.ServeHTTP(w, r)
  302. return
  303. }
  304. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  305. return
  306. })
  307. }
  308. // DoesUserHaveAWSIntegrationAccess looks for a project_id parameter and an
  309. // aws_integration_id parameter, and verifies that the infra belongs
  310. // to the project
  311. func (auth *Auth) DoesUserHaveAWSIntegrationAccess(
  312. next http.Handler,
  313. projLoc IDLocation,
  314. awsLoc IDLocation,
  315. optional bool,
  316. ) http.Handler {
  317. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  318. awsID, err := findAWSIntegrationIDInRequest(r, awsLoc)
  319. if awsID == 0 && optional {
  320. next.ServeHTTP(w, r)
  321. return
  322. }
  323. if awsID == 0 || err != nil {
  324. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  325. return
  326. }
  327. projID, err := findProjIDInRequest(r, projLoc)
  328. if err != nil {
  329. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  330. return
  331. }
  332. awsInts, err := auth.repo.AWSIntegration.ListAWSIntegrationsByProjectID(uint(projID))
  333. if err != nil {
  334. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  335. return
  336. }
  337. doesExist := false
  338. for _, awsInt := range awsInts {
  339. if awsInt.ID == uint(awsID) {
  340. doesExist = true
  341. break
  342. }
  343. }
  344. if doesExist {
  345. next.ServeHTTP(w, r)
  346. return
  347. }
  348. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  349. return
  350. })
  351. }
  352. // DoesUserHaveGCPIntegrationAccess looks for a project_id parameter and an
  353. // gcp_integration_id parameter, and verifies that the infra belongs
  354. // to the project
  355. func (auth *Auth) DoesUserHaveGCPIntegrationAccess(
  356. next http.Handler,
  357. projLoc IDLocation,
  358. gcpLoc IDLocation,
  359. optional bool,
  360. ) http.Handler {
  361. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  362. gcpID, err := findGCPIntegrationIDInRequest(r, gcpLoc)
  363. if gcpID == 0 && optional {
  364. next.ServeHTTP(w, r)
  365. return
  366. }
  367. if gcpID == 0 || err != nil {
  368. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  369. return
  370. }
  371. projID, err := findProjIDInRequest(r, projLoc)
  372. if err != nil {
  373. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  374. return
  375. }
  376. gcpInts, err := auth.repo.GCPIntegration.ListGCPIntegrationsByProjectID(uint(projID))
  377. if err != nil {
  378. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  379. return
  380. }
  381. doesExist := false
  382. for _, awsInt := range gcpInts {
  383. if awsInt.ID == uint(gcpID) {
  384. doesExist = true
  385. break
  386. }
  387. }
  388. if doesExist {
  389. next.ServeHTTP(w, r)
  390. return
  391. }
  392. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  393. return
  394. })
  395. }
  396. // DoesUserHaveDOIntegrationAccess looks for a project_id parameter and an
  397. // do_integration_id parameter, and verifies that the infra belongs
  398. // to the project
  399. func (auth *Auth) DoesUserHaveDOIntegrationAccess(
  400. next http.Handler,
  401. projLoc IDLocation,
  402. doLoc IDLocation,
  403. optional bool,
  404. ) http.Handler {
  405. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  406. doID, err := findDOIntegrationIDInRequest(r, doLoc)
  407. if doID == 0 && optional {
  408. next.ServeHTTP(w, r)
  409. return
  410. }
  411. if doID == 0 || err != nil {
  412. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  413. return
  414. }
  415. projID, err := findProjIDInRequest(r, projLoc)
  416. if err != nil {
  417. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  418. return
  419. }
  420. oauthInts, err := auth.repo.OAuthIntegration.ListOAuthIntegrationsByProjectID(uint(projID))
  421. if err != nil {
  422. http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  423. return
  424. }
  425. doesExist := false
  426. for _, oauthInt := range oauthInts {
  427. if oauthInt.ID == uint(doID) {
  428. doesExist = true
  429. break
  430. }
  431. }
  432. if doesExist {
  433. next.ServeHTTP(w, r)
  434. return
  435. }
  436. http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
  437. return
  438. })
  439. }
  440. // Helpers
  441. func (auth *Auth) doesSessionMatchID(r *http.Request, id uint) bool {
  442. session, _ := auth.store.Get(r, auth.cookieName)
  443. if sessID, ok := session.Values["user_id"].(uint); !ok || sessID != id {
  444. return false
  445. }
  446. return true
  447. }
  448. func (auth *Auth) isLoggedIn(w http.ResponseWriter, r *http.Request) bool {
  449. session, err := auth.store.Get(r, auth.cookieName)
  450. if err != nil {
  451. session.Values["authenticated"] = false
  452. if err := session.Save(r, w); err != nil {
  453. fmt.Println("error while saving session in isLoggedIn", err)
  454. }
  455. return false
  456. }
  457. if auth, ok := session.Values["authenticated"].(bool); !auth || !ok {
  458. return false
  459. }
  460. return true
  461. }
  462. func findUserIDInRequest(r *http.Request, userLoc IDLocation) (uint64, error) {
  463. var userID uint64
  464. var err error
  465. if userLoc == URLParam {
  466. userID, err = strconv.ParseUint(chi.URLParam(r, "user_id"), 0, 64)
  467. if err != nil {
  468. return 0, err
  469. }
  470. } else if userLoc == BodyParam {
  471. form := &bodyUserID{}
  472. body, err := ioutil.ReadAll(r.Body)
  473. if err != nil {
  474. return 0, err
  475. }
  476. err = json.Unmarshal(body, form)
  477. if err != nil {
  478. return 0, err
  479. }
  480. userID = form.UserID
  481. // need to create a new stream for the body
  482. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  483. } else {
  484. vals, err := url.ParseQuery(r.URL.RawQuery)
  485. if err != nil {
  486. return 0, err
  487. }
  488. if userStrArr, ok := vals["user_id"]; ok && len(userStrArr) == 1 {
  489. userID, err = strconv.ParseUint(userStrArr[0], 10, 64)
  490. } else {
  491. return 0, errors.New("user id not found")
  492. }
  493. }
  494. return userID, nil
  495. }
  496. func findProjIDInRequest(r *http.Request, projLoc IDLocation) (uint64, error) {
  497. var projID uint64
  498. var err error
  499. if projLoc == URLParam {
  500. projID, err = strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
  501. if err != nil {
  502. return 0, err
  503. }
  504. } else if projLoc == BodyParam {
  505. form := &bodyProjectID{}
  506. body, err := ioutil.ReadAll(r.Body)
  507. if err != nil {
  508. return 0, err
  509. }
  510. err = json.Unmarshal(body, form)
  511. if err != nil {
  512. return 0, err
  513. }
  514. projID = form.ProjectID
  515. // need to create a new stream for the body
  516. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  517. } else {
  518. vals, err := url.ParseQuery(r.URL.RawQuery)
  519. if err != nil {
  520. return 0, err
  521. }
  522. if projStrArr, ok := vals["project_id"]; ok && len(projStrArr) == 1 {
  523. projID, err = strconv.ParseUint(projStrArr[0], 10, 64)
  524. } else {
  525. return 0, errors.New("project id not found")
  526. }
  527. }
  528. return projID, nil
  529. }
  530. func findClusterIDInRequest(r *http.Request, clusterLoc IDLocation) (uint64, error) {
  531. var clusterID uint64
  532. var err error
  533. if clusterLoc == URLParam {
  534. clusterID, err = strconv.ParseUint(chi.URLParam(r, "cluster_id"), 0, 64)
  535. if err != nil {
  536. return 0, err
  537. }
  538. } else if clusterLoc == BodyParam {
  539. form := &bodyClusterID{}
  540. body, err := ioutil.ReadAll(r.Body)
  541. if err != nil {
  542. return 0, err
  543. }
  544. err = json.Unmarshal(body, form)
  545. if err != nil {
  546. return 0, err
  547. }
  548. clusterID = form.ClusterID
  549. // need to create a new stream for the body
  550. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  551. } else {
  552. vals, err := url.ParseQuery(r.URL.RawQuery)
  553. if err != nil {
  554. return 0, err
  555. }
  556. if clStrArr, ok := vals["cluster_id"]; ok && len(clStrArr) == 1 {
  557. clusterID, err = strconv.ParseUint(clStrArr[0], 10, 64)
  558. } else {
  559. return 0, errors.New("cluster id not found")
  560. }
  561. }
  562. return clusterID, nil
  563. }
  564. func findRegistryIDInRequest(r *http.Request, registryLoc IDLocation) (uint64, error) {
  565. var regID uint64
  566. var err error
  567. if registryLoc == URLParam {
  568. regID, err = strconv.ParseUint(chi.URLParam(r, "registry_id"), 0, 64)
  569. if err != nil {
  570. return 0, err
  571. }
  572. } else if registryLoc == BodyParam {
  573. form := &bodyRegistryID{}
  574. body, err := ioutil.ReadAll(r.Body)
  575. if err != nil {
  576. return 0, err
  577. }
  578. err = json.Unmarshal(body, form)
  579. if err != nil {
  580. return 0, err
  581. }
  582. regID = form.RegistryID
  583. // need to create a new stream for the body
  584. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  585. } else {
  586. vals, err := url.ParseQuery(r.URL.RawQuery)
  587. if err != nil {
  588. return 0, err
  589. }
  590. if regStrArr, ok := vals["registry_id"]; ok && len(regStrArr) == 1 {
  591. regID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  592. } else {
  593. return 0, errors.New("registry id not found")
  594. }
  595. }
  596. return regID, nil
  597. }
  598. func findGitRepoIDInRequest(r *http.Request, gitRepoLoc IDLocation) (uint64, error) {
  599. var grID uint64
  600. var err error
  601. if gitRepoLoc == URLParam {
  602. grID, err = strconv.ParseUint(chi.URLParam(r, "git_repo_id"), 0, 64)
  603. if err != nil {
  604. return 0, err
  605. }
  606. } else if gitRepoLoc == BodyParam {
  607. form := &bodyGitRepoID{}
  608. body, err := ioutil.ReadAll(r.Body)
  609. if err != nil {
  610. return 0, err
  611. }
  612. err = json.Unmarshal(body, form)
  613. if err != nil {
  614. return 0, err
  615. }
  616. grID = form.GitRepoID
  617. // need to create a new stream for the body
  618. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  619. } else {
  620. vals, err := url.ParseQuery(r.URL.RawQuery)
  621. if err != nil {
  622. return 0, err
  623. }
  624. if regStrArr, ok := vals["git_repo_id"]; ok && len(regStrArr) == 1 {
  625. grID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  626. } else {
  627. return 0, errors.New("git repo id not found")
  628. }
  629. }
  630. return grID, nil
  631. }
  632. func findInfraIDInRequest(r *http.Request, infraLoc IDLocation) (uint64, error) {
  633. var infraID uint64
  634. var err error
  635. if infraLoc == URLParam {
  636. infraID, err = strconv.ParseUint(chi.URLParam(r, "infra_id"), 0, 64)
  637. if err != nil {
  638. return 0, err
  639. }
  640. } else if infraLoc == BodyParam {
  641. form := &bodyInfraID{}
  642. body, err := ioutil.ReadAll(r.Body)
  643. if err != nil {
  644. return 0, err
  645. }
  646. err = json.Unmarshal(body, form)
  647. if err != nil {
  648. return 0, err
  649. }
  650. infraID = form.InfraID
  651. // need to create a new stream for the body
  652. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  653. } else {
  654. vals, err := url.ParseQuery(r.URL.RawQuery)
  655. if err != nil {
  656. return 0, err
  657. }
  658. if regStrArr, ok := vals["infra_id"]; ok && len(regStrArr) == 1 {
  659. infraID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  660. } else {
  661. return 0, errors.New("infra id not found")
  662. }
  663. }
  664. return infraID, nil
  665. }
  666. func findAWSIntegrationIDInRequest(r *http.Request, awsLoc IDLocation) (uint64, error) {
  667. var awsID uint64
  668. var err error
  669. if awsLoc == URLParam {
  670. awsID, err = strconv.ParseUint(chi.URLParam(r, "aws_integration_id"), 0, 64)
  671. if err != nil {
  672. return 0, err
  673. }
  674. } else if awsLoc == BodyParam {
  675. form := &bodyAWSIntegrationID{}
  676. body, err := ioutil.ReadAll(r.Body)
  677. if err != nil {
  678. return 0, err
  679. }
  680. err = json.Unmarshal(body, form)
  681. if err != nil {
  682. return 0, err
  683. }
  684. awsID = form.AWSIntegrationID
  685. // need to create a new stream for the body
  686. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  687. } else {
  688. vals, err := url.ParseQuery(r.URL.RawQuery)
  689. if err != nil {
  690. return 0, err
  691. }
  692. if regStrArr, ok := vals["aws_integration_id"]; ok && len(regStrArr) == 1 {
  693. awsID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  694. } else {
  695. return 0, errors.New("aws integration id not found")
  696. }
  697. }
  698. return awsID, nil
  699. }
  700. func findGCPIntegrationIDInRequest(r *http.Request, gcpLoc IDLocation) (uint64, error) {
  701. var gcpID uint64
  702. var err error
  703. if gcpLoc == URLParam {
  704. gcpID, err = strconv.ParseUint(chi.URLParam(r, "gcp_integration_id"), 0, 64)
  705. if err != nil {
  706. return 0, err
  707. }
  708. } else if gcpLoc == BodyParam {
  709. form := &bodyGCPIntegrationID{}
  710. body, err := ioutil.ReadAll(r.Body)
  711. if err != nil {
  712. return 0, err
  713. }
  714. err = json.Unmarshal(body, form)
  715. if err != nil {
  716. return 0, err
  717. }
  718. gcpID = form.GCPIntegrationID
  719. // need to create a new stream for the body
  720. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  721. } else {
  722. vals, err := url.ParseQuery(r.URL.RawQuery)
  723. if err != nil {
  724. return 0, err
  725. }
  726. if regStrArr, ok := vals["gcp_integration_id"]; ok && len(regStrArr) == 1 {
  727. gcpID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  728. } else {
  729. return 0, errors.New("gcp integration id not found")
  730. }
  731. }
  732. return gcpID, nil
  733. }
  734. func findDOIntegrationIDInRequest(r *http.Request, doLoc IDLocation) (uint64, error) {
  735. var doID uint64
  736. var err error
  737. if doLoc == URLParam {
  738. doID, err = strconv.ParseUint(chi.URLParam(r, "do_integration_id"), 0, 64)
  739. if err != nil {
  740. return 0, err
  741. }
  742. } else if doLoc == BodyParam {
  743. form := &bodyDOIntegrationID{}
  744. body, err := ioutil.ReadAll(r.Body)
  745. if err != nil {
  746. return 0, err
  747. }
  748. err = json.Unmarshal(body, form)
  749. if err != nil {
  750. return 0, err
  751. }
  752. doID = form.DOIntegrationID
  753. // need to create a new stream for the body
  754. r.Body = ioutil.NopCloser(bytes.NewReader(body))
  755. } else {
  756. vals, err := url.ParseQuery(r.URL.RawQuery)
  757. if err != nil {
  758. return 0, err
  759. }
  760. if regStrArr, ok := vals["do_integration_id"]; ok && len(regStrArr) == 1 {
  761. doID, err = strconv.ParseUint(regStrArr[0], 10, 64)
  762. } else {
  763. return 0, errors.New("do integration id not found")
  764. }
  765. }
  766. return doID, nil
  767. }