diff --git a/pkg/api/org.go b/pkg/api/org.go index 4131d753658..9030412153f 100644 --- a/pkg/api/org.go +++ b/pkg/api/org.go @@ -348,7 +348,7 @@ type UpdateCurrentOrgAddressParams struct { type UpdateCurrentOrgUserParams struct { // in:body // required:true - Body models.UpdateOrgUserCommand `json:"body"` + Body org.UpdateOrgUserCommand `json:"body"` // in:path // required:true UserID int64 `json:"user_id"` diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 841ab359697..5cf7b7f0706 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -148,7 +148,7 @@ func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *user.U // user exists, add org role createOrgUserCmd := org.AddOrgUserCommand{OrgID: c.OrgID, UserID: user.ID, Role: inviteDto.Role} if err := hs.orgService.AddOrgUser(c.Req.Context(), &createOrgUserCmd); err != nil { - if errors.Is(err, models.ErrOrgUserAlreadyAdded) { + if errors.Is(err, org.ErrOrgUserAlreadyAdded) { return response.Error(412, fmt.Sprintf("User %s is already added to organization", inviteDto.LoginOrEmail), err) } return response.Error(500, "Error while trying to create org user", err) @@ -312,7 +312,7 @@ func (hs *HTTPServer) applyUserInvite(ctx context.Context, usr *user.User, invit // add to org addOrgUserCmd := org.AddOrgUserCommand{OrgID: invite.OrgID, UserID: usr.ID, Role: invite.Role} if err := hs.orgService.AddOrgUser(ctx, &addOrgUserCmd); err != nil { - if !errors.Is(err, models.ErrOrgUserAlreadyAdded) { + if !errors.Is(err, org.ErrOrgUserAlreadyAdded) { return false, response.Error(500, "Error while trying to create org user", err) } } diff --git a/pkg/api/org_users.go b/pkg/api/org_users.go index a4798619824..0d35a766191 100644 --- a/pkg/api/org_users.go +++ b/pkg/api/org_users.go @@ -86,7 +86,7 @@ func (hs *HTTPServer) addOrgUserHelper(c *models.ReqContext, cmd org.AddOrgUserC cmd.UserID = userToAdd.ID if err := hs.orgService.AddOrgUser(c.Req.Context(), &cmd); err != nil { - if errors.Is(err, models.ErrOrgUserAlreadyAdded) { + if errors.Is(err, org.ErrOrgUserAlreadyAdded) { return response.JSON(409, util.DynMap{ "message": "User is already member of this organization", "userId": cmd.UserID, @@ -387,7 +387,7 @@ func (hs *HTTPServer) updateOrgUserHelper(c *models.ReqContext, cmd org.UpdateOr return response.Error(http.StatusForbidden, "Cannot assign a role higher than user's role", nil) } if err := hs.orgService.UpdateOrgUser(c.Req.Context(), &cmd); err != nil { - if errors.Is(err, models.ErrLastOrgAdmin) { + if errors.Is(err, org.ErrLastOrgAdmin) { return response.Error(400, "Cannot change role so that there is no organization admin left", nil) } return response.Error(500, "Failed update org user", err) @@ -452,7 +452,7 @@ func (hs *HTTPServer) RemoveOrgUser(c *models.ReqContext) response.Response { func (hs *HTTPServer) removeOrgUserHelper(ctx context.Context, cmd *org.RemoveOrgUserCommand) response.Response { if err := hs.orgService.RemoveOrgUser(ctx, cmd); err != nil { - if errors.Is(err, models.ErrLastOrgAdmin) { + if errors.Is(err, org.ErrLastOrgAdmin) { return response.Error(400, "Cannot remove last organization admin", nil) } return response.Error(500, "Failed to remove user from organization", err) @@ -478,14 +478,14 @@ func (hs *HTTPServer) removeOrgUserHelper(ctx context.Context, cmd *org.RemoveOr type AddOrgUserToCurrentOrgParams struct { // in:body // required:true - Body models.AddOrgUserCommand `json:"body"` + Body org.AddOrgUserCommand `json:"body"` } // swagger:parameters addOrgUser type AddOrgUserParams struct { // in:body // required:true - Body models.AddOrgUserCommand `json:"body"` + Body org.AddOrgUserCommand `json:"body"` // in:path // required:true OrgID int64 `json:"org_id"` @@ -512,7 +512,7 @@ type GetOrgUsersParams struct { type UpdateOrgUserForCurrentOrgParams struct { // in:body // required:true - Body models.UpdateOrgUserCommand `json:"body"` + Body org.UpdateOrgUserCommand `json:"body"` // in:path // required:true UserID int64 `json:"user_id"` @@ -522,7 +522,7 @@ type UpdateOrgUserForCurrentOrgParams struct { type UpdateOrgUserParams struct { // in:body // required:true - Body models.UpdateOrgUserCommand `json:"body"` + Body org.UpdateOrgUserCommand `json:"body"` // in:path // required:true OrgID int64 `json:"org_id"` @@ -559,12 +559,12 @@ type GetOrgUsersForCurrentOrgLookupResponse struct { type GetOrgUsersForCurrentOrgResponse struct { // The response message // in: body - Body []*models.OrgUserDTO `json:"body"` + Body []*org.OrgUserDTO `json:"body"` } // swagger:response getOrgUsersResponse type GetOrgUsersResponse struct { // The response message // in: body - Body []*models.OrgUserDTO `json:"body"` + Body []*org.OrgUserDTO `json:"body"` } diff --git a/pkg/api/org_users_test.go b/pkg/api/org_users_test.go index a035242e3bf..6ce64e7461c 100644 --- a/pkg/api/org_users_test.go +++ b/pkg/api/org_users_test.go @@ -78,7 +78,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) { require.Equal(t, http.StatusOK, sc.resp.Code) - var resp []models.OrgUserDTO + var resp []org.OrgUserDTO err := json.Unmarshal(sc.resp.Body.Bytes(), &resp) require.NoError(t, err) assert.Len(t, resp, 3) @@ -169,7 +169,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) { require.Equal(t, http.StatusOK, sc.resp.Code) - var resp []models.OrgUserDTO + var resp []org.OrgUserDTO err := json.Unmarshal(sc.resp.Body.Bytes(), &resp) require.NoError(t, err) assert.Len(t, resp, 2) @@ -425,7 +425,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) { response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(url, tc.targetOrg), nil, t) require.Equal(t, tc.expectedCode, response.Code) - var userList []*models.OrgUserDTO + var userList []*org.OrgUserDTO err = json.NewDecoder(response.Body).Decode(&userList) require.NoError(t, err) @@ -533,7 +533,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControl(t *testing.T) { require.Equal(t, tc.expectedCode, response.Code) if tc.expectedCode != http.StatusForbidden { - var userList []*models.OrgUserDTO + var userList []*org.OrgUserDTO err := json.NewDecoder(response.Body).Decode(&userList) require.NoError(t, err) diff --git a/pkg/models/org_user.go b/pkg/models/org_user.go deleted file mode 100644 index 207a7e96856..00000000000 --- a/pkg/models/org_user.go +++ /dev/null @@ -1,104 +0,0 @@ -package models - -import ( - "errors" - "time" - - "github.com/grafana/grafana/pkg/services/org" - "github.com/grafana/grafana/pkg/services/user" -) - -// Typed errors -var ( - ErrLastOrgAdmin = errors.New("cannot remove last organization admin") - ErrOrgUserNotFound = errors.New("cannot find the organization user") - ErrOrgUserAlreadyAdded = errors.New("user is already added to organization") -) - -type OrgUser struct { - Id int64 - OrgId int64 - UserId int64 - Role org.RoleType - Created time.Time - Updated time.Time -} - -// --------------------- -// COMMANDS - -type RemoveOrgUserCommand struct { - UserId int64 - OrgId int64 - ShouldDeleteOrphanedUser bool - UserWasDeleted bool -} - -type AddOrgUserCommand struct { - LoginOrEmail string `json:"loginOrEmail" binding:"Required"` - Role org.RoleType `json:"role" binding:"Required"` - - OrgId int64 `json:"-"` - UserId int64 `json:"-"` - - // internal use: avoid adding service accounts to orgs via user routes - AllowAddingServiceAccount bool `json:"-"` -} - -type UpdateOrgUserCommand struct { - Role org.RoleType `json:"role" binding:"Required"` - - OrgId int64 `json:"-"` - UserId int64 `json:"-"` -} - -// ---------------------- -// QUERIES - -type GetOrgUsersQuery struct { - UserID int64 - OrgId int64 - Query string - Limit int - // Flag used to allow oss edition to query users without access control - DontEnforceAccessControl bool - - User *user.SignedInUser - Result []*OrgUserDTO -} - -type SearchOrgUsersQuery struct { - OrgID int64 - Query string - Page int - Limit int - - User *user.SignedInUser - Result SearchOrgUsersQueryResult -} - -type SearchOrgUsersQueryResult struct { - TotalCount int64 `json:"totalCount"` - OrgUsers []*OrgUserDTO `json:"OrgUsers"` - Page int `json:"page"` - PerPage int `json:"perPage"` -} - -// ---------------------- -// Projections and DTOs - -type OrgUserDTO struct { - OrgId int64 `json:"orgId"` - UserId int64 `json:"userId"` - Email string `json:"email"` - Name string `json:"name"` - AvatarUrl string `json:"avatarUrl"` - Login string `json:"login"` - Role string `json:"role"` - LastSeenAt time.Time `json:"lastSeenAt"` - Updated time.Time `json:"-"` - Created time.Time `json:"-"` - LastSeenAtAge string `json:"lastSeenAtAge"` - AccessControl map[string]bool `json:"accessControl,omitempty"` - IsDisabled bool `json:"isDisabled"` -} diff --git a/pkg/services/authn/authnimpl/usersync/orgsync.go b/pkg/services/authn/authnimpl/usersync/orgsync.go index 33b3447fee3..e51745f29e8 100644 --- a/pkg/services/authn/authnimpl/usersync/orgsync.go +++ b/pkg/services/authn/authnimpl/usersync/orgsync.go @@ -8,7 +8,6 @@ import ( "github.com/grafana/grafana/pkg/cmd/grafana-cli/logger" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/org" @@ -92,7 +91,7 @@ func (s *OrgSync) SyncOrgUser(ctx context.Context, id *authn.Identity, _ *authn. "userId", userID, "orgId", orgId) cmd := &org.RemoveOrgUserCommand{OrgID: orgId, UserID: userID} if err := s.orgService.RemoveOrgUser(ctx, cmd); err != nil { - if errors.Is(err, models.ErrLastOrgAdmin) { + if errors.Is(err, org.ErrLastOrgAdmin) { logger.Error(err.Error(), "userId", cmd.UserID, "orgId", cmd.OrgID) continue } diff --git a/pkg/services/login/loginservice/loginservice.go b/pkg/services/login/loginservice/loginservice.go index 40133a4e901..e9231ee6995 100644 --- a/pkg/services/login/loginservice/loginservice.go +++ b/pkg/services/login/loginservice/loginservice.go @@ -306,7 +306,7 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, usr *user.User, extU "userId", usr.ID, "orgId", orgId) cmd := &org.RemoveOrgUserCommand{OrgID: orgId, UserID: usr.ID} if err := ls.orgService.RemoveOrgUser(ctx, cmd); err != nil { - if errors.Is(err, models.ErrLastOrgAdmin) { + if errors.Is(err, org.ErrLastOrgAdmin) { logger.Error(err.Error(), "userId", cmd.UserID, "orgId", cmd.OrgID) continue } diff --git a/pkg/services/login/loginservice/loginservice_test.go b/pkg/services/login/loginservice/loginservice_test.go index a3d6f28b012..0798d744045 100644 --- a/pkg/services/login/loginservice/loginservice_test.go +++ b/pkg/services/login/loginservice/loginservice_test.go @@ -60,7 +60,7 @@ func Test_syncOrgRoles_whenTryingToRemoveLastOrgLogsError(t *testing.T) { err := login.syncOrgRoles(context.Background(), &user, &externalUser) require.NoError(t, err) - assert.Contains(t, buf.String(), models.ErrLastOrgAdmin.Error()) + assert.Contains(t, buf.String(), org.ErrLastOrgAdmin.Error()) } func Test_teamSync(t *testing.T) { @@ -158,7 +158,7 @@ func createResponseWithOneErrLastOrgAdminItem() orgtest.OrgListResponse { remResp := orgtest.OrgListResponse{ { OrgID: 10, - Response: models.ErrLastOrgAdmin, + Response: org.ErrLastOrgAdmin, }, { OrgID: 11, diff --git a/pkg/services/org/model.go b/pkg/services/org/model.go index d000d1a54b7..081bc60fbf2 100644 --- a/pkg/services/org/model.go +++ b/pkg/services/org/model.go @@ -11,8 +11,11 @@ import ( // Typed errors var ( - ErrOrgNotFound = errors.New("organization not found") - ErrOrgNameTaken = errors.New("organization name is taken") + ErrOrgNotFound = errors.New("organization not found") + ErrOrgNameTaken = errors.New("organization name is taken") + ErrLastOrgAdmin = errors.New("cannot remove last organization admin") + ErrOrgUserNotFound = errors.New("cannot find the organization user") + ErrOrgUserAlreadyAdded = errors.New("user is already added to organization") ) type Org struct { diff --git a/pkg/services/org/orgimpl/store.go b/pkg/services/org/orgimpl/store.go index 9e3a775d3e7..f281d8ccb70 100644 --- a/pkg/services/org/orgimpl/store.go +++ b/pkg/services/org/orgimpl/store.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota" @@ -357,7 +356,7 @@ func (ss *sqlStore) AddOrgUser(ctx context.Context, cmd *org.AddOrgUserCommand) if res, err := sess.Query("SELECT 1 from org_user WHERE org_id=? and user_id=?", cmd.OrgID, usr.ID); err != nil { return err } else if len(res) == 1 { - return models.ErrOrgUserAlreadyAdded + return org.ErrOrgUserAlreadyAdded } if res, err := sess.Query("SELECT 1 from org WHERE id=?", cmd.OrgID); err != nil { @@ -483,7 +482,7 @@ func (ss *sqlStore) UpdateOrgUser(ctx context.Context, cmd *org.UpdateOrgUserCom } if !exists { - return models.ErrOrgUserNotFound + return org.ErrOrgUserNotFound } orgUser.Role = cmd.Role @@ -505,7 +504,7 @@ func validateOneAdminLeftInOrg(orgID int64, sess *db.Session) error { } if len(res) == 0 { - return models.ErrLastOrgAdmin + return org.ErrLastOrgAdmin } return err diff --git a/pkg/services/org/orgimpl/store_test.go b/pkg/services/org/orgimpl/store_test.go index 32239f60a83..98582a28466 100644 --- a/pkg/services/org/orgimpl/store_test.go +++ b/pkg/services/org/orgimpl/store_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" @@ -391,7 +390,7 @@ func TestIntegrationOrgUserDataAccess(t *testing.T) { require.NoError(t, err) cmd := org.UpdateOrgUserCommand{OrgID: ac1.OrgID, UserID: ac1.ID, Role: org.RoleViewer} err = orgUserStore.UpdateOrgUser(context.Background(), &cmd) - require.Equal(t, models.ErrLastOrgAdmin, err) + require.Equal(t, org.ErrLastOrgAdmin, err) }) t.Run("Removing user from org should delete user completely if in no other org", func(t *testing.T) { @@ -409,7 +408,7 @@ func TestIntegrationOrgUserDataAccess(t *testing.T) { t.Run("Cannot delete last admin org user", func(t *testing.T) { cmd := org.RemoveOrgUserCommand{OrgID: ac1.OrgID, UserID: ac1.ID} err := orgUserStore.RemoveOrgUser(context.Background(), &cmd) - require.Equal(t, err, models.ErrLastOrgAdmin) + require.Equal(t, err, org.ErrLastOrgAdmin) }) }) diff --git a/pkg/services/serviceaccounts/database/store.go b/pkg/services/serviceaccounts/database/store.go index e3001493a49..eb46e3bd1a0 100644 --- a/pkg/services/serviceaccounts/database/store.go +++ b/pkg/services/serviceaccounts/database/store.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apikey" "github.com/grafana/grafana/pkg/services/org" @@ -124,7 +123,7 @@ func (s *ServiceAccountsStoreImpl) UpdateServiceAccount( updateTime := time.Now() if saForm.Role != nil { - var orgUser models.OrgUser + var orgUser org.OrgUser orgUser.Role = *saForm.Role orgUser.Updated = updateTime diff --git a/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go b/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go index 6c806f93a28..d04b182b622 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go @@ -82,7 +82,7 @@ func (p *teamPermissionMigrator) mapPermissionToRBAC(permission models.Permissio } func (p *teamPermissionMigrator) getUserRoleByOrgMapping() (map[int64]map[int64]string, error) { - var orgUsers []*models.OrgUserDTO + var orgUsers []*org.OrgUserDTO if err := p.sess.SQL(`SELECT * FROM org_user`).Cols("org_user.org_id", "org_user.user_id", "org_user.role").Find(&orgUsers); err != nil { return nil, err } @@ -91,13 +91,13 @@ func (p *teamPermissionMigrator) getUserRoleByOrgMapping() (map[int64]map[int64] // Loop through users and organise them by organization ID for _, orgUser := range orgUsers { - orgRoles, initialized := userRolesByOrg[orgUser.OrgId] + orgRoles, initialized := userRolesByOrg[orgUser.OrgID] if !initialized { orgRoles = map[int64]string{} } - orgRoles[orgUser.UserId] = orgUser.Role - userRolesByOrg[orgUser.OrgId] = orgRoles + orgRoles[orgUser.UserID] = orgUser.Role + userRolesByOrg[orgUser.OrgID] = orgRoles } return userRolesByOrg, nil diff --git a/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go b/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go index e18459ecd70..5387221838f 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go @@ -273,38 +273,38 @@ func setupTeams(t *testing.T, x *xorm.Engine) { require.NoError(t, errInsertUsers) require.Equal(t, int64(5), usersCount, "needed 5 users for this test to run") - orgUsers := []models.OrgUser{ + orgUsers := []org.OrgUser{ { - OrgId: 1, - UserId: 1, + OrgID: 1, + UserID: 1, Role: org.RoleViewer, Created: now, Updated: now, }, { - OrgId: 1, - UserId: 2, + OrgID: 1, + UserID: 2, Role: org.RoleViewer, Created: now, Updated: now, }, { - OrgId: 1, - UserId: 3, + OrgID: 1, + UserID: 3, Role: org.RoleEditor, Created: now, Updated: now, }, { - OrgId: 1, - UserId: 4, + OrgID: 1, + UserID: 4, Role: org.RoleAdmin, Created: now, Updated: now, }, { - OrgId: 2, - UserId: 5, + OrgID: 2, + UserID: 5, Role: org.RoleEditor, Created: now, Updated: now, diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index e12ca1137c4..266c88424fa 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -8,7 +8,6 @@ import ( "time" "github.com/grafana/grafana/pkg/events" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" @@ -110,9 +109,9 @@ func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args user.C Email: usr.Email, }) - orgUser := models.OrgUser{ - OrgId: orgID, - UserId: usr.ID, + orgUser := org.OrgUser{ + OrgID: orgID, + UserID: usr.ID, Role: org.RoleAdmin, Created: time.Now(), Updated: time.Now(),