| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | package userimpl | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/events" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore/db" | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore/migrator" | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/user" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type store interface { | 
					
						
							|  |  |  | 	Insert(context.Context, *user.User) (int64, error) | 
					
						
							|  |  |  | 	Get(context.Context, *user.User) (*user.User, error) | 
					
						
							| 
									
										
										
										
											2022-08-02 22:58:05 +08:00
										 |  |  | 	GetByID(context.Context, int64) (*user.User, error) | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 	GetNotServiceAccount(context.Context, int64) (*user.User, error) | 
					
						
							|  |  |  | 	Delete(context.Context, int64) error | 
					
						
							| 
									
										
										
										
											2022-08-02 22:58:05 +08:00
										 |  |  | 	CaseInsensitiveLoginConflict(context.Context, string, string) error | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlStore struct { | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 	db      db.DB | 
					
						
							|  |  |  | 	dialect migrator.Dialect | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) { | 
					
						
							|  |  |  | 	var userID int64 | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	err = ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							|  |  |  | 		sess.UseBool("is_admin") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if userID, err = sess.Insert(cmd); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		sess.PublishAfterCommit(&events.UserCreated{ | 
					
						
							|  |  |  | 			Timestamp: cmd.Created, | 
					
						
							|  |  |  | 			Id:        cmd.ID, | 
					
						
							|  |  |  | 			Name:      cmd.Name, | 
					
						
							|  |  |  | 			Login:     cmd.Login, | 
					
						
							|  |  |  | 			Email:     cmd.Email, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return 0, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return userID, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | func (ss *sqlStore) Get(ctx context.Context, usr *user.User) (*user.User, error) { | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | 	err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 		exists, err := sess.Where("email=? OR login=?", usr.Email, usr.Login).Get(usr) | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | 		if !exists { | 
					
						
							| 
									
										
										
										
											2022-07-20 20:50:06 +08:00
										 |  |  | 			return user.ErrUserNotFound | 
					
						
							| 
									
										
										
										
											2022-06-28 20:32:25 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return usr, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (ss *sqlStore) Delete(ctx context.Context, userID int64) error { | 
					
						
							|  |  |  | 	err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							|  |  |  | 		var rawSQL = "DELETE FROM " + ss.dialect.Quote("user") + " WHERE id = ?" | 
					
						
							|  |  |  | 		_, err := sess.Exec(rawSQL, userID) | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (ss *sqlStore) GetNotServiceAccount(ctx context.Context, userID int64) (*user.User, error) { | 
					
						
							| 
									
										
										
										
											2022-07-20 20:50:06 +08:00
										 |  |  | 	usr := user.User{ID: userID} | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 	err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							| 
									
										
										
										
											2022-07-20 20:50:06 +08:00
										 |  |  | 		has, err := sess.Where(ss.notServiceAccountFilter()).Get(&usr) | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !has { | 
					
						
							| 
									
										
										
										
											2022-07-20 20:50:06 +08:00
										 |  |  | 			return user.ErrUserNotFound | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-20 20:50:06 +08:00
										 |  |  | 	return &usr, err | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 22:58:05 +08:00
										 |  |  | func (ss *sqlStore) GetByID(ctx context.Context, userID int64) (*user.User, error) { | 
					
						
							|  |  |  | 	var usr user.User | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							|  |  |  | 		has, err := sess.ID(&userID). | 
					
						
							|  |  |  | 			Where(ss.notServiceAccountFilter()). | 
					
						
							|  |  |  | 			Get(&usr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} else if !has { | 
					
						
							|  |  |  | 			return user.ErrUserNotFound | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	return &usr, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 22:01:05 +08:00
										 |  |  | func (ss *sqlStore) notServiceAccountFilter() string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("%s.is_service_account = %s", | 
					
						
							|  |  |  | 		ss.dialect.Quote("user"), | 
					
						
							|  |  |  | 		ss.dialect.BooleanStr(false)) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-08-02 22:58:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (ss *sqlStore) CaseInsensitiveLoginConflict(ctx context.Context, login, email string) error { | 
					
						
							|  |  |  | 	users := make([]user.User, 0) | 
					
						
							|  |  |  | 	err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { | 
					
						
							|  |  |  | 		if err := sess.Where("LOWER(email)=LOWER(?) OR LOWER(login)=LOWER(?)", | 
					
						
							|  |  |  | 			email, login).Find(&users); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if len(users) > 1 { | 
					
						
							|  |  |  | 			return &user.ErrCaseInsensitiveLoginConflict{Users: users} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } |