grafana/pkg/models/user.go

284 lines
6.0 KiB
Go
Raw Normal View History

package models
import (
"errors"
"time"
)
// Typed errors
var (
ErrUserNotFound = errors.New("user not found")
ErrUserAlreadyExists = errors.New("user already exists")
ErrLastGrafanaAdmin = errors.New("cannot remove last grafana admin")
ErrProtectedUser = errors.New("cannot adopt protected user")
)
type Password string
func (p Password) IsWeak() bool {
return len(p) <= 4
}
type User struct {
Id int64
Version int
Email string
Name string
Login string
Password string
Salt string
Rands string
Company string
EmailVerified bool
Theme string
HelpFlags1 HelpFlags1
IsDisabled bool
ServiceAccounts: Delete ServiceAccount (#40470) * Add extra fields to OSS types to support enterprise * WIP service accounts * Update public/app/features/api-keys/ApiKeysForm.tsx Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> * Create a service account at the same time as the API key * Use service account credentials when accessing API with APIkey * Throw better error * Use Boolean for "create service account button" * Add GetRole to service, merge RoleDTO and Role structs This patch merges the identical OSS and Enterprise data structures, which improves the code for two reasons: 1. Makes switching between OSS and Enterprise easier 2. Reduces the chance of incompatibilities developing between the same functions in OSS and Enterprise * Start work cloning permissions onto service account * If API key is not linked to a service account, continue login as usual * Fallback to old auth if no service account linked to key * Commented * Add CloneUserToServiceAccount * Update mock.go * Put graphical bits behind a feature toggle * Start adding LinkAPIKeyToServiceAccount * Update pkg/models/user.go Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com> * Update pkg/api/apikey.go Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com> * Update pkg/api/apikey.go Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com> * Finish LinkAPIKeyToServiceAccount * Update comment * Handle api key link error * Update pkg/services/sqlstore/apikey.go Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> * Feature toggle * Update pkg/services/accesscontrol/accesscontrol.go Co-authored-by: Ieva <ieva.vasiljeva@grafana.com> * Not needed (yet) * Better error messages for OSS accesscontrol * Set an invalid user id as default * ServiceAccountId should be string * Re-arrange field names * ServiceAccountId is integer * Update ossaccesscontrol.go * Linter * Remove fronend edits * Remove console log * Update ApiKeysForm.tsx * feat: add serviceaccount deletion * feat: make sure we do not accidently delete serviceaccount * feat: ServiceAccount Type * refactor: userDeletions function * refactor: serviceaccount deletions\ * refactor: error name and removed attribute for userDeletecommand * refactor:: remove serviceaccount type for now * WIP * add mocked function * Remove unnecessary db query, move to right place * Update pkg/services/accesscontrol/mock/mock.go Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> * Update pkg/services/accesscontrol/mock/mock.go Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> * Update pkg/services/accesscontrol/mock/mock.go Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> * Better error messages * Better and correcter error messages * add mocked function * refactor: move function call, add error msg * add IsServiceAccount and fix table * add service accounts package * WIP * WIP * working serviceaccountsapi registration * WIP tests * test * test working * test running for service * moved the error out of the models package * fixed own review * linting errors * Update pkg/services/serviceaccounts/database/database.go Co-authored-by: Jeremy Price <Jeremy.price@grafana.com> * tests running for api * WIP * WIP * removed unused secrets background svc * removed background svc for serviceaccount infavor or wire.go * serviceaccounts manager tests * registering as backend service Co-authored-by: Jeremy Price <jeremy.price@grafana.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> Co-authored-by: Ieva <ieva.vasiljeva@grafana.com> Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
2021-11-11 09:10:24 -06:00
IsAdmin bool
IsServiceAccount bool
OrgId int64
Created time.Time
Updated time.Time
LastSeenAt time.Time
}
func (u *User) NameOrFallback() string {
if u.Name != "" {
return u.Name
}
if u.Login != "" {
return u.Login
}
return u.Email
}
// ---------------------
// COMMANDS
type CreateUserCommand struct {
Email string
Login string
Name string
Company string
OrgId int64
OrgName string
Password string
EmailVerified bool
IsAdmin bool
IsDisabled bool
SkipOrgSetup bool
DefaultOrgRole string
IsServiceAccount bool
Result User
}
type UpdateUserCommand struct {
Name string `json:"name"`
Email string `json:"email"`
Login string `json:"login"`
Theme string `json:"theme"`
UserId int64 `json:"-"`
}
type ChangeUserPasswordCommand struct {
OldPassword string `json:"oldPassword"`
NewPassword string `json:"newPassword"`
UserId int64 `json:"-"`
}
type DisableUserCommand struct {
UserId int64
IsDisabled bool
}
type BatchDisableUsersCommand struct {
UserIds []int64
IsDisabled bool
}
type DeleteUserCommand struct {
UserId int64
}
type SetUsingOrgCommand struct {
UserId int64
OrgId int64
}
// ----------------------
// QUERIES
type GetUserByLoginQuery struct {
LoginOrEmail string
Result *User
}
type GetUserByEmailQuery struct {
Email string
Result *User
}
type GetUserByIdQuery struct {
Id int64
Result *User
}
type GetSignedInUserQuery struct {
UserId int64
Login string
Email string
OrgId int64
Result *SignedInUser
}
type GetUserProfileQuery struct {
UserId int64
Result UserProfileDTO
}
type SearchUsersQuery struct {
OrgId int64
Query string
Page int
Limit int
AuthModule string
Filters []Filter
IsDisabled *bool
Result SearchUserQueryResult
}
type SearchUserQueryResult struct {
TotalCount int64 `json:"totalCount"`
Users []*UserSearchHitDTO `json:"users"`
Page int `json:"page"`
PerPage int `json:"perPage"`
}
type GetUserOrgListQuery struct {
UserId int64
Result []*UserOrgDTO
}
// ------------------------
// DTO & Projections
type SignedInUser struct {
UserId int64
OrgId int64
OrgName string
OrgRole RoleType
Login string
Name string
Email string
ApiKeyId int64
OrgCount int
IsGrafanaAdmin bool
IsAnonymous bool
HelpFlags1 HelpFlags1
LastSeenAt time.Time
2018-10-25 08:20:01 -05:00
Teams []int64
// Permissions grouped by orgID and actions
Permissions map[int64]map[string][]string `json:"-"`
}
func (u *SignedInUser) ShouldUpdateLastSeenAt() bool {
return u.UserId > 0 && time.Since(u.LastSeenAt) > time.Minute*5
}
func (u *SignedInUser) NameOrFallback() string {
if u.Name != "" {
return u.Name
}
if u.Login != "" {
return u.Login
}
return u.Email
}
func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO {
return &UserDisplayDTO{
Id: u.UserId,
Login: u.Login,
Name: u.Name,
}
}
type UpdateUserLastSeenAtCommand struct {
UserId int64
}
func (u *SignedInUser) HasRole(role RoleType) bool {
if u.IsGrafanaAdmin {
2017-06-16 20:25:24 -05:00
return true
}
return u.OrgRole.Includes(role)
2017-06-16 20:25:24 -05:00
}
func (u *SignedInUser) IsRealUser() bool {
return u.UserId != 0
}
type UserProfileDTO struct {
Id int64 `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Login string `json:"login"`
Theme string `json:"theme"`
OrgId int64 `json:"orgId"`
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
IsDisabled bool `json:"isDisabled"`
IsExternal bool `json:"isExternal"`
AuthLabels []string `json:"authLabels"`
UpdatedAt time.Time `json:"updatedAt"`
CreatedAt time.Time `json:"createdAt"`
AvatarUrl string `json:"avatarUrl"`
AccessControl map[string]bool `json:"accessControl,omitempty"`
}
type UserSearchHitDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Login string `json:"login"`
Email string `json:"email"`
AvatarUrl string `json:"avatarUrl"`
IsAdmin bool `json:"isAdmin"`
IsDisabled bool `json:"isDisabled"`
LastSeenAt time.Time `json:"lastSeenAt"`
LastSeenAtAge string `json:"lastSeenAtAge"`
AuthLabels []string `json:"authLabels"`
AuthModule AuthModuleConversion `json:"-"`
}
2015-11-16 08:55:02 -06:00
type UserDisplayDTO struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Login string `json:"login,omitempty"`
AvatarUrl string `json:"avatarUrl"`
}
2015-11-16 08:55:02 -06:00
type UserIdDTO struct {
2015-11-16 09:28:38 -06:00
Id int64 `json:"id"`
Message string `json:"message"`
2015-11-16 08:55:02 -06:00
}
// implement Conversion interface to define custom field mapping (xorm feature)
type AuthModuleConversion []string
func (auth *AuthModuleConversion) FromDB(data []byte) error {
auth_module := string(data)
*auth = []string{auth_module}
return nil
}
// Just a stub, we don't want to write to database
func (auth *AuthModuleConversion) ToDB() ([]byte, error) {
return []byte{}, nil
}