2015-10-08 12:27:09 -04:00
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
2015-06-14 23:53:32 -08:00
// See License.txt for license information.
package store
import (
2016-07-14 04:18:18 -08:00
"crypto/md5"
2016-03-11 10:48:43 -05:00
"database/sql"
2015-06-14 23:53:32 -08:00
"fmt"
2016-04-21 22:37:01 -07:00
"strconv"
2016-01-20 13:36:16 -06:00
"strings"
2016-04-21 22:37:01 -07:00
"github.com/mattermost/platform/model"
2016-06-14 12:12:46 -04:00
"github.com/mattermost/platform/utils"
2015-06-14 23:53:32 -08:00
)
2016-01-05 14:53:41 -06:00
const (
2016-03-11 10:48:43 -05:00
MISSING_ACCOUNT_ERROR = "store.sql_user.missing_account.const"
MISSING_AUTH_ACCOUNT_ERROR = "store.sql_user.get_by_auth.missing_account.app_error"
2016-01-05 14:53:41 -06:00
)
2015-06-14 23:53:32 -08:00
type SqlUserStore struct {
* SqlStore
}
func NewSqlUserStore ( sqlStore * SqlStore ) UserStore {
us := & SqlUserStore { sqlStore }
for _ , db := range sqlStore . GetAllConns ( ) {
table := db . AddTableWithName ( model . User { } , "Users" ) . SetKeys ( false , "Id" )
table . ColMap ( "Id" ) . SetMaxSize ( 26 )
2016-04-21 22:37:01 -07:00
table . ColMap ( "Username" ) . SetMaxSize ( 64 ) . SetUnique ( true )
2015-06-14 23:53:32 -08:00
table . ColMap ( "Password" ) . SetMaxSize ( 128 )
2016-05-11 11:04:30 -07:00
table . ColMap ( "AuthData" ) . SetMaxSize ( 128 ) . SetUnique ( true )
2015-07-22 15:05:20 -04:00
table . ColMap ( "AuthService" ) . SetMaxSize ( 32 )
2016-04-21 22:37:01 -07:00
table . ColMap ( "Email" ) . SetMaxSize ( 128 ) . SetUnique ( true )
2015-07-09 13:59:19 -04:00
table . ColMap ( "Nickname" ) . SetMaxSize ( 64 )
2015-07-09 17:06:04 -04:00
table . ColMap ( "FirstName" ) . SetMaxSize ( 64 )
table . ColMap ( "LastName" ) . SetMaxSize ( 64 )
2015-06-14 23:53:32 -08:00
table . ColMap ( "Roles" ) . SetMaxSize ( 64 )
table . ColMap ( "Props" ) . SetMaxSize ( 4000 )
table . ColMap ( "NotifyProps" ) . SetMaxSize ( 2000 )
2016-01-19 22:00:01 -06:00
table . ColMap ( "Locale" ) . SetMaxSize ( 5 )
2016-03-30 12:49:29 -04:00
table . ColMap ( "MfaSecret" ) . SetMaxSize ( 128 )
2015-06-14 23:53:32 -08:00
}
return us
}
func ( us SqlUserStore ) CreateIndexesIfNotExists ( ) {
2015-07-12 14:56:44 -08:00
us . CreateIndexIfNotExists ( "idx_users_email" , "Users" , "Email" )
2015-06-14 23:53:32 -08:00
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) Save ( user * model . User ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if len ( user . Id ) > 0 {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Save" , "store.sql_user.save.existing.app_error" , nil , "user_id=" + user . Id )
2015-06-14 23:53:32 -08:00
storeChannel <- result
close ( storeChannel )
return
}
user . PreSave ( )
if result . Err = user . IsValid ( ) ; result . Err != nil {
storeChannel <- result
close ( storeChannel )
return
}
if err := us . GetMaster ( ) . Insert ( user ) ; err != nil {
2016-05-17 12:52:10 -07:00
if IsUniqueConstraintError ( err . Error ( ) , [ ] string { "Email" , "users_email_key" , "idx_users_email_unique" } ) {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Save" , "store.sql_user.save.email_exists.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2016-05-17 12:52:10 -07:00
} else if IsUniqueConstraintError ( err . Error ( ) , [ ] string { "Username" , "users_username_key" , "idx_users_username_unique" } ) {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Save" , "store.sql_user.save.username_exists.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Save" , "store.sql_user.save.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
}
} else {
result . Data = user
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-03 15:27:00 -04:00
func ( us SqlUserStore ) Update ( user * model . User , trustedUpdateData bool ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
user . PreUpdate ( )
if result . Err = user . IsValid ( ) ; result . Err != nil {
storeChannel <- result
close ( storeChannel )
return
}
if oldUserResult , err := us . GetMaster ( ) . Get ( model . User { } , user . Id ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.finding.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else if oldUserResult == nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.find.app_error" , nil , "user_id=" + user . Id )
2015-06-14 23:53:32 -08:00
} else {
oldUser := oldUserResult . ( * model . User )
user . CreateAt = oldUser . CreateAt
user . AuthData = oldUser . AuthData
2015-10-22 10:53:39 -04:00
user . AuthService = oldUser . AuthService
2015-06-14 23:53:32 -08:00
user . Password = oldUser . Password
user . LastPasswordUpdate = oldUser . LastPasswordUpdate
2015-07-16 08:55:37 -07:00
user . LastPictureUpdate = oldUser . LastPictureUpdate
2015-06-14 23:53:32 -08:00
user . EmailVerified = oldUser . EmailVerified
2015-07-29 01:26:10 -08:00
user . FailedAttempts = oldUser . FailedAttempts
2016-03-30 12:49:29 -04:00
user . MfaSecret = oldUser . MfaSecret
user . MfaActive = oldUser . MfaActive
2015-06-14 23:53:32 -08:00
2016-05-03 15:27:00 -04:00
if ! trustedUpdateData {
2015-06-14 23:53:32 -08:00
user . Roles = oldUser . Roles
user . DeleteAt = oldUser . DeleteAt
}
2016-04-21 22:37:01 -07:00
if user . IsOAuthUser ( ) {
2015-11-06 08:56:13 -05:00
user . Email = oldUser . Email
2016-05-03 15:27:00 -04:00
} else if user . IsLDAPUser ( ) && ! trustedUpdateData {
2016-05-02 08:07:58 -04:00
if user . Username != oldUser . Username ||
user . Email != oldUser . Email {
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.can_not_change_ldap.app_error" , nil , "user_id=" + user . Id )
storeChannel <- result
close ( storeChannel )
return
}
} else if user . Email != oldUser . Email {
2015-06-14 23:53:32 -08:00
user . EmailVerified = false
}
2015-08-20 14:29:40 -07:00
if user . Username != oldUser . Username {
2016-04-25 08:20:45 -04:00
user . UpdateMentionKeysFromUsername ( oldUser . Username )
2015-08-20 14:29:40 -07:00
}
2015-06-14 23:53:32 -08:00
if count , err := us . GetMaster ( ) . Update ( user ) ; err != nil {
2016-05-17 12:52:10 -07:00
if IsUniqueConstraintError ( err . Error ( ) , [ ] string { "Email" , "users_email_key" , "idx_users_email_unique" } ) {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.email_taken.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2016-05-17 12:52:10 -07:00
} else if IsUniqueConstraintError ( err . Error ( ) , [ ] string { "Username" , "users_username_key" , "idx_users_username_unique" } ) {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.username_taken.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2015-07-29 09:42:13 -07:00
} else {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.updating.app_error" , nil , "user_id=" + user . Id + ", " + err . Error ( ) )
2015-07-29 09:42:13 -07:00
}
2015-06-14 23:53:32 -08:00
} else if count != 1 {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Update" , "store.sql_user.update.app_error" , nil , fmt . Sprintf ( "user_id=%v, count=%v" , user . Id , count ) )
2015-06-14 23:53:32 -08:00
} else {
result . Data = [ 2 ] * model . User { user , oldUser }
}
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) UpdateLastPictureUpdate ( userId string ) StoreChannel {
2015-07-09 16:37:03 -07:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2015-07-16 08:55:37 -07:00
curTime := model . GetMillis ( )
2015-07-27 17:04:44 -04:00
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET LastPictureUpdate = :Time, UpdateAt = :Time WHERE Id = :UserId" , map [ string ] interface { } { "Time" : curTime , "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateUpdateAt" , "store.sql_user.update_last_picture_update.app_error" , nil , "user_id=" + userId )
2015-07-09 16:37:03 -07:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-12 18:36:30 -07:00
func ( us SqlUserStore ) UpdateUpdateAt ( userId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
curTime := model . GetMillis ( )
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET UpdateAt = :Time WHERE Id = :UserId" , map [ string ] interface { } { "Time" : curTime , "UserId" : userId } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateUpdateAt" , "store.sql_user.update_update.app_error" , nil , "user_id=" + userId )
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) UpdatePassword ( userId , hashedPassword string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
updateAt := model . GetMillis ( )
2016-05-11 11:04:30 -07:00
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET Password = :Password, LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt, AuthData = NULL, AuthService = '', EmailVerified = true, FailedAttempts = 0 WHERE Id = :UserId" , map [ string ] interface { } { "Password" : hashedPassword , "LastPasswordUpdate" : updateAt , "UpdateAt" : updateAt , "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.UpdatePassword" , "store.sql_user.update_password.app_error" , nil , "id=" + userId + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) UpdateFailedPasswordAttempts ( userId string , attempts int ) StoreChannel {
2015-07-29 01:26:10 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET FailedAttempts = :FailedAttempts WHERE Id = :UserId" , map [ string ] interface { } { "FailedAttempts" : attempts , "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateFailedPasswordAttempts" , "store.sql_user.update_failed_pwd_attempts.app_error" , nil , "user_id=" + userId )
2015-07-29 01:26:10 -08:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-11 11:04:30 -07:00
func ( us SqlUserStore ) UpdateAuthData ( userId string , service string , authData * string , email string ) StoreChannel {
2015-12-17 12:44:46 -05:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-04-13 14:31:27 -04:00
email = strings . ToLower ( email )
2015-12-17 12:44:46 -05:00
updateAt := model . GetMillis ( )
2016-02-03 10:32:37 -05:00
query := `
UPDATE
Users
SET
Password = ' ' ,
LastPasswordUpdate = : LastPasswordUpdate ,
UpdateAt = : UpdateAt ,
FailedAttempts = 0 ,
AuthService = : AuthService ,
AuthData = : AuthData `
if len ( email ) != 0 {
query += ", Email = :Email"
}
query += " WHERE Id = :UserId"
if _ , err := us . GetMaster ( ) . Exec ( query , map [ string ] interface { } { "LastPasswordUpdate" : updateAt , "UpdateAt" : updateAt , "UserId" : userId , "AuthService" : service , "AuthData" : authData , "Email" : email } ) ; err != nil {
2016-06-15 08:02:07 -04:00
if IsUniqueConstraintError ( err . Error ( ) , [ ] string { "Email" , "users_email_key" , "idx_users_email_unique" } ) {
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateAuthData" , "store.sql_user.update_auth_data.email_exists.app_error" , map [ string ] interface { } { "Service" : service , "Email" : email } , "user_id=" + userId + ", " + err . Error ( ) )
} else {
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateAuthData" , "store.sql_user.update_auth_data.app_error" , nil , "id=" + userId + ", " + err . Error ( ) )
}
2015-12-17 12:44:46 -05:00
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-03-30 12:49:29 -04:00
func ( us SqlUserStore ) UpdateMfaSecret ( userId , secret string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
updateAt := model . GetMillis ( )
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET MfaSecret = :Secret, UpdateAt = :UpdateAt WHERE Id = :UserId" , map [ string ] interface { } { "Secret" : secret , "UpdateAt" : updateAt , "UserId" : userId } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateMfaSecret" , "store.sql_user.update_mfa_secret.app_error" , nil , "id=" + userId + ", " + err . Error ( ) )
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
func ( us SqlUserStore ) UpdateMfaActive ( userId string , active bool ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
updateAt := model . GetMillis ( )
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET MfaActive = :Active, UpdateAt = :UpdateAt WHERE Id = :UserId" , map [ string ] interface { } { "Active" : active , "UpdateAt" : updateAt , "UserId" : userId } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.UpdateMfaActive" , "store.sql_user.update_mfa_active.app_error" , nil , "id=" + userId + ", " + err . Error ( ) )
} else {
result . Data = userId
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) Get ( id string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if obj , err := us . GetReplica ( ) . Get ( model . User { } , id ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Get" , "store.sql_user.get.app_error" , nil , "user_id=" + id + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else if obj == nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.Get" , MISSING_ACCOUNT_ERROR , nil , "user_id=" + id )
2015-06-14 23:53:32 -08:00
} else {
result . Data = obj . ( * model . User )
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-04-21 22:37:01 -07:00
func ( us SqlUserStore ) GetAll ( ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var data [ ] * model . User
if _ , err := us . GetReplica ( ) . Select ( & data , "SELECT * FROM Users" ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetAll" , "store.sql_user.get.app_error" , nil , err . Error ( ) )
}
result . Data = data
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
func ( s SqlUserStore ) GetEtagForDirectProfiles ( userId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-07-14 04:18:18 -08:00
var ids [ ] string
_ , err := s . GetReplica ( ) . Select ( ids , `
2016-05-06 12:08:58 -04:00
SELECT
2016-07-14 04:18:18 -08:00
Id
2016-04-21 22:37:01 -07:00
FROM
Users
WHERE
Id IN ( SELECT DISTINCT
UserId
FROM
ChannelMembers
WHERE
ChannelMembers . UserId != : UserId
AND ChannelMembers . ChannelId IN ( SELECT
Channels . Id
FROM
Channels ,
ChannelMembers
WHERE
Channels . Type = 'D'
AND Channels . Id = ChannelMembers . ChannelId
AND ChannelMembers . UserId = : UserId ) )
2016-05-06 12:08:58 -04:00
OR Id IN ( SELECT
2016-05-04 06:31:42 -07:00
Name
FROM
Preferences
WHERE
UserId = : UserId
AND Category = ' direct_channel_show ' )
2016-07-14 04:18:18 -08:00
ORDER BY UpdateAt DESC
2016-05-04 06:31:42 -07:00
` , map [ string ] interface { } { "UserId" : userId } )
2016-07-14 04:18:18 -08:00
if err != nil || len ( ids ) == 0 {
result . Data = fmt . Sprintf ( "%v.%v.0.%v.%v" , model . CurrentVersion , model . GetMillis ( ) , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2016-05-04 06:31:42 -07:00
} else {
2016-07-14 04:18:18 -08:00
allIds := strings . Join ( ids , "" )
2016-08-04 09:25:37 -08:00
result . Data = fmt . Sprintf ( "%v.%x.%v.%v.%v" , model . CurrentVersion , md5 . Sum ( [ ] byte ( allIds ) ) , len ( ids ) , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2016-05-04 06:31:42 -07:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
func ( s SqlUserStore ) GetEtagForAllProfiles ( ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
updateAt , err := s . GetReplica ( ) . SelectInt ( "SELECT UpdateAt FROM Users ORDER BY UpdateAt DESC LIMIT 1" )
2016-04-21 22:37:01 -07:00
if err != nil {
2016-06-14 12:12:46 -04:00
result . Data = fmt . Sprintf ( "%v.%v.%v.%v" , model . CurrentVersion , model . GetMillis ( ) , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2016-04-21 22:37:01 -07:00
} else {
2016-06-14 12:12:46 -04:00
result . Data = fmt . Sprintf ( "%v.%v.%v.%v" , model . CurrentVersion , updateAt , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2016-04-21 22:37:01 -07:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-04 06:31:42 -07:00
func ( us SqlUserStore ) GetAllProfiles ( ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var users [ ] * model . User
if _ , err := us . GetReplica ( ) . Select ( & users , "SELECT * FROM Users" ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetProfiles" , "store.sql_user.get_profiles.app_error" , nil , err . Error ( ) )
} else {
userMap := make ( map [ string ] * model . User )
for _ , u := range users {
u . Password = ""
2016-05-11 11:04:30 -07:00
u . AuthData = new ( string )
* u . AuthData = ""
2016-05-04 06:31:42 -07:00
userMap [ u . Id ] = u
}
result . Data = userMap
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( s SqlUserStore ) GetEtagForProfiles ( teamId string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-04-21 22:37:01 -07:00
updateAt , err := s . GetReplica ( ) . SelectInt ( "SELECT UpdateAt FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId ORDER BY UpdateAt DESC LIMIT 1" , map [ string ] interface { } { "TeamId" : teamId } )
2015-06-14 23:53:32 -08:00
if err != nil {
2016-06-14 12:12:46 -04:00
result . Data = fmt . Sprintf ( "%v.%v.%v.%v" , model . CurrentVersion , model . GetMillis ( ) , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2015-06-14 23:53:32 -08:00
} else {
2016-06-14 12:12:46 -04:00
result . Data = fmt . Sprintf ( "%v.%v.%v.%v" , model . CurrentVersion , updateAt , utils . Cfg . PrivacySettings . ShowFullName , utils . Cfg . PrivacySettings . ShowEmailAddress )
2015-06-14 23:53:32 -08:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) GetProfiles ( teamId string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var users [ ] * model . User
2016-04-21 22:37:01 -07:00
if _ , err := us . GetReplica ( ) . Select ( & users , "SELECT Users.* FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId" , map [ string ] interface { } { "TeamId" : teamId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetProfiles" , "store.sql_user.get_profiles.app_error" , nil , err . Error ( ) )
2015-06-14 23:53:32 -08:00
} else {
userMap := make ( map [ string ] * model . User )
for _ , u := range users {
u . Password = ""
2016-05-11 11:04:30 -07:00
u . AuthData = new ( string )
* u . AuthData = ""
2015-06-14 23:53:32 -08:00
userMap [ u . Id ] = u
}
result . Data = userMap
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-04-21 22:37:01 -07:00
func ( us SqlUserStore ) GetDirectProfiles ( userId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var users [ ] * model . User
if _ , err := us . GetReplica ( ) . Select ( & users , `
SELECT
Users . *
FROM
Users
WHERE
Id IN ( SELECT DISTINCT
UserId
FROM
ChannelMembers
WHERE
ChannelMembers . UserId != : UserId
AND ChannelMembers . ChannelId IN ( SELECT
Channels . Id
FROM
Channels ,
ChannelMembers
WHERE
Channels . Type = 'D'
AND Channels . Id = ChannelMembers . ChannelId
2016-05-04 06:31:42 -07:00
AND ChannelMembers . UserId = : UserId ) )
OR Id IN ( SELECT
Name
FROM
Preferences
WHERE
UserId = : UserId
AND Category = ' direct_channel_show ' )
` , map [ string ] interface { } { "UserId" : userId } ) ; err != nil {
2016-04-21 22:37:01 -07:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetDirectProfiles" , "store.sql_user.get_profiles.app_error" , nil , err . Error ( ) )
} else {
userMap := make ( map [ string ] * model . User )
for _ , u := range users {
u . Password = ""
2016-05-11 11:04:30 -07:00
u . AuthData = new ( string )
* u . AuthData = ""
2016-04-21 22:37:01 -07:00
userMap [ u . Id ] = u
}
result . Data = userMap
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
func ( us SqlUserStore ) GetProfileByIds ( userIds [ ] string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var users [ ] * model . User
props := make ( map [ string ] interface { } )
idQuery := ""
for index , userId := range userIds {
if len ( idQuery ) > 0 {
idQuery += ", "
}
props [ "userId" + strconv . Itoa ( index ) ] = userId
idQuery += ":userId" + strconv . Itoa ( index )
}
if _ , err := us . GetReplica ( ) . Select ( & users , "SELECT * FROM Users WHERE Users.Id IN (" + idQuery + ")" , props ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetProfileByIds" , "store.sql_user.get_profiles.app_error" , nil , err . Error ( ) )
} else {
userMap := make ( map [ string ] * model . User )
for _ , u := range users {
u . Password = ""
2016-05-11 11:04:30 -07:00
u . AuthData = new ( string )
* u . AuthData = ""
2016-04-21 22:37:01 -07:00
userMap [ u . Id ] = u
}
result . Data = userMap
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) GetSystemAdminProfiles ( ) StoreChannel {
2015-10-05 17:33:45 -07:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var users [ ] * model . User
2016-09-13 12:42:48 -04:00
if _ , err := us . GetReplica ( ) . Select ( & users , "SELECT * FROM Users WHERE Roles LIKE :Roles" , map [ string ] interface { } { "Roles" : "%system_admin%" } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetSystemAdminProfiles" , "store.sql_user.get_sysadmin_profiles.app_error" , nil , err . Error ( ) )
2015-10-05 17:33:45 -07:00
} else {
userMap := make ( map [ string ] * model . User )
for _ , u := range users {
u . Password = ""
2016-05-11 11:04:30 -07:00
u . AuthData = new ( string )
* u . AuthData = ""
2015-10-05 17:33:45 -07:00
userMap [ u . Id ] = u
}
result . Data = userMap
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-04-21 22:37:01 -07:00
func ( us SqlUserStore ) GetByEmail ( email string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-04-13 14:31:27 -04:00
email = strings . ToLower ( email )
2015-06-14 23:53:32 -08:00
user := model . User { }
2016-04-21 22:37:01 -07:00
if err := us . GetReplica ( ) . SelectOne ( & user , "SELECT * FROM Users WHERE Email = :Email" , map [ string ] interface { } { "Email" : email } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetByEmail" , MISSING_ACCOUNT_ERROR , nil , "email=" + email + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
}
result . Data = & user
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-11 11:04:30 -07:00
func ( us SqlUserStore ) GetByAuth ( authData * string , authService string ) StoreChannel {
2015-07-15 12:48:50 -04:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-05-11 11:04:30 -07:00
if authData == nil || * authData == "" {
result . Err = model . NewLocAppError ( "SqlUserStore.GetByAuth" , MISSING_AUTH_ACCOUNT_ERROR , nil , "authData='', authService=" + authService )
storeChannel <- result
close ( storeChannel )
return
}
2015-07-15 12:48:50 -04:00
user := model . User { }
2016-04-21 22:37:01 -07:00
if err := us . GetReplica ( ) . SelectOne ( & user , "SELECT * FROM Users WHERE AuthData = :AuthData AND AuthService = :AuthService" , map [ string ] interface { } { "AuthData" : authData , "AuthService" : authService } ) ; err != nil {
2016-03-11 10:48:43 -05:00
if err == sql . ErrNoRows {
2016-05-11 11:04:30 -07:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetByAuth" , MISSING_AUTH_ACCOUNT_ERROR , nil , "authData=" + * authData + ", authService=" + authService + ", " + err . Error ( ) )
2016-03-11 10:48:43 -05:00
} else {
2016-05-11 11:04:30 -07:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetByAuth" , "store.sql_user.get_by_auth.other.app_error" , nil , "authData=" + * authData + ", authService=" + authService + ", " + err . Error ( ) )
2016-03-11 10:48:43 -05:00
}
2015-07-15 12:48:50 -04:00
}
result . Data = & user
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-06-03 09:33:59 -04:00
func ( us SqlUserStore ) GetAllUsingAuthService ( authService string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
var data [ ] * model . User
if _ , err := us . GetReplica ( ) . Select ( & data , "SELECT * FROM Users WHERE AuthService = :AuthService" , map [ string ] interface { } { "AuthService" : authService } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetByAuth" , "store.sql_user.get_by_auth.other.app_error" , nil , "authService=" + authService + ", " + err . Error ( ) )
}
result . Data = data
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-04-21 22:37:01 -07:00
func ( us SqlUserStore ) GetByUsername ( username string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
user := model . User { }
2016-04-21 22:37:01 -07:00
if err := us . GetReplica ( ) . SelectOne ( & user , "SELECT * FROM Users WHERE Username = :Username" , map [ string ] interface { } { "Username" : username } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetByUsername" , "store.sql_user.get_by_username.app_error" ,
2016-04-21 22:37:01 -07:00
nil , err . Error ( ) )
2015-06-14 23:53:32 -08:00
}
result . Data = & user
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-05-03 14:10:36 -04:00
func ( us SqlUserStore ) GetForLogin ( loginId string , allowSignInWithUsername , allowSignInWithEmail , ldapEnabled bool ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
params := map [ string ] interface { } {
"LoginId" : loginId ,
"AllowSignInWithUsername" : allowSignInWithUsername ,
"AllowSignInWithEmail" : allowSignInWithEmail ,
"LdapEnabled" : ldapEnabled ,
}
users := [ ] * model . User { }
if _ , err := us . GetReplica ( ) . Select (
& users ,
` SELECT
*
FROM
Users
WHERE
( : AllowSignInWithUsername AND Username = : LoginId )
OR ( : AllowSignInWithEmail AND Email = : LoginId )
OR ( : LdapEnabled AND AuthService = ' ` +model.USER_AUTH_SERVICE_LDAP+ ` ' AND AuthData = : LoginId ) ` ,
params ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetForLogin" , "store.sql_user.get_for_login.app_error" , nil , err . Error ( ) )
} else if len ( users ) == 1 {
result . Data = users [ 0 ]
} else if len ( users ) > 1 {
result . Err = model . NewLocAppError ( "SqlUserStore.GetForLogin" , "store.sql_user.get_for_login.multiple_users" , nil , "" )
} else {
result . Err = model . NewLocAppError ( "SqlUserStore.GetForLogin" , "store.sql_user.get_for_login.app_error" , nil , "" )
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) VerifyEmail ( userId string ) StoreChannel {
2015-06-14 23:53:32 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-05-03 03:08:48 +09:00
if _ , err := us . GetMaster ( ) . Exec ( "UPDATE Users SET EmailVerified = true WHERE Id = :UserId" , map [ string ] interface { } { "UserId" : userId } ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.VerifyEmail" , "store.sql_user.verify_email.app_error" , nil , "userId=" + userId + ", " + err . Error ( ) )
2015-06-14 23:53:32 -08:00
}
result . Data = userId
storeChannel <- result
2015-08-26 12:49:07 -04:00
close ( storeChannel )
} ( )
return storeChannel
}
2015-09-23 15:52:59 -07:00
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) GetTotalUsersCount ( ) StoreChannel {
2015-09-23 15:52:59 -07:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if count , err := us . GetReplica ( ) . SelectInt ( "SELECT COUNT(Id) FROM Users" ) ; err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetTotalUsersCount" , "store.sql_user.get_total_users_count.app_error" , nil , err . Error ( ) )
2015-10-09 12:24:39 -07:00
} else {
result . Data = count
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2015-11-15 18:18:02 -08:00
2016-01-20 13:36:16 -06:00
func ( us SqlUserStore ) PermanentDelete ( userId string ) StoreChannel {
2015-11-15 18:18:02 -08:00
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if _ , err := us . GetMaster ( ) . Exec ( "DELETE FROM Users WHERE Id = :UserId" , map [ string ] interface { } { "UserId" : userId } ) ; err != nil {
2016-04-13 14:31:27 -04:00
result . Err = model . NewLocAppError ( "SqlUserStore.PermanentDelete" , "store.sql_user.permanent_delete.app_error" , nil , "userId=" + userId + ", " + err . Error ( ) )
2015-11-15 18:18:02 -08:00
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-01-21 12:14:17 -05:00
func ( us SqlUserStore ) AnalyticsUniqueUserCount ( teamId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
query := "SELECT COUNT(DISTINCT Email) FROM Users"
if len ( teamId ) > 0 {
2016-04-21 22:37:01 -07:00
query += ", TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId"
2016-01-21 12:14:17 -05:00
}
v , err := us . GetReplica ( ) . SelectInt ( query , map [ string ] interface { } { "TeamId" : teamId } )
if err != nil {
2016-01-25 16:08:06 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.AnalyticsUniqueUserCount" , "store.sql_user.analytics_unique_user_count.app_error" , nil , err . Error ( ) )
2016-01-21 12:14:17 -05:00
} else {
result . Data = v
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-03-11 00:14:55 -03:00
func ( us SqlUserStore ) GetUnreadCount ( userId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
2016-08-18 18:45:35 -04:00
if count , err := us . GetReplica ( ) . SelectInt ( "SELECT SUM(CASE WHEN c.Type = 'D' THEN (c.TotalMsgCount - cm.MsgCount) ELSE cm.MentionCount END) FROM Channels c INNER JOIN ChannelMembers cm ON cm.ChannelId = c.Id AND cm.UserId = :UserId" , map [ string ] interface { } { "UserId" : userId } ) ; err != nil {
2016-03-11 00:14:55 -03:00
result . Err = model . NewLocAppError ( "SqlUserStore.GetMentionCount" , "store.sql_user.get_unread_count.app_error" , nil , err . Error ( ) )
} else {
result . Data = count
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}
2016-08-31 12:52:14 -04:00
func ( us SqlUserStore ) GetUnreadCountForChannel ( userId string , channelId string ) StoreChannel {
storeChannel := make ( StoreChannel )
go func ( ) {
result := StoreResult { }
if count , err := us . GetReplica ( ) . SelectInt ( "SELECT SUM(CASE WHEN c.Type = 'D' THEN (c.TotalMsgCount - cm.MsgCount) ELSE cm.MentionCount END) FROM Channels c INNER JOIN ChannelMembers cm ON c.Id = :ChannelId AND cm.ChannelId = :ChannelId AND cm.UserId = :UserId" , map [ string ] interface { } { "ChannelId" : channelId , "UserId" : userId } ) ; err != nil {
result . Err = model . NewLocAppError ( "SqlUserStore.GetMentionCountForChannel" , "store.sql_user.get_unread_count_for_channel.app_error" , nil , err . Error ( ) )
} else {
result . Data = count
}
storeChannel <- result
close ( storeChannel )
} ( )
return storeChannel
}