summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md20
-rw-r--r--api/api_test.go2
-rw-r--r--api/auto_users.go4
-rw-r--r--api/channel.go5
-rw-r--r--api/channel_benchmark_test.go2
-rw-r--r--api/channel_test.go56
-rw-r--r--api/command.go2
-rw-r--r--api/command_test.go8
-rw-r--r--api/context.go10
-rw-r--r--api/file_test.go10
-rw-r--r--api/post.go34
-rw-r--r--api/post_test.go44
-rw-r--r--api/server.go3
-rw-r--r--api/team.go7
-rw-r--r--api/team_test.go24
-rw-r--r--api/templates/reset_body.html2
-rw-r--r--api/user.go10
-rw-r--r--api/user_test.go64
-rw-r--r--api/web_conn.go2
-rw-r--r--api/web_hub.go38
-rw-r--r--api/web_socket_test.go7
-rw-r--r--api/web_team_hub.go40
-rw-r--r--config/config.json4
-rw-r--r--config/config_docker.json4
-rw-r--r--manualtesting/manual_testing.go2
-rw-r--r--model/channel_extra.go5
-rw-r--r--model/user.go43
-rw-r--r--model/user_test.go64
-rw-r--r--store/redis.go75
-rw-r--r--store/redis_test.go59
-rw-r--r--store/sql_channel_store.go8
-rw-r--r--store/sql_channel_store_test.go4
-rw-r--r--store/sql_store.go47
-rw-r--r--store/sql_user_store.go27
-rw-r--r--utils/config.go6
-rw-r--r--web/react/components/channel_header.jsx2
-rw-r--r--web/react/components/member_list_team.jsx4
-rw-r--r--web/react/components/mention_list.jsx18
-rw-r--r--web/react/components/post_info.jsx3
-rw-r--r--web/react/components/post_list.jsx2
-rw-r--r--web/react/components/search_bar.jsx2
-rw-r--r--web/react/components/sidebar.jsx4
-rw-r--r--web/react/components/user_settings.jsx107
-rw-r--r--web/react/stores/user_store.jsx18
-rw-r--r--web/react/utils/utils.jsx26
-rw-r--r--web/sass-files/sass/partials/_headers.scss7
-rw-r--r--web/sass-files/sass/partials/_modal.scss2
-rw-r--r--web/sass-files/sass/partials/_responsive.scss9
-rw-r--r--web/sass-files/sass/partials/_search.scss13
-rw-r--r--web/templates/head.html7
-rw-r--r--web/web.go6
51 files changed, 486 insertions, 486 deletions
diff --git a/README.md b/README.md
index a4f95dbdf..65a3e7c66 100644
--- a/README.md
+++ b/README.md
@@ -108,26 +108,10 @@ AWS Elastic Beanstalk Setup (Docker)
11. You can set the configuration details as you please but they may be left at their defaults. When you are done press next.
12. Environment tags my be left blank. Press next.
13. You will be asked to review your information. Press Launch.
- 14. Up near the top of the dashboard you will see a domain of the form \*.elasticbeanstalk.com copy this as you will need it later.
-
-2. Map a wildcard domain to the new elastic beanstalk application
- 15. From the AWS console select route 53
- 16. From the sidebar select Hosted Zones
- 17. Select the domain you want to use or create a new one.
- 18. Modify an existing CNAME record set or create a new one with the name * and the value of the domain you copied in step 1.13.
- 19. Save the record set
-
-3. Set the environment variable "MATTERMOST\_DOMAIN" to the domain you mapped above (example.com not www.example.com)
- 20. Return the Elastic Beanstalk from the AWS console.
- 21. Select the environment you created.
- 22. Select configuration from the sidebar.
- 23. Click the gear beside software configuration.
- 24. Add an environment property with the name “MATTERMOST\_DOMAIN” and a value of the domain you mapped in route 53. For example if your domain is \*.example.com you would enter example.com not www.example.com.
- 25. Select apply.
4. Try it out!
- 26. Return to the dashboard on the sidebar and wait for beanstalk update the environment.
- 27. Try it out by entering the domain you mapped into your browser.
+ 14. Wait for beanstalk to update the environment.
+ 15. Try it out by entering the domain of the form \*.elasticbeanstalk.com found at the top of the dashboard into your browser. You can also map your own domain if you wish.
Contributing
------------
diff --git a/api/api_test.go b/api/api_test.go
index b407c2a5e..7d2faed4f 100644
--- a/api/api_test.go
+++ b/api/api_test.go
@@ -26,7 +26,7 @@ func SetupBenchmark() (*model.Team, *model.User, *model.Channel) {
team := &model.Team{Name: "Benchmark Team", Domain: "z-z-" + model.NewId() + "a", Email: "benchmark@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "benchmark@test.com", FullName: "Mr. Benchmarker", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "benchmark@test.com", Nickname: "Mr. Benchmarker", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
Client.LoginByEmail(team.Domain, user.Email, "pwd")
diff --git a/api/auto_users.go b/api/auto_users.go
index 493ec5c17..d6918f13a 100644
--- a/api/auto_users.go
+++ b/api/auto_users.go
@@ -41,7 +41,7 @@ func CreateBasicUser(client *model.Client) *model.AppError {
return err
}
basicteam := result.Data.(*model.Team)
- newuser := &model.User{TeamId: basicteam.Id, Email: BTEST_USER_EMAIL, FullName: BTEST_USER_NAME, Password: BTEST_USER_PASSWORD}
+ newuser := &model.User{TeamId: basicteam.Id, Email: BTEST_USER_EMAIL, Nickname: BTEST_USER_NAME, Password: BTEST_USER_PASSWORD}
result, err = client.CreateUser(newuser, "")
if err != nil {
return err
@@ -65,7 +65,7 @@ func (cfg *AutoUserCreator) createRandomUser() (*model.User, bool) {
user := &model.User{
TeamId: cfg.teamID,
Email: userEmail,
- FullName: userName,
+ Nickname: userName,
Password: USER_PASSWORD}
result, err := cfg.client.CreateUser(user, "")
diff --git a/api/channel.go b/api/channel.go
index 88db27def..4d8dbad09 100644
--- a/api/channel.go
+++ b/api/channel.go
@@ -8,7 +8,6 @@ import (
"fmt"
"github.com/gorilla/mux"
"github.com/mattermost/platform/model"
- "github.com/mattermost/platform/store"
"net/http"
"strings"
)
@@ -542,7 +541,7 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
message := model.NewMessage(c.Session.TeamId, id, c.Session.UserId, model.ACTION_VIEWED)
message.Add("channel_id", id)
- store.PublishAndForget(message)
+ PublishAndForget(message)
result := make(map[string]string)
result["id"] = id
@@ -657,7 +656,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
message := model.NewMessage(c.Session.TeamId, "", userId, model.ACTION_USER_ADDED)
- store.PublishAndForget(message)
+ PublishAndForget(message)
<-Srv.Store.Channel().UpdateLastViewedAt(id, oUser.Id)
w.Write([]byte(cm.ToJson()))
diff --git a/api/channel_benchmark_test.go b/api/channel_benchmark_test.go
index 461a7ed3a..17d3deb27 100644
--- a/api/channel_benchmark_test.go
+++ b/api/channel_benchmark_test.go
@@ -138,7 +138,7 @@ func BenchmarkJoinChannel(b *testing.B) {
}
// Secondary test user to join channels created by primary test user
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "random@test.com", FullName: "That Guy", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "random@test.com", Nickname: "That Guy", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
Client.LoginByEmail(team.Domain, user.Email, "pwd")
diff --git a/api/channel_test.go b/api/channel_test.go
index ed0554693..31ab85117 100644
--- a/api/channel_test.go
+++ b/api/channel_test.go
@@ -20,7 +20,7 @@ func TestCreateChannel(t *testing.T) {
team2 := &model.Team{Name: "Name Team 2", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -97,11 +97,11 @@ func TestCreateDirectChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -152,15 +152,15 @@ func TestUpdateChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
+ userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
- userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
- userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
userStd.Roles = ""
@@ -223,7 +223,7 @@ func TestUpdateChannelDesc(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -266,7 +266,7 @@ func TestUpdateChannelDesc(t *testing.T) {
t.Fatal("should have errored on bad channel desc")
}
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -285,7 +285,7 @@ func TestGetChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -327,7 +327,7 @@ func TestGetMoreChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -339,7 +339,7 @@ func TestGetMoreChannel(t *testing.T) {
channel2 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -371,7 +371,7 @@ func TestJoinChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -383,7 +383,7 @@ func TestJoinChannel(t *testing.T) {
channel3 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -399,7 +399,7 @@ func TestJoinChannel(t *testing.T) {
data["user_id"] = user1.Id
rchannel := Client.Must(Client.CreateDirectChannel(data)).Data.(*model.Channel)
- user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
Client.LoginByEmail(team.Domain, user3.Email, "pwd")
@@ -415,7 +415,7 @@ func TestLeaveChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -427,7 +427,7 @@ func TestLeaveChannel(t *testing.T) {
channel3 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -464,11 +464,11 @@ func TestDeleteChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
+ userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
- userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
@@ -500,7 +500,7 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal("should have failed to post to deleted channel")
}
- userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
@@ -534,7 +534,7 @@ func TestGetChannelExtraInfo(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -555,7 +555,7 @@ func TestAddChannelMember(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -564,7 +564,7 @@ func TestAddChannelMember(t *testing.T) {
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -613,11 +613,11 @@ func TestRemoveChannelMember(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, FullName: "Corey Hulen", Password: "pwd"}
+ userTeamAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
userTeamAdmin = Client.Must(Client.CreateUser(userTeamAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userTeamAdmin.Id))
- userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userChannelAdmin := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userChannelAdmin = Client.Must(Client.CreateUser(userChannelAdmin, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userChannelAdmin.Id))
@@ -633,7 +633,7 @@ func TestRemoveChannelMember(t *testing.T) {
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
- userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userStd := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
userStd = Client.Must(Client.CreateUser(userStd, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(userStd.Id))
@@ -683,7 +683,7 @@ func TestUpdateNotifyLevel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -746,7 +746,7 @@ func TestUpdateNotifyLevel(t *testing.T) {
t.Fatal("Should have errored - bad notify level")
}
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
@@ -765,7 +765,7 @@ func TestFuzzyChannel(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
diff --git a/api/command.go b/api/command.go
index 810a8a07e..ee7a11af3 100644
--- a/api/command.go
+++ b/api/command.go
@@ -27,8 +27,6 @@ var commands = []commandHandler{
func InitCommand(r *mux.Router) {
l4g.Debug("Initializing command api routes")
r.Handle("/command", ApiUserRequired(command)).Methods("POST")
-
- hub.Start()
}
func command(c *Context, w http.ResponseWriter, r *http.Request) {
diff --git a/api/command_test.go b/api/command_test.go
index 624c445e6..d9912f9d8 100644
--- a/api/command_test.go
+++ b/api/command_test.go
@@ -15,7 +15,7 @@ func TestSuggestRootCommands(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -58,7 +58,7 @@ func TestLogoutCommands(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -76,7 +76,7 @@ func TestJoinCommands(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -90,7 +90,7 @@ func TestJoinCommands(t *testing.T) {
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
Client.Must(Client.LeaveChannel(channel2.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
diff --git a/api/context.go b/api/context.go
index bea0fbeff..054e42e2e 100644
--- a/api/context.go
+++ b/api/context.go
@@ -265,6 +265,16 @@ func (c *Context) IsSystemAdmin() bool {
return false
}
+func (c *Context) IsTeamAdmin(userId string) bool {
+ if uresult := <-Srv.Store.User().Get(userId); uresult.Err != nil {
+ c.Err = uresult.Err
+ return false
+ } else {
+ user := uresult.Data.(*model.User)
+ return strings.Contains(c.Session.Roles, model.ROLE_ADMIN) && user.TeamId == c.Session.TeamId
+ }
+}
+
func (c *Context) RemoveSessionCookie(w http.ResponseWriter) {
sessionCache.Remove(c.Session.Id)
diff --git a/api/file_test.go b/api/file_test.go
index e334fd6e5..044cad921 100644
--- a/api/file_test.go
+++ b/api/file_test.go
@@ -27,7 +27,7 @@ func TestUploadFile(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -114,7 +114,7 @@ func TestGetFile(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -176,7 +176,7 @@ func TestGetFile(t *testing.T) {
team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user2 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -261,11 +261,11 @@ func TestGetPublicLink(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
diff --git a/api/post.go b/api/post.go
index 02f997166..27dedbf71 100644
--- a/api/post.go
+++ b/api/post.go
@@ -11,10 +11,10 @@ import (
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
"net/http"
+ "path/filepath"
"strconv"
"strings"
"time"
- "path/filepath"
)
func InitPost(r *mux.Router) {
@@ -298,14 +298,11 @@ func fireAndForgetNotifications(post *model.Post, teamId, teamUrl string) {
for _, k := range splitKeys {
keywordMap[k] = append(keywordMap[strings.ToLower(k)], profile.Id)
}
+ }
- // If turned on, add the user's case sensitive first name
- if profile.NotifyProps["first_name"] == "true" {
- splitName := strings.Split(profile.FullName, " ")
- if len(splitName) > 0 && splitName[0] != "" {
- keywordMap[splitName[0]] = append(keywordMap[splitName[0]], profile.Id)
- }
- }
+ // If turned on, add the user's case sensitive first name
+ if profile.NotifyProps["first_name"] == "true" {
+ keywordMap[profile.FirstName] = append(keywordMap[profile.FirstName], profile.Id)
}
// Add @all to keywords if user has them turned on
@@ -395,10 +392,8 @@ func fireAndForgetNotifications(post *model.Post, teamId, teamUrl string) {
continue
}
- firstName := strings.Split(profileMap[id].FullName, " ")[0]
-
bodyPage := NewServerTemplatePage("post_body", teamUrl)
- bodyPage.Props["FullName"] = firstName
+ bodyPage.Props["Nickname"] = profileMap[id].FirstName
bodyPage.Props["TeamName"] = teamName
bodyPage.Props["ChannelName"] = channelName
bodyPage.Props["BodyText"] = bodyText
@@ -455,7 +450,7 @@ func fireAndForgetNotifications(post *model.Post, teamId, teamUrl string) {
message.Add("mentions", model.ArrayToJson(mentionedUsers))
}
- store.PublishAndForget(message)
+ PublishAndForget(message)
}()
}
@@ -521,7 +516,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
message.Add("channel_id", rpost.ChannelId)
message.Add("message", rpost.Message)
- store.PublishAndForget(message)
+ PublishAndForget(message)
w.Write([]byte(rpost.ToJson()))
}
@@ -634,16 +629,17 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(postId)
- if !c.HasPermissionsToChannel(cchan, "deletePost") {
- return
- }
-
if result := <-pchan; result.Err != nil {
c.Err = result.Err
return
} else {
+
post := result.Data.(*model.PostList).Posts[postId]
+ if !c.HasPermissionsToChannel(cchan, "deletePost") && !c.IsTeamAdmin(post.UserId){
+ return
+ }
+
if post == nil {
c.SetInvalidParam("deletePost", "postId")
return
@@ -655,7 +651,7 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if post.UserId != c.Session.UserId {
+ if post.UserId != c.Session.UserId && !strings.Contains(c.Session.Roles,model.ROLE_ADMIN) {
c.Err = model.NewAppError("deletePost", "You do not have the appropriate permissions", "")
c.Err.StatusCode = http.StatusForbidden
return
@@ -670,7 +666,7 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
message.Add("post_id", post.Id)
message.Add("channel_id", post.ChannelId)
- store.PublishAndForget(message)
+ PublishAndForget(message)
result := make(map[string]string)
result["id"] = postId
diff --git a/api/post_test.go b/api/post_test.go
index 970307759..583d1be43 100644
--- a/api/post_test.go
+++ b/api/post_test.go
@@ -21,11 +21,11 @@ func TestCreatePost(t *testing.T) {
team2 := &model.Team{Name: "Name Team 2", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -103,7 +103,7 @@ func TestCreatePost(t *testing.T) {
t.Fatal("Should have been forbidden")
}
- user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
@@ -132,11 +132,11 @@ func TestCreateValetPost(t *testing.T) {
team2 := &model.Team{Name: "Name Team 2", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -188,7 +188,7 @@ func TestCreateValetPost(t *testing.T) {
t.Fatal(err)
}
- user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
@@ -224,11 +224,11 @@ func TestUpdatePost(t *testing.T) {
team2 := &model.Team{Name: "Name Team 2", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -292,7 +292,7 @@ func TestGetPosts(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -357,7 +357,7 @@ func TestSearchPosts(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -403,7 +403,7 @@ func TestSearchHashtagPosts(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -434,7 +434,7 @@ func TestGetPostsCache(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -483,7 +483,11 @@ func TestDeletePosts(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ userAdmin := &model.User{TeamId: team.Id, Email: team.Email, Nickname: "Corey Hulen", Password: "pwd"}
+ userAdmin = Client.Must(Client.CreateUser(userAdmin, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(userAdmin.Id))
+
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -521,8 +525,16 @@ func TestDeletePosts(t *testing.T) {
r2 := Client.Must(Client.GetPosts(channel1.Id, 0, 10, "")).Data.(*model.PostList)
if len(r2.Posts) != 4 {
- t.Fatal("should have returned 5 items")
+ t.Fatal("should have returned 4 items")
}
+
+ time.Sleep(10 * time.Millisecond)
+ post4 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
+ post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
+
+ Client.LoginByEmail(team.Domain, userAdmin.Email, "pwd")
+
+ Client.Must(Client.DeletePost(channel1.Id, post4.Id))
}
func TestEmailMention(t *testing.T) {
@@ -531,7 +543,7 @@ func TestEmailMention(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: "corey@test.com", FullName: "Bob Bobby", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: "corey@test.com", Nickname: "Bob Bobby", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
@@ -553,7 +565,7 @@ func TestFuzzyPosts(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
diff --git a/api/server.go b/api/server.go
index 58986a8d4..3163f79f5 100644
--- a/api/server.go
+++ b/api/server.go
@@ -28,7 +28,6 @@ func NewServer() {
Srv = &Server{}
Srv.Server = manners.NewServer()
Srv.Store = store.NewSqlStore()
- store.RedisClient()
Srv.Router = mux.NewRouter()
Srv.Router.NotFoundHandler = http.HandlerFunc(Handle404)
@@ -54,7 +53,7 @@ func StopServer() {
Srv.Server.Shutdown <- true
Srv.Store.Close()
- store.RedisClose()
+ hub.Stop()
l4g.Info("Server stopped")
}
diff --git a/api/team.go b/api/team.go
index f9aeecd7e..7a4cabf7e 100644
--- a/api/team.go
+++ b/api/team.go
@@ -487,12 +487,7 @@ func InviteMembers(team *model.Team, user *model.User, invites []string) {
teamUrl = fmt.Sprintf("http://%v.%v", team.Domain, utils.Cfg.ServiceSettings.Domain)
}
- sender := ""
- if len(strings.TrimSpace(user.FullName)) == 0 {
- sender = user.Username
- } else {
- sender = user.FullName
- }
+ sender := user.GetDisplayName()
senderRole := ""
if strings.Contains(user.Roles, model.ROLE_ADMIN) || strings.Contains(user.Roles, model.ROLE_SYSTEM_ADMIN) {
diff --git a/api/team_test.go b/api/team_test.go
index 2bf3219e4..f61babe8e 100644
--- a/api/team_test.go
+++ b/api/team_test.go
@@ -33,7 +33,7 @@ func TestCreateFromSignupTeam(t *testing.T) {
hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt))
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
- user := model.User{Email: props["email"], FullName: "Corey Hulen", Password: "hello"}
+ user := model.User{Email: props["email"], Nickname: "Corey Hulen", Password: "hello"}
ts := model.TeamSignup{Team: team, User: user, Invites: []string{"corey@test.com"}, Data: data, Hash: hash}
@@ -77,7 +77,7 @@ func TestCreateTeam(t *testing.T) {
t.Fatal(err)
}
- user := &model.User{TeamId: rteam.Data.(*model.Team).Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: rteam.Data.(*model.Team).Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -114,7 +114,7 @@ func TestFindTeamByEmail(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -142,7 +142,7 @@ func TestFindTeamByDomain(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -182,7 +182,7 @@ func TestFindTeamByEmailSend(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -206,7 +206,7 @@ func TestInviteMembers(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -235,11 +235,11 @@ func TestUpdateTeamName(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -310,7 +310,7 @@ func TestGetMyTeam(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser, _ := Client.CreateUser(&user, "")
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
@@ -337,18 +337,18 @@ func TestUpdateValetFeature(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
diff --git a/api/templates/reset_body.html b/api/templates/reset_body.html
index 3a5d62ab4..4b5976663 100644
--- a/api/templates/reset_body.html
+++ b/api/templates/reset_body.html
@@ -18,7 +18,7 @@
<tr>
<td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;">
<h2 style="font-weight: normal; margin-top: 10px;">You requested a password reset</h2>
- <p>To change your password, click below.<br>If you did not mean to reset your password, please ignore this email and your password will remain the same.</p>
+ <p>To change your password, click "Reset Password" below.<br>If you did not mean to reset your password, please ignore this email and your password will remain the same.</p>
<p style="margin: 20px 0 15px">
<a href="{{.Props.ResetUrl}}" style="background: #2389D7; border-radius: 3px; color: #fff; border: none; outline: none; min-width: 200px; padding: 15px 25px; font-size: 14px; font-family: inherit; cursor: pointer; -webkit-appearance: none;text-decoration: none;">Reset Password</a>
</p>
diff --git a/api/user.go b/api/user.go
index 3c0062f8c..f6422f844 100644
--- a/api/user.go
+++ b/api/user.go
@@ -181,14 +181,14 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User {
l4g.Error("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", ruser.Id, ruser.TeamId, err)
}
- //fireAndForgetWelcomeEmail(strings.Split(ruser.FullName, " ")[0], ruser.Email, team.Name, c.TeamUrl+"/channels/town-square")
+ //fireAndForgetWelcomeEmail(ruser.FirstName, ruser.Email, team.Name, c.TeamUrl+"/channels/town-square")
if user.EmailVerified {
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
l4g.Error("Failed to set email verified err=%v", cresult.Err)
}
} else {
- FireAndForgetVerifyEmail(result.Data.(*model.User).Id, strings.Split(ruser.FullName, " ")[0], ruser.Email, team.Name, c.TeamUrl)
+ FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.FirstName, ruser.Email, team.Name, c.TeamUrl)
}
ruser.Sanitize(map[string]bool{})
@@ -196,7 +196,7 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User {
// This message goes to every channel, so the channelId is irrelevant
message := model.NewMessage(team.Id, "", ruser.Id, model.ACTION_NEW_USER)
- store.PublishAndForget(message)
+ PublishAndForget(message)
return ruser
}
@@ -207,7 +207,7 @@ func fireAndForgetWelcomeEmail(name, email, teamName, link string) {
subjectPage := NewServerTemplatePage("welcome_subject", link)
bodyPage := NewServerTemplatePage("welcome_body", link)
- bodyPage.Props["FullName"] = name
+ bodyPage.Props["Nickname"] = name
bodyPage.Props["TeamName"] = teamName
bodyPage.Props["FeedbackName"] = utils.Cfg.EmailSettings.FeedbackName
@@ -226,7 +226,7 @@ func FireAndForgetVerifyEmail(userId, name, email, teamName, teamUrl string) {
subjectPage := NewServerTemplatePage("verify_subject", teamUrl)
subjectPage.Props["TeamName"] = teamName
bodyPage := NewServerTemplatePage("verify_body", teamUrl)
- bodyPage.Props["FullName"] = name
+ bodyPage.Props["Nickname"] = name
bodyPage.Props["TeamName"] = teamName
bodyPage.Props["VerifyUrl"] = link
diff --git a/api/user_test.go b/api/user_test.go
index 6e99ab930..edbef7c9a 100644
--- a/api/user_test.go
+++ b/api/user_test.go
@@ -28,15 +28,15 @@ func TestCreateUser(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "hello"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "hello"}
ruser, err := Client.CreateUser(&user, "")
if err != nil {
t.Fatal(err)
}
- if ruser.Data.(*model.User).FullName != user.FullName {
- t.Fatal("full name didn't match")
+ if ruser.Data.(*model.User).Nickname != user.Nickname {
+ t.Fatal("nickname didn't match")
}
if ruser.Data.(*model.User).Password != "" {
@@ -61,7 +61,7 @@ func TestCreateUser(t *testing.T) {
}
}
- user2 := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "hello", Username: model.BOT_USERNAME}
+ user2 := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "hello", Username: model.BOT_USERNAME}
if _, err := Client.CreateUser(&user2, ""); err == nil {
t.Fatal("Should have failed using reserved bot name")
@@ -78,7 +78,7 @@ func TestCreateUserAllowedDomains(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_INVITE, AllowedDomains: "spinpunch.com, @nowh.com,@hello.com"}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "hello"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "hello"}
_, err := Client.CreateUser(&user, "")
if err == nil {
@@ -98,7 +98,7 @@ func TestLogin(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser, _ := Client.CreateUser(&user, "")
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
@@ -138,7 +138,7 @@ func TestLogin(t *testing.T) {
team2 := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_INVITE}
rteam2 := Client.Must(Client.CreateTeam(&team2))
- user2 := model.User{TeamId: rteam2.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := model.User{TeamId: rteam2.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
if _, err := Client.CreateUserFromSignup(&user2, "junk", "1231312"); err == nil {
t.Fatal("Should have errored, signed up without hashed email")
@@ -167,7 +167,7 @@ func TestSessions(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
@@ -224,11 +224,11 @@ func TestGetUser(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser, _ := Client.CreateUser(&user, "")
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
- user2 := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser2, _ := Client.CreateUser(&user2, "")
store.Must(Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id))
@@ -295,7 +295,7 @@ func TestGetAudits(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser, _ := Client.CreateUser(&user, "")
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
@@ -348,7 +348,7 @@ func TestUserCreateImage(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -364,7 +364,7 @@ func TestUserUploadProfileImage(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -463,7 +463,7 @@ func TestUserUpdate(t *testing.T) {
time1 := model.GetMillis()
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd", LastActivityAt: time1, LastPingAt: time1, Roles: ""}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd", LastActivityAt: time1, LastPingAt: time1, Roles: ""}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -479,7 +479,7 @@ func TestUserUpdate(t *testing.T) {
time.Sleep(100 * time.Millisecond)
- user.FullName = "Jim Jimmy"
+ user.Nickname = "Jim Jimmy"
user.TeamId = "12345678901234567890123456"
user.LastActivityAt = time2
user.LastPingAt = time2
@@ -489,8 +489,8 @@ func TestUserUpdate(t *testing.T) {
if result, err := Client.UpdateUser(user); err != nil {
t.Fatal(err)
} else {
- if result.Data.(*model.User).FullName != "Jim Jimmy" {
- t.Fatal("FullName did not update properly")
+ if result.Data.(*model.User).Nickname != "Jim Jimmy" {
+ t.Fatal("Nickname did not update properly")
}
if result.Data.(*model.User).TeamId != team.Id {
t.Fatal("TeamId should not have updated")
@@ -519,13 +519,13 @@ func TestUserUpdate(t *testing.T) {
t.Fatal("Should have errored")
}
- user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
- user.FullName = "Tim Timmy"
+ user.Nickname = "Tim Timmy"
if _, err := Client.UpdateUser(user); err == nil {
t.Fatal("Should have errored")
@@ -538,7 +538,7 @@ func TestUserUpdatePassword(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -581,7 +581,7 @@ func TestUserUpdatePassword(t *testing.T) {
t.Fatal(err)
}
- user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
@@ -597,11 +597,11 @@ func TestUserUpdateRoles(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
- user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -622,7 +622,7 @@ func TestUserUpdateRoles(t *testing.T) {
team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
@@ -666,11 +666,11 @@ func TestUserUpdateActive(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
- user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
@@ -687,7 +687,7 @@ func TestUserUpdateActive(t *testing.T) {
team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)
- user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", FullName: "Corey Hulen", Password: "pwd"}
+ user3 := &model.User{TeamId: team2.Id, Email: "test@nowhere.com", Nickname: "Corey Hulen", Password: "pwd"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
@@ -730,7 +730,7 @@ func TestSendPasswordReset(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -770,7 +770,7 @@ func TestResetPassword(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -854,7 +854,7 @@ func TestUserUpdateNotify(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd", Roles: ""}
+ user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd", Roles: ""}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
@@ -933,7 +933,7 @@ func TestFuzzyUserCreate(t *testing.T) {
testEmail = utils.FUZZY_STRINGS_EMAILS[i]
}
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + testEmail, FullName: testName, Password: "hello"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + testEmail, Nickname: testName, Password: "hello"}
_, err := Client.CreateUser(&user, "")
if err != nil {
@@ -948,7 +948,7 @@ func TestStatuses(t *testing.T) {
team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team)
- user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user := model.User{TeamId: rteam.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
diff --git a/api/web_conn.go b/api/web_conn.go
index 751f6f407..0990de8ef 100644
--- a/api/web_conn.go
+++ b/api/web_conn.go
@@ -70,7 +70,7 @@ func (c *WebConn) readPump() {
} else {
msg.TeamId = c.TeamId
msg.UserId = c.UserId
- store.PublishAndForget(&msg)
+ PublishAndForget(&msg)
}
}
}
diff --git a/api/web_hub.go b/api/web_hub.go
index bf5fbb321..c7be19cac 100644
--- a/api/web_hub.go
+++ b/api/web_hub.go
@@ -5,12 +5,14 @@ package api
import (
l4g "code.google.com/p/log4go"
+ "github.com/mattermost/platform/model"
)
type Hub struct {
teamHubs map[string]*TeamHub
register chan *WebConn
unregister chan *WebConn
+ broadcast chan *model.Message
stop chan string
}
@@ -18,9 +20,16 @@ var hub = &Hub{
register: make(chan *WebConn),
unregister: make(chan *WebConn),
teamHubs: make(map[string]*TeamHub),
+ broadcast: make(chan *model.Message),
stop: make(chan string),
}
+func PublishAndForget(message *model.Message) {
+ go func() {
+ hub.Broadcast(message)
+ }()
+}
+
func (h *Hub) Register(webConn *WebConn) {
h.register <- webConn
}
@@ -29,8 +38,14 @@ func (h *Hub) Unregister(webConn *WebConn) {
h.unregister <- webConn
}
-func (h *Hub) Stop(teamId string) {
- h.stop <- teamId
+func (h *Hub) Broadcast(message *model.Message) {
+ if message != nil {
+ h.broadcast <- message
+ }
+}
+
+func (h *Hub) Stop() {
+ h.stop <- "all"
}
func (h *Hub) Start() {
@@ -53,18 +68,17 @@ func (h *Hub) Start() {
if nh, ok := h.teamHubs[c.TeamId]; ok {
nh.Unregister(c)
}
-
+ case msg := <-h.broadcast:
+ nh := h.teamHubs[msg.TeamId]
+ if nh != nil {
+ nh.broadcast <- msg
+ }
case s := <-h.stop:
- if len(s) == 0 {
- l4g.Debug("stopping all connections")
- for _, v := range h.teamHubs {
- v.Stop()
- }
- return
- } else if nh, ok := h.teamHubs[s]; ok {
- delete(h.teamHubs, s)
- nh.Stop()
+ l4g.Debug("stopping %v connections", s)
+ for _, v := range h.teamHubs {
+ v.Stop()
}
+ return
}
}
}()
diff --git a/api/web_socket_test.go b/api/web_socket_test.go
index 4cb49220f..07fdfea36 100644
--- a/api/web_socket_test.go
+++ b/api/web_socket_test.go
@@ -20,7 +20,7 @@ func TestSocket(t *testing.T) {
team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
- user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
Client.LoginByEmail(team.Domain, user1.Email, "pwd")
@@ -39,7 +39,7 @@ func TestSocket(t *testing.T) {
t.Fatal(err)
}
- user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
+ user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
@@ -115,9 +115,6 @@ func TestSocket(t *testing.T) {
}()
time.Sleep(2 * time.Second)
-
- hub.Stop(team.Id)
-
}
func TestZZWebSocketTearDown(t *testing.T) {
diff --git a/api/web_team_hub.go b/api/web_team_hub.go
index 7c7981e76..7a63b84d1 100644
--- a/api/web_team_hub.go
+++ b/api/web_team_hub.go
@@ -6,8 +6,6 @@ package api
import (
l4g "code.google.com/p/log4go"
"github.com/mattermost/platform/model"
- "github.com/mattermost/platform/store"
- "strings"
)
type TeamHub struct {
@@ -43,43 +41,6 @@ func (h *TeamHub) Stop() {
}
func (h *TeamHub) Start() {
-
- pubsub := store.RedisClient().PubSub()
-
- go func() {
- defer func() {
- l4g.Debug("redis reader finished for teamId=%v", h.teamId)
- hub.Stop(h.teamId)
- }()
-
- l4g.Debug("redis reader starting for teamId=%v", h.teamId)
-
- err := pubsub.Subscribe(h.teamId)
- if err != nil {
- l4g.Error("Error while subscribing to redis %v %v", h.teamId, err)
- return
- }
-
- for {
- if payload, err := pubsub.ReceiveTimeout(REDIS_WAIT); err != nil {
- if strings.Contains(err.Error(), "i/o timeout") {
- if len(h.connections) == 0 {
- l4g.Debug("No active connections so sending stop %v", h.teamId)
- return
- }
- } else {
- return
- }
- } else {
- msg := store.GetMessageFromPayload(payload)
- if msg != nil {
- h.broadcast <- msg
- }
- }
- }
-
- }()
-
go func() {
for {
select {
@@ -110,7 +71,6 @@ func (h *TeamHub) Start() {
webCon.WebSocket.Close()
}
- pubsub.Close()
return
}
}
diff --git a/config/config.json b/config/config.json
index d5bb7e553..27ca57e86 100644
--- a/config/config.json
+++ b/config/config.json
@@ -31,10 +31,6 @@
"Trace": false,
"AtRestEncryptKey": "Ya0xMrybACJ3sZZVWQC7e31h5nSDWZFS"
},
- "RedisSettings": {
- "DataSource": "dockerhost:6379",
- "MaxOpenConns": 1000
- },
"AWSSettings": {
"S3AccessKeyId": "",
"S3SecretAccessKey": "",
diff --git a/config/config_docker.json b/config/config_docker.json
index 91ed0ef10..185e9f215 100644
--- a/config/config_docker.json
+++ b/config/config_docker.json
@@ -31,10 +31,6 @@
"Trace": false,
"AtRestEncryptKey": "Ya0xMrybACJ3sZZVWQC7e31h5nSDWZFS"
},
- "RedisSettings": {
- "DataSource": "localhost:6379",
- "MaxOpenConns": 1000
- },
"AWSSettings": {
"S3AccessKeyId": "",
"S3SecretAccessKey": "",
diff --git a/manualtesting/manual_testing.go b/manualtesting/manual_testing.go
index 929f7ab5d..6c4958a7b 100644
--- a/manualtesting/manual_testing.go
+++ b/manualtesting/manual_testing.go
@@ -90,7 +90,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
user := &model.User{
TeamId: teamID,
Email: utils.RandomEmail(utils.Range{20, 20}, utils.LOWERCASE),
- FullName: username[0],
+ Nickname: username[0],
Password: api.USER_PASSWORD}
result, err := client.CreateUser(user, "")
diff --git a/model/channel_extra.go b/model/channel_extra.go
index a5c9acf71..3a918b524 100644
--- a/model/channel_extra.go
+++ b/model/channel_extra.go
@@ -10,7 +10,7 @@ import (
type ExtraMember struct {
Id string `json:"id"`
- FullName string `json:"full_name"`
+ Nickname string `json:"nickname"`
Email string `json:"email"`
Roles string `json:"roles"`
Username string `json:"username"`
@@ -20,9 +20,6 @@ func (o *ExtraMember) Sanitize(options map[string]bool) {
if len(options) == 0 || !options["email"] {
o.Email = ""
}
- if len(options) == 0 || !options["fullname"] {
- o.FullName = ""
- }
}
type ChannelExtra struct {
diff --git a/model/user.go b/model/user.go
index c5a4d846d..727165b8c 100644
--- a/model/user.go
+++ b/model/user.go
@@ -37,7 +37,9 @@ type User struct {
AuthData string `json:"auth_data"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
- FullName string `json:"full_name"`
+ Nickname string `json:"nickname"`
+ FirstName string `json:"first_name"`
+ LastName string `json:"last_name"`
Roles string `json:"roles"`
LastActivityAt int64 `json:"last_activity_at"`
LastPingAt int64 `json:"last_ping_at"`
@@ -82,8 +84,16 @@ func (u *User) IsValid() *AppError {
return NewAppError("User.IsValid", "Invalid email", "user_id="+u.Id)
}
- if len(u.FullName) > 64 {
- return NewAppError("User.IsValid", "Invalid full name", "user_id="+u.Id)
+ if len(u.Nickname) > 64 {
+ return NewAppError("User.IsValid", "Invalid nickname", "user_id="+u.Id)
+ }
+
+ if len(u.FirstName) > 64 {
+ return NewAppError("User.IsValid", "Invalid first name", "user_id="+u.Id)
+ }
+
+ if len(u.LastName) > 64 {
+ return NewAppError("User.IsValid", "Invalid last name", "user_id="+u.Id)
}
return nil
@@ -152,7 +162,7 @@ func (u *User) SetDefaultNotifications() {
u.NotifyProps["first_name"] = "false"
u.NotifyProps["all"] = "true"
u.NotifyProps["channel"] = "true"
- splitName := strings.Split(u.FullName, " ")
+ splitName := strings.Split(u.Nickname, " ")
if len(splitName) > 0 && splitName[0] != "" {
u.NotifyProps["first_name"] = "true"
u.NotifyProps["mention_keys"] += "," + splitName[0]
@@ -191,7 +201,8 @@ func (u *User) Sanitize(options map[string]bool) {
u.Email = ""
}
if len(options) != 0 && !options["fullname"] {
- u.FullName = ""
+ u.FirstName = ""
+ u.LastName = ""
}
if len(options) != 0 && !options["skypeid"] {
// TODO - fill in when SkypeId is added to user model
@@ -226,6 +237,28 @@ func (u *User) AddNotifyProp(key string, value string) {
u.NotifyProps[key] = value
}
+func (u *User) GetFullName() string {
+ if u.FirstName != "" && u.LastName != "" {
+ return u.FirstName + " " + u.LastName
+ } else if u.FirstName != "" {
+ return u.FirstName
+ } else if u.LastName != "" {
+ return u.LastName
+ } else {
+ return ""
+ }
+}
+
+func (u *User) GetDisplayName() string {
+ if u.Nickname != "" {
+ return u.Nickname
+ } else if fullName := u.GetFullName(); fullName != "" {
+ return fullName
+ } else {
+ return u.Username
+ }
+}
+
// UserFromJson will decode the input and return a User
func UserFromJson(data io.Reader) *User {
decoder := json.NewDecoder(data)
diff --git a/model/user_test.go b/model/user_test.go
index df9ac19c2..a48c3f2e7 100644
--- a/model/user_test.go
+++ b/model/user_test.go
@@ -80,13 +80,73 @@ func TestUserIsValid(t *testing.T) {
}
user.Email = "test@nowhere.com"
- user.FullName = strings.Repeat("01234567890", 20)
+ user.Nickname = strings.Repeat("01234567890", 20)
if err := user.IsValid(); err == nil {
t.Fatal()
}
- user.FullName = ""
+ user.Nickname = ""
if err := user.IsValid(); err != nil {
t.Fatal(err)
}
+
+ user.FirstName = ""
+ user.LastName = ""
+ if err := user.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ user.FirstName = strings.Repeat("01234567890", 20)
+ if err := user.IsValid(); err == nil {
+ t.Fatal(err)
+ }
+
+ user.FirstName = ""
+ user.LastName = strings.Repeat("01234567890", 20)
+ if err := user.IsValid(); err == nil {
+ t.Fatal(err)
+ }
+}
+
+func TestUserGetFullName(t *testing.T) {
+ user := User{}
+
+ if fullName := user.GetFullName(); fullName != "" {
+ t.Fatal("Full name should be blank")
+ }
+
+ user.FirstName = "first"
+ if fullName := user.GetFullName(); fullName != "first" {
+ t.Fatal("Full name should be first name")
+ }
+
+ user.FirstName = ""
+ user.LastName = "last"
+ if fullName := user.GetFullName(); fullName != "last" {
+ t.Fatal("Full name should be last name")
+ }
+
+ user.FirstName = "first"
+ if fullName := user.GetFullName(); fullName != "first last" {
+ t.Fatal("Full name should be first name and last name")
+ }
+}
+
+func TestUserGetDisplayName(t *testing.T) {
+ user := User{Username: "user"}
+
+ if displayName := user.GetDisplayName(); displayName != "user" {
+ t.Fatal("Display name should be username")
+ }
+
+ user.FirstName = "first"
+ user.LastName = "last"
+ if displayName := user.GetDisplayName(); displayName != "first last" {
+ t.Fatal("Display name should be full name")
+ }
+
+ user.Nickname = "nickname"
+ if displayName := user.GetDisplayName(); displayName != "nickname" {
+ t.Fatal("Display name should be nickname")
+ }
}
diff --git a/store/redis.go b/store/redis.go
deleted file mode 100644
index 262040d43..000000000
--- a/store/redis.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package store
-
-import (
- l4g "code.google.com/p/log4go"
- "github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "gopkg.in/redis.v2"
- "strings"
- "time"
-)
-
-var client *redis.Client
-
-func RedisClient() *redis.Client {
-
- if client == nil {
-
- addr := utils.Cfg.RedisSettings.DataSource
-
- client = redis.NewTCPClient(&redis.Options{
- Addr: addr,
- Password: "",
- DB: 0,
- PoolSize: utils.Cfg.RedisSettings.MaxOpenConns,
- })
-
- l4g.Info("Pinging redis at '%v'", addr)
- pong, err := client.Ping().Result()
-
- if err != nil {
- l4g.Critical("Failed to open redis connection to '%v' err:%v", addr, err)
- time.Sleep(time.Second)
- panic("Failed to open redis connection " + err.Error())
- }
-
- if pong != "PONG" {
- l4g.Critical("Failed to ping redis connection to '%v' err:%v", addr, err)
- time.Sleep(time.Second)
- panic("Failed to open ping connection " + err.Error())
- }
- }
-
- return client
-}
-
-func RedisClose() {
- l4g.Info("Closing redis")
-
- if client != nil {
- client.Close()
- client = nil
- }
-}
-
-func PublishAndForget(message *model.Message) {
-
- go func() {
- c := RedisClient()
- result := c.Publish(message.TeamId, message.ToJson())
- if result.Err() != nil {
- l4g.Error("Failed to publish message err=%v, payload=%v", result.Err(), message.ToJson())
- }
- }()
-}
-
-func GetMessageFromPayload(m interface{}) *model.Message {
- if msg, found := m.(*redis.Message); found {
- return model.MessageFromJson(strings.NewReader(msg.Payload))
- } else {
- return nil
- }
-}
diff --git a/store/redis_test.go b/store/redis_test.go
deleted file mode 100644
index 11bd9ca6a..000000000
--- a/store/redis_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package store
-
-import (
- "fmt"
- "github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "testing"
-)
-
-func TestRedis(t *testing.T) {
- utils.LoadConfig("config.json")
-
- c := RedisClient()
-
- if c == nil {
- t.Fatal("should have a valid redis connection")
- }
-
- pubsub := c.PubSub()
- defer pubsub.Close()
-
- m := model.NewMessage(model.NewId(), model.NewId(), model.NewId(), model.ACTION_TYPING)
- m.Add("RootId", model.NewId())
-
- err := pubsub.Subscribe(m.TeamId)
- if err != nil {
- t.Fatal(err)
- }
-
- // should be the subscribe success message
- // lets gobble that up
- if _, err := pubsub.Receive(); err != nil {
- t.Fatal(err)
- }
-
- PublishAndForget(m)
-
- fmt.Println("here1")
-
- if msg, err := pubsub.Receive(); err != nil {
- t.Fatal(err)
- } else {
-
- rmsg := GetMessageFromPayload(msg)
-
- if m.TeamId != rmsg.TeamId {
- t.Fatal("Ids do not match")
- }
-
- if m.Props["RootId"] != rmsg.Props["RootId"] {
- t.Fatal("Ids do not match")
- }
- }
-
- RedisClose()
-}
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index d61fbcdd0..6820b2326 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -81,11 +81,11 @@ func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
dupChannel := model.Channel{}
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId=? AND Name=? AND DeleteAt > 0", channel.TeamId, channel.Name)
- if (dupChannel.DeleteAt > 0) {
+ if dupChannel.DeleteAt > 0 {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
- }
+ }
} else {
result.Err = model.NewAppError("SqlChannelStore.Save", "We couldn't save the channel", "id="+channel.Id+", "+err.Error())
}
@@ -119,7 +119,7 @@ func (s SqlChannelStore) Update(channel *model.Channel) StoreChannel {
if strings.Contains(err.Error(), "Duplicate entry") && strings.Contains(err.Error(), "for key 'Name'") {
dupChannel := model.Channel{}
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId=? AND Name=? AND DeleteAt > 0", channel.TeamId, channel.Name)
- if (dupChannel.DeleteAt > 0) {
+ if dupChannel.DeleteAt > 0 {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
} else {
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
@@ -358,7 +358,7 @@ func (s SqlChannelStore) GetExtraMembers(channelId string, limit int) StoreChann
result := StoreResult{}
var members []model.ExtraMember
- _, err := s.GetReplica().Select(&members, "SELECT Id, FullName, Email, ChannelMembers.Roles, Username FROM ChannelMembers, Users WHERE ChannelMembers.UserId = Users.Id AND ChannelId = ? LIMIT ?", channelId, limit)
+ _, err := s.GetReplica().Select(&members, "SELECT Id, Nickname, Email, ChannelMembers.Roles, Username FROM ChannelMembers, Users WHERE ChannelMembers.UserId = Users.Id AND ChannelId = ? LIMIT ?", channelId, limit)
if err != nil {
result.Err = model.NewAppError("SqlChannelStore.GetExtraMembers", "We couldn't get the extra info for channel members", "channel_id="+channelId+", "+err.Error())
} else {
diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go
index 9821e9ad0..9cc1c2b06 100644
--- a/store/sql_channel_store_test.go
+++ b/store/sql_channel_store_test.go
@@ -200,13 +200,13 @@ func TestChannelMemberStore(t *testing.T) {
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
- u1.FullName = model.NewId()
+ u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
u2 := model.User{}
u2.TeamId = model.NewId()
u2.Email = model.NewId()
- u2.FullName = model.NewId()
+ u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
o1 := model.ChannelMember{}
diff --git a/store/sql_store.go b/store/sql_store.go
index 7a2d059b9..2e4981e6b 100644
--- a/store/sql_store.go
+++ b/store/sql_store.go
@@ -126,9 +126,9 @@ func setupConnection(con_type string, driver string, dataSource string, maxIdle
return dbmap
}
-func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool {
count, err := ss.GetMaster().SelectInt(
- `SELECT
+ `SELECT
COUNT(0) AS column_exists
FROM
information_schema.COLUMNS
@@ -145,11 +145,15 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
panic("Failed to check if column exists " + err.Error())
}
- if count > 0 {
+ return count > 0
+}
+
+func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+ if ss.DoesColumnExist(tableName, columnName) {
return false
}
- _, err = ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + colType + " DEFAULT '" + defaultValue + "'" + " AFTER " + afterName)
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + colType + " DEFAULT '" + defaultValue + "'" + " AFTER " + afterName)
if err != nil {
l4g.Critical("Failed to create column %v", err)
time.Sleep(time.Second)
@@ -160,31 +164,32 @@ func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string,
}
func (ss SqlStore) RemoveColumnIfExists(tableName string, columnName string) bool {
- count, err := ss.GetMaster().SelectInt(
- `SELECT
- COUNT(0) AS column_exists
- FROM
- information_schema.COLUMNS
- WHERE
- TABLE_SCHEMA = DATABASE()
- AND TABLE_NAME = ?
- AND COLUMN_NAME = ?`,
- tableName,
- columnName,
- )
+ if !ss.DoesColumnExist(tableName, columnName) {
+ return false
+ }
+
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
if err != nil {
- l4g.Critical("Failed to check if column exists %v", err)
+ l4g.Critical("Failed to drop column %v", err)
time.Sleep(time.Second)
- panic("Failed to check if column exists " + err.Error())
+ panic("Failed to drop column " + err.Error())
}
- if count == 0 {
+ return true
+}
+
+func (ss SqlStore) RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool {
+ if !ss.DoesColumnExist(tableName, oldColumnName) {
return false
}
- _, err = ss.GetMaster().Exec("ALTER TABLE " + tableName + " DROP COLUMN " + columnName)
+ _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " CHANGE " + oldColumnName + " " + newColumnName + " " + colType)
+
+ // when we eventually support PostgreSQL, we can use the following instead
+ //_, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " RENAME COLUMN " + oldColumnName + " TO " + newColumnName)
+
if err != nil {
- l4g.Critical("Failed to drop column %v", err)
+ l4g.Critical("Failed to rename column %v", err)
time.Sleep(time.Second)
panic("Failed to drop column " + err.Error())
}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index 665e4d697..d8ab4482e 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -25,7 +25,9 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
table.ColMap("Password").SetMaxSize(128)
table.ColMap("AuthData").SetMaxSize(128)
table.ColMap("Email").SetMaxSize(128)
- table.ColMap("FullName").SetMaxSize(64)
+ table.ColMap("Nickname").SetMaxSize(64)
+ table.ColMap("FirstName").SetMaxSize(64)
+ table.ColMap("LastName").SetMaxSize(64)
table.ColMap("Roles").SetMaxSize(64)
table.ColMap("Props").SetMaxSize(4000)
table.ColMap("NotifyProps").SetMaxSize(2000)
@@ -36,10 +38,29 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
return us
}
-func (s SqlUserStore) UpgradeSchemaIfNeeded() {
- s.CreateColumnIfNotExists("Users","LastPictureUpdate", "LastPasswordUpdate", "bigint(20)", "0")
+func (us SqlUserStore) UpgradeSchemaIfNeeded() {
+ us.CreateColumnIfNotExists("Users", "LastPictureUpdate", "LastPasswordUpdate", "bigint(20)", "0")
+
+ // migrating the FullName column to Nickname and adding the FirstName and LastName columns for MM-825
+ if us.RenameColumnIfExists("Users", "FullName", "Nickname", "varchar(64)") {
+ us.CreateColumnIfNotExists("Users", "FirstName", "Nickname", "varchar(64)", "")
+ us.CreateColumnIfNotExists("Users", "LastName", "FirstName", "varchar(64)", "")
+
+ // infer values of first and last name by splitting the previous full name
+ if _, err := us.GetMaster().Exec("UPDATE Users SET FirstName = SUBSTRING_INDEX(SUBSTRING_INDEX(Nickname, ' ', 1), ' ', -1)"); err != nil {
+ panic("Failed to set first name from nickname " + err.Error())
+ }
+
+ // only set the last name from full names that are comprised of multiple words (ie that have at least one space in them)
+ if _, err := us.GetMaster().Exec("Update Users SET LastName = SUBSTRING(Nickname, INSTR(Nickname, ' ') + 1) " +
+ "WHERE CHAR_LENGTH(REPLACE(Nickname, ' ', '')) < CHAR_LENGTH(Nickname)"); err != nil {
+ panic("Failed to set last name from nickname " + err.Error())
+ }
+ }
}
+//func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
+
func (us SqlUserStore) CreateIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_team_id", "Users", "TeamId")
}
diff --git a/utils/config.go b/utils/config.go
index 97cb99f3e..6ad29ab7d 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -42,11 +42,6 @@ type SqlSettings struct {
AtRestEncryptKey string
}
-type RedisSettings struct {
- DataSource string
- MaxOpenConns int
-}
-
type LogSettings struct {
ConsoleEnable bool
ConsoleLevel string
@@ -113,7 +108,6 @@ type Config struct {
LogSettings LogSettings
ServiceSettings ServiceSettings
SqlSettings SqlSettings
- RedisSettings RedisSettings
AWSSettings AWSSettings
ImageSettings ImageSettings
EmailSettings EmailSettings
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index 2e430489f..30435dc08 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -153,7 +153,7 @@ module.exports = React.createClass({
if (isDirect) {
if (this.state.users.length > 1) {
var contact = this.state.users[((this.state.users[0].id === currentId) ? 1 : 0)];
- channelTitle = <UserProfile userId={contact.id} overwriteName={contact.full_name || contact.username} />;
+ channelTitle = <UserProfile userId={contact.id} overwriteName={contact.nickname || contact.username} />;
}
}
diff --git a/web/react/components/member_list_team.jsx b/web/react/components/member_list_team.jsx
index 89b5e49d5..6f1d83193 100644
--- a/web/react/components/member_list_team.jsx
+++ b/web/react/components/member_list_team.jsx
@@ -85,8 +85,8 @@ var MemberListTeamItem = React.createClass({
return (
<div className="row member-div">
<img className="post-profile-img pull-left" src={"/api/v1/users/" + user.id + "/image?time=" + timestamp} height="36" width="36" />
- <span className="member-name">{user.full_name.trim() ? user.full_name : user.username}</span>
- <span className="member-email">{user.full_name.trim() ? user.username : email}</span>
+ <span className="member-name">{utils.getDisplayName(user)}</span>
+ <span className="member-email">{email}</span>
<div className="dropdown member-drop">
<a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
<span>{currentRoles} </span>
diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx
index c5ff82346..7e939812d 100644
--- a/web/react/components/mention_list.jsx
+++ b/web/react/components/mention_list.jsx
@@ -165,14 +165,14 @@ module.exports = React.createClass({
var all = {};
all.username = "all";
- all.full_name = "";
+ all.nickname = "";
all.secondary_text = "Notifies everyone in the team";
all.id = "allmention";
users.push(all);
var channel = {};
channel.username = "channel";
- channel.full_name = "";
+ channel.nickname = "";
channel.secondary_text = "Notifies everyone in the channel";
channel.id = "channelmention";
users.push(channel);
@@ -188,21 +188,13 @@ module.exports = React.createClass({
for (var i = 0; i < users.length && index < MAX_ITEMS_IN_LIST; i++) {
if (this.alreadyMentioned(users[i].username)) continue;
- var firstName = "", lastName = "";
- if (users[i].full_name.length > 0) {
- var splitName = users[i].full_name.split(' ');
- firstName = splitName[0].toLowerCase();
- lastName = splitName.length > 1 ? splitName[splitName.length-1].toLowerCase() : "";
- users[i].secondary_text = users[i].full_name;
- }
-
- if (firstName.lastIndexOf(mentionText,0) === 0
- || lastName.lastIndexOf(mentionText,0) === 0 || users[i].username.lastIndexOf(mentionText,0) === 0) {
+ if ((users[i].first_name && users[i].first_name.lastIndexOf(mentionText,0) === 0)
+ || (users[i].last_name && users[i].last_name.lastIndexOf(mentionText,0) === 0) || users[i].username.lastIndexOf(mentionText,0) === 0) {
mentions[index] = (
<Mention
ref={'mention' + index}
username={users[i].username}
- secondary_text={users[i].secondary_text}
+ secondary_text={users[i].first_name + " " + users[i].last_name}
id={users[i].id}
listId={index}
isFocused={this.state.selectedMention === index ? "mentions-focus" : ""}
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx
index 17746655d..d6422fe3a 100644
--- a/web/react/components/post_info.jsx
+++ b/web/react/components/post_info.jsx
@@ -11,6 +11,7 @@ module.exports = React.createClass({
render: function() {
var post = this.props.post;
var isOwner = UserStore.getCurrentId() == post.user_id;
+ var isAdmin = UserStore.getCurrentUser().roles.indexOf("admin") > -1
var type = "Post"
if (post.root_id.length > 0) {
@@ -34,7 +35,7 @@ module.exports = React.createClass({
<ul className="dropdown-menu" role="menu">
{ isOwner ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#edit_post" data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Edit</a></li>
: "" }
- { isOwner ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#delete_post" data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Delete</a></li>
+ { isOwner || isAdmin ? <li role="presentation"><a href="#" role="menuitem" data-toggle="modal" data-target="#delete_post" data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={type === "Post" ? this.props.commentCount : 0}>Delete</a></li>
: "" }
{ this.props.allowReply === "true" ? <li role="presentation"><a className="reply-link theme" href="#" onClick={this.props.handleCommentClick}>Reply</a></li>
: "" }
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 573799a19..5439ca43d 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -305,7 +305,7 @@ module.exports = React.createClass({
var teammate = utils.getDirectTeammate(channel.id)
if (teammate) {
- var teammate_name = teammate.full_name.length > 0 ? teammate.full_name : teammate.username;
+ var teammate_name = teammate.nickname.length > 0 ? teammate.nickname : teammate.username;
more_messages = (
<div className="channel-intro">
<div className="post-profile-img__container channel-intro-img">
diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index ab7e99d60..f21f0cd58 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -92,7 +92,7 @@ module.exports = React.createClass({
render: function() {
return (
<div>
- <div className="sidebar__collapse" onClick={this.handleClose}></div>
+ <div className="sidebar__collapse" onClick={this.handleClose}>Cancel</div>
<span className="glyphicon glyphicon-search sidebar__search-icon"></span>
<form role="form" className="search__form relative-div" onSubmit={this.handleSubmit}>
<input
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index cae9425d3..65727c597 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -131,7 +131,7 @@ function getStateFromStores() {
var channel = ChannelStore.getByName(channelName);
if (channel != null) {
- channel.display_name = teammate.full_name.trim() != "" ? teammate.full_name : teammate.username;
+ channel.display_name = utils.getDisplayName(teammate);
channel.teammate_username = teammate.username;
channel.status = UserStore.getStatus(teammate.id);
@@ -150,7 +150,7 @@ function getStateFromStores() {
var tempChannel = {};
tempChannel.fake = true;
tempChannel.name = channelName;
- tempChannel.display_name = teammate.full_name.trim() != "" ? teammate.full_name : teammate.username;
+ tempChannel.display_name = utils.getDisplayName(teammate);
tempChannel.status = UserStore.getStatus(teammate.id);
tempChannel.last_post_at = 0;
readDirectChannels.push(tempChannel);
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index 38e4b1aea..59c97c309 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -156,6 +156,8 @@ var NotificationsTab = React.createClass({
var self = this;
+ var user = this.props.user;
+
var desktopSection;
if (this.props.activeSection === 'desktop') {
var notifyActive = [false, false, false];
@@ -314,20 +316,14 @@ var NotificationsTab = React.createClass({
var keysSection;
if (this.props.activeSection === 'keys') {
- var user = this.props.user;
- var first_name = "";
- if (user.full_name.length > 0) {
- first_name = user.full_name.split(' ')[0];
- }
-
var inputs = [];
- if (first_name != "") {
+ if (user.first_name) {
inputs.push(
<div>
<div className="checkbox">
<label>
- <input type="checkbox" checked={this.state.first_name_key} onChange={function(e){self.updateFirstNameKey(e.target.checked);}}>{'Your case sensitive first name "' + first_name + '"'}</input>
+ <input type="checkbox" checked={this.state.first_name_key} onChange={function(e){self.updateFirstNameKey(e.target.checked);}}>{'Your case sensitive first name "' + user.first_name + '"'}</input>
</label>
</div>
</div>
@@ -396,14 +392,9 @@ var NotificationsTab = React.createClass({
);
} else {
var keys = [];
- if (this.state.first_name_key) {
- var first_name = "";
- var user = this.props.user;
- if (user.full_name.length > 0) first_name = user.full_name.split(' ')[0];
- if (first_name != "") keys.push(first_name);
- }
- if (this.state.username_key) keys.push(this.props.user.username);
- if (this.state.mention_key) keys.push('@'+this.props.user.username);
+ if (this.state.first_name_key) keys.push(user.first_name);
+ if (this.state.username_key) keys.push(user.username);
+ if (this.state.mention_key) keys.push('@'+user.username);
if (this.state.all_key) keys.push('@all');
if (this.state.channel_key) keys.push('@channel');
if (this.state.custom_keys.length > 0) keys = keys.concat(this.state.custom_keys.split(','));
@@ -752,6 +743,21 @@ var GeneralTab = React.createClass({
this.submitUser(user);
},
+ submitNickname: function(e) {
+ e.preventDefault();
+
+ var user = UserStore.getCurrentUser();
+ var nickname = this.state.nickname.trim();
+
+ if (user.nickname === nickname) {
+ this.setState({client_error: "You must submit a new nickname"})
+ return;
+ }
+
+ user.nickname = nickname;
+
+ this.submitUser(user);
+ },
submitName: function(e) {
e.preventDefault();
@@ -759,14 +765,13 @@ var GeneralTab = React.createClass({
var firstName = this.state.first_name.trim();
var lastName = this.state.last_name.trim();
- var fullName = firstName + ' ' + lastName;
-
- if (user.full_name === fullName) {
- this.setState({client_error: "You must submit a new name"})
+ if (user.first_name === firstName && user.last_name === lastName) {
+ this.setState({client_error: "You must submit a new first or last name"})
return;
}
- user.full_name = fullName;
+ user.first_name = firstName;
+ user.last_name = lastName;
this.submitUser(user);
},
@@ -839,6 +844,9 @@ var GeneralTab = React.createClass({
updateLastName: function(e) {
this.setState({ last_name: e.target.value});
},
+ updateNickname: function(e) {
+ this.setState({nickname: e.target.value});
+ },
updateEmail: function(e) {
this.setState({ email: e.target.value});
},
@@ -861,11 +869,7 @@ var GeneralTab = React.createClass({
getInitialState: function() {
var user = this.props.user;
- var splitStr = user.full_name.split(' ');
- var firstName = splitStr.shift();
- var lastName = splitStr.join(' ');
-
- return { username: user.username, first_name: firstName, last_name: lastName,
+ return { username: user.username, first_name: user.first_name, last_name: user.last_name, nickname: user.nickname,
email: user.email, picture: null };
},
render: function() {
@@ -901,7 +905,7 @@ var GeneralTab = React.createClass({
nameSection = (
<SettingItemMax
- title="Name"
+ title="Full Name"
inputs={inputs}
submit={this.submitName}
server_error={server_error}
@@ -910,15 +914,58 @@ var GeneralTab = React.createClass({
/>
);
} else {
+ var full_name = "";
+
+ if (user.first_name && user.last_name) {
+ full_name = user.first_name + " " + user.last_name;
+ } else if (user.first_name) {
+ full_name = user.first_name;
+ } else if (user.last_name) {
+ full_name = user.last_name;
+ }
+
nameSection = (
<SettingItemMin
- title="Name"
- describe={UserStore.getCurrentUser().full_name}
+ title="Full Name"
+ describe={full_name}
updateSection={function(){self.updateSection("name");}}
/>
);
}
+ var nicknameSection;
+ if (this.props.activeSection === 'nickname') {
+ var inputs = [];
+
+ inputs.push(
+ <div className="form-group">
+ <label className="col-sm-5 control-label">{utils.isMobile() ? "": "Nickname"}</label>
+ <div className="col-sm-7">
+ <input className="form-control" type="text" onChange={this.updateNickname} value={this.state.nickname}/>
+ </div>
+ </div>
+ );
+
+ nicknameSection = (
+ <SettingItemMax
+ title="Nickname"
+ inputs={inputs}
+ submit={this.submitNickname}
+ server_error={server_error}
+ client_error={client_error}
+ updateSection={function(e){self.updateSection("");e.preventDefault();}}
+ />
+ );
+ } else {
+ nicknameSection = (
+ <SettingItemMin
+ title="Nickname"
+ describe={UserStore.getCurrentUser().nickname}
+ updateSection={function(){self.updateSection("nickname");}}
+ />
+ );
+ }
+
var usernameSection;
if (this.props.activeSection === 'username') {
var inputs = [];
@@ -1026,6 +1073,8 @@ var GeneralTab = React.createClass({
<div className="divider-light"/>
{usernameSection}
<div className="divider-light"/>
+ {nicknameSection}
+ <div className="divider-light"/>
{emailSection}
<div className="divider-light"/>
{pictureSection}
diff --git a/web/react/stores/user_store.jsx b/web/react/stores/user_store.jsx
index dd207ca80..b0ea719d4 100644
--- a/web/react/stores/user_store.jsx
+++ b/web/react/stores/user_store.jsx
@@ -177,21 +177,15 @@ var UserStore = assign({}, EventEmitter.prototype, {
},
getCurrentMentionKeys: function() {
var user = this.getCurrentUser();
- if (user && user.notify_props && user.notify_props.mention_keys) {
- var keys = user.notify_props.mention_keys.split(',');
- if (user.full_name.length > 0 && user.notify_props.first_name === "true") {
- var first = user.full_name.split(' ')[0];
- if (first.length > 0) keys.push(first);
- }
+ var keys = [];
- if (user.notify_props.all === "true") keys.push('@all');
- if (user.notify_props.channel === "true") keys.push('@channel');
+ if (user.notify_props && user.notify_props.mention_keys) keys = keys.concat(user.notify_props.mention_keys.split(','));
+ if (user.first_name && user.notify_props.first_name === "true") keys.push(user.first_name);
+ if (user.notify_props.all === "true") keys.push('@all');
+ if (user.notify_props.channel === "true") keys.push('@channel');
- return keys;
- } else {
- return [];
- }
+ return keys;
},
getLastVersion: function() {
return BrowserStore.getItem("last_version", '');
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 7186251e7..416ea5ae4 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -796,7 +796,6 @@ module.exports.getHomeLink = function() {
return window.location.protocol + "//" + parts.join(".");
}
-
module.exports.changeColor =function(col, amt) {
var usePound = false;
@@ -824,5 +823,30 @@ module.exports.changeColor =function(col, amt) {
else if (g < 0) g = 0;
return (usePound?"#":"") + String("000000" + (g | (b << 8) | (r << 16)).toString(16)).slice(-6);
+};
+
+module.exports.getFullName = function(user) {
+ if (user.first_name && user.last_name) {
+ return user.first_name + " " + user.last_name;
+ } else if (user.first_name) {
+ return user.first_name;
+ } else if (user.last_name) {
+ return user.last_name;
+ } else {
+ return "";
+ }
+};
+
+module.exports.getDisplayName = function(user) {
+ if (user.nickname && user.nickname.trim().length > 0) {
+ return user.nickname;
+ } else {
+ var fullName = module.exports.getFullName(user);
+ if (fullName) {
+ return fullName;
+ } else {
+ return user.username;
+ }
+ }
};
diff --git a/web/sass-files/sass/partials/_headers.scss b/web/sass-files/sass/partials/_headers.scss
index d876d8b37..c2740891a 100644
--- a/web/sass-files/sass/partials/_headers.scss
+++ b/web/sass-files/sass/partials/_headers.scss
@@ -157,6 +157,7 @@
font-size: 14px;
line-height: 50px;
#member_popover {
+ margin-right: 5px;
width: 45px;
color: #999;
cursor: pointer;
@@ -232,12 +233,16 @@
vertical-align: top;
display: inline-block;
width: 15px;
- margin: 9px 3px 3px 0;
+ margin: 9px 4px 3px 0;
&:hover {
svg {
fill: #888;
}
}
+ a {
+ height: 100%;
+ display: block;
+ }
svg {
vertical-align: top;
margin-top: 8px;
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss
index 1b0338884..f359037c5 100644
--- a/web/sass-files/sass/partials/_modal.scss
+++ b/web/sass-files/sass/partials/_modal.scss
@@ -155,7 +155,7 @@
position: relative;
max-width: 90%;
min-height: 50px;
- min-width: 280px;
+ min-width: 320px;
@include border-radius(3px);
display: table;
margin: 0 auto;
diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss
index 1f9643175..a33d69378 100644
--- a/web/sass-files/sass/partials/_responsive.scss
+++ b/web/sass-files/sass/partials/_responsive.scss
@@ -432,13 +432,16 @@
color: #fff;
.search__form {
border: none;
- padding: 0 10px 0 30px;
+ padding: 0 60px 0 25px;
.form-control {
+ line-height: 31px;
background: none;
color: #fff;
- border-bottom: 1px solid rgba(#fff, 0.7);
border-radius: 0;
- padding: 0 10px 0 23px;
+ padding: 0 10px 0;
+ @include input-placeholder {
+ color: rgba(#fff, 0.6);
+ }
}
::-webkit-input-placeholder {
color: #fff;
diff --git a/web/sass-files/sass/partials/_search.scss b/web/sass-files/sass/partials/_search.scss
index 8d51d00c0..d4a4da243 100644
--- a/web/sass-files/sass/partials/_search.scss
+++ b/web/sass-files/sass/partials/_search.scss
@@ -2,21 +2,20 @@
padding: 8px 8px 8px 0;
}
.sidebar__collapse {
- width: 20px;
- height: 30px;
+ width: auto;
+ height: auto;
position: absolute;
- top: 10px;
- left: 6px;
+ top: 17px;
+ right: 15px;
cursor: pointer;
- background: url("../images/arrow-left.png") center no-repeat;
- @include background-size(10px 15px);
z-index: 5;
display: none;
}
.sidebar__search-icon {
position: absolute;
- left: 40px;
+ left: 15px;
top: 18px;
+ font-size: 16px;
@include opacity(0.8);
display: none;
}
diff --git a/web/templates/head.html b/web/templates/head.html
index 5b423d487..d14340998 100644
--- a/web/templates/head.html
+++ b/web/templates/head.html
@@ -42,6 +42,9 @@
}
config.SiteName = '{{ .SiteName }}';
</script>
+
+ <script src="/static/js/bundle.js"></script>
+
<script>
if (config.LogglyWriteKey != null && config.LogglyWriteKey !== "") {
var _LTracker = _LTracker || [];
@@ -59,7 +62,7 @@
var user = window.UserStore.getCurrentUser(true);
if (user) {
analytics.identify(user.id, {
- name: user.full_name,
+ name: user.nickname,
email: user.email,
createdAt: user.create_at,
username: user.username,
@@ -101,7 +104,5 @@
}
</script>
<!-- Snowplow stops plowing -->
-
- <script src="/static/js/bundle.js"></script>
</head>
{{end}}
diff --git a/web/web.go b/web/web.go
index e771157d8..b11e6e6b1 100644
--- a/web/web.go
+++ b/web/web.go
@@ -303,8 +303,8 @@ func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) {
//api.Handle404(w, r)
//Bad channel urls just redirect to the town-square for now
-
- http.Redirect(w,r,"/channels/town-square", http.StatusFound)
+
+ http.Redirect(w, r, "/channels/town-square", http.StatusFound)
return
}
}
@@ -351,7 +351,7 @@ func verifyEmail(c *api.Context, w http.ResponseWriter, r *http.Request) {
return
} else {
user := result.Data.(*model.User)
- api.FireAndForgetVerifyEmail(user.Id, strings.Split(user.FullName, " ")[0], user.Email, domain, c.TeamUrl)
+ api.FireAndForgetVerifyEmail(user.Id, user.FirstName, user.Email, domain, c.TeamUrl)
http.Redirect(w, r, "/", http.StatusFound)
return
}