| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2023-06-08 16:09:30 +08:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 19:58:49 +08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/routing" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/infra/log" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" | 
					
						
							| 
									
										
										
										
											2022-11-24 22:38:55 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/actest" | 
					
						
							| 
									
										
										
										
											2024-07-05 17:31:23 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/authz/zanzana" | 
					
						
							| 
									
										
										
										
											2024-05-10 18:56:52 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/org" | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/serviceaccounts" | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 	satests "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/user" | 
					
						
							| 
									
										
										
										
											2022-02-07 21:51:54 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web/webtest" | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	type TestCase struct { | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 		desc         string | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		basicRole    org.RoleType | 
					
						
							|  |  |  | 		permissions  []accesscontrol.Permission | 
					
						
							|  |  |  | 		body         string | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 		expectedCode int | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		expectedSA   *serviceaccounts.ServiceAccountDTO | 
					
						
							|  |  |  | 		expectedErr  error | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tests := []TestCase{ | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:        "should be able to create service account with correct permission", | 
					
						
							|  |  |  | 			basicRole:   org.RoleViewer, | 
					
						
							|  |  |  | 			permissions: []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, | 
					
						
							|  |  |  | 			body:        `{"name": "test", "isDisabled": false, "role": "Viewer"}`, | 
					
						
							|  |  |  | 			expectedSA: &serviceaccounts.ServiceAccountDTO{ | 
					
						
							|  |  |  | 				Name:       "test", | 
					
						
							|  |  |  | 				OrgId:      1, | 
					
						
							|  |  |  | 				IsDisabled: false, | 
					
						
							|  |  |  | 				Role:       string(org.RoleViewer), | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 			expectedCode: http.StatusCreated, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-07-08 00:32:56 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to create service account without permission", | 
					
						
							|  |  |  | 			basicRole:    org.RoleViewer, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{}}, | 
					
						
							|  |  |  | 			body:         `{"name": "test", "isDisabled": false, "role": "Viewer"}`, | 
					
						
							| 
									
										
										
										
											2022-07-08 00:32:56 +08:00
										 |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to create service account with role that has higher privilege than caller", | 
					
						
							|  |  |  | 			basicRole:    org.RoleViewer, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, | 
					
						
							|  |  |  | 			body:         `{"name": "test", "isDisabled": false, "role": "Editor"}`, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2022-07-08 00:32:56 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to create service account with invalid role", | 
					
						
							|  |  |  | 			basicRole:    org.RoleViewer, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, | 
					
						
							|  |  |  | 			body:         `{"name": "test", "isDisabled": false, "role": "random"}`, | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 			expectedCode: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to create service account with missing name", | 
					
						
							|  |  |  | 			basicRole:    org.RoleViewer, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, | 
					
						
							|  |  |  | 			body:         `{"name": "", "isDisabled": false, "role": "Viewer"}`, | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 			expectedCode: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := setupTests(t, func(a *ServiceAccountsAPI) { | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 				a.service = &satests.FakeServiceAccountService{ExpectedServiceAccount: tt.expectedSA, ExpectedErr: tt.expectedErr} | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			req := server.NewRequest(http.MethodPost, "/api/serviceaccounts/", strings.NewReader(tt.body)) | 
					
						
							| 
									
										
										
										
											2023-08-10 20:20:58 +08:00
										 |  |  | 			webtest.RequestWithSignedInUser(req, &user.SignedInUser{ | 
					
						
							|  |  |  | 				OrgRole: tt.basicRole, OrgID: 1, IsAnonymous: true, | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 				Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions)}}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			res, err := server.SendJSON(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							| 
									
										
										
										
											2022-03-08 19:07:58 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	type TestCase struct { | 
					
						
							|  |  |  | 		desc         string | 
					
						
							|  |  |  | 		id           int64 | 
					
						
							|  |  |  | 		permissions  []accesscontrol.Permission | 
					
						
							|  |  |  | 		expectedCode int | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	tests := []TestCase{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to delete service account with correct permission", | 
					
						
							|  |  |  | 			id:           1, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionDelete, Scope: "serviceaccounts:id:1"}}, | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not ba able to delete with wrong permission", | 
					
						
							|  |  |  | 			id:           2, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionDelete, Scope: "serviceaccounts:id:1"}}, | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := setupTests(t) | 
					
						
							|  |  |  | 			req := server.NewRequest(http.MethodDelete, fmt.Sprintf("/api/serviceaccounts/%d", tt.id), nil) | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 			webtest.RequestWithSignedInUser(req, &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions)}}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			res, err := server.Send(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-02-07 21:51:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2021-11-11 23:10:24 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	type TestCase struct { | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 		desc         string | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		id           int64 | 
					
						
							|  |  |  | 		permissions  []accesscontrol.Permission | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 		expectedCode int | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		expectedSA   *serviceaccounts.ServiceAccountProfileDTO | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tests := []TestCase{ | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should be able to get service account with correct permission", | 
					
						
							|  |  |  | 			id:           1, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: "serviceaccounts:id:1"}}, | 
					
						
							|  |  |  | 			expectedSA:   &serviceaccounts.ServiceAccountProfileDTO{}, | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not ba able to get service account with wrong permission", | 
					
						
							|  |  |  | 			id:           2, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: "serviceaccounts:id:1"}}, | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := setupTests(t, func(a *ServiceAccountsAPI) { | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 				a.service = &satests.FakeServiceAccountService{ExpectedServiceAccountProfile: tt.expectedSA} | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			req := server.NewGetRequest(fmt.Sprintf("/api/serviceaccounts/%d", tt.id)) | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 			webtest.RequestWithSignedInUser(req, &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions)}}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			res, err := server.Send(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							| 
									
										
										
										
											2022-01-19 17:23:46 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	type TestCase struct { | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 		desc         string | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		id           int64 | 
					
						
							|  |  |  | 		body         string | 
					
						
							|  |  |  | 		basicRole    org.RoleType | 
					
						
							|  |  |  | 		permissions  []accesscontrol.Permission | 
					
						
							|  |  |  | 		expectedSA   *serviceaccounts.ServiceAccountProfileDTO | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 		expectedCode int | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	tests := []TestCase{ | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should be able to update service account with correct permission", | 
					
						
							|  |  |  | 			id:           1, | 
					
						
							|  |  |  | 			body:         `{"role": "Editor"}`, | 
					
						
							|  |  |  | 			basicRole:    org.RoleAdmin, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, | 
					
						
							|  |  |  | 			expectedSA:   &serviceaccounts.ServiceAccountProfileDTO{}, | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-04-14 00:11:03 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to update service account with wrong permission", | 
					
						
							|  |  |  | 			id:           2, | 
					
						
							|  |  |  | 			body:         `{}`, | 
					
						
							|  |  |  | 			basicRole:    org.RoleAdmin, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, | 
					
						
							| 
									
										
										
										
											2022-04-14 00:11:03 +08:00
										 |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to update service account with a role that has higher privilege then caller", | 
					
						
							|  |  |  | 			id:           1, | 
					
						
							|  |  |  | 			body:         `{"role": "Admin"}`, | 
					
						
							|  |  |  | 			basicRole:    org.RoleEditor, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			desc:         "should not be able to update service account with invalid role", | 
					
						
							|  |  |  | 			id:           1, | 
					
						
							|  |  |  | 			body:         `{"role": "fake"}`, | 
					
						
							|  |  |  | 			basicRole:    org.RoleEditor, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusBadRequest, | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := setupTests(t, func(a *ServiceAccountsAPI) { | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 				a.service = &satests.FakeServiceAccountService{ExpectedServiceAccountProfile: tt.expectedSA} | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			req := server.NewRequest(http.MethodPatch, fmt.Sprintf("/api/serviceaccounts/%d", tt.id), strings.NewReader(tt.body)) | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 			webtest.RequestWithSignedInUser(req, &user.SignedInUser{OrgRole: tt.basicRole, OrgID: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions)}}) | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 			res, err := server.SendJSON(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-17 20:19:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 16:09:30 +08:00
										 |  |  | func TestServiceAccountsAPI_MigrateApiKeysToServiceAccounts(t *testing.T) { | 
					
						
							|  |  |  | 	type TestCase struct { | 
					
						
							|  |  |  | 		desc                    string | 
					
						
							|  |  |  | 		orgId                   int64 | 
					
						
							|  |  |  | 		basicRole               org.RoleType | 
					
						
							|  |  |  | 		permissions             []accesscontrol.Permission | 
					
						
							|  |  |  | 		expectedMigrationResult *serviceaccounts.MigrationResult | 
					
						
							|  |  |  | 		expectedCode            int | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tests := []TestCase{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:      "should be able to migrate API keys to service accounts with correct permissions", | 
					
						
							|  |  |  | 			orgId:     1, | 
					
						
							|  |  |  | 			basicRole: org.RoleAdmin, | 
					
						
							|  |  |  | 			permissions: []accesscontrol.Permission{ | 
					
						
							|  |  |  | 				{Action: serviceaccounts.ActionCreate, Scope: serviceaccounts.ScopeAll}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expectedMigrationResult: &serviceaccounts.MigrationResult{ | 
					
						
							|  |  |  | 				Total:         5, | 
					
						
							|  |  |  | 				Migrated:      4, | 
					
						
							|  |  |  | 				Failed:        1, | 
					
						
							|  |  |  | 				FailedDetails: []string{"API key name: failedKey - Error: migration error"}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:      "should not be able to migrate API keys to service accounts with wrong permissions", | 
					
						
							|  |  |  | 			orgId:     2, | 
					
						
							|  |  |  | 			basicRole: org.RoleAdmin, | 
					
						
							|  |  |  | 			permissions: []accesscontrol.Permission{ | 
					
						
							|  |  |  | 				{Action: serviceaccounts.ActionCreate, Scope: serviceaccounts.ScopeAll}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := setupTests(t, func(a *ServiceAccountsAPI) { | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 				a.service = &satests.FakeServiceAccountService{ExpectedMigrationResult: tt.expectedMigrationResult} | 
					
						
							| 
									
										
										
										
											2023-06-08 16:09:30 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			req := server.NewRequest(http.MethodPost, "/api/serviceaccounts/migrate", nil) | 
					
						
							| 
									
										
										
										
											2024-07-03 14:08:57 +08:00
										 |  |  | 			webtest.RequestWithSignedInUser(req, &user.SignedInUser{OrgRole: tt.basicRole, OrgID: tt.orgId, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions)}}) | 
					
						
							| 
									
										
										
										
											2023-06-08 16:09:30 +08:00
										 |  |  | 			res, err := server.SendJSON(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			if tt.expectedCode == http.StatusOK { | 
					
						
							|  |  |  | 				var result serviceaccounts.MigrationResult | 
					
						
							|  |  |  | 				err := json.NewDecoder(res.Body).Decode(&result) | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							|  |  |  | 				assert.Equal(t, tt.expectedMigrationResult, &result) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | func setupTests(t *testing.T, opts ...func(a *ServiceAccountsAPI)) *webtest.Server { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 	cfg := setting.NewCfg() | 
					
						
							|  |  |  | 	api := &ServiceAccountsAPI{ | 
					
						
							|  |  |  | 		cfg:                  cfg, | 
					
						
							| 
									
										
										
										
											2023-10-25 18:40:30 +08:00
										 |  |  | 		service:              &satests.FakeServiceAccountService{}, | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		accesscontrolService: &actest.FakeService{}, | 
					
						
							| 
									
										
										
										
											2024-07-05 17:31:23 +08:00
										 |  |  | 		accesscontrol:        acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 		RouterRegister:       routing.NewRouteRegister(), | 
					
						
							|  |  |  | 		log:                  log.NewNopLogger(), | 
					
						
							|  |  |  | 		permissionService:    &actest.FakePermissionsService{}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-15 01:24:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-19 16:27:52 +08:00
										 |  |  | 	for _, o := range opts { | 
					
						
							|  |  |  | 		o(api) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	api.RegisterAPIEndpoints() | 
					
						
							|  |  |  | 	return webtest.NewServer(t, api.RouterRegister) | 
					
						
							|  |  |  | } |