The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/services/sqlstore/user.go

864 lines
22 KiB

package sqlstore
import (
"context"
"fmt"
"sort"
"strconv"
"strings"
"time"
"github.com/google/uuid"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
func (ss *SQLStore) addUserQueryAndCommandHandlers() {
ss.Bus.AddHandler(ss.GetSignedInUserWithCacheCtx)
bus.AddHandler("sql", ss.GetUserById)
bus.AddHandler("sql", ss.UpdateUser)
bus.AddHandler("sql", ss.ChangeUserPassword)
bus.AddHandler("sql", ss.GetUserByLogin)
bus.AddHandler("sql", ss.GetUserByEmail)
bus.AddHandler("sql", ss.SetUsingOrg)
bus.AddHandler("sql", ss.UpdateUserLastSeenAt)
bus.AddHandler("sql", ss.GetUserProfile)
bus.AddHandler("sql", SearchUsers)
bus.AddHandler("sql", ss.GetUserOrgList)
bus.AddHandler("sql", ss.DisableUser)
bus.AddHandler("sql", ss.BatchDisableUsers)
bus.AddHandler("sql", ss.DeleteUser)
bus.AddHandler("sql", ss.SetUserHelpFlag)
}
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func getOrgIdForNewUser(sess *DBSession, cmd models.CreateUserCommand) (int64, error) {
if cmd.SkipOrgSetup {
return -1, nil
}
if setting.AutoAssignOrg && cmd.OrgId != 0 {
err := verifyExistingOrg(sess, cmd.OrgId)
if err != nil {
return -1, err
}
return cmd.OrgId, nil
}
orgName := cmd.OrgName
if len(orgName) == 0 {
orgName = util.StringsFallback2(cmd.Email, cmd.Login)
}
return getOrCreateOrg(sess, orgName)
}
type userCreationArgs struct {
Login string
Email string
Name string
Company string
Password string
IsAdmin bool
IsDisabled bool
EmailVerified bool
OrgID int64
OrgName string
DefaultOrgRole string
}
func (ss *SQLStore) getOrgIDForNewUser(sess *DBSession, args userCreationArgs) (int64, error) {
if ss.Cfg.AutoAssignOrg && args.OrgID != 0 {
if err := verifyExistingOrg(sess, args.OrgID); err != nil {
return -1, err
}
return args.OrgID, nil
}
orgName := args.OrgName
if orgName == "" {
orgName = util.StringsFallback2(args.Email, args.Login)
}
return ss.getOrCreateOrg(sess, orgName)
}
// createUser creates a user in the database
func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args userCreationArgs, skipOrgSetup bool) (models.User, error) {
var user models.User
var orgID int64 = -1
if !skipOrgSetup {
var err error
orgID, err = ss.getOrgIDForNewUser(sess, args)
if err != nil {
return user, err
}
}
if args.Email == "" {
args.Email = args.Login
}
exists, err := sess.Where("email=? OR login=?", args.Email, args.Login).Get(&models.User{})
if err != nil {
return user, err
}
if exists {
return user, models.ErrUserAlreadyExists
}
// create user
user = models.User{
Email: args.Email,
Name: args.Name,
Login: args.Login,
Company: args.Company,
IsAdmin: args.IsAdmin,
IsDisabled: args.IsDisabled,
OrgId: orgID,
EmailVerified: args.EmailVerified,
Created: time.Now(),
Updated: time.Now(),
LastSeenAt: time.Now().AddDate(-10, 0, 0),
}
salt, err := util.GetRandomString(10)
if err != nil {
return user, err
}
user.Salt = salt
rands, err := util.GetRandomString(10)
if err != nil {
return user, err
}
user.Rands = rands
if len(args.Password) > 0 {
encodedPassword, err := util.EncodePassword(args.Password, user.Salt)
if err != nil {
return user, err
}
user.Password = encodedPassword
}
sess.UseBool("is_admin")
if _, err := sess.Insert(&user); err != nil {
return user, err
}
sess.publishAfterCommit(&events.UserCreated{
Timestamp: user.Created,
Id: user.Id,
Name: user.Name,
Login: user.Login,
Email: user.Email,
})
// create org user link
if !skipOrgSetup {
orgUser := models.OrgUser{
OrgId: orgID,
UserId: user.Id,
Role: models.ROLE_ADMIN,
Created: time.Now(),
Updated: time.Now(),
}
if ss.Cfg.AutoAssignOrg && !user.IsAdmin {
if len(args.DefaultOrgRole) > 0 {
orgUser.Role = models.RoleType(args.DefaultOrgRole)
} else {
orgUser.Role = models.RoleType(ss.Cfg.AutoAssignOrgRole)
}
}
if _, err = sess.Insert(&orgUser); err != nil {
return user, err
}
}
return user, nil
}
func (ss *SQLStore) CloneUserToServiceAccount(ctx context.Context, siUser *models.SignedInUser) (*models.User, error) {
cmd := models.CreateUserCommand{
Login: "Service-Account-" + uuid.New().String(),
Email: uuid.New().String(),
Password: "Password-" + uuid.New().String(),
Name: siUser.Name + "-Service-Account-" + uuid.New().String(),
OrgId: siUser.OrgId,
IsServiceAccount: true,
}
newuser, err := ss.CreateUser(ctx, cmd)
if err != nil {
ss.log.Warn("user not cloned", "err", err)
return nil, fmt.Errorf("failed to create user: %w", err)
}
return newuser, err
}
func (ss *SQLStore) CreateServiceAccountForApikey(ctx context.Context, orgId int64, keyname string, role models.RoleType) (*models.User, error) {
prefix := "Service-Account-Autogen-"
cmd := models.CreateUserCommand{
Login: fmt.Sprintf("%v-%v-%v", prefix, orgId, keyname),
Name: prefix + keyname,
OrgId: orgId,
DefaultOrgRole: string(role),
IsServiceAccount: true,
}
newuser, err := ss.CreateUser(ctx, cmd)
if err != nil {
return nil, fmt.Errorf("failed to create user: %w", err)
}
return newuser, err
}
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func (ss *SQLStore) CreateUser(ctx context.Context, cmd models.CreateUserCommand) (*models.User, error) {
var user *models.User
err := ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
orgId, err := getOrgIdForNewUser(sess, cmd)
if err != nil {
return err
}
if cmd.Email == "" {
cmd.Email = cmd.Login
}
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
exists, err := sess.Where("email=? OR login=?", cmd.Email, cmd.Login).Get(&models.User{})
if err != nil {
return err
}
if exists {
return models.ErrUserAlreadyExists
}
// create user
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
user = &models.User{
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>
4 years ago
Email: cmd.Email,
Name: cmd.Name,
Login: cmd.Login,
Company: cmd.Company,
IsAdmin: cmd.IsAdmin,
IsDisabled: cmd.IsDisabled,
OrgId: orgId,
EmailVerified: cmd.EmailVerified,
Created: time.Now(),
Updated: time.Now(),
LastSeenAt: time.Now().AddDate(-10, 0, 0),
IsServiceAccount: cmd.IsServiceAccount,
}
salt, err := util.GetRandomString(10)
if err != nil {
return err
}
user.Salt = salt
rands, err := util.GetRandomString(10)
if err != nil {
return err
}
user.Rands = rands
if len(cmd.Password) > 0 {
encodedPassword, err := util.EncodePassword(cmd.Password, user.Salt)
if err != nil {
return err
}
user.Password = encodedPassword
}
sess.UseBool("is_admin")
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
if _, err := sess.Insert(user); err != nil {
return err
}
sess.publishAfterCommit(&events.UserCreated{
Timestamp: user.Created,
Id: user.Id,
Name: user.Name,
Login: user.Login,
Email: user.Email,
})
// create org user link
if !cmd.SkipOrgSetup {
orgUser := models.OrgUser{
OrgId: orgId,
UserId: user.Id,
Role: models.ROLE_ADMIN,
Created: time.Now(),
Updated: time.Now(),
}
if setting.AutoAssignOrg && !user.IsAdmin {
if len(cmd.DefaultOrgRole) > 0 {
orgUser.Role = models.RoleType(cmd.DefaultOrgRole)
} else {
orgUser.Role = models.RoleType(setting.AutoAssignOrgRole)
}
}
if _, err = sess.Insert(&orgUser); err != nil {
return err
}
}
return nil
})
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
return user, err
}
func (ss SQLStore) GetUserById(ctx context.Context, query *models.GetUserByIdQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
user := new(models.User)
has, err := sess.ID(query.Id).Get(user)
if err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
query.Result = user
return nil
})
}
func (ss *SQLStore) GetUserByLogin(ctx context.Context, query *models.GetUserByLoginQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
if query.LoginOrEmail == "" {
return models.ErrUserNotFound
}
// Try and find the user by login first.
// It's not sufficient to assume that a LoginOrEmail with an "@" is an email.
user := &models.User{Login: query.LoginOrEmail}
has, err := sess.Get(user)
if err != nil {
return err
}
if !has && strings.Contains(query.LoginOrEmail, "@") {
// If the user wasn't found, and it contains an "@" fallback to finding the
// user by email.
user = &models.User{Email: query.LoginOrEmail}
has, err = sess.Get(user)
}
if err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
query.Result = user
return nil
})
}
func (ss *SQLStore) GetUserByEmail(ctx context.Context, query *models.GetUserByEmailQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
if query.Email == "" {
return models.ErrUserNotFound
}
user := &models.User{Email: query.Email}
has, err := sess.Get(user)
if err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
query.Result = user
return nil
})
}
func (ss *SQLStore) UpdateUser(ctx context.Context, cmd *models.UpdateUserCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Name: cmd.Name,
Email: cmd.Email,
Login: cmd.Login,
Theme: cmd.Theme,
Updated: time.Now(),
}
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
if _, err := sess.ID(cmd.UserId).Update(&user); err != nil {
return err
}
sess.publishAfterCommit(&events.UserUpdated{
Timestamp: user.Created,
Id: user.Id,
Name: user.Name,
Login: user.Login,
Email: user.Email,
})
return nil
})
}
func (ss *SQLStore) ChangeUserPassword(ctx context.Context, cmd *models.ChangeUserPasswordCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Password: cmd.NewPassword,
Updated: time.Now(),
}
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
_, err := sess.ID(cmd.UserId).Update(&user)
Simplify error returns (gosimple) This fixes: pkg/api/avatar/avatar.go:261:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/log/file.go:102:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/metrics/graphitebridge/graphite.go:298:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/provisioning/provisioning.go:23:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:351:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:435:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/stats.go:22:2: 'if err != nil { return err }; return err' can be simplified to 'return err' (S1013) pkg/services/sqlstore/team.go:213:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013)
7 years ago
return err
})
}
func (ss *SQLStore) UpdateUserLastSeenAt(ctx context.Context, cmd *models.UpdateUserLastSeenAtCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Id: cmd.UserId,
LastSeenAt: time.Now(),
}
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
_, err := sess.ID(cmd.UserId).Update(&user)
Simplify error returns (gosimple) This fixes: pkg/api/avatar/avatar.go:261:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/log/file.go:102:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/metrics/graphitebridge/graphite.go:298:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/provisioning/provisioning.go:23:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:351:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:435:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/stats.go:22:2: 'if err != nil { return err }; return err' can be simplified to 'return err' (S1013) pkg/services/sqlstore/team.go:213:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013)
7 years ago
return err
})
}
func (ss *SQLStore) SetUsingOrg(ctx context.Context, cmd *models.SetUsingOrgCommand) error {
getOrgsForUserCmd := &models.GetUserOrgListQuery{UserId: cmd.UserId}
if err := ss.GetUserOrgList(ctx, getOrgsForUserCmd); err != nil {
return err
}
valid := false
for _, other := range getOrgsForUserCmd.Result {
if other.OrgId == cmd.OrgId {
valid = true
}
}
if !valid {
return fmt.Errorf("user does not belong to org")
}
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
return setUsingOrgInTransaction(sess, cmd.UserId, cmd.OrgId)
})
}
func setUsingOrgInTransaction(sess *DBSession, userID int64, orgID int64) error {
user := models.User{
Id: userID,
OrgId: orgID,
}
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
_, err := sess.ID(userID).Update(&user)
return err
}
func (ss *SQLStore) GetUserProfile(ctx context.Context, query *models.GetUserProfileQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
var user models.User
has, err := sess.ID(query.UserId).Get(&user)
if err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
query.Result = models.UserProfileDTO{
Id: user.Id,
Name: user.Name,
Email: user.Email,
Login: user.Login,
Theme: user.Theme,
IsGrafanaAdmin: user.IsAdmin,
IsDisabled: user.IsDisabled,
OrgId: user.OrgId,
UpdatedAt: user.Updated,
CreatedAt: user.Created,
}
return err
})
}
type byOrgName []*models.UserOrgDTO
// 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
}
func (ss *SQLStore) GetUserOrgList(ctx context.Context, query *models.GetUserOrgListQuery) error {
query.Result = make([]*models.UserOrgDTO, 0)
sess := x.Table("org_user")
sess.Join("INNER", "org", "org_user.org_id=org.id")
sess.Where("org_user.user_id=?", query.UserId)
sess.Cols("org.name", "org_user.role", "org_user.org_id")
sess.OrderBy("org.name")
err := sess.Find(&query.Result)
sort.Sort(byOrgName(query.Result))
return err
}
func newSignedInUserCacheKey(orgID, userID int64) string {
return fmt.Sprintf("signed-in-user-%d-%d", userID, orgID)
}
func (ss *SQLStore) GetSignedInUserWithCacheCtx(ctx context.Context, query *models.GetSignedInUserQuery) error {
cacheKey := newSignedInUserCacheKey(query.OrgId, query.UserId)
if cached, found := ss.CacheService.Get(cacheKey); found {
cachedUser := cached.(models.SignedInUser)
query.Result = &cachedUser
return nil
}
err := ss.GetSignedInUser(ctx, query)
if err != nil {
return err
}
cacheKey = newSignedInUserCacheKey(query.Result.OrgId, query.UserId)
ss.CacheService.Set(cacheKey, *query.Result, time.Second*5)
return nil
}
func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSignedInUserQuery) error {
orgId := "u.org_id"
if query.OrgId > 0 {
orgId = strconv.FormatInt(query.OrgId, 10)
}
var rawSQL = `SELECT
u.id as user_id,
u.is_admin as is_grafana_admin,
u.email as email,
u.login as login,
u.name as name,
u.help_flags1 as help_flags1,
u.last_seen_at as last_seen_at,
(SELECT COUNT(*) FROM org_user where org_user.user_id = u.id) as org_count,
org.name as org_name,
org_user.role as org_role,
org.id as org_id
FROM ` + dialect.Quote("user") + ` as u
LEFT OUTER JOIN org_user on org_user.org_id = ` + orgId + ` and org_user.user_id = u.id
LEFT OUTER JOIN org on org.id = org_user.org_id `
sess := x.Table("user")
sess = sess.Context(ctx)
switch {
case query.UserId > 0:
sess.SQL(rawSQL+"WHERE u.id=?", query.UserId)
case query.Login != "":
sess.SQL(rawSQL+"WHERE u.login=?", query.Login)
case query.Email != "":
sess.SQL(rawSQL+"WHERE u.email=?", query.Email)
}
var user models.SignedInUser
has, err := sess.Get(&user)
if err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
if user.OrgRole == "" {
user.OrgId = -1
user.OrgName = "Org missing"
}
getTeamsByUserQuery := &models.GetTeamsByUserQuery{OrgId: user.OrgId, UserId: user.UserId}
err = ss.GetTeamsByUser(ctx, getTeamsByUserQuery)
if err != nil {
return err
}
user.Teams = make([]int64, len(getTeamsByUserQuery.Result))
for i, t := range getTeamsByUserQuery.Result {
user.Teams[i] = t.Id
}
query.Result = &user
return err
}
func SearchUsers(ctx context.Context, query *models.SearchUsersQuery) error {
query.Result = models.SearchUserQueryResult{
Users: make([]*models.UserSearchHitDTO, 0),
}
queryWithWildcards := "%" + query.Query + "%"
whereConditions := make([]string, 0)
whereParams := make([]interface{}, 0)
sess := x.Table("user").Alias("u")
Serviceaccounts: Filtering service accounts from user queries (#41410) * 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 * wip * Filtering service accounts from the user queries in frontend * clean up * Update pkg/services/sqlstore/org_test.go * methods on same type should have same receiver * _ unused variable and comment * add additional join for results query * remove unused code * remove error fmt * refactor: change to only have false * no new variable to the left hand side * refactor: create serviceaccount cmd * dialect fix 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>
4 years ago
// TODO: add to chore, for cleaning up after we have created
// service accounts table in the modelling
whereConditions = append(whereConditions, "u.is_service_account = false")
// Join with only most recent auth module
joinCondition := `(
SELECT id from user_auth
WHERE user_auth.user_id = u.id
ORDER BY user_auth.created DESC `
joinCondition = "user_auth.id=" + joinCondition + dialect.Limit(1) + ")"
sess.Join("LEFT", "user_auth", joinCondition)
if query.OrgId > 0 {
whereConditions = append(whereConditions, "org_id = ?")
whereParams = append(whereParams, query.OrgId)
}
if query.Query != "" {
whereConditions = append(whereConditions, "(email "+dialect.LikeStr()+" ? OR name "+dialect.LikeStr()+" ? OR login "+dialect.LikeStr()+" ?)")
whereParams = append(whereParams, queryWithWildcards, queryWithWildcards, queryWithWildcards)
}
if query.IsDisabled != nil {
whereConditions = append(whereConditions, "is_disabled = ?")
whereParams = append(whereParams, query.IsDisabled)
}
if query.AuthModule != "" {
whereConditions = append(whereConditions, `auth_module=?`)
whereParams = append(whereParams, query.AuthModule)
}
if len(whereConditions) > 0 {
sess.Where(strings.Join(whereConditions, " AND "), whereParams...)
}
for _, filter := range query.Filters {
if jc := filter.JoinCondition(); jc != nil {
sess.Join(jc.Operator, jc.Table, jc.Params)
}
if ic := filter.InCondition(); ic != nil {
sess.In(ic.Condition, ic.Params)
}
if wc := filter.WhereCondition(); wc != nil {
sess.Where(wc.Condition, wc.Params)
}
}
if query.Limit > 0 {
offset := query.Limit * (query.Page - 1)
sess.Limit(query.Limit, offset)
}
sess.Cols("u.id", "u.email", "u.name", "u.login", "u.is_admin", "u.is_disabled", "u.last_seen_at", "user_auth.auth_module")
sess.Asc("u.login", "u.email")
if err := sess.Find(&query.Result.Users); err != nil {
return err
}
// get total
user := models.User{}
countSess := x.Table("user").Alias("u")
// Join with user_auth table if users filtered by auth_module
if query.AuthModule != "" {
countSess.Join("LEFT", "user_auth", joinCondition)
}
if len(whereConditions) > 0 {
countSess.Where(strings.Join(whereConditions, " AND "), whereParams...)
}
for _, filter := range query.Filters {
if jc := filter.JoinCondition(); jc != nil {
countSess.Join(jc.Operator, jc.Table, jc.Params)
}
if ic := filter.InCondition(); ic != nil {
countSess.In(ic.Condition, ic.Params)
}
if wc := filter.WhereCondition(); wc != nil {
countSess.Where(wc.Condition, wc.Params)
}
}
count, err := countSess.Count(&user)
query.Result.TotalCount = count
for _, user := range query.Result.Users {
user.LastSeenAtAge = util.GetAgeString(user.LastSeenAt)
}
return err
}
func (ss *SQLStore) DisableUser(ctx context.Context, cmd *models.DisableUserCommand) error {
user := models.User{}
sess := x.Table("user")
if has, err := sess.ID(cmd.UserId).Get(&user); err != nil {
return err
} else if !has {
return models.ErrUserNotFound
}
user.IsDisabled = cmd.IsDisabled
sess.UseBool("is_disabled")
_, err := sess.ID(cmd.UserId).Update(&user)
return err
}
func (ss *SQLStore) BatchDisableUsers(ctx context.Context, cmd *models.BatchDisableUsersCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
userIds := cmd.UserIds
if len(userIds) == 0 {
return nil
}
user_id_params := strings.Repeat(",?", len(userIds)-1)
disableSQL := "UPDATE " + dialect.Quote("user") + " SET is_disabled=? WHERE Id IN (?" + user_id_params + ")"
disableParams := []interface{}{disableSQL, cmd.IsDisabled}
for _, v := range userIds {
disableParams = append(disableParams, v)
}
_, err := sess.Exec(disableParams...)
if err != nil {
return err
}
return nil
})
}
func (ss *SQLStore) DeleteUser(ctx context.Context, cmd *models.DeleteUserCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
return deleteUserInTransaction(sess, cmd)
})
}
func deleteUserInTransaction(sess *DBSession, cmd *models.DeleteUserCommand) error {
// Check if user exists
user := models.User{Id: cmd.UserId}
has, err := sess.Get(&user)
if err != nil {
return err
}
if !has {
return models.ErrUserNotFound
}
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>
4 years ago
for _, sql := range userDeletions() {
_, err := sess.Exec(sql, cmd.UserId)
if err != nil {
return err
}
}
return nil
}
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>
4 years ago
func userDeletions() []string {
deletes := []string{
"DELETE FROM star WHERE user_id = ?",
"DELETE FROM " + dialect.Quote("user") + " WHERE id = ?",
"DELETE FROM org_user WHERE user_id = ?",
"DELETE FROM dashboard_acl WHERE user_id = ?",
"DELETE FROM preferences WHERE user_id = ?",
"DELETE FROM team_member WHERE user_id = ?",
"DELETE FROM user_auth WHERE user_id = ?",
"DELETE FROM user_auth_token WHERE user_id = ?",
"DELETE FROM quota WHERE user_id = ?",
}
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>
4 years ago
return deletes
}
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>
4 years ago
func ServiceAccountDeletions() []string {
deletes := []string{
"DELETE FROM api_key WHERE service_account_id = ?",
}
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>
4 years ago
deletes = append(deletes, userDeletions()...)
return deletes
}
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
var user models.User
if _, err := sess.ID(userID).Get(&user); err != nil {
return err
}
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
user.IsAdmin = isAdmin
sess.UseBool("is_admin")
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
_, err := sess.ID(user.Id).Update(&user)
if err != nil {
return err
}
// validate that after update there is at least one server admin
if err := validateOneAdminLeft(sess); err != nil {
return err
}
return nil
})
}
func (ss *SQLStore) SetUserHelpFlag(ctx context.Context, cmd *models.SetUserHelpFlagCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Id: cmd.UserId,
HelpFlags1: cmd.HelpFlags1,
Updated: time.Now(),
}
pkg/services/sqlstore: Fix sess.Id is deprecated: use ID instead. (megacheck) See, $ gometalinter --vendor --disable-all --enable=megacheck --disable=gotype --deadline 6m ./... | grep ID alert.go:193:15:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) alert.go:252:18:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) annotation.go:113:12:warning: sess.Table("annotation").Id is deprecated: use ID instead (SA1019) (megacheck) org.go:136:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org.go:169:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:24:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:88:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) org_users.go:141:21:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) plugin_setting.go:103:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) preferences.go:97:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:119:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) quota.go:221:17:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) team.go:77:24:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:243:16:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:267:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:282:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:313:12:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:475:3:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:479:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck) user.go:493:13:warning: sess.Id is deprecated: use ID instead (SA1019) (megacheck)
7 years ago
_, err := sess.ID(cmd.UserId).Cols("help_flags1").Update(&user)
Simplify error returns (gosimple) This fixes: pkg/api/avatar/avatar.go:261:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/log/file.go:102:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/metrics/graphitebridge/graphite.go:298:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/provisioning/provisioning.go:23:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/alert_notification.go:27:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/annotation.go:105:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:351:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard.go:435:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/dashboard_acl.go:38:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/stats.go:22:2: 'if err != nil { return err }; return err' can be simplified to 'return err' (S1013) pkg/services/sqlstore/team.go:213:2: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:256:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:274:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) pkg/services/sqlstore/user.go:482:3: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013)
7 years ago
return err
})
}
func validateOneAdminLeft(sess *DBSession) error {
// validate that there is an admin user left
count, err := sess.Where("is_admin=?", true).Count(&models.User{})
if err != nil {
return err
}
if count == 0 {
return models.ErrLastGrafanaAdmin
}
return nil
}