/engine/api/router_middleware_auth_permission_test.go

https://github.com/ovh/cds · Go · 1079 lines · 984 code · 85 blank · 10 comment · 46 complexity · 315aa8ea0a5c8120b716b03df480d3f9 MD5 · raw file

  1. package api
  2. import (
  3. "context"
  4. "reflect"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. "github.com/ovh/cds/engine/api/action"
  10. "github.com/ovh/cds/engine/api/authentication"
  11. "github.com/ovh/cds/engine/api/authentication/local"
  12. "github.com/ovh/cds/engine/api/group"
  13. "github.com/ovh/cds/engine/api/test/assets"
  14. "github.com/ovh/cds/engine/api/user"
  15. "github.com/ovh/cds/engine/api/workermodel"
  16. "github.com/ovh/cds/engine/api/workflowtemplate"
  17. "github.com/ovh/cds/sdk"
  18. )
  19. func Test_checkWorkflowPermissions(t *testing.T) {
  20. api, db, _ := newTestAPI(t)
  21. wctx := testRunWorkflow(t, api, api.Router)
  22. user := wctx.user
  23. admin, _ := assets.InsertAdminUser(t, db)
  24. maintainer, _ := assets.InsertAdminUser(t, db)
  25. ctx := context.Background()
  26. consumer := &sdk.AuthConsumer{}
  27. // test case: has enough permission
  28. consumer.AuthentifiedUser = user
  29. ctx = context.WithValue(ctx, contextAPIConsumer, consumer)
  30. err := api.checkWorkflowPermissions(ctx, wctx.workflow.Name, sdk.PermissionReadWriteExecute, map[string]string{
  31. "key": wctx.project.Key,
  32. "permWorkflowName": wctx.workflow.Name,
  33. })
  34. assert.NoError(t, err, "should be granted because has permission (max permission = 7)")
  35. // test case: is Admin
  36. consumer.GroupIDs = nil
  37. consumer.AuthentifiedUser.Groups = nil
  38. consumer.AuthentifiedUser = admin
  39. ctx = context.WithValue(ctx, contextAPIConsumer, consumer)
  40. err = api.checkWorkflowPermissions(ctx, wctx.workflow.Name, sdk.PermissionReadWriteExecute, map[string]string{
  41. "key": wctx.project.Key,
  42. "permWorkflowName": wctx.workflow.Name,
  43. })
  44. assert.NoError(t, err, "should be granted because because is admin")
  45. // test case: is Maintainer
  46. consumer.GroupIDs = nil
  47. consumer.AuthentifiedUser.Groups = nil
  48. consumer.AuthentifiedUser = maintainer
  49. ctx = context.WithValue(ctx, contextAPIConsumer, consumer)
  50. err = api.checkWorkflowPermissions(ctx, wctx.workflow.Name, sdk.PermissionRead, map[string]string{
  51. "key": wctx.project.Key,
  52. "permWorkflowName": wctx.workflow.Name,
  53. })
  54. assert.NoError(t, err, "should be granted because because is maintainer")
  55. // test case: forbidden
  56. consumer.GroupIDs = nil
  57. consumer.AuthentifiedUser.Groups = nil
  58. consumer.AuthentifiedUser.Ring = ""
  59. consumer.AuthentifiedUser = user
  60. ctx = context.WithValue(ctx, contextAPIConsumer, consumer)
  61. err = api.checkWorkflowPermissions(ctx, wctx.workflow.Name, sdk.PermissionRead, map[string]string{
  62. "key": wctx.project.Key,
  63. "permWorkflowName": wctx.workflow.Name,
  64. })
  65. assert.Error(t, err, "should not be granted")
  66. }
  67. func Test_checkProjectPermissions(t *testing.T) {
  68. api, db, _ := newTestAPI(t)
  69. g := assets.InsertGroup(t, db)
  70. authUser, _ := assets.InsertLambdaUser(t, db, g)
  71. p := assets.InsertTestProject(t, db, api.Cache, sdk.RandomString(10), sdk.RandomString(10))
  72. require.NoError(t, group.InsertLinkGroupUser(context.TODO(), db, &group.LinkGroupUser{
  73. GroupID: p.ProjectGroups[0].Group.ID,
  74. AuthentifiedUserID: authUser.ID,
  75. Admin: false,
  76. }))
  77. // Reload the groups for the user
  78. groups, err := group.LoadAllByUserID(context.TODO(), api.mustDB(), authUser.ID)
  79. require.NoError(t, err)
  80. authUser.Groups = groups
  81. var consumer sdk.AuthConsumer
  82. consumer.AuthentifiedUser = authUser
  83. ctx := context.Background()
  84. // test case: has enough permission
  85. ctx = context.WithValue(ctx, contextAPIConsumer, &consumer)
  86. err = api.checkProjectPermissions(ctx, p.Key, sdk.PermissionReadWriteExecute, nil)
  87. assert.NoError(t, err, "should be granted because has permission (max permission = 7)")
  88. // test case: is Admin
  89. consumer.AuthentifiedUser.Ring = sdk.UserRingAdmin
  90. consumer.GroupIDs = nil
  91. consumer.AuthentifiedUser.Groups = nil
  92. ctx = context.WithValue(ctx, contextAPIConsumer, &consumer)
  93. err = api.checkProjectPermissions(ctx, p.Key, sdk.PermissionReadWriteExecute, nil)
  94. assert.NoError(t, err, "should be granted because because is admin")
  95. // test case: is Maintainer
  96. consumer.GroupIDs = nil
  97. consumer.AuthentifiedUser.Groups = nil
  98. ctx = context.WithValue(ctx, contextAPIConsumer, &consumer)
  99. err = api.checkProjectPermissions(ctx, p.Key, sdk.PermissionRead, nil)
  100. assert.NoError(t, err, "should be granted because because is maintainer")
  101. // test case: forbidden
  102. consumer.GroupIDs = nil
  103. consumer.AuthentifiedUser.Groups = nil
  104. consumer.AuthentifiedUser.Ring = ""
  105. ctx = context.WithValue(ctx, contextAPIConsumer, &consumer)
  106. err = api.checkProjectPermissions(ctx, p.Key, sdk.PermissionRead, nil)
  107. assert.Error(t, err, "should not be granted")
  108. }
  109. func Test_checkUserPermissions(t *testing.T) {
  110. api, db, _ := newTestAPI(t)
  111. authUser, _ := assets.InsertLambdaUser(t, db)
  112. authUserMaintainer, _ := assets.InsertMaintainerUser(t, db)
  113. authUserAdmin, _ := assets.InsertAdminUser(t, db)
  114. cases := []struct {
  115. Name string
  116. ConsumerAuthentifiedUser *sdk.AuthentifiedUser
  117. TargetAuthentifiedUser *sdk.AuthentifiedUser
  118. Permission int
  119. Granted bool
  120. }{
  121. {
  122. Name: "RW on himself",
  123. ConsumerAuthentifiedUser: authUser,
  124. TargetAuthentifiedUser: authUser,
  125. Permission: sdk.PermissionReadWriteExecute,
  126. Granted: true,
  127. },
  128. {
  129. Name: "R on other by lambda user",
  130. ConsumerAuthentifiedUser: authUser,
  131. TargetAuthentifiedUser: authUserAdmin,
  132. Permission: sdk.PermissionRead,
  133. Granted: false,
  134. },
  135. {
  136. Name: "R on other by admin user",
  137. ConsumerAuthentifiedUser: authUserAdmin,
  138. TargetAuthentifiedUser: authUser,
  139. Permission: sdk.PermissionRead,
  140. Granted: true,
  141. },
  142. {
  143. Name: "R on other by maintainer user",
  144. ConsumerAuthentifiedUser: authUserMaintainer,
  145. TargetAuthentifiedUser: authUser,
  146. Permission: sdk.PermissionRead,
  147. Granted: true,
  148. },
  149. {
  150. Name: "RW on other by lambda user",
  151. ConsumerAuthentifiedUser: authUser,
  152. TargetAuthentifiedUser: authUserAdmin,
  153. Permission: sdk.PermissionReadWriteExecute,
  154. Granted: false,
  155. },
  156. {
  157. Name: "RW on other by maintainer user",
  158. ConsumerAuthentifiedUser: authUserMaintainer,
  159. TargetAuthentifiedUser: authUser,
  160. Permission: sdk.PermissionReadWriteExecute,
  161. Granted: false,
  162. },
  163. {
  164. Name: "RW on other by admin user",
  165. ConsumerAuthentifiedUser: authUserAdmin,
  166. TargetAuthentifiedUser: authUser,
  167. Permission: sdk.PermissionReadWriteExecute,
  168. Granted: true,
  169. },
  170. }
  171. for _, c := range cases {
  172. t.Run(c.Name, func(t *testing.T) {
  173. ctx := context.WithValue(context.TODO(), contextAPIConsumer, &sdk.AuthConsumer{
  174. AuthentifiedUserID: c.ConsumerAuthentifiedUser.ID,
  175. AuthentifiedUser: c.ConsumerAuthentifiedUser,
  176. IssuedAt: time.Now(),
  177. })
  178. err := api.checkUserPermissions(ctx, c.TargetAuthentifiedUser.Username, c.Permission, nil)
  179. if c.Granted {
  180. assert.NoError(t, err, "should be granted")
  181. } else {
  182. assert.Error(t, err, "should not be granted")
  183. }
  184. })
  185. }
  186. }
  187. func Test_checkUserPublicPermissions(t *testing.T) {
  188. api, db, _ := newTestAPI(t)
  189. authUser, _ := assets.InsertLambdaUser(t, db)
  190. authUserMaintainer, _ := assets.InsertMaintainerUser(t, db)
  191. authUserAdmin, _ := assets.InsertAdminUser(t, db)
  192. cases := []struct {
  193. Name string
  194. ConsumerAuthentifiedUser *sdk.AuthentifiedUser
  195. TargetAuthentifiedUser *sdk.AuthentifiedUser
  196. Permission int
  197. Granted bool
  198. }{
  199. {
  200. Name: "RW on himself",
  201. ConsumerAuthentifiedUser: authUser,
  202. TargetAuthentifiedUser: authUser,
  203. Permission: sdk.PermissionReadWriteExecute,
  204. Granted: true,
  205. },
  206. {
  207. Name: "R on other by lambda user",
  208. ConsumerAuthentifiedUser: authUser,
  209. TargetAuthentifiedUser: authUserAdmin,
  210. Permission: sdk.PermissionRead,
  211. Granted: true,
  212. },
  213. {
  214. Name: "R on other by admin user",
  215. ConsumerAuthentifiedUser: authUserAdmin,
  216. TargetAuthentifiedUser: authUser,
  217. Permission: sdk.PermissionRead,
  218. Granted: true,
  219. },
  220. {
  221. Name: "R on other by maintainer user",
  222. ConsumerAuthentifiedUser: authUserMaintainer,
  223. TargetAuthentifiedUser: authUser,
  224. Permission: sdk.PermissionRead,
  225. Granted: true,
  226. },
  227. {
  228. Name: "RW on other by lambda user",
  229. ConsumerAuthentifiedUser: authUser,
  230. TargetAuthentifiedUser: authUserAdmin,
  231. Permission: sdk.PermissionReadWriteExecute,
  232. Granted: false,
  233. },
  234. {
  235. Name: "RW on other by maintainer user",
  236. ConsumerAuthentifiedUser: authUserMaintainer,
  237. TargetAuthentifiedUser: authUser,
  238. Permission: sdk.PermissionReadWriteExecute,
  239. Granted: false,
  240. },
  241. {
  242. Name: "RW on other by admin user",
  243. ConsumerAuthentifiedUser: authUserAdmin,
  244. TargetAuthentifiedUser: authUser,
  245. Permission: sdk.PermissionReadWriteExecute,
  246. Granted: true,
  247. },
  248. }
  249. for _, c := range cases {
  250. t.Run(c.Name, func(t *testing.T) {
  251. ctx := context.WithValue(context.TODO(), contextAPIConsumer, &sdk.AuthConsumer{
  252. AuthentifiedUserID: c.ConsumerAuthentifiedUser.ID,
  253. AuthentifiedUser: c.ConsumerAuthentifiedUser,
  254. IssuedAt: time.Now(),
  255. })
  256. err := api.checkUserPublicPermissions(ctx, c.TargetAuthentifiedUser.Username, c.Permission, nil)
  257. if c.Granted {
  258. assert.NoError(t, err, "should be granted")
  259. } else {
  260. assert.Error(t, err, "should not be granted")
  261. }
  262. })
  263. }
  264. }
  265. func Test_checkConsumerPermissions(t *testing.T) {
  266. api, db, _ := newTestAPI(t)
  267. authUser, _ := assets.InsertLambdaUser(t, db)
  268. authUserConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, authUser.ID)
  269. require.NoError(t, err)
  270. authUserMaintainer, _ := assets.InsertMaintainerUser(t, db)
  271. authUserMaintainerConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, authUserMaintainer.ID)
  272. require.NoError(t, err)
  273. authUserAdmin, _ := assets.InsertAdminUser(t, db)
  274. cases := []struct {
  275. Name string
  276. ConsumerAuthentifiedUser *sdk.AuthentifiedUser
  277. TargetConsumer *sdk.AuthConsumer
  278. Permission int
  279. Granted bool
  280. }{
  281. {
  282. Name: "RW on himself",
  283. ConsumerAuthentifiedUser: authUser,
  284. TargetConsumer: authUserConsumer,
  285. Permission: sdk.PermissionReadWriteExecute,
  286. Granted: true,
  287. },
  288. {
  289. Name: "R on other by lambda user",
  290. ConsumerAuthentifiedUser: authUser,
  291. TargetConsumer: authUserMaintainerConsumer,
  292. Permission: sdk.PermissionRead,
  293. Granted: false,
  294. },
  295. {
  296. Name: "R on other by admin user",
  297. ConsumerAuthentifiedUser: authUserAdmin,
  298. TargetConsumer: authUserConsumer,
  299. Permission: sdk.PermissionRead,
  300. Granted: true,
  301. },
  302. {
  303. Name: "R on other by maintainer user",
  304. ConsumerAuthentifiedUser: authUserMaintainer,
  305. TargetConsumer: authUserConsumer,
  306. Permission: sdk.PermissionRead,
  307. Granted: true,
  308. },
  309. {
  310. Name: "RW on other by lambda user",
  311. ConsumerAuthentifiedUser: authUser,
  312. TargetConsumer: authUserMaintainerConsumer,
  313. Permission: sdk.PermissionReadWriteExecute,
  314. Granted: false,
  315. },
  316. {
  317. Name: "RW on other by maintainer user",
  318. ConsumerAuthentifiedUser: authUserMaintainer,
  319. TargetConsumer: authUserConsumer,
  320. Permission: sdk.PermissionReadWriteExecute,
  321. Granted: false,
  322. },
  323. {
  324. Name: "RW on other by admin user",
  325. ConsumerAuthentifiedUser: authUserAdmin,
  326. TargetConsumer: authUserConsumer,
  327. Permission: sdk.PermissionReadWriteExecute,
  328. Granted: true,
  329. },
  330. }
  331. for _, c := range cases {
  332. t.Run(c.Name, func(t *testing.T) {
  333. ctx := context.WithValue(context.TODO(), contextAPIConsumer, &sdk.AuthConsumer{
  334. AuthentifiedUserID: c.ConsumerAuthentifiedUser.ID,
  335. AuthentifiedUser: c.ConsumerAuthentifiedUser,
  336. IssuedAt: time.Now(),
  337. })
  338. err := api.checkConsumerPermissions(ctx, c.TargetConsumer.ID, c.Permission, nil)
  339. if c.Granted {
  340. assert.NoError(t, err, "should be granted")
  341. } else {
  342. assert.Error(t, err, "should not be granted")
  343. }
  344. })
  345. }
  346. }
  347. func Test_checkSessionPermissions(t *testing.T) {
  348. api, db, _ := newTestAPI(t)
  349. authUser, _ := assets.InsertLambdaUser(t, db)
  350. authUserConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, authUser.ID)
  351. require.NoError(t, err)
  352. authUserSession, err := authentication.NewSession(context.TODO(), db, authUserConsumer, 10*time.Second, false)
  353. require.NoError(t, err)
  354. authUserMaintainer, _ := assets.InsertMaintainerUser(t, db)
  355. authUserMaintainerConsumer, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), db, sdk.ConsumerLocal, authUserMaintainer.ID)
  356. require.NoError(t, err)
  357. authUserMaintainerSession, err := authentication.NewSession(context.TODO(), db, authUserMaintainerConsumer, 10*time.Second, false)
  358. require.NoError(t, err)
  359. authUserAdmin, _ := assets.InsertAdminUser(t, db)
  360. cases := []struct {
  361. Name string
  362. ConsumerAuthentifiedUser *sdk.AuthentifiedUser
  363. TargetSession *sdk.AuthSession
  364. Permission int
  365. Granted bool
  366. }{
  367. {
  368. Name: "RW on himself",
  369. ConsumerAuthentifiedUser: authUser,
  370. TargetSession: authUserSession,
  371. Permission: sdk.PermissionReadWriteExecute,
  372. Granted: true,
  373. },
  374. {
  375. Name: "R on other by lambda user",
  376. ConsumerAuthentifiedUser: authUser,
  377. TargetSession: authUserMaintainerSession,
  378. Permission: sdk.PermissionRead,
  379. Granted: false,
  380. },
  381. {
  382. Name: "R on other by admin user",
  383. ConsumerAuthentifiedUser: authUserAdmin,
  384. TargetSession: authUserSession,
  385. Permission: sdk.PermissionRead,
  386. Granted: true,
  387. },
  388. {
  389. Name: "R on other by maintainer user",
  390. ConsumerAuthentifiedUser: authUserMaintainer,
  391. TargetSession: authUserSession,
  392. Permission: sdk.PermissionRead,
  393. Granted: true,
  394. },
  395. {
  396. Name: "RW on other by lambda user",
  397. ConsumerAuthentifiedUser: authUser,
  398. TargetSession: authUserMaintainerSession,
  399. Permission: sdk.PermissionReadWriteExecute,
  400. Granted: false,
  401. },
  402. {
  403. Name: "RW on other by maintainer user",
  404. ConsumerAuthentifiedUser: authUserMaintainer,
  405. TargetSession: authUserSession,
  406. Permission: sdk.PermissionReadWriteExecute,
  407. Granted: false,
  408. },
  409. {
  410. Name: "RW on other by admin user",
  411. ConsumerAuthentifiedUser: authUserAdmin,
  412. TargetSession: authUserSession,
  413. Permission: sdk.PermissionReadWriteExecute,
  414. Granted: true,
  415. },
  416. }
  417. for _, c := range cases {
  418. t.Run(c.Name, func(t *testing.T) {
  419. ctx := context.WithValue(context.TODO(), contextAPIConsumer, &sdk.AuthConsumer{
  420. AuthentifiedUserID: c.ConsumerAuthentifiedUser.ID,
  421. AuthentifiedUser: c.ConsumerAuthentifiedUser,
  422. IssuedAt: time.Now(),
  423. })
  424. err := api.checkSessionPermissions(ctx, c.TargetSession.ID, c.Permission, nil)
  425. if c.Granted {
  426. assert.NoError(t, err, "should be granted")
  427. } else {
  428. assert.Error(t, err, "should not be granted")
  429. }
  430. })
  431. }
  432. }
  433. func Test_checkWorkerModelPermissions(t *testing.T) {
  434. api, db, _ := newTestAPI(t)
  435. g := assets.InsertTestGroup(t, db, sdk.RandomString(10))
  436. defer func() {
  437. assets.DeleteTestGroup(t, db, g)
  438. }()
  439. m := sdk.Model{
  440. Name: sdk.RandomString(10),
  441. Type: sdk.Docker,
  442. ModelDocker: sdk.ModelDocker{
  443. Image: "foo/bar:3.4",
  444. },
  445. GroupID: g.ID,
  446. }
  447. require.NoError(t, workermodel.Insert(context.TODO(), db, &m))
  448. defer func() {
  449. require.NoError(t, workermodel.DeleteByID(db, m.ID))
  450. }()
  451. assert.Error(t, api.checkWorkerModelPermissions(context.TODO(), m.Name, sdk.PermissionRead, map[string]string{
  452. "permGroupName": sdk.RandomString(10),
  453. }), "error should be returned for random worker model name")
  454. assert.Error(t, api.checkWorkerModelPermissions(context.TODO(), sdk.RandomString(10), sdk.PermissionRead, map[string]string{
  455. "permGroupName": g.Name,
  456. }), "error should be returned for random worker model name")
  457. assert.NoError(t, api.checkWorkerModelPermissions(context.TODO(), m.Name, sdk.PermissionRead, map[string]string{
  458. "permGroupName": g.Name,
  459. }), "no error should be returned for the right group an worker model names")
  460. }
  461. func Test_checkWorkflowPermissionsByUser(t *testing.T) {
  462. api, db, _ := newTestAPI(t)
  463. type setup struct {
  464. UserAdmin bool
  465. UserGroupNames []string
  466. ProjGroupPermissions map[string]int
  467. WorkflowGroupPermissions map[string]int
  468. }
  469. type args struct {
  470. wName string
  471. pKey string
  472. permissionLevel int
  473. }
  474. tests := []struct {
  475. name string
  476. setup setup
  477. args args
  478. want bool
  479. }{
  480. {
  481. name: "Should return true for user [read permission]",
  482. setup: setup{
  483. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  484. ProjGroupPermissions: map[string]int{
  485. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  486. },
  487. WorkflowGroupPermissions: map[string]int{
  488. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  489. },
  490. },
  491. args: args{
  492. wName: "workflow1",
  493. pKey: "key1",
  494. permissionLevel: 4,
  495. },
  496. want: true,
  497. }, {
  498. name: "Should return false for user [read permission]",
  499. setup: setup{
  500. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  501. ProjGroupPermissions: map[string]int{},
  502. WorkflowGroupPermissions: map[string]int{},
  503. },
  504. args: args{
  505. wName: "workflow1",
  506. pKey: "key2",
  507. permissionLevel: 4,
  508. },
  509. want: false,
  510. },
  511. {
  512. name: "Should return true for user [write permission]",
  513. setup: setup{
  514. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  515. ProjGroupPermissions: map[string]int{
  516. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  517. },
  518. WorkflowGroupPermissions: map[string]int{
  519. "Test_checkWorkflowPermissionsByUser": sdk.PermissionReadWriteExecute,
  520. },
  521. },
  522. args: args{
  523. wName: "workflow1",
  524. pKey: "key1",
  525. permissionLevel: 7,
  526. },
  527. want: true,
  528. },
  529. {
  530. name: "Should return false for user [wrong workflow]",
  531. setup: setup{
  532. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  533. ProjGroupPermissions: map[string]int{
  534. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  535. },
  536. WorkflowGroupPermissions: map[string]int{},
  537. },
  538. args: args{
  539. wName: "workflow1",
  540. pKey: "key1",
  541. permissionLevel: 7,
  542. },
  543. want: false,
  544. },
  545. {
  546. name: "Should return false for user [wrong permission]",
  547. setup: setup{
  548. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  549. ProjGroupPermissions: map[string]int{
  550. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  551. },
  552. WorkflowGroupPermissions: map[string]int{
  553. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  554. },
  555. },
  556. args: args{
  557. wName: "workflow1",
  558. pKey: "key1",
  559. permissionLevel: 7,
  560. },
  561. want: false,
  562. },
  563. {
  564. name: "Should return true for user [execution]",
  565. setup: setup{
  566. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  567. ProjGroupPermissions: map[string]int{
  568. "Test_checkWorkflowPermissionsByUser": sdk.PermissionReadExecute,
  569. },
  570. WorkflowGroupPermissions: map[string]int{
  571. "Test_checkWorkflowPermissionsByUser": sdk.PermissionReadExecute,
  572. },
  573. },
  574. args: args{
  575. wName: "workflow1",
  576. pKey: "key1",
  577. permissionLevel: 5,
  578. },
  579. want: true,
  580. },
  581. {
  582. name: "Should return false for user [execution]",
  583. setup: setup{
  584. UserGroupNames: []string{"Test_checkWorkflowPermissionsByUser"},
  585. ProjGroupPermissions: map[string]int{
  586. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  587. },
  588. WorkflowGroupPermissions: map[string]int{
  589. "Test_checkWorkflowPermissionsByUser": sdk.PermissionRead,
  590. },
  591. },
  592. args: args{
  593. wName: "workflow1",
  594. pKey: "key1",
  595. permissionLevel: 5,
  596. },
  597. want: false,
  598. },
  599. }
  600. for _, tt := range tests {
  601. var suffix = "-" + sdk.RandomString(10)
  602. var groups []*sdk.Group
  603. for _, s := range tt.setup.UserGroupNames {
  604. groups = append(groups, &sdk.Group{Name: s + suffix})
  605. }
  606. var usr *sdk.AuthentifiedUser
  607. if tt.setup.UserAdmin {
  608. usr, _ = assets.InsertAdminUser(t, db)
  609. } else {
  610. usr, _ = assets.InsertLambdaUser(t, db, groups...)
  611. }
  612. proj := assets.InsertTestProject(t, db, api.Cache, tt.args.pKey, tt.args.pKey)
  613. wrkflw := assets.InsertTestWorkflow(t, db, api.Cache, proj, tt.args.wName)
  614. for groupName, permLevel := range tt.setup.ProjGroupPermissions {
  615. g, err := group.LoadByName(context.TODO(), api.mustDB(), groupName+suffix, group.LoadOptions.WithMembers)
  616. require.NoError(t, err)
  617. require.NoError(t, group.InsertLinkGroupProject(context.TODO(), db, &group.LinkGroupProject{
  618. GroupID: g.ID,
  619. ProjectID: proj.ID,
  620. Role: permLevel,
  621. }))
  622. }
  623. for groupName, permLevel := range tt.setup.WorkflowGroupPermissions {
  624. g, err := group.LoadByName(context.TODO(), api.mustDB(), groupName+suffix, group.LoadOptions.WithMembers)
  625. require.NoError(t, err)
  626. require.NoError(t, group.AddWorkflowGroup(context.TODO(), api.mustDB(), wrkflw, sdk.GroupPermission{
  627. Group: *g,
  628. Permission: permLevel,
  629. }))
  630. }
  631. cons, err := authentication.LoadConsumerByTypeAndUserID(context.TODO(), api.mustDB(), sdk.ConsumerLocal, usr.ID, authentication.LoadConsumerOptions.WithAuthentifiedUser)
  632. require.NoError(t, err)
  633. ctx := context.WithValue(context.TODO(), contextAPIConsumer, cons)
  634. m := map[string]string{}
  635. m["key"] = tt.args.pKey
  636. err = api.checkWorkflowPermissions(ctx, tt.args.wName, tt.args.permissionLevel, m)
  637. got := err == nil
  638. if !reflect.DeepEqual(got, tt.want) {
  639. t.Errorf("%q. Test_checkWorkflowPermissionsByUser() = %v, want %v", tt.name, got, tt.want)
  640. }
  641. }
  642. }
  643. func Test_checkJobIDPermissions(t *testing.T) {
  644. // TODO
  645. }
  646. func Test_checkGroupPermissions(t *testing.T) {
  647. api, db, _ := newTestAPI(t)
  648. type setup struct {
  649. currentUser string
  650. currenUserIsAdmin bool
  651. currenUserIsMaitainer bool
  652. groupAdmins []string
  653. groupMembers []string
  654. }
  655. type args struct {
  656. groupName string
  657. permissionLevel int
  658. }
  659. tests := []struct {
  660. name string
  661. setup setup
  662. args args
  663. wantErr bool
  664. }{
  665. {
  666. name: "invalid group name",
  667. wantErr: true,
  668. },
  669. {
  670. name: "group does not exist",
  671. wantErr: true,
  672. },
  673. {
  674. name: "admin can get group",
  675. wantErr: false,
  676. setup: setup{
  677. currentUser: "admin",
  678. currenUserIsAdmin: true,
  679. },
  680. args: args{
  681. groupName: "my_group",
  682. permissionLevel: sdk.PermissionRead,
  683. },
  684. },
  685. {
  686. name: "maintainer can get group",
  687. wantErr: false,
  688. setup: setup{
  689. currentUser: "maintainer",
  690. currenUserIsMaitainer: true,
  691. },
  692. args: args{
  693. groupName: "my_group",
  694. permissionLevel: sdk.PermissionRead,
  695. },
  696. },
  697. {
  698. name: "admin can update group",
  699. wantErr: false,
  700. setup: setup{
  701. currentUser: "admin",
  702. currenUserIsAdmin: true,
  703. },
  704. args: args{
  705. groupName: "my_group",
  706. permissionLevel: sdk.PermissionReadWriteExecute,
  707. },
  708. },
  709. {
  710. name: "maintainer can't update group",
  711. wantErr: true,
  712. setup: setup{
  713. currentUser: "maintainer",
  714. currenUserIsMaitainer: true,
  715. },
  716. args: args{
  717. groupName: "my_group",
  718. permissionLevel: sdk.PermissionReadWriteExecute,
  719. },
  720. },
  721. {
  722. name: "group admin can read group",
  723. wantErr: false,
  724. setup: setup{
  725. currentUser: "group_admin",
  726. groupAdmins: []string{"group_admin"},
  727. },
  728. args: args{
  729. groupName: "my_group",
  730. permissionLevel: sdk.PermissionRead,
  731. },
  732. },
  733. {
  734. name: "group member can read group",
  735. wantErr: false,
  736. setup: setup{
  737. currentUser: "group_member",
  738. groupMembers: []string{"group_member"},
  739. },
  740. args: args{
  741. groupName: "my_group",
  742. permissionLevel: sdk.PermissionRead,
  743. },
  744. },
  745. {
  746. name: "group admin can update group",
  747. wantErr: false,
  748. setup: setup{
  749. currentUser: "group_admin",
  750. groupAdmins: []string{"group_admin"},
  751. },
  752. args: args{
  753. groupName: "my_group",
  754. permissionLevel: sdk.PermissionReadWriteExecute,
  755. },
  756. },
  757. {
  758. name: "group member can't update group",
  759. wantErr: true,
  760. setup: setup{
  761. currentUser: "group_member",
  762. groupMembers: []string{"group_member"},
  763. },
  764. args: args{
  765. groupName: "my_group",
  766. permissionLevel: sdk.PermissionReadWriteExecute,
  767. },
  768. },
  769. {
  770. name: "lambda user can't get group",
  771. wantErr: true,
  772. setup: setup{
  773. currentUser: "user",
  774. },
  775. args: args{
  776. groupName: "my_group",
  777. permissionLevel: sdk.PermissionRead,
  778. },
  779. },
  780. {
  781. name: "lambda user can't update group",
  782. wantErr: true,
  783. setup: setup{
  784. currentUser: "user",
  785. },
  786. args: args{
  787. groupName: "my_group",
  788. permissionLevel: sdk.PermissionReadWriteExecute,
  789. },
  790. },
  791. }
  792. for _, tt := range tests {
  793. t.Run(tt.name, func(t *testing.T) {
  794. prefix := sdk.RandomString(10) + "."
  795. currentUser := sdk.AuthentifiedUser{
  796. Username: prefix + tt.setup.currentUser,
  797. }
  798. if tt.setup.currenUserIsAdmin {
  799. currentUser.Ring = sdk.UserRingAdmin
  800. } else if tt.setup.currenUserIsMaitainer {
  801. currentUser.Ring = sdk.UserRingMaintainer
  802. } else {
  803. currentUser.Ring = sdk.UserRingUser
  804. }
  805. require.NoError(t, user.Insert(context.TODO(), db, &currentUser))
  806. groupAdmin := &sdk.AuthentifiedUser{
  807. Username: prefix + "auto-group-admin",
  808. }
  809. require.NoError(t, user.Insert(context.TODO(), db, groupAdmin))
  810. var err error
  811. groupAdmin, err = user.LoadByID(context.TODO(), api.mustDB(), groupAdmin.ID)
  812. require.NoError(t, err)
  813. tt.args.groupName = prefix + tt.args.groupName
  814. g := sdk.Group{
  815. Name: tt.args.groupName,
  816. }
  817. require.NoError(t, group.Create(context.TODO(), db, &g, groupAdmin.ID))
  818. for _, adm := range tt.setup.groupAdmins {
  819. adm = prefix + adm
  820. uAdm, _ := user.LoadByUsername(context.TODO(), api.mustDB(), adm)
  821. if uAdm == nil {
  822. uAdm = &sdk.AuthentifiedUser{
  823. Username: adm,
  824. Ring: sdk.UserRingUser,
  825. }
  826. require.NoError(t, user.Insert(context.TODO(), db, uAdm))
  827. defer assert.NoError(t, user.DeleteByID(api.mustDB(), uAdm.ID))
  828. }
  829. uAdm, _ = user.LoadByID(context.TODO(), api.mustDB(), uAdm.ID)
  830. require.NoError(t, group.InsertLinkGroupUser(context.TODO(), db, &group.LinkGroupUser{
  831. Admin: true,
  832. GroupID: g.ID,
  833. AuthentifiedUserID: uAdm.ID,
  834. }))
  835. }
  836. for _, member := range tt.setup.groupMembers {
  837. member = prefix + member
  838. uMember, _ := user.LoadByUsername(context.TODO(), api.mustDB(), member)
  839. if uMember == nil {
  840. uMember = &sdk.AuthentifiedUser{
  841. Username: member,
  842. Ring: sdk.UserRingUser,
  843. }
  844. require.NoError(t, user.Insert(context.TODO(), db, uMember))
  845. defer assert.NoError(t, user.DeleteByID(api.mustDB(), uMember.ID))
  846. }
  847. uMember, _ = user.LoadByID(context.TODO(), api.mustDB(), uMember.ID)
  848. require.NoError(t, group.InsertLinkGroupUser(context.TODO(), db, &group.LinkGroupUser{
  849. Admin: false,
  850. GroupID: g.ID,
  851. AuthentifiedUserID: uMember.ID,
  852. }))
  853. }
  854. consumer, err := local.NewConsumer(context.TODO(), db, currentUser.ID)
  855. require.NoError(t, err)
  856. consumer, err = authentication.LoadConsumerByID(context.TODO(), api.mustDB(), consumer.ID, authentication.LoadConsumerOptions.WithAuthentifiedUser)
  857. require.NoError(t, err)
  858. ctx := context.TODO()
  859. ctx = context.WithValue(ctx, contextAPIConsumer, consumer)
  860. err = api.checkGroupPermissions(ctx, tt.args.groupName, tt.args.permissionLevel, nil)
  861. if tt.wantErr {
  862. require.Error(t, err)
  863. } else {
  864. require.NoError(t, err)
  865. }
  866. })
  867. }
  868. }
  869. func Test_checkTemplateSlugPermissions(t *testing.T) {
  870. api, db, _ := newTestAPI(t)
  871. type setup struct {
  872. groupName string
  873. templateSlug string
  874. }
  875. type args struct {
  876. groupName string
  877. templateSlug string
  878. }
  879. tests := []struct {
  880. name string
  881. setup setup
  882. args args
  883. wantErr bool
  884. }{
  885. {
  886. name: "invalid workflow template",
  887. wantErr: true,
  888. },
  889. {
  890. name: "wrong group",
  891. wantErr: true,
  892. setup: setup{
  893. groupName: "group",
  894. templateSlug: "template",
  895. },
  896. args: args{
  897. groupName: "wronggroup",
  898. templateSlug: "template",
  899. },
  900. },
  901. {
  902. name: "wrong template",
  903. wantErr: true,
  904. setup: setup{
  905. groupName: "group",
  906. templateSlug: "template",
  907. },
  908. args: args{
  909. groupName: "group",
  910. templateSlug: "wrongtemplate",
  911. },
  912. },
  913. {
  914. name: "rignt group and template",
  915. wantErr: false,
  916. setup: setup{
  917. groupName: "group",
  918. templateSlug: "template",
  919. },
  920. args: args{
  921. groupName: "group",
  922. templateSlug: "template",
  923. },
  924. },
  925. }
  926. for _, tt := range tests {
  927. t.Run(tt.name, func(t *testing.T) {
  928. prefix := sdk.RandomString(10) + "."
  929. if tt.setup.groupName != "" {
  930. groupAdmin := &sdk.AuthentifiedUser{
  931. Username: prefix + "auto-group-admin",
  932. }
  933. require.NoError(t, user.Insert(context.TODO(), db, groupAdmin))
  934. var err error
  935. groupAdmin, err = user.LoadByID(context.TODO(), db, groupAdmin.ID)
  936. require.NoError(t, err)
  937. tt.setup.groupName = prefix + tt.setup.groupName
  938. g := sdk.Group{
  939. Name: tt.setup.groupName,
  940. }
  941. require.NoError(t, group.Create(context.TODO(), db, &g, groupAdmin.ID))
  942. t.Logf("group %s created", g.Name)
  943. if tt.setup.templateSlug != "" {
  944. tt.setup.templateSlug = prefix + tt.setup.templateSlug
  945. template := sdk.WorkflowTemplate{
  946. GroupID: g.ID,
  947. Name: tt.setup.templateSlug,
  948. Slug: tt.setup.templateSlug,
  949. }
  950. require.NoError(t, workflowtemplate.Insert(api.mustDB(), &template))
  951. t.Logf("template %s created", template.Name)
  952. }
  953. }
  954. ctx := context.TODO()
  955. err := api.checkTemplateSlugPermissions(ctx, prefix+tt.args.templateSlug, sdk.PermissionRead, map[string]string{"permGroupName": prefix + tt.args.groupName})
  956. if tt.wantErr {
  957. require.Error(t, err)
  958. } else {
  959. require.NoError(t, err)
  960. }
  961. })
  962. }
  963. }
  964. func Test_checkActionPermissions(t *testing.T) {
  965. api, db, _ := newTestAPI(t)
  966. g := assets.InsertTestGroup(t, db, sdk.RandomString(10))
  967. defer func() {
  968. assets.DeleteTestGroup(t, db, g)
  969. }()
  970. a := sdk.Action{
  971. GroupID: &g.ID,
  972. Type: sdk.DefaultAction,
  973. Name: sdk.RandomString(10),
  974. }
  975. require.NoError(t, action.Insert(db, &a))
  976. defer func() {
  977. require.NoError(t, action.Delete(db, &a))
  978. }()
  979. assert.Error(t, api.checkActionPermissions(context.TODO(), a.Name, sdk.PermissionRead, map[string]string{
  980. "permGroupName": sdk.RandomString(10),
  981. }), "error should be returned for random group name")
  982. assert.Error(t, api.checkActionPermissions(context.TODO(), sdk.RandomString(10), sdk.PermissionRead, map[string]string{
  983. "permGroupName": g.Name,
  984. }), "error should be returned for random action name")
  985. assert.NoError(t, api.checkActionPermissions(context.TODO(), a.Name, sdk.PermissionRead, map[string]string{
  986. "permGroupName": g.Name,
  987. }), "no error should be returned for the right group an action names")
  988. }
  989. func Test_checkActionBuiltinPermissions(t *testing.T) {
  990. api, db, _ := newTestAPI(t)
  991. scriptAction := assets.GetBuiltinOrPluginActionByName(t, db, "Script")
  992. assert.Error(t, api.checkActionBuiltinPermissions(context.TODO(), sdk.RandomString(10), sdk.PermissionRead, nil), "error should be returned for random action name")
  993. assert.NoError(t, api.checkActionBuiltinPermissions(context.TODO(), scriptAction.Name, sdk.PermissionRead, nil), "no error should be returned for valid action name")
  994. }