grafana/pkg/services/org/model.go
Gabriel MABILLE 96cbe70b14
User: Support sort query param for user and org user, search endpoints (#75229)
* User: Add sort option to user search

* Switch to an approach that uses the dashboard search options

* Cable user sort on the org endpoint

* Alias user table with u in org store

* Add test and cover orgs/:orgID/users/search endpoint

* Add test to userimpl store

* Simplify the store_test with sortopts.ParseSortQueryParam

* Account for PR feedback

* Positive check

* Update docs

* Update docs

* Switch to ErrOrFallback

Co-authored-by: Karl Persson <kalle.persson@grafana.com>

---------

Co-authored-by: Karl Persson <kalle.persson@grafana.com>
2023-09-28 10:16:18 +02:00

233 lines
5.8 KiB
Go

package org
import (
"errors"
"strings"
"time"
"github.com/grafana/grafana/pkg/models/roletype"
"github.com/grafana/grafana/pkg/services/auth/identity"
"github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/util/errutil"
)
// Typed errors
var (
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")
ErrOrgNotFound = errutil.NotFound("org.notFound", errutil.WithPublicMessage("organization not found"))
ErrCannotChangeRoleForExternallySyncedUser = errutil.Forbidden("org.externallySynced", errutil.WithPublicMessage("cannot change role for externally synced user"))
)
type Org struct {
ID int64 `xorm:"pk autoincr 'id'"`
Version int
Name string
Address1 string
Address2 string
City string
ZipCode string
State string
Country string
Created time.Time
Updated time.Time
}
type OrgUser struct {
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
UserID int64 `xorm:"user_id"`
Role RoleType
Created time.Time
Updated time.Time
}
type RoleType = roletype.RoleType
const (
RoleNone RoleType = roletype.RoleNone
RoleViewer RoleType = roletype.RoleViewer
RoleEditor RoleType = roletype.RoleEditor
RoleAdmin RoleType = roletype.RoleAdmin
)
type CreateOrgCommand struct {
Name string `json:"name" binding:"Required"`
// initial admin user for account
UserID int64 `json:"-" xorm:"user_id"`
}
type GetOrgIDForNewUserCommand struct {
Email string
Login string
OrgID int64
OrgName string
SkipOrgSetup bool
}
type GetUserOrgListQuery struct {
UserID int64 `xorm:"user_id"`
}
type UserOrgDTO struct {
OrgID int64 `json:"orgId" xorm:"org_id"`
Name string `json:"name"`
Role RoleType `json:"role"`
}
type UpdateOrgCommand struct {
Name string
OrgId int64
}
type SearchOrgsQuery struct {
Query string
Name string
Limit int
Page int
IDs []int64 `xorm:"ids"`
}
type OrgDTO struct {
ID int64 `json:"id" xorm:"id"`
Name string `json:"name"`
}
type GetOrgByIDQuery struct {
ID int64
}
type GetOrgByNameQuery struct {
Name string
}
type UpdateOrgAddressCommand struct {
OrgID int64 `xorm:"org_id"`
Address
}
type Address struct {
Address1 string `json:"address1"`
Address2 string `json:"address2"`
City string `json:"city"`
ZipCode string `json:"zipCode"`
State string `json:"state"`
Country string `json:"country"`
}
type DeleteOrgCommand struct {
ID int64 `xorm:"id"`
}
type AddOrgUserCommand struct {
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
Role RoleType `json:"role" binding:"Required"`
OrgID int64 `json:"-" xorm:"org_id"`
UserID int64 `json:"-" xorm:"user_id"`
// internal use: avoid adding service accounts to orgs via user routes
AllowAddingServiceAccount bool `json:"-"`
}
type UpdateOrgUserCommand struct {
Role RoleType `json:"role" binding:"Required"`
OrgID int64 `json:"-"`
UserID int64 `json:"-"`
}
type OrgUserDTO struct {
OrgID int64 `json:"orgId" xorm:"org_id"`
UserID int64 `json:"userId" xorm:"user_id"`
Email string `json:"email"`
Name string `json:"name"`
AvatarURL string `json:"avatarUrl" xorm:"avatar_url"`
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"`
AuthLabels []string `json:"authLabels" xorm:"-"`
IsExternallySynced bool `json:"isExternallySynced"`
}
type RemoveOrgUserCommand struct {
UserID int64 `xorm:"user_id"`
OrgID int64 `xorm:"org_id"`
ShouldDeleteOrphanedUser bool
UserWasDeleted bool
}
type GetOrgUsersQuery struct {
UserID int64 `xorm:"user_id"`
OrgID int64 `xorm:"org_id"`
Query string
Page int
Limit int
// Flag used to allow oss edition to query users without access control
DontEnforceAccessControl bool
User identity.Requester
}
type SearchOrgUsersQuery struct {
UserID int64 `xorm:"user_id"`
OrgID int64 `xorm:"org_id"`
Query string
Page int
Limit int
SortOpts []model.SortOption
// Flag used to allow oss edition to query users without access control
DontEnforceAccessControl bool
User identity.Requester
}
type SearchOrgUsersQueryResult struct {
TotalCount int64 `json:"totalCount"`
OrgUsers []*OrgUserDTO `json:"orgUsers"`
Page int `json:"page"`
PerPage int `json:"perPage"`
}
type ByOrgName []*UserOrgDTO
type OrgDetailsDTO struct {
ID int64 `json:"id"`
Name string `json:"name"`
Address Address `json:"address"`
}
// Len returns the length of an array of organisations.
func (o ByOrgName) Len() int {
return len(o)
}
// Swap swaps two indices of an array of organizations.
func (o ByOrgName) Swap(i, j int) {
o[i], o[j] = o[j], o[i]
}
// Less returns whether element i of an array of organizations is less than element j.
func (o ByOrgName) Less(i, j int) bool {
if strings.ToLower(o[i].Name) < strings.ToLower(o[j].Name) {
return true
}
return o[i].Name < o[j].Name
}
const (
QuotaTargetSrv string = "org"
OrgQuotaTarget string = "org"
OrgUserQuotaTarget string = "org_user"
)