2020-10-28 14:35:41 +01:00
|
|
|
package sqlstore
|
|
|
|
|
|
|
|
import (
|
2021-06-04 15:23:15 +02:00
|
|
|
"database/sql"
|
2020-11-06 16:46:35 +01:00
|
|
|
"encoding/json"
|
2021-07-09 03:09:02 +02:00
|
|
|
"fmt"
|
2021-06-04 15:23:15 +02:00
|
|
|
"log"
|
2020-10-28 14:35:41 +01:00
|
|
|
|
2021-01-26 23:13:46 +01:00
|
|
|
"github.com/mattermost/focalboard/server/model"
|
2021-10-07 13:51:01 +02:00
|
|
|
"github.com/mattermost/focalboard/server/utils"
|
2020-10-28 14:35:41 +01:00
|
|
|
|
|
|
|
sq "github.com/Masterminds/squirrel"
|
|
|
|
)
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
type UserNotFoundError struct {
|
|
|
|
id string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (unf UserNotFoundError) Error() string {
|
|
|
|
return fmt.Sprintf("user not found (%s)", unf.id)
|
|
|
|
}
|
|
|
|
|
2021-01-27 18:22:33 +01:00
|
|
|
func (s *SQLStore) GetRegisteredUserCount() (int, error) {
|
2021-01-14 01:56:01 +01:00
|
|
|
query := s.getQueryBuilder().
|
|
|
|
Select("count(*)").
|
2021-04-17 09:06:57 +02:00
|
|
|
From(s.tablePrefix + "users").
|
2021-01-14 01:56:01 +01:00
|
|
|
Where(sq.Eq{"delete_at": 0})
|
|
|
|
row := query.QueryRow()
|
|
|
|
|
|
|
|
var count int
|
|
|
|
err := row.Scan(&count)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return count, nil
|
|
|
|
}
|
|
|
|
|
2020-10-28 14:35:41 +01:00
|
|
|
func (s *SQLStore) getUserByCondition(condition sq.Eq) (*model.User, error) {
|
2021-06-04 15:23:15 +02:00
|
|
|
users, err := s.getUsersByCondition(condition)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(users) == 0 {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return users[0], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) getUsersByCondition(condition sq.Eq) ([]*model.User, error) {
|
2020-10-28 14:35:41 +01:00
|
|
|
query := s.getQueryBuilder().
|
2021-06-04 15:23:15 +02:00
|
|
|
Select(
|
|
|
|
"id",
|
|
|
|
"username",
|
|
|
|
"email",
|
|
|
|
"password",
|
|
|
|
"mfa_secret",
|
|
|
|
"auth_service",
|
|
|
|
"auth_data",
|
|
|
|
"props",
|
|
|
|
"create_at",
|
|
|
|
"update_at",
|
|
|
|
"delete_at",
|
|
|
|
).
|
2021-04-17 09:06:57 +02:00
|
|
|
From(s.tablePrefix + "users").
|
2020-12-07 20:40:16 +01:00
|
|
|
Where(sq.Eq{"delete_at": 0}).
|
2020-10-28 14:35:41 +01:00
|
|
|
Where(condition)
|
2021-06-04 15:23:15 +02:00
|
|
|
rows, err := query.Query()
|
2020-11-06 16:46:35 +01:00
|
|
|
if err != nil {
|
2021-06-04 15:23:15 +02:00
|
|
|
log.Printf("getUsersByCondition ERROR: %v", err)
|
2020-11-06 16:46:35 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
2021-07-06 22:44:11 +02:00
|
|
|
defer s.CloseRows(rows)
|
2020-11-06 16:46:35 +01:00
|
|
|
|
2021-06-04 15:23:15 +02:00
|
|
|
users, err := s.usersFromRows(rows)
|
2020-10-28 14:35:41 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-06-04 15:23:15 +02:00
|
|
|
if len(users) == 0 {
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
return users, nil
|
2020-10-28 14:35:41 +01:00
|
|
|
}
|
|
|
|
|
2021-06-21 11:21:42 +02:00
|
|
|
func (s *SQLStore) GetUserByID(userID string) (*model.User, error) {
|
2020-10-28 14:35:41 +01:00
|
|
|
return s.getUserByCondition(sq.Eq{"id": userID})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) GetUserByEmail(email string) (*model.User, error) {
|
|
|
|
return s.getUserByCondition(sq.Eq{"email": email})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) GetUserByUsername(username string) (*model.User, error) {
|
|
|
|
return s.getUserByCondition(sq.Eq{"username": username})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) CreateUser(user *model.User) error {
|
2021-10-07 13:51:01 +02:00
|
|
|
now := utils.GetMillis()
|
2020-10-28 14:35:41 +01:00
|
|
|
|
2020-11-06 16:46:35 +01:00
|
|
|
propsBytes, err := json.Marshal(user.Props)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-04-17 09:06:57 +02:00
|
|
|
query := s.getQueryBuilder().Insert(s.tablePrefix+"users").
|
2020-10-28 14:35:41 +01:00
|
|
|
Columns("id", "username", "email", "password", "mfa_secret", "auth_service", "auth_data", "props", "create_at", "update_at", "delete_at").
|
2020-11-06 16:46:35 +01:00
|
|
|
Values(user.ID, user.Username, user.Email, user.Password, user.MfaSecret, user.AuthService, user.AuthData, propsBytes, now, now, 0)
|
|
|
|
|
|
|
|
_, err = query.Exec()
|
|
|
|
return err
|
2020-10-28 14:35:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) UpdateUser(user *model.User) error {
|
2021-10-07 13:51:01 +02:00
|
|
|
now := utils.GetMillis()
|
2020-11-06 16:46:35 +01:00
|
|
|
|
|
|
|
propsBytes, err := json.Marshal(user.Props)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-04-17 09:06:57 +02:00
|
|
|
query := s.getQueryBuilder().Update(s.tablePrefix+"users").
|
2020-11-06 16:46:35 +01:00
|
|
|
Set("username", user.Username).
|
|
|
|
Set("email", user.Email).
|
|
|
|
Set("props", propsBytes).
|
2021-01-20 22:52:25 +01:00
|
|
|
Set("update_at", now).
|
|
|
|
Where(sq.Eq{"id": user.ID})
|
2020-11-06 16:46:35 +01:00
|
|
|
|
2021-02-01 19:49:57 +01:00
|
|
|
result, err := query.Exec()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
rowCount, err := result.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if rowCount < 1 {
|
2021-07-09 03:09:02 +02:00
|
|
|
return UserNotFoundError{user.ID}
|
2021-02-01 19:49:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2020-10-28 14:35:41 +01:00
|
|
|
}
|
2021-01-20 22:52:25 +01:00
|
|
|
|
2021-03-21 09:28:26 +01:00
|
|
|
func (s *SQLStore) UpdateUserPassword(username, password string) error {
|
2021-10-07 13:51:01 +02:00
|
|
|
now := utils.GetMillis()
|
2021-01-20 22:52:25 +01:00
|
|
|
|
2021-04-17 09:06:57 +02:00
|
|
|
query := s.getQueryBuilder().Update(s.tablePrefix+"users").
|
2021-01-20 22:52:25 +01:00
|
|
|
Set("password", password).
|
|
|
|
Set("update_at", now).
|
|
|
|
Where(sq.Eq{"username": username})
|
|
|
|
|
2021-02-01 19:49:57 +01:00
|
|
|
result, err := query.Exec()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
rowCount, err := result.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if rowCount < 1 {
|
2021-07-09 03:09:02 +02:00
|
|
|
return UserNotFoundError{username}
|
2021-02-01 19:49:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-01-20 22:52:25 +01:00
|
|
|
}
|
2021-01-22 20:28:45 +01:00
|
|
|
|
2021-03-21 09:28:26 +01:00
|
|
|
func (s *SQLStore) UpdateUserPasswordByID(userID, password string) error {
|
2021-10-07 13:51:01 +02:00
|
|
|
now := utils.GetMillis()
|
2021-01-21 19:16:40 +01:00
|
|
|
|
2021-04-17 09:06:57 +02:00
|
|
|
query := s.getQueryBuilder().Update(s.tablePrefix+"users").
|
2021-01-21 19:16:40 +01:00
|
|
|
Set("password", password).
|
|
|
|
Set("update_at", now).
|
|
|
|
Where(sq.Eq{"id": userID})
|
|
|
|
|
2021-02-01 19:49:57 +01:00
|
|
|
result, err := query.Exec()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
rowCount, err := result.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if rowCount < 1 {
|
2021-07-09 03:09:02 +02:00
|
|
|
return UserNotFoundError{userID}
|
2021-02-01 19:49:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-01-21 19:16:40 +01:00
|
|
|
}
|
2021-06-04 15:23:15 +02:00
|
|
|
|
|
|
|
func (s *SQLStore) GetUsersByWorkspace(workspaceID string) ([]*model.User, error) {
|
|
|
|
return s.getUsersByCondition(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLStore) usersFromRows(rows *sql.Rows) ([]*model.User, error) {
|
|
|
|
users := []*model.User{}
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var user model.User
|
|
|
|
var propsBytes []byte
|
|
|
|
|
|
|
|
err := rows.Scan(
|
|
|
|
&user.ID,
|
|
|
|
&user.Username,
|
|
|
|
&user.Email,
|
|
|
|
&user.Password,
|
|
|
|
&user.MfaSecret,
|
|
|
|
&user.AuthService,
|
|
|
|
&user.AuthData,
|
|
|
|
&propsBytes,
|
|
|
|
&user.CreateAt,
|
|
|
|
&user.UpdateAt,
|
|
|
|
&user.DeleteAt,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.Unmarshal(propsBytes, &user.Props)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
users = append(users, &user)
|
|
|
|
}
|
|
|
|
|
|
|
|
return users, nil
|
|
|
|
}
|